@zmdb/cli 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +19 -0
- package/dist/__fixtures__/http-client/src/contract.d.ts +38 -0
- package/dist/__fixtures__/http-client/src/contract.d.ts.map +1 -0
- package/dist/__fixtures__/http-client/src/contract.js +121 -0
- package/dist/__fixtures__/http-client/src/contract.js.map +1 -0
- package/dist/__fixtures__/http-client/src/models.d.ts +11 -0
- package/dist/__fixtures__/http-client/src/models.d.ts.map +1 -0
- package/dist/__fixtures__/http-client/src/models.js +2 -0
- package/dist/__fixtures__/http-client/src/models.js.map +1 -0
- package/dist/__fixtures__/http-client/src/schema.d.ts +4 -0
- package/dist/__fixtures__/http-client/src/schema.d.ts.map +1 -0
- package/dist/__fixtures__/http-client/src/schema.js +2 -0
- package/dist/__fixtures__/http-client/src/schema.js.map +1 -0
- package/dist/__fixtures__/http-client/src/unrelated.d.ts +2 -0
- package/dist/__fixtures__/http-client/src/unrelated.d.ts.map +1 -0
- package/dist/__fixtures__/http-client/src/unrelated.js +2 -0
- package/dist/__fixtures__/http-client/src/unrelated.js.map +1 -0
- package/dist/__fixtures__/http-client/zmdb.config.d.ts +16 -0
- package/dist/__fixtures__/http-client/zmdb.config.d.ts.map +1 -0
- package/dist/__fixtures__/http-client/zmdb.config.js +12 -0
- package/dist/__fixtures__/http-client/zmdb.config.js.map +1 -0
- package/dist/__fixtures__/project/src/schema.d.ts +6 -0
- package/dist/__fixtures__/project/src/schema.d.ts.map +1 -0
- package/dist/__fixtures__/project/src/schema.js +2 -0
- package/dist/__fixtures__/project/src/schema.js.map +1 -0
- package/dist/__fixtures__/project/zmdb.config.d.ts +22 -0
- package/dist/__fixtures__/project/zmdb.config.d.ts.map +1 -0
- package/dist/__fixtures__/project/zmdb.config.js +55 -0
- package/dist/__fixtures__/project/zmdb.config.js.map +1 -0
- package/dist/application-loader.d.ts +4 -0
- package/dist/application-loader.d.ts.map +1 -0
- package/dist/application-loader.js +102 -0
- package/dist/application-loader.js.map +1 -0
- package/dist/args.d.ts +23 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +353 -0
- package/dist/args.js.map +1 -0
- package/dist/atomic.d.ts +13 -0
- package/dist/atomic.d.ts.map +1 -0
- package/dist/atomic.js +28 -0
- package/dist/atomic.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +4 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/check.d.ts +5 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +7 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/client.d.ts +38 -0
- package/dist/commands/client.d.ts.map +1 -0
- package/dist/commands/client.js +347 -0
- package/dist/commands/client.js.map +1 -0
- package/dist/commands/codegen.d.ts +9 -0
- package/dist/commands/codegen.d.ts.map +1 -0
- package/dist/commands/codegen.js +56 -0
- package/dist/commands/codegen.js.map +1 -0
- package/dist/commands/embed.d.ts +8 -0
- package/dist/commands/embed.d.ts.map +1 -0
- package/dist/commands/embed.js +17 -0
- package/dist/commands/embed.js.map +1 -0
- package/dist/commands/export.d.ts +5 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +6 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/generate.d.ts +5 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +6 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/migrate.d.ts +9 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +18 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/new.d.ts +4 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +35 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/pull.d.ts +5 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +14 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +6 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +11 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/studio.d.ts +31 -0
- package/dist/commands/studio.d.ts.map +1 -0
- package/dist/commands/studio.js +154 -0
- package/dist/commands/studio.js.map +1 -0
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +11 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/database.d.ts +4 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +8 -0
- package/dist/database.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +626 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle.d.ts +6 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +75 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/migration-project.d.ts +14 -0
- package/dist/migration-project.d.ts.map +1 -0
- package/dist/migration-project.js +74 -0
- package/dist/migration-project.js.map +1 -0
- package/dist/output.d.ts +27 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +60 -0
- package/dist/output.js.map +1 -0
- package/dist/repl.d.ts +48 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/repl.js +265 -0
- package/dist/repl.js.map +1 -0
- package/dist/scaffold.d.ts +28 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +414 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/studio/index.d.ts +20 -0
- package/dist/studio/index.d.ts.map +1 -0
- package/dist/studio/index.js +607 -0
- package/dist/studio/index.js.map +1 -0
- package/dist/templates/command.d.ts +3 -0
- package/dist/templates/command.d.ts.map +1 -0
- package/dist/templates/command.js +65 -0
- package/dist/templates/command.js.map +1 -0
- package/dist/templates/controller.d.ts +3 -0
- package/dist/templates/controller.d.ts.map +1 -0
- package/dist/templates/controller.js +41 -0
- package/dist/templates/controller.js.map +1 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +18 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/module.d.ts +3 -0
- package/dist/templates/module.d.ts.map +1 -0
- package/dist/templates/module.js +41 -0
- package/dist/templates/module.js.map +1 -0
- package/dist/templates/project.d.ts +3 -0
- package/dist/templates/project.d.ts.map +1 -0
- package/dist/templates/project.js +280 -0
- package/dist/templates/project.js.map +1 -0
- package/dist/templates/repository.d.ts +3 -0
- package/dist/templates/repository.d.ts.map +1 -0
- package/dist/templates/repository.js +66 -0
- package/dist/templates/repository.js.map +1 -0
- package/dist/templates/schema.d.ts +3 -0
- package/dist/templates/schema.d.ts.map +1 -0
- package/dist/templates/schema.js +36 -0
- package/dist/templates/schema.js.map +1 -0
- package/dist/templates/types.d.ts +25 -0
- package/dist/templates/types.d.ts.map +1 -0
- package/dist/templates/types.js +17 -0
- package/dist/templates/types.js.map +1 -0
- package/package.json +72 -0
- package/src/__fixtures__/http-client/package.json +5 -0
- package/src/__fixtures__/http-client/src/contract.ts +85 -0
- package/src/__fixtures__/http-client/src/models.ts +12 -0
- package/src/__fixtures__/http-client/src/schema.ts +3 -0
- package/src/__fixtures__/http-client/src/unrelated.ts +1 -0
- package/src/__fixtures__/http-client/tsconfig.json +17 -0
- package/src/__fixtures__/http-client/zmdb.config.ts +12 -0
- package/src/__fixtures__/project/package.json +5 -0
- package/src/__fixtures__/project/src/schema.ts +6 -0
- package/src/__fixtures__/project/tsconfig.json +24 -0
- package/src/__fixtures__/project/zmdb.config.ts +57 -0
- package/src/application-loader.ts +108 -0
- package/src/args.ts +391 -0
- package/src/atomic.ts +43 -0
- package/src/bin.ts +5 -0
- package/src/commands/check.ts +11 -0
- package/src/commands/client.ts +415 -0
- package/src/commands/codegen.ts +73 -0
- package/src/commands/embed.ts +36 -0
- package/src/commands/export.ts +10 -0
- package/src/commands/generate.ts +14 -0
- package/src/commands/migrate.ts +38 -0
- package/src/commands/new.ts +48 -0
- package/src/commands/pull.ts +32 -0
- package/src/commands/push.ts +21 -0
- package/src/commands/studio.ts +200 -0
- package/src/commands/upgrade.ts +14 -0
- package/src/database.ts +9 -0
- package/src/errors.ts +19 -0
- package/src/index.ts +710 -0
- package/src/lifecycle.ts +73 -0
- package/src/migration-project.ts +91 -0
- package/src/output.ts +77 -0
- package/src/repl.ts +328 -0
- package/src/scaffold.ts +485 -0
- package/src/studio/index.ts +674 -0
- package/src/templates/command.ts +66 -0
- package/src/templates/controller.ts +42 -0
- package/src/templates/index.ts +29 -0
- package/src/templates/module.ts +42 -0
- package/src/templates/project.ts +281 -0
- package/src/templates/repository.ts +67 -0
- package/src/templates/schema.ts +37 -0
- package/src/templates/types.ts +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/templates/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,eAAO,MAAM,cAAc,EAAE,YAe5B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;AAErG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,YAAY,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const FORMAT_OPTIONS = {
|
|
2
|
+
arrowParens: 'avoid',
|
|
3
|
+
bracketSpacing: true,
|
|
4
|
+
endOfLine: 'lf',
|
|
5
|
+
insertFinalNewline: true,
|
|
6
|
+
objectWrap: 'preserve',
|
|
7
|
+
printWidth: 120,
|
|
8
|
+
quoteProps: 'as-needed',
|
|
9
|
+
semi: true,
|
|
10
|
+
singleQuote: true,
|
|
11
|
+
sortImports: true,
|
|
12
|
+
sortPackageJson: true,
|
|
13
|
+
tabWidth: 2,
|
|
14
|
+
trailingComma: 'all',
|
|
15
|
+
useTabs: false,
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/templates/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,WAAW,EAAE,OAAO;IACpB,cAAc,EAAE,IAAI;IACpB,SAAS,EAAE,IAAI;IACf,kBAAkB,EAAE,IAAI;IACxB,UAAU,EAAE,UAAU;IACtB,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,WAAW;IACvB,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,IAAI;IACjB,eAAe,EAAE,IAAI;IACrB,QAAQ,EAAE,CAAC;IACX,aAAa,EAAE,KAAK;IACpB,OAAO,EAAE,KAAK;CACf,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zmdb/cli",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "The zmdb executable and developer command APIs for schema, application and HTTP workflows.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"migrations",
|
|
8
|
+
"sql",
|
|
9
|
+
"typescript",
|
|
10
|
+
"zmdb"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/ambasta/zmdb#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/ambasta/zmdb/issues"
|
|
15
|
+
},
|
|
16
|
+
"license": "GPL-3.0-or-later",
|
|
17
|
+
"author": "zmdb contributors",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/ambasta/zmdb.git",
|
|
21
|
+
"directory": "packages/cli"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"zmdb": "./dist/bin.js"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public",
|
|
36
|
+
"tag": "beta"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "node ../../scripts/build-package.mjs",
|
|
40
|
+
"test": "vitest run"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@zmdb/compiler": "1.0.0-beta.1",
|
|
44
|
+
"@zmdb/migrations": "1.0.0-beta.1",
|
|
45
|
+
"oxfmt": "0.66.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@zmdb/app": "1.0.0-beta.1",
|
|
49
|
+
"@zmdb/orm": "1.0.0-beta.1",
|
|
50
|
+
"@zmdb/schema": "1.0.0-beta.1",
|
|
51
|
+
"@zmdb/sql": "1.0.0-beta.1",
|
|
52
|
+
"@zmdb/web": "1.0.0-beta.1",
|
|
53
|
+
"esbuild": ">=0.28.2 <0.29.0",
|
|
54
|
+
"typescript": ">=7.0.2 <8.0.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"@zmdb/app": {
|
|
58
|
+
"optional": true
|
|
59
|
+
},
|
|
60
|
+
"@zmdb/web": {
|
|
61
|
+
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"esbuild": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=26"
|
|
69
|
+
},
|
|
70
|
+
"main": "./dist/index.js",
|
|
71
|
+
"types": "./dist/index.d.ts"
|
|
72
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { defineHttpContract, httpOperation } from '@zmdb/web/contract';
|
|
2
|
+
import { Controller, Get, Public } from '@zmdb/web/routing';
|
|
3
|
+
|
|
4
|
+
import type { AcceptedAccount, Account, Health } from './models.js';
|
|
5
|
+
|
|
6
|
+
const previousLoads: unknown = Reflect.get(globalThis, '__zmdbHttpContractFixtureLoads');
|
|
7
|
+
Reflect.set(globalThis, '__zmdbHttpContractFixtureLoads', typeof previousLoads === 'number' ? previousLoads + 1 : 1);
|
|
8
|
+
|
|
9
|
+
interface GetAccountOperation {
|
|
10
|
+
readonly path: { readonly accountId: string };
|
|
11
|
+
readonly responses: {
|
|
12
|
+
readonly 200: { readonly body: Account };
|
|
13
|
+
readonly 202: { readonly body: AcceptedAccount };
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface HealthOperation {
|
|
18
|
+
readonly responses: {
|
|
19
|
+
readonly 200: { readonly body: Health };
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Controller('/accounts')
|
|
24
|
+
export class AccountsController {
|
|
25
|
+
@Get('/:accountId')
|
|
26
|
+
getAccount() {
|
|
27
|
+
return { id: 'account-1', displayName: 'Account 1' };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Public()
|
|
31
|
+
@Get('/health')
|
|
32
|
+
health() {
|
|
33
|
+
return { ok: true };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const HTTP_CONTRACT = defineHttpContract({
|
|
38
|
+
securitySchemes: {
|
|
39
|
+
bearerAuth: { type: 'http', scheme: 'bearer' },
|
|
40
|
+
},
|
|
41
|
+
operations: {
|
|
42
|
+
get_accounts_accountId: httpOperation<GetAccountOperation>({
|
|
43
|
+
controller: AccountsController,
|
|
44
|
+
handler: 'getAccount',
|
|
45
|
+
method: 'GET',
|
|
46
|
+
path: '/accounts/:accountId',
|
|
47
|
+
parameters: [{ in: 'path', property: 'accountId', name: 'accountId' }],
|
|
48
|
+
responses: {
|
|
49
|
+
200: {
|
|
50
|
+
description: 'Found',
|
|
51
|
+
body: { kind: 'json', mediaType: 'application/json' },
|
|
52
|
+
},
|
|
53
|
+
202: {
|
|
54
|
+
description: 'Accepted',
|
|
55
|
+
body: { kind: 'json', mediaType: 'application/json' },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
security: [{ bearerAuth: [] }],
|
|
59
|
+
version: { kind: 'none' },
|
|
60
|
+
deprecated: false,
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const HEALTH_CONTRACT = defineHttpContract({
|
|
66
|
+
securitySchemes: {},
|
|
67
|
+
operations: {
|
|
68
|
+
get_accounts_health: httpOperation<HealthOperation>({
|
|
69
|
+
controller: AccountsController,
|
|
70
|
+
handler: 'health',
|
|
71
|
+
method: 'GET',
|
|
72
|
+
path: '/accounts/health',
|
|
73
|
+
parameters: [],
|
|
74
|
+
responses: {
|
|
75
|
+
200: {
|
|
76
|
+
description: 'Healthy',
|
|
77
|
+
body: { kind: 'json', mediaType: 'application/json' },
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
security: [],
|
|
81
|
+
version: { kind: 'none' },
|
|
82
|
+
deprecated: false,
|
|
83
|
+
}),
|
|
84
|
+
},
|
|
85
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const unrelated = 'not part of the HTTP contract dependency set';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowImportingTsExtensions": false,
|
|
4
|
+
"exactOptionalPropertyTypes": true,
|
|
5
|
+
"isolatedModules": true,
|
|
6
|
+
"lib": ["ESNext", "DOM"],
|
|
7
|
+
"module": "NodeNext",
|
|
8
|
+
"moduleResolution": "NodeNext",
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"target": "ESNext",
|
|
13
|
+
"types": [],
|
|
14
|
+
"verbatimModuleSyntax": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*.ts"]
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { sqlite } from '@zmdb/sqlite';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
schema: './src/schema.ts',
|
|
5
|
+
dialect: sqlite,
|
|
6
|
+
project: './tsconfig.json',
|
|
7
|
+
http: {
|
|
8
|
+
contracts: './src/contract.ts#HTTP_CONTRACT',
|
|
9
|
+
openApi: { out: './generated/openapi.json' },
|
|
10
|
+
client: { out: './generated/http-client.generated.ts' },
|
|
11
|
+
},
|
|
12
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowImportingTsExtensions": false,
|
|
4
|
+
"exactOptionalPropertyTypes": true,
|
|
5
|
+
"isolatedModules": true,
|
|
6
|
+
"lib": ["ESNext"],
|
|
7
|
+
"module": "NodeNext",
|
|
8
|
+
"moduleResolution": "NodeNext",
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"paths": {
|
|
11
|
+
"@zmdb/sql": ["__ROOT__/packages/sql/src/index.ts"],
|
|
12
|
+
"@zmdb/sql/*": ["__ROOT__/packages/sql/src/*/index.ts"],
|
|
13
|
+
"@zmdb/schema": ["__ROOT__/packages/schema/src/index.ts"],
|
|
14
|
+
"@zmdb/schema/*": ["__ROOT__/packages/schema/src/*/index.ts"],
|
|
15
|
+
"zmdb/tags": ["__ROOT__/packages/zmdb/src/tags.ts"]
|
|
16
|
+
},
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"strict": true,
|
|
19
|
+
"target": "ESNext",
|
|
20
|
+
"types": [],
|
|
21
|
+
"verbatimModuleSyntax": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src/**/*.ts"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DatabaseSync, type SQLInputValue } from 'node:sqlite';
|
|
2
|
+
|
|
3
|
+
import { sqlite } from '@zmdb/sqlite';
|
|
4
|
+
|
|
5
|
+
const databasePath = process.env.ZMDB_TEST_DATABASE;
|
|
6
|
+
if (databasePath === undefined) throw new Error('ZMDB_TEST_DATABASE is required');
|
|
7
|
+
|
|
8
|
+
function sqliteValue(value: unknown): SQLInputValue {
|
|
9
|
+
if (
|
|
10
|
+
value === null ||
|
|
11
|
+
typeof value === 'number' ||
|
|
12
|
+
typeof value === 'bigint' ||
|
|
13
|
+
typeof value === 'string' ||
|
|
14
|
+
value instanceof Uint8Array
|
|
15
|
+
) {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
if (value instanceof Date) return value.toISOString();
|
|
19
|
+
throw new TypeError(`cannot bind ${typeof value} to sqlite`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
schema: 'src/**/*.ts',
|
|
24
|
+
dialect: sqlite,
|
|
25
|
+
project: './tsconfig.json',
|
|
26
|
+
out: './migrations',
|
|
27
|
+
driver: () => {
|
|
28
|
+
const database = new DatabaseSync(databasePath);
|
|
29
|
+
const driver = {
|
|
30
|
+
dialect: sqlite,
|
|
31
|
+
async execute(query: { readonly text: string; readonly parameters: readonly unknown[] }) {
|
|
32
|
+
const read = /^\s*(?:PRAGMA|SELECT|WITH)\b/i.test(query.text) || /\bRETURNING\b/i.test(query.text);
|
|
33
|
+
const parameters = query.parameters.map(sqliteValue);
|
|
34
|
+
if (!read && query.parameters.length === 0) {
|
|
35
|
+
database.exec(query.text);
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
const statement = database.prepare(query.text);
|
|
39
|
+
return read ? statement.all(...parameters) : (statement.run(...parameters), []);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
...driver,
|
|
44
|
+
async transaction<Result>(run: (transaction: typeof driver) => Promise<Result>): Promise<Result> {
|
|
45
|
+
database.exec('BEGIN');
|
|
46
|
+
try {
|
|
47
|
+
const result = await run(driver);
|
|
48
|
+
database.exec('COMMIT');
|
|
49
|
+
return result;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
database.exec('ROLLBACK');
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { registerHooks } from 'node:module';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
+
|
|
6
|
+
import type { ModuleClass } from '@zmdb/app/modules';
|
|
7
|
+
|
|
8
|
+
import { CliInvocationError } from './errors.js';
|
|
9
|
+
|
|
10
|
+
let applicationLoader: Promise<void> | undefined;
|
|
11
|
+
|
|
12
|
+
export function requireOptionalPeer(name: '@zmdb/app' | '@zmdb/web' | 'esbuild'): void {
|
|
13
|
+
try {
|
|
14
|
+
import.meta.resolve(name);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
if (error instanceof Error && 'code' in error && error.code === 'ERR_MODULE_NOT_FOUND') {
|
|
17
|
+
throw new CliInvocationError(`this command requires ${name}; install ${name}`);
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function loadRootModule(moduleSpec: string, cwd: string): Promise<ModuleClass> {
|
|
24
|
+
const hash = moduleSpec.lastIndexOf('#');
|
|
25
|
+
if (hash <= 0 || hash === moduleSpec.length - 1) {
|
|
26
|
+
throw new CliInvocationError(`module spec "${moduleSpec}" must be <path>#<export>`);
|
|
27
|
+
}
|
|
28
|
+
const namedPath = moduleSpec.slice(0, hash);
|
|
29
|
+
const exportName = moduleSpec.slice(hash + 1);
|
|
30
|
+
const file = resolve(cwd, namedPath);
|
|
31
|
+
if (!existsSync(file)) {
|
|
32
|
+
throw new CliInvocationError(`module path "${namedPath}" does not exist; cannot load export "${exportName}"`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
requireOptionalPeer('esbuild');
|
|
36
|
+
await installApplicationLoader();
|
|
37
|
+
let loaded: object;
|
|
38
|
+
try {
|
|
39
|
+
const candidate: unknown = await import(pathToFileURL(file).href);
|
|
40
|
+
if (typeof candidate !== 'object' || candidate === null) {
|
|
41
|
+
throw new Error(`module path "${namedPath}" did not load as a module record`);
|
|
42
|
+
}
|
|
43
|
+
loaded = candidate;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
throw new Error(`could not import module path "${namedPath}" for export "${exportName}": ${errorMessage(error)}`, {
|
|
46
|
+
cause: error,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const root: unknown = Reflect.get(loaded, exportName);
|
|
50
|
+
if (!isModuleClass(root)) {
|
|
51
|
+
throw new CliInvocationError(`module path "${namedPath}" has no class export "${exportName}"`);
|
|
52
|
+
}
|
|
53
|
+
return root;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Lower Stage-3 decorators while importing application TypeScript.
|
|
58
|
+
*
|
|
59
|
+
* Node 26 strips types but does not parse standard decorator syntax. The hook
|
|
60
|
+
* applies the same esbuild transform used by the repository's Vitest setup, and
|
|
61
|
+
* only after the CLI command asks to import application source.
|
|
62
|
+
*/
|
|
63
|
+
async function installApplicationLoader(): Promise<void> {
|
|
64
|
+
applicationLoader ??= import('esbuild').then(({ transformSync }) => {
|
|
65
|
+
registerHooks({
|
|
66
|
+
resolve(specifier, context, nextResolve) {
|
|
67
|
+
if (context.parentURL !== undefined && /^\.{1,2}\/.*\.js$/.test(specifier)) {
|
|
68
|
+
const asJavaScript = new URL(specifier, context.parentURL);
|
|
69
|
+
if (!existsSync(fileURLToPath(asJavaScript))) {
|
|
70
|
+
const asTypeScript = new URL(`${specifier.slice(0, -'.js'.length)}.ts`, context.parentURL);
|
|
71
|
+
if (existsSync(fileURLToPath(asTypeScript))) {
|
|
72
|
+
return { url: asTypeScript.href, shortCircuit: true };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return nextResolve(specifier, context);
|
|
77
|
+
},
|
|
78
|
+
load(url, context, nextLoad) {
|
|
79
|
+
if (!url.startsWith('file:') || !/\.[cm]?tsx?$/.test(new URL(url).pathname)) {
|
|
80
|
+
return nextLoad(url, context);
|
|
81
|
+
}
|
|
82
|
+
const file = fileURLToPath(url);
|
|
83
|
+
const transformed = transformSync(readFileSync(file, 'utf8'), {
|
|
84
|
+
loader: file.endsWith('.tsx') ? 'tsx' : 'ts',
|
|
85
|
+
format: 'esm',
|
|
86
|
+
target: 'es2022',
|
|
87
|
+
sourcefile: file,
|
|
88
|
+
sourcemap: 'inline',
|
|
89
|
+
tsconfigRaw: {
|
|
90
|
+
compilerOptions: {
|
|
91
|
+
experimentalDecorators: false,
|
|
92
|
+
useDefineForClassFields: true,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
return { format: 'module', source: transformed.code, shortCircuit: true };
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
await applicationLoader;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function errorMessage(error: unknown): string {
|
|
104
|
+
return error instanceof Error ? error.message : String(error);
|
|
105
|
+
}
|
|
106
|
+
function isModuleClass(value: unknown): value is ModuleClass {
|
|
107
|
+
return typeof value === 'function';
|
|
108
|
+
}
|