Compare commits
17 Commits
6f2ca2c15d
...
hydrators-
| Author | SHA1 | Date | |
|---|---|---|---|
| 09d85c8f22 | |||
| a0ce5183b2 | |||
| c83202b681 | |||
| 2c1d297be1 | |||
| 2d697c1e61 | |||
| 410bb671f1 | |||
| 0ae197f939 | |||
| 370bea5d98 | |||
| 9d34768051 | |||
| b752eb5080 | |||
| 1ed5aa4b33 | |||
| 4d1c30b874 | |||
| 02edf259f0 | |||
| db1f2151de | |||
| 6e669d025a | |||
| a1dbf71de4 | |||
| 0afc3efa5d |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
framework/downloads
|
diachron/downloads
|
||||||
framework/binaries
|
diachron/binaries
|
||||||
framework/.nodejs
|
diachron/.nodejs
|
||||||
framework/.nodejs-config
|
diachron/.nodejs-config
|
||||||
|
|||||||
10
CLAUDE.md
10
CLAUDE.md
@@ -38,7 +38,7 @@ master process. Key design principles:
|
|||||||
|
|
||||||
**Format TypeScript code:**
|
**Format TypeScript code:**
|
||||||
```bash
|
```bash
|
||||||
cd express && ../cmd pnpm biome check --write .
|
cd backend && ../cmd pnpm biome check --write .
|
||||||
```
|
```
|
||||||
|
|
||||||
**Build Go master process:**
|
**Build Go master process:**
|
||||||
@@ -54,9 +54,9 @@ cd master && go build
|
|||||||
|
|
||||||
### Components
|
### Components
|
||||||
|
|
||||||
- **express/** - TypeScript/Express.js backend application
|
- **backend/** - TypeScript/Express.js backend application
|
||||||
- **master/** - Go-based master process for file watching and process management
|
- **master/** - Go-based master process for file watching and process management
|
||||||
- **framework/** - Managed binaries (Node.js, pnpm), command wrappers, and
|
- **diachron/** - Managed binaries (Node.js, pnpm), command wrappers, and
|
||||||
framework-specific library code
|
framework-specific library code
|
||||||
- **monitor/** - Go file watcher that triggers rebuilds (experimental)
|
- **monitor/** - Go file watcher that triggers rebuilds (experimental)
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ Responsibilities:
|
|||||||
- Proxy web requests to backend workers
|
- Proxy web requests to backend workers
|
||||||
- Behaves identically in all environments (no dev/prod distinction)
|
- Behaves identically in all environments (no dev/prod distinction)
|
||||||
|
|
||||||
### Express App Structure
|
### Backend App Structure
|
||||||
|
|
||||||
- `app.ts` - Main Express application setup with route matching
|
- `app.ts` - Main Express application setup with route matching
|
||||||
- `routes.ts` - Route definitions
|
- `routes.ts` - Route definitions
|
||||||
@@ -78,7 +78,7 @@ Responsibilities:
|
|||||||
|
|
||||||
### Framework Command System
|
### Framework Command System
|
||||||
|
|
||||||
Commands flow through: `./cmd` → `framework/cmd.d/*` → `framework/shims/*` → managed binaries in `framework/binaries/`
|
Commands flow through: `./cmd` → `diachron/cmd.d/*` → `diachron/shims/*` → managed binaries in `diachron/binaries/`
|
||||||
|
|
||||||
This ensures consistent tooling versions across the team without system-wide installations.
|
This ensures consistent tooling versions across the team without system-wide installations.
|
||||||
|
|
||||||
|
|||||||
0
express/.gitignore → backend/.gitignore
vendored
0
express/.gitignore → backend/.gitignore
vendored
@@ -3,15 +3,13 @@ import express, {
|
|||||||
type Response as ExpressResponse,
|
type Response as ExpressResponse,
|
||||||
} from "express";
|
} from "express";
|
||||||
import { match } from "path-to-regexp";
|
import { match } from "path-to-regexp";
|
||||||
import { Session } from "./auth";
|
import { Session } from "./diachron/auth";
|
||||||
import { cli } from "./cli";
|
import { cli } from "./diachron/cli";
|
||||||
import { contentTypes } from "./content-types";
|
import { contentTypes } from "./diachron/content-types";
|
||||||
import { runWithContext } from "./context";
|
import { runWithContext } from "./diachron/context";
|
||||||
import { core } from "./core";
|
import { core } from "./diachron/core";
|
||||||
import { httpCodes } from "./http-codes";
|
import { httpCodes } from "./diachron/http-codes";
|
||||||
import { request } from "./request";
|
import { request } from "./diachron/request";
|
||||||
import { routes } from "./routes";
|
|
||||||
|
|
||||||
// import { URLPattern } from 'node:url';
|
// import { URLPattern } from 'node:url';
|
||||||
import {
|
import {
|
||||||
AuthenticationRequired,
|
AuthenticationRequired,
|
||||||
@@ -25,7 +23,8 @@ import {
|
|||||||
type ProcessedRoute,
|
type ProcessedRoute,
|
||||||
type Result,
|
type Result,
|
||||||
type Route,
|
type Route,
|
||||||
} from "./types";
|
} from "./diachron/types";
|
||||||
|
import { routes } from "./routes";
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ check_dir="$DIR"
|
|||||||
|
|
||||||
out_dir="$check_dir/out"
|
out_dir="$check_dir/out"
|
||||||
|
|
||||||
source "$check_dir"/../framework/shims/common
|
source "$check_dir"/../diachron/shims/common
|
||||||
source "$check_dir"/../framework/shims/node.common
|
source "$check_dir"/../diachron/shims/node.common
|
||||||
|
|
||||||
$ROOT/cmd pnpm tsc --outDir "$out_dir"
|
$ROOT/cmd pnpm tsc --outDir "$out_dir"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { DateTime } from "ts-luxon";
|
import { DateTime } from "ts-luxon";
|
||||||
import { get, User } from "../framework/hydrators/user";
|
import { get, User } from "../hydrators/user";
|
||||||
import { request } from "../request";
|
import { request } from "../request";
|
||||||
import { html, render } from "../request/util";
|
import { html, render } from "../request/util";
|
||||||
import type { Call, Result, Route } from "../types";
|
import type { Call, Result, Route } from "../types";
|
||||||
@@ -113,7 +113,7 @@ async function raw<T = unknown>(
|
|||||||
//
|
//
|
||||||
// Migrations directory: express/migrations/
|
// Migrations directory: express/migrations/
|
||||||
|
|
||||||
const FRAMEWORK_MIGRATIONS_DIR = path.join(__dirname, "framework/migrations");
|
const FRAMEWORK_MIGRATIONS_DIR = path.join(__dirname, "diachron/migrations");
|
||||||
const APP_MIGRATIONS_DIR = path.join(__dirname, "migrations");
|
const APP_MIGRATIONS_DIR = path.join(__dirname, "migrations");
|
||||||
const MIGRATIONS_TABLE = "_migrations";
|
const MIGRATIONS_TABLE = "_migrations";
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Kysely, PostgresDialect } from "kysely";
|
import { Kysely, PostgresDialect } from "kysely";
|
||||||
import { Pool } from "pg";
|
import { Pool } from "pg";
|
||||||
import { connectionConfig } from "../../database";
|
|
||||||
import type { DB } from "../../generated/db";
|
import type { DB } from "../../generated/db";
|
||||||
|
import { connectionConfig } from "../database";
|
||||||
|
|
||||||
const db = new Kysely<DB>({
|
const db = new Kysely<DB>({
|
||||||
dialect: new PostgresDialect({
|
dialect: new PostgresDialect({
|
||||||
1
backend/diachron/hydrators/index.ts
Normal file
1
backend/diachron/hydrators/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export type Hydrators = {};
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// Run: DB_PORT=5433 DB_USER=diachron_test DB_PASSWORD=diachron_test DB_NAME=diachron_test npx tsx --test tests/*.test.ts
|
// Run: DB_PORT=5433 DB_USER=diachron_test DB_PASSWORD=diachron_test DB_NAME=diachron_test npx tsx --test tests/*.test.ts
|
||||||
|
|
||||||
import { Pool } from "pg";
|
import { Pool } from "pg";
|
||||||
import { connectionConfig, migrate } from "../../../database";
|
import { connectionConfig, migrate } from "../../database";
|
||||||
|
|
||||||
const pool = new Pool(connectionConfig);
|
const pool = new Pool(connectionConfig);
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// Tests for user hydrator
|
// Tests for user hydrator
|
||||||
// Run with: cd express && DB_PORT=5433 DB_USER=diachron_test DB_PASSWORD=diachron_test DB_NAME=diachron_test ../cmd npx tsx --test framework/hydrators/tests/user.test.ts
|
// Run with: cd express && DB_PORT=5433 DB_USER=diachron_test DB_PASSWORD=diachron_test DB_NAME=diachron_test ../cmd npx tsx --test diachron/hydrators/tests/user.test.ts
|
||||||
|
|
||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import { after, before, beforeEach, describe, it } from "node:test";
|
import { after, before, beforeEach, describe, it } from "node:test";
|
||||||
59
backend/diachron/hydrators/user.ts
Normal file
59
backend/diachron/hydrators/user.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
ColumnType,
|
||||||
|
Generated,
|
||||||
|
Insertable,
|
||||||
|
JSONColumnType,
|
||||||
|
Selectable,
|
||||||
|
Updateable,
|
||||||
|
} from "kysely";
|
||||||
|
import type { TypeID } from "typeid-js";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { db, Hydrator } from "./hydrator";
|
||||||
|
|
||||||
|
const parser = z.object({
|
||||||
|
// id: z.uuidv7(),
|
||||||
|
id: z.uuid(),
|
||||||
|
display_name: z.string(),
|
||||||
|
// FIXME: status is duplicated elsewhere
|
||||||
|
status: z.union([
|
||||||
|
z.literal("active"),
|
||||||
|
z.literal("suspended"),
|
||||||
|
z.literal("pending"),
|
||||||
|
]),
|
||||||
|
email: z.email(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const tp = parser.parse({
|
||||||
|
id: "cfae0a19-6515-4813-bc2d-1e032b72b203",
|
||||||
|
display_name: "foo",
|
||||||
|
status: "active",
|
||||||
|
email: "mw@philologue.net",
|
||||||
|
});
|
||||||
|
|
||||||
|
export type User = z.infer<typeof parser>;
|
||||||
|
|
||||||
|
const get = async (id: string): Promise<null | User> => {
|
||||||
|
const ret = await db
|
||||||
|
.selectFrom("users")
|
||||||
|
.where("users.id", "=", id)
|
||||||
|
.innerJoin("user_emails", "user_emails.user_id", "users.id")
|
||||||
|
.select([
|
||||||
|
"users.id",
|
||||||
|
"users.status",
|
||||||
|
"users.display_name",
|
||||||
|
"user_emails.email",
|
||||||
|
])
|
||||||
|
.executeTakeFirst();
|
||||||
|
|
||||||
|
if (ret === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.dir(ret);
|
||||||
|
|
||||||
|
const parsed = parser.parse(ret);
|
||||||
|
|
||||||
|
return parsed;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { get };
|
||||||
109
backend/generated/db.d.ts
vendored
Normal file
109
backend/generated/db.d.ts
vendored
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* This file was generated by kysely-codegen.
|
||||||
|
* Please do not edit it manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { ColumnType } from "kysely";
|
||||||
|
|
||||||
|
export type Generated<T> =
|
||||||
|
T extends ColumnType<infer S, infer I, infer U>
|
||||||
|
? ColumnType<S, I | undefined, U>
|
||||||
|
: ColumnType<T, T | undefined, T>;
|
||||||
|
|
||||||
|
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
||||||
|
|
||||||
|
export interface _Migrations {
|
||||||
|
applied_at: Generated<Timestamp>;
|
||||||
|
id: Generated<number>;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Capabilities {
|
||||||
|
description: string | null;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Groups {
|
||||||
|
created_at: Generated<Timestamp>;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoleCapabilities {
|
||||||
|
capability_id: string;
|
||||||
|
granted_at: Generated<Timestamp>;
|
||||||
|
revoked_at: Timestamp | null;
|
||||||
|
role_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Roles {
|
||||||
|
description: string | null;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Sessions {
|
||||||
|
auth_method: string;
|
||||||
|
created_at: Generated<Timestamp>;
|
||||||
|
expires_at: Timestamp;
|
||||||
|
id: Generated<string>;
|
||||||
|
ip_address: string | null;
|
||||||
|
is_used: Generated<boolean | null>;
|
||||||
|
revoked_at: Timestamp | null;
|
||||||
|
token_hash: string;
|
||||||
|
token_type: string;
|
||||||
|
user_agent: string | null;
|
||||||
|
user_email_id: string | null;
|
||||||
|
user_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserCredentials {
|
||||||
|
created_at: Generated<Timestamp>;
|
||||||
|
credential_type: Generated<string>;
|
||||||
|
id: string;
|
||||||
|
password_hash: string | null;
|
||||||
|
updated_at: Generated<Timestamp>;
|
||||||
|
user_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserEmails {
|
||||||
|
created_at: Generated<Timestamp>;
|
||||||
|
email: string;
|
||||||
|
id: string;
|
||||||
|
is_primary: Generated<boolean>;
|
||||||
|
is_verified: Generated<boolean>;
|
||||||
|
normalized_email: string;
|
||||||
|
revoked_at: Timestamp | null;
|
||||||
|
user_id: string;
|
||||||
|
verified_at: Timestamp | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserGroupRoles {
|
||||||
|
granted_at: Generated<Timestamp>;
|
||||||
|
group_id: string;
|
||||||
|
revoked_at: Timestamp | null;
|
||||||
|
role_id: string;
|
||||||
|
user_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Users {
|
||||||
|
created_at: Generated<Timestamp>;
|
||||||
|
display_name: string | null;
|
||||||
|
id: string;
|
||||||
|
status: Generated<string>;
|
||||||
|
updated_at: Generated<Timestamp>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DB {
|
||||||
|
_migrations: _Migrations;
|
||||||
|
capabilities: Capabilities;
|
||||||
|
groups: Groups;
|
||||||
|
role_capabilities: RoleCapabilities;
|
||||||
|
roles: Roles;
|
||||||
|
sessions: Sessions;
|
||||||
|
user_credentials: UserCredentials;
|
||||||
|
user_emails: UserEmails;
|
||||||
|
user_group_roles: UserGroupRoles;
|
||||||
|
users: Users;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
CREATE TABLE test_application_table ();
|
||||||
1
backend/migrations/2026-01-15_01.sql
Normal file
1
backend/migrations/2026-01-15_01.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CREATE TABLE test_application_table ();
|
||||||
20
backend/package.json
Normal file
20
backend/package.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "my app",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "DB_PORT=5433 DB_USER=diachron_test DB_PASSWORD=diachron_test DB_NAME=diachron_test tsx --test '**/*.{test,spec}.ts'",
|
||||||
|
"test:watch": "DB_PORT=5433 DB_USER=diachron_test DB_PASSWORD=diachron_test DB_NAME=diachron_test tsx --test --watch '**/*.{test,spec}.ts'",
|
||||||
|
"nodemon": "nodemon dist/index.js",
|
||||||
|
"kysely-codegen": "kysely-codegen"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"packageManager": "pnpm@10.12.4",
|
||||||
|
"dependencies": {
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
}
|
||||||
|
}
|
||||||
2
backend/pnpm-workspace.yaml
Normal file
2
backend/pnpm-workspace.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
- 'diachron'
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
import nunjucks from "nunjucks";
|
import nunjucks from "nunjucks";
|
||||||
import { DateTime } from "ts-luxon";
|
import { DateTime } from "ts-luxon";
|
||||||
import { authRoutes } from "./auth/routes";
|
import { authRoutes } from "./diachron/auth/routes";
|
||||||
import { routes as basicRoutes } from "./basic/routes";
|
import { routes as basicRoutes } from "./diachron/basic/routes";
|
||||||
import { contentTypes } from "./content-types";
|
import { contentTypes } from "./diachron/content-types";
|
||||||
import { core } from "./core";
|
import { core } from "./diachron/core";
|
||||||
import { multiHandler } from "./handlers";
|
import { multiHandler } from "./diachron/handlers";
|
||||||
import { httpCodes } from "./http-codes";
|
import { httpCodes } from "./diachron/http-codes";
|
||||||
import type { Call, Result, Route } from "./types";
|
import type { Call, Result, Route } from "./diachron/types";
|
||||||
|
|
||||||
// FIXME: Obviously put this somewhere else
|
// FIXME: Obviously put this somewhere else
|
||||||
const okText = (result: string): Result => {
|
const okText = (result: string): Result => {
|
||||||
@@ -6,7 +6,7 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
|
|
||||||
check_dir="$DIR"
|
check_dir="$DIR"
|
||||||
|
|
||||||
source "$check_dir"/../framework/shims/common
|
source "$check_dir"/../diachron/shims/common
|
||||||
source "$check_dir"/../framework/shims/node.common
|
source "$check_dir"/../diachron/shims/node.common
|
||||||
|
|
||||||
$ROOT/cmd pnpm tsc --showConfig
|
$ROOT/cmd pnpm tsc --showConfig
|
||||||
@@ -9,5 +9,6 @@
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
"types": ["node"],
|
"types": ["node"],
|
||||||
"outDir": "out"
|
"outDir": "out"
|
||||||
}
|
},
|
||||||
|
"exclude": ["**/*.spec.ts", "**/*.test.ts"]
|
||||||
}
|
}
|
||||||
@@ -6,8 +6,8 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
|
|
||||||
check_dir="$DIR"
|
check_dir="$DIR"
|
||||||
|
|
||||||
source "$check_dir"/../framework/shims/common
|
source "$check_dir"/../diachron/shims/common
|
||||||
source "$check_dir"/../framework/shims/node.common
|
source "$check_dir"/../diachron/shims/node.common
|
||||||
|
|
||||||
# $ROOT/cmd pnpm tsc --lib ES2023 --esModuleInterop -w $check_dir/app.ts
|
# $ROOT/cmd pnpm tsc --lib ES2023 --esModuleInterop -w $check_dir/app.ts
|
||||||
# $ROOT/cmd pnpm tsc -w $check_dir/app.ts
|
# $ROOT/cmd pnpm tsc -w $check_dir/app.ts
|
||||||
6
check.sh
6
check.sh
@@ -10,7 +10,7 @@ cd "$DIR"
|
|||||||
#
|
#
|
||||||
exclusions="SC2002"
|
exclusions="SC2002"
|
||||||
|
|
||||||
source "$DIR/framework/versions"
|
source "$DIR/diachron/versions"
|
||||||
|
|
||||||
if [[ $# -ne 0 ]]; then
|
if [[ $# -ne 0 ]]; then
|
||||||
shellcheck --exclude="$exclusions" "$@"
|
shellcheck --exclude="$exclusions" "$@"
|
||||||
@@ -20,10 +20,10 @@ fi
|
|||||||
shell_scripts="$(fd .sh | xargs)"
|
shell_scripts="$(fd .sh | xargs)"
|
||||||
|
|
||||||
# The files we need to check all either end in .sh or else they're the files
|
# The files we need to check all either end in .sh or else they're the files
|
||||||
# in framework/cmd.d and framework/shims. -x instructs shellcheck to also
|
# in diachron/cmd.d and diachron/shims. -x instructs shellcheck to also
|
||||||
# check `source`d files.
|
# check `source`d files.
|
||||||
|
|
||||||
shellcheck -x --exclude="$exclusions" "$DIR/cmd" "$DIR"/framework/cmd.d/* "$DIR"/framework/shims/* "$shell_scripts"
|
shellcheck -x --exclude="$exclusions" "$DIR/cmd" "$DIR"/diachron/cmd.d/* "$DIR"/diachron/shims/* "$shell_scripts"
|
||||||
|
|
||||||
pushd "$DIR/master"
|
pushd "$DIR/master"
|
||||||
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:$golangci_lint golangci-lint run
|
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:$golangci_lint golangci-lint run
|
||||||
|
|||||||
4
cmd
4
cmd
@@ -13,7 +13,7 @@ if [ $# -lt 1 ]; then
|
|||||||
echo "Usage: ./cmd <command> [args...]"
|
echo "Usage: ./cmd <command> [args...]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Available commands:"
|
echo "Available commands:"
|
||||||
for cmd in "$DIR"/framework/cmd.d/*; do
|
for cmd in "$DIR"/diachron/cmd.d/*; do
|
||||||
if [ -x "$cmd" ]; then
|
if [ -x "$cmd" ]; then
|
||||||
basename "$cmd"
|
basename "$cmd"
|
||||||
fi
|
fi
|
||||||
@@ -24,4 +24,4 @@ fi
|
|||||||
subcmd="$1"
|
subcmd="$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
exec "$DIR"/framework/cmd.d/"$subcmd" "$@"
|
exec "$DIR"/diachron/cmd.d/"$subcmd" "$@"
|
||||||
|
|||||||
4
develop
4
develop
@@ -13,7 +13,7 @@ if [ $# -lt 1 ]; then
|
|||||||
echo "Usage: ./develop <command> [args...]"
|
echo "Usage: ./develop <command> [args...]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Available commands:"
|
echo "Available commands:"
|
||||||
for cmd in "$DIR"/framework/develop.d/*; do
|
for cmd in "$DIR"/diachron/develop.d/*; do
|
||||||
if [ -x "$cmd" ]; then
|
if [ -x "$cmd" ]; then
|
||||||
basename "$cmd"
|
basename "$cmd"
|
||||||
fi
|
fi
|
||||||
@@ -24,4 +24,4 @@ fi
|
|||||||
subcmd="$1"
|
subcmd="$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
exec "$DIR"/framework/develop.d/"$subcmd" "$@"
|
exec "$DIR"/diachron/develop.d/"$subcmd" "$@"
|
||||||
|
|||||||
0
diachron/.nodejs/.gitignore
vendored
Normal file
0
diachron/.nodejs/.gitignore
vendored
Normal file
0
diachron/binaries/.gitignore
vendored
Normal file
0
diachron/binaries/.gitignore
vendored
Normal file
15
diachron/cmd.d/test
Executable file
15
diachron/cmd.d/test
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
cd "$DIR/../../backend"
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
# Find all test files - use -print0/xargs to handle filenames safely
|
||||||
|
find . -type f \( -name '*.spec.ts' -o -name '*.test.ts' \) -print0 |
|
||||||
|
xargs -0 "$DIR"/../shims/pnpm tsx --test
|
||||||
|
else
|
||||||
|
"$DIR"/../shims/pnpm tsx --test "$@"
|
||||||
|
fi
|
||||||
@@ -5,5 +5,5 @@ set -eu
|
|||||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
ROOT="$DIR/../.."
|
ROOT="$DIR/../.."
|
||||||
|
|
||||||
cd "$ROOT/express"
|
cd "$ROOT/backend"
|
||||||
"$DIR"/tsx migrate.ts "$@"
|
"$DIR"/tsx migrate.ts "$@"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user