@arki/dot 0.2.0 → 0.4.0
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/README.md +86 -86
- package/dist/cli/discover.js +2 -2
- package/dist/cli/discover.js.map +1 -1
- package/dist/cli/error-codes.d.ts +8 -0
- package/dist/cli/error-codes.d.ts.map +1 -1
- package/dist/cli/error-codes.js +12 -0
- package/dist/cli/error-codes.js.map +1 -1
- package/dist/cli/index.d.ts +11 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +66 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/new.d.ts +1 -1
- package/dist/cli/new.js +1 -1
- package/dist/cli/render-doctor.d.ts +1 -1
- package/dist/cli/render-doctor.js +23 -23
- package/dist/cli/render-doctor.js.map +1 -1
- package/dist/cli/render-explain.d.ts.map +1 -1
- package/dist/cli/render-explain.js +33 -19
- package/dist/cli/render-explain.js.map +1 -1
- package/dist/cli/render-graph.d.ts +3 -3
- package/dist/cli/render-graph.js +12 -12
- package/dist/cli/render-graph.js.map +1 -1
- package/dist/cli/render-openapi.d.ts +38 -0
- package/dist/cli/render-openapi.d.ts.map +1 -0
- package/dist/cli/render-openapi.js +131 -0
- package/dist/cli/render-openapi.js.map +1 -0
- package/dist/cli/render-projection.d.ts +29 -0
- package/dist/cli/render-projection.d.ts.map +1 -0
- package/dist/cli/render-projection.js +202 -0
- package/dist/cli/render-projection.js.map +1 -0
- package/dist/define-app.d.ts +49 -17
- package/dist/define-app.d.ts.map +1 -1
- package/dist/define-app.js +16 -9
- package/dist/define-app.js.map +1 -1
- package/dist/diagnostics.d.ts +19 -15
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +2 -2
- package/dist/index.d.ts +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/init-pips.d.ts +45 -0
- package/dist/init-pips.d.ts.map +1 -0
- package/dist/init-pips.js +49 -0
- package/dist/init-pips.js.map +1 -0
- package/dist/init-plugins.d.ts +45 -0
- package/dist/init-plugins.d.ts.map +1 -0
- package/dist/init-plugins.js +49 -0
- package/dist/init-plugins.js.map +1 -0
- package/dist/kernel/app-instance.d.ts +5 -5
- package/dist/kernel/app-instance.d.ts.map +1 -1
- package/dist/kernel/app-instance.js +375 -244
- package/dist/kernel/app-instance.js.map +1 -1
- package/dist/kernel/otel.d.ts +19 -19
- package/dist/kernel/otel.d.ts.map +1 -1
- package/dist/kernel/otel.js +22 -22
- package/dist/kernel/otel.js.map +1 -1
- package/dist/lifecycle-observer.d.ts +10 -10
- package/dist/lifecycle-observer.d.ts.map +1 -1
- package/dist/lifecycle-observer.js +1 -1
- package/dist/lifecycle.d.ts +18 -14
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +13 -9
- package/dist/lifecycle.js.map +1 -1
- package/dist/manifest.d.ts +70 -29
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +74 -5
- package/dist/manifest.js.map +1 -1
- package/dist/pip-contract.d.ts +40 -10
- package/dist/pip-contract.d.ts.map +1 -1
- package/dist/pip-contract.js +1 -25
- package/dist/pip-contract.js.map +1 -1
- package/dist/pip.d.ts +7 -4
- package/dist/pip.d.ts.map +1 -1
- package/dist/pip.js +2 -0
- package/dist/pip.js.map +1 -1
- package/dist/plugin-contract.d.ts +335 -143
- package/dist/plugin-contract.d.ts.map +1 -1
- package/dist/plugin-contract.js +201 -36
- package/dist/plugin-contract.js.map +1 -1
- package/dist/plugin.d.ts +18 -15
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +11 -11
- package/dist/plugin.js.map +1 -1
- package/dist/test-harness.d.ts +31 -31
- package/dist/test-harness.d.ts.map +1 -1
- package/dist/test-harness.js +29 -28
- package/dist/test-harness.js.map +1 -1
- package/dist/timeline.d.ts +2 -2
- package/dist/timeline.js +5 -5
- package/dist/timeline.js.map +1 -1
- package/package.json +9 -9
- package/src/cli/discover.ts +2 -2
- package/src/cli/error-codes.ts +12 -0
- package/src/cli/index.ts +93 -15
- package/src/cli/new.ts +1 -1
- package/src/cli/render-doctor.ts +21 -21
- package/src/cli/render-explain.ts +37 -19
- package/src/cli/render-graph.ts +12 -12
- package/src/cli/render-projection.ts +239 -0
- package/src/define-app.ts +85 -22
- package/src/diagnostics.ts +19 -15
- package/src/index.ts +38 -20
- package/src/init-plugins.ts +142 -0
- package/src/kernel/app-instance.ts +428 -282
- package/src/kernel/otel.ts +27 -27
- package/src/lifecycle-observer.ts +10 -10
- package/src/lifecycle.ts +19 -15
- package/src/manifest.ts +128 -31
- package/src/{pip-contract.ts → plugin-contract.ts} +83 -44
- package/src/{pip.ts → plugin.ts} +38 -18
- package/src/test-harness.ts +52 -51
- package/src/timeline.ts +6 -6
- package/templates/app-minimal/AGENTS.md.tmpl +9 -9
- package/templates/app-minimal/README.md.tmpl +1 -1
- package/templates/app-minimal/tests/boot.test.ts.tmpl +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer for `dot explain --openapi`.
|
|
3
|
+
*
|
|
4
|
+
* Emits an OpenAPI 3.1 document straight from `manifest.routes` — no boot
|
|
5
|
+
* required. Adapters (e.g. `@arki/http`'s `registerRoutes`) convert their
|
|
6
|
+
* validation schemas to JSON Schema at `configure` time and register them
|
|
7
|
+
* via `ctx.registerRoute`, so the manifest already carries everything the
|
|
8
|
+
* document needs: methods, paths, per-location input schemas, output
|
|
9
|
+
* schemas, and the `streaming` flag for `text/event-stream` responses.
|
|
10
|
+
*
|
|
11
|
+
* Deterministic: paths and operations follow manifest registration order
|
|
12
|
+
* (which follows pip declaration order). Only `transport: 'http'` routes
|
|
13
|
+
* are rendered — rpc mounts have their own schema story.
|
|
14
|
+
*/
|
|
15
|
+
import type { DotAppManifest } from '../manifest.js';
|
|
16
|
+
import type { DotCliEnvelope, RenderOptions } from './render-explain.js';
|
|
17
|
+
/** Envelope payload for OpenAPI output. */
|
|
18
|
+
export type OpenApiData = {
|
|
19
|
+
format: 'openapi';
|
|
20
|
+
/** OpenAPI 3.1 document. */
|
|
21
|
+
document: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Build an OpenAPI 3.1 document from a manifest. First registration wins
|
|
25
|
+
* on a method+path collision — collisions are an app bug the serving
|
|
26
|
+
* adapter rejects at boot; the document renderer stays total.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildOpenApiDocument(manifest: DotAppManifest): Record<string, unknown>;
|
|
29
|
+
/**
|
|
30
|
+
* Render the OpenAPI output. Plain mode prints the document as JSON
|
|
31
|
+
* (pipe it into a file or a swagger viewer); `--json` wraps it in the
|
|
32
|
+
* standard CLI envelope under `data.document`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function renderOpenApi(source: {
|
|
35
|
+
manifest: DotAppManifest;
|
|
36
|
+
command: 'explain';
|
|
37
|
+
}, opts: RenderOptions): DotCliEnvelope<OpenApiData>;
|
|
38
|
+
//# sourceMappingURL=render-openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-openapi.d.ts","sourceRoot":"","sources":["../../src/cli/render-openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzE,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,SAAS,CAAC;IAClB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AAmEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmBtF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,SAAS,CAAA;CAAE,EACxD,IAAI,EAAE,aAAa,GAClB,cAAc,CAAC,WAAW,CAAC,CAsB7B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer for `dot explain --openapi`.
|
|
3
|
+
*
|
|
4
|
+
* Emits an OpenAPI 3.1 document straight from `manifest.routes` — no boot
|
|
5
|
+
* required. Adapters (e.g. `@arki/http`'s `registerRoutes`) convert their
|
|
6
|
+
* validation schemas to JSON Schema at `configure` time and register them
|
|
7
|
+
* via `ctx.registerRoute`, so the manifest already carries everything the
|
|
8
|
+
* document needs: methods, paths, per-location input schemas, output
|
|
9
|
+
* schemas, and the `streaming` flag for `text/event-stream` responses.
|
|
10
|
+
*
|
|
11
|
+
* Deterministic: paths and operations follow manifest registration order
|
|
12
|
+
* (which follows pip declaration order). Only `transport: 'http'` routes
|
|
13
|
+
* are rendered — rpc mounts have their own schema story.
|
|
14
|
+
*/
|
|
15
|
+
function openApiPath(path) {
|
|
16
|
+
return path.replaceAll(/:(\w+)/g, '{$1}');
|
|
17
|
+
}
|
|
18
|
+
function pathParamNames(path) {
|
|
19
|
+
return [...path.matchAll(/:(\w+)/g)]
|
|
20
|
+
.map(match => match[1])
|
|
21
|
+
.filter((name) => name !== undefined);
|
|
22
|
+
}
|
|
23
|
+
function buildOperation(route) {
|
|
24
|
+
const parameters = pathParamNames(route.path ?? '').map(name => ({
|
|
25
|
+
name,
|
|
26
|
+
in: 'path',
|
|
27
|
+
required: true,
|
|
28
|
+
schema: { type: 'string' },
|
|
29
|
+
}));
|
|
30
|
+
const querySchema = route.input?.query;
|
|
31
|
+
if (querySchema !== undefined) {
|
|
32
|
+
const properties = (querySchema['properties'] ?? {});
|
|
33
|
+
const required = new Set(querySchema['required']);
|
|
34
|
+
for (const [name, propertySchema] of Object.entries(properties)) {
|
|
35
|
+
parameters.push({ name, in: 'query', required: required.has(name), schema: propertySchema });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const operation = {
|
|
39
|
+
operationId: route.id,
|
|
40
|
+
tags: [route.pip],
|
|
41
|
+
};
|
|
42
|
+
if (route.description !== undefined)
|
|
43
|
+
operation['summary'] = route.description;
|
|
44
|
+
if (parameters.length > 0)
|
|
45
|
+
operation['parameters'] = parameters;
|
|
46
|
+
const bodySchema = route.input?.body;
|
|
47
|
+
if (bodySchema !== undefined) {
|
|
48
|
+
operation['requestBody'] = {
|
|
49
|
+
required: true,
|
|
50
|
+
content: { 'application/json': { schema: bodySchema } },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (route.streaming === true) {
|
|
54
|
+
operation['responses'] = {
|
|
55
|
+
'200': {
|
|
56
|
+
description: 'event stream',
|
|
57
|
+
content: {
|
|
58
|
+
'text/event-stream': route.output === undefined ? {} : { schema: route.output },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
else if (route.output === undefined) {
|
|
64
|
+
operation['responses'] = { '200': { description: 'success' } };
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
operation['responses'] = {
|
|
68
|
+
'200': {
|
|
69
|
+
description: 'success',
|
|
70
|
+
content: { 'application/json': { schema: route.output } },
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return operation;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build an OpenAPI 3.1 document from a manifest. First registration wins
|
|
78
|
+
* on a method+path collision — collisions are an app bug the serving
|
|
79
|
+
* adapter rejects at boot; the document renderer stays total.
|
|
80
|
+
*/
|
|
81
|
+
export function buildOpenApiDocument(manifest) {
|
|
82
|
+
const paths = {};
|
|
83
|
+
for (const route of manifest.routes) {
|
|
84
|
+
if (route.transport !== 'http')
|
|
85
|
+
continue;
|
|
86
|
+
if (route.path === undefined)
|
|
87
|
+
continue;
|
|
88
|
+
const path = openApiPath(route.path);
|
|
89
|
+
const method = (route.method ?? 'GET').toLowerCase();
|
|
90
|
+
const entry = (paths[path] ??= {});
|
|
91
|
+
if (entry[method] !== undefined)
|
|
92
|
+
continue;
|
|
93
|
+
entry[method] = buildOperation(route);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
openapi: '3.1.0',
|
|
97
|
+
info: {
|
|
98
|
+
title: manifest.app.name,
|
|
99
|
+
version: manifest.app.version ?? '0.0.0',
|
|
100
|
+
},
|
|
101
|
+
paths,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Render the OpenAPI output. Plain mode prints the document as JSON
|
|
106
|
+
* (pipe it into a file or a swagger viewer); `--json` wraps it in the
|
|
107
|
+
* standard CLI envelope under `data.document`.
|
|
108
|
+
*/
|
|
109
|
+
export function renderOpenApi(source, opts) {
|
|
110
|
+
const document = buildOpenApiDocument(source.manifest);
|
|
111
|
+
const nowFactory = opts.now ?? (() => new Date());
|
|
112
|
+
const envelope = {
|
|
113
|
+
status: 'success',
|
|
114
|
+
command: source.command,
|
|
115
|
+
generatedAt: nowFactory().toISOString(),
|
|
116
|
+
data: { format: 'openapi', document },
|
|
117
|
+
errors: [],
|
|
118
|
+
};
|
|
119
|
+
const out = opts.out ??
|
|
120
|
+
((line) => {
|
|
121
|
+
process.stdout.write(line);
|
|
122
|
+
});
|
|
123
|
+
if (opts.json) {
|
|
124
|
+
out(`${JSON.stringify(envelope, null, 2)}\n`);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
out(`${JSON.stringify(document, null, 2)}\n`);
|
|
128
|
+
}
|
|
129
|
+
return envelope;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=render-openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-openapi.js","sourceRoot":"","sources":["../../src/cli/render-openapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer for `dot explain --as <format>`.
|
|
3
|
+
*
|
|
4
|
+
* The kernel owns selection, app-file-relative module resolution, import, and
|
|
5
|
+
* envelope printing. The adapter owns the projection module and document
|
|
6
|
+
* vocabulary.
|
|
7
|
+
*/
|
|
8
|
+
import type { DotAppManifest, JsonValue } from '../manifest.js';
|
|
9
|
+
import type { DotCliEnvelope, RenderOptions } from './render-explain.js';
|
|
10
|
+
export type ProjectionData = {
|
|
11
|
+
format: string;
|
|
12
|
+
document: JsonValue;
|
|
13
|
+
};
|
|
14
|
+
export type ProjectionSource = {
|
|
15
|
+
manifest: DotAppManifest;
|
|
16
|
+
command: 'explain';
|
|
17
|
+
format: string;
|
|
18
|
+
/** Absolute app file path; projection specifiers resolve relative to it. */
|
|
19
|
+
appFilePath: string;
|
|
20
|
+
/** Per-invocation debug override for the selected projection module. */
|
|
21
|
+
module?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Render an adapter-owned projection. Plain mode prints strings verbatim and
|
|
25
|
+
* JSON values as pretty JSON; JSON mode wraps the document in the standard
|
|
26
|
+
* CLI envelope.
|
|
27
|
+
*/
|
|
28
|
+
export declare function renderProjection(source: ProjectionSource, opts: RenderOptions): Promise<DotCliEnvelope<ProjectionData>>;
|
|
29
|
+
//# sourceMappingURL=render-projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-projection.d.ts","sourceRoot":"","sources":["../../src/cli/render-projection.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAsB,MAAM,gBAAgB,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAMF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAgKF;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAqCzC"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer for `dot explain --as <format>`.
|
|
3
|
+
*
|
|
4
|
+
* The kernel owns selection, app-file-relative module resolution, import, and
|
|
5
|
+
* envelope printing. The adapter owns the projection module and document
|
|
6
|
+
* vocabulary.
|
|
7
|
+
*/
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { dirname, isAbsolute } from 'node:path';
|
|
10
|
+
import { pathToFileURL } from 'node:url';
|
|
11
|
+
import { DotCliError, DotCliErrorCode } from './error-codes.js';
|
|
12
|
+
const defaultOut = (line) => {
|
|
13
|
+
process.stdout.write(line);
|
|
14
|
+
};
|
|
15
|
+
function nowIso(opts) {
|
|
16
|
+
const factory = opts.now ?? (() => new Date());
|
|
17
|
+
return factory().toISOString();
|
|
18
|
+
}
|
|
19
|
+
function isJsonPrimitive(value) {
|
|
20
|
+
return value === null || typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number';
|
|
21
|
+
}
|
|
22
|
+
function isPlainObject(value) {
|
|
23
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
24
|
+
return false;
|
|
25
|
+
const prototype = Object.getPrototypeOf(value);
|
|
26
|
+
return prototype === Object.prototype || prototype === null;
|
|
27
|
+
}
|
|
28
|
+
function isJsonValue(value) {
|
|
29
|
+
if (isJsonPrimitive(value))
|
|
30
|
+
return typeof value !== 'number' || Number.isFinite(value);
|
|
31
|
+
if (Array.isArray(value))
|
|
32
|
+
return value.every(isJsonValue);
|
|
33
|
+
if (!isPlainObject(value))
|
|
34
|
+
return false;
|
|
35
|
+
return Object.values(value).every(isJsonValue);
|
|
36
|
+
}
|
|
37
|
+
function jsonDeepEqual(left, right) {
|
|
38
|
+
if (isJsonPrimitive(left) || isJsonPrimitive(right))
|
|
39
|
+
return Object.is(left, right);
|
|
40
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
41
|
+
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length)
|
|
42
|
+
return false;
|
|
43
|
+
return left.every((value, index) => jsonDeepEqual(value, right[index]));
|
|
44
|
+
}
|
|
45
|
+
if (!isPlainObject(left) || !isPlainObject(right))
|
|
46
|
+
return false;
|
|
47
|
+
const leftEntries = Object.entries(left);
|
|
48
|
+
const rightEntries = Object.entries(right);
|
|
49
|
+
if (leftEntries.length !== rightEntries.length)
|
|
50
|
+
return false;
|
|
51
|
+
for (const [key, value] of leftEntries) {
|
|
52
|
+
if (!Object.hasOwn(right, key) || !jsonDeepEqual(value, right[key]))
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
function toProjectionJsonValue(value) {
|
|
58
|
+
let serialized;
|
|
59
|
+
try {
|
|
60
|
+
serialized = JSON.stringify(value);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
throw new TypeError('Projection output must be JSON-serializable.', { cause: error });
|
|
64
|
+
}
|
|
65
|
+
if (serialized === undefined) {
|
|
66
|
+
throw new TypeError('Projection output must be JSON-serializable.');
|
|
67
|
+
}
|
|
68
|
+
const parsed = JSON.parse(serialized);
|
|
69
|
+
if (!isJsonValue(parsed) || !jsonDeepEqual(value, parsed)) {
|
|
70
|
+
throw new TypeError('Projection output must survive a JSON round trip without lossy coercions.');
|
|
71
|
+
}
|
|
72
|
+
return parsed;
|
|
73
|
+
}
|
|
74
|
+
function selectProjection(manifest, format) {
|
|
75
|
+
const projections = manifest.projections.filter(projection => projection.format === format);
|
|
76
|
+
if (projections.length === 0) {
|
|
77
|
+
const formats = [...new Set(manifest.projections.map(projection => projection.format))];
|
|
78
|
+
throw new DotCliError({
|
|
79
|
+
code: DotCliErrorCode.ProjectionNotFound,
|
|
80
|
+
message: `No projection is registered for format "${format}".`,
|
|
81
|
+
remediation: formats.length === 0
|
|
82
|
+
? 'Register an adapter that contributes this projection format, or remove --as.'
|
|
83
|
+
: `Use one of the registered formats (${formats.join(', ')}), or mount the adapter that provides "${format}".`,
|
|
84
|
+
metadata: { format, registeredFormats: formats },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const modules = new Set(projections.map(projection => projection.module));
|
|
88
|
+
if (modules.size > 1) {
|
|
89
|
+
throw new DotCliError({
|
|
90
|
+
code: DotCliErrorCode.ProjectionConflict,
|
|
91
|
+
message: `Multiple projection modules are registered for format "${format}".`,
|
|
92
|
+
remediation: 'Only one module may own a projection format. Remove one registration, or make both plugins register the same module specifier.',
|
|
93
|
+
metadata: {
|
|
94
|
+
format,
|
|
95
|
+
projections: projections.map(projection => ({ plugin: projection.plugin, module: projection.module })),
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return projections[0];
|
|
100
|
+
}
|
|
101
|
+
function getBunResolver() {
|
|
102
|
+
const candidate = globalThis.Bun;
|
|
103
|
+
if (typeof candidate !== 'object' || candidate === null)
|
|
104
|
+
return undefined;
|
|
105
|
+
const resolveSync = candidate.resolveSync;
|
|
106
|
+
if (typeof resolveSync !== 'function')
|
|
107
|
+
return undefined;
|
|
108
|
+
return { resolveSync: (specifier, from) => resolveSync.call(candidate, specifier, from) };
|
|
109
|
+
}
|
|
110
|
+
function importSpecifierFor(resolved) {
|
|
111
|
+
if (resolved.startsWith('file:'))
|
|
112
|
+
return resolved;
|
|
113
|
+
if (isAbsolute(resolved))
|
|
114
|
+
return pathToFileURL(resolved).href;
|
|
115
|
+
return resolved;
|
|
116
|
+
}
|
|
117
|
+
function resolveProjectionSpecifier(specifier, appFilePath) {
|
|
118
|
+
const fromDir = dirname(appFilePath);
|
|
119
|
+
const bun = getBunResolver();
|
|
120
|
+
if (bun !== undefined)
|
|
121
|
+
return bun.resolveSync(specifier, fromDir);
|
|
122
|
+
return createRequire(appFilePath).resolve(specifier);
|
|
123
|
+
}
|
|
124
|
+
async function loadProjectionModule(specifier, appFilePath, registeringPlugin) {
|
|
125
|
+
let resolved;
|
|
126
|
+
try {
|
|
127
|
+
resolved = resolveProjectionSpecifier(specifier, appFilePath);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
throw new DotCliError({
|
|
131
|
+
code: DotCliErrorCode.ProjectionImportFailed,
|
|
132
|
+
message: `Failed to resolve projection module "${specifier}".`,
|
|
133
|
+
remediation: 'Check that the projection module is installed and that package subpath exports include a default condition. Use --module <specifier> to debug with a replacement module.',
|
|
134
|
+
metadata: { specifier, appFilePath, registeringPlugin },
|
|
135
|
+
cause: error,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
let imported;
|
|
139
|
+
try {
|
|
140
|
+
imported = await import(importSpecifierFor(resolved));
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
throw new DotCliError({
|
|
144
|
+
code: DotCliErrorCode.ProjectionImportFailed,
|
|
145
|
+
message: `Failed to import projection module "${specifier}".`,
|
|
146
|
+
remediation: 'Fix the projection module export, or use --module <specifier> to debug with a replacement module.',
|
|
147
|
+
metadata: { specifier, resolved, registeringPlugin },
|
|
148
|
+
cause: error,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (typeof imported !== 'object' || imported === null || typeof imported.project !== 'function') {
|
|
152
|
+
throw new DotCliError({
|
|
153
|
+
code: DotCliErrorCode.ProjectionImportFailed,
|
|
154
|
+
message: `Projection module "${specifier}" does not export project(manifest).`,
|
|
155
|
+
remediation: 'Export a named `project(manifest)` function from the projection module. Use --module <specifier> to test a corrected module.',
|
|
156
|
+
metadata: { specifier, resolved, registeringPlugin },
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return { module: imported, resolved };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Render an adapter-owned projection. Plain mode prints strings verbatim and
|
|
163
|
+
* JSON values as pretty JSON; JSON mode wraps the document in the standard
|
|
164
|
+
* CLI envelope.
|
|
165
|
+
*/
|
|
166
|
+
export async function renderProjection(source, opts) {
|
|
167
|
+
const projection = selectProjection(source.manifest, source.format);
|
|
168
|
+
const specifier = source.module ?? projection.module;
|
|
169
|
+
const { module } = await loadProjectionModule(specifier, source.appFilePath, projection.plugin);
|
|
170
|
+
let document;
|
|
171
|
+
try {
|
|
172
|
+
document = toProjectionJsonValue(await module.project(source.manifest));
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
throw new DotCliError({
|
|
176
|
+
code: DotCliErrorCode.ProjectionExecutionFailed,
|
|
177
|
+
message: `Projection "${source.format}" failed while rendering.`,
|
|
178
|
+
remediation: 'Fix the projection project(manifest) function so it is pure and returns JSON-round-trip-safe output.',
|
|
179
|
+
metadata: { format: source.format, specifier, registeringPlugin: projection.plugin },
|
|
180
|
+
cause: error,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
const envelope = {
|
|
184
|
+
status: 'success',
|
|
185
|
+
command: source.command,
|
|
186
|
+
generatedAt: nowIso(opts),
|
|
187
|
+
data: { format: source.format, document },
|
|
188
|
+
errors: [],
|
|
189
|
+
};
|
|
190
|
+
const out = opts.out ?? defaultOut;
|
|
191
|
+
if (opts.json) {
|
|
192
|
+
out(`${JSON.stringify(envelope, null, 2)}\n`);
|
|
193
|
+
}
|
|
194
|
+
else if (typeof document === 'string') {
|
|
195
|
+
out(`${document}\n`);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
out(`${JSON.stringify(document, null, 2)}\n`);
|
|
199
|
+
}
|
|
200
|
+
return envelope;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=render-projection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-projection.js","sourceRoot":"","sources":["../../src/cli/render-projection.ts"],"names":[],"mappings":"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"}
|
package/dist/define-app.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Public entry point for the DOT kernel (v2).
|
|
3
3
|
*
|
|
4
|
-
* `defineApp(name)` returns a `DotAppBuilder` that accumulates
|
|
5
|
-
* `.use(
|
|
4
|
+
* `defineApp(name)` returns a `DotAppBuilder` that accumulates plugins via
|
|
5
|
+
* `.use(plugin)`, then transitions through the 5-hook lifecycle:
|
|
6
6
|
*
|
|
7
7
|
* defineApp -> use* -> configure() -> boot() -> start() -> stop() -> dispose()
|
|
8
8
|
*
|
|
9
|
-
* `.use()` is compile-time guarded: a
|
|
9
|
+
* `.use()` is compile-time guarded: a plugin whose `needs` are not satisfied
|
|
10
10
|
* by services provided so far — or whose provides collide with existing
|
|
11
11
|
* wire keys — fails to typecheck at the call site ("Expected 2 arguments,
|
|
12
12
|
* but got 1", with the diagnostic embedded in the expected second
|
|
@@ -22,7 +22,7 @@ import type { DotDiagnosticsSnapshot } from './diagnostics.js';
|
|
|
22
22
|
import type { DotLifecycleObserver } from './lifecycle-observer.js';
|
|
23
23
|
import type { DotLifecycleState } from './lifecycle.js';
|
|
24
24
|
import type { DotAppManifest } from './manifest.js';
|
|
25
|
-
import type { EmptyShape,
|
|
25
|
+
import type { AnyPlugin, EmptyShape, Plugin, ServiceRecord } from './plugin-contract.js';
|
|
26
26
|
type MissingKeys<TAvail, TNeeds> = {
|
|
27
27
|
readonly [K in Exclude<keyof TNeeds, keyof TAvail>]: TNeeds[K];
|
|
28
28
|
};
|
|
@@ -33,27 +33,53 @@ type MismatchedKeys<TAvail, TNeeds> = {
|
|
|
33
33
|
};
|
|
34
34
|
};
|
|
35
35
|
type NeedsError<TAvail extends ServiceRecord, TNeeds extends ServiceRecord> = {
|
|
36
|
-
readonly 'DOT:
|
|
36
|
+
readonly 'DOT: plugin needs services no earlier .use() provides': {
|
|
37
37
|
readonly missing: MissingKeys<TAvail, TNeeds>;
|
|
38
38
|
readonly mismatched: MismatchedKeys<TAvail, TNeeds>;
|
|
39
39
|
};
|
|
40
40
|
};
|
|
41
41
|
type CollisionError<TAvail, TProvides> = {
|
|
42
|
-
readonly 'DOT:
|
|
42
|
+
readonly 'DOT: plugin provides wire keys already provided (use rename())': keyof TAvail & keyof TProvides;
|
|
43
43
|
};
|
|
44
44
|
/**
|
|
45
|
-
* A
|
|
45
|
+
* A plugin whose `boot` always throws infers `TProvides = never`, which would
|
|
46
46
|
* poison both the collision check (`keyof never` matches everything) and
|
|
47
|
-
* the accumulated record (`TAvail & never` = `never`). Such a
|
|
47
|
+
* the accumulated record (`TAvail & never` = `never`). Such a plugin provides
|
|
48
48
|
* nothing — normalize to the empty shape.
|
|
49
49
|
*/
|
|
50
|
-
type NormalizeProvides<TP extends ServiceRecord> = [TP] extends [never] ? EmptyShape : TP;
|
|
50
|
+
export type NormalizeProvides<TP extends ServiceRecord> = [TP] extends [never] ? EmptyShape : TP;
|
|
51
51
|
/**
|
|
52
|
-
* Rest-tuple guard. Satisfied → `[]` (call `.use(
|
|
52
|
+
* Rest-tuple guard. Satisfied → `[]` (call `.use(plugin)` with one argument).
|
|
53
53
|
* Violated → a required second argument of an unconstructible error type,
|
|
54
54
|
* so the call site fails with the diagnostic embedded in the expected type.
|
|
55
55
|
*/
|
|
56
56
|
export type UseGuard<TAvail extends ServiceRecord, TNeeds extends ServiceRecord, TProvides extends ServiceRecord> = [TAvail] extends [TNeeds] ? [keyof TAvail & keyof TProvides] extends [never] ? [] : [error: CollisionError<TAvail, TProvides>] : [error: NeedsError<TAvail, TNeeds>];
|
|
57
|
+
type UseAllState<TAvail extends ServiceRecord, TPlugins extends readonly AnyPlugin[]> = TPlugins extends readonly [
|
|
58
|
+
infer Head,
|
|
59
|
+
...infer Tail
|
|
60
|
+
] ? Head extends Plugin<infer TNeeds, infer TProvides> ? UseGuard<TAvail, TNeeds, NormalizeProvides<TProvides>> extends [] ? UseAllState<TAvail & NormalizeProvides<TProvides>, Extract<Tail, readonly AnyPlugin[]>> : {
|
|
61
|
+
readonly avail: TAvail;
|
|
62
|
+
readonly error: {
|
|
63
|
+
readonly 'DOT: useAll tuple contains a plugin that cannot be used at this position': UseGuard<TAvail, TNeeds, NormalizeProvides<TProvides>>[0];
|
|
64
|
+
};
|
|
65
|
+
} : {
|
|
66
|
+
readonly avail: TAvail;
|
|
67
|
+
readonly error: {
|
|
68
|
+
readonly 'DOT: useAll accepts only plugins': Head;
|
|
69
|
+
};
|
|
70
|
+
} : {
|
|
71
|
+
readonly avail: TAvail;
|
|
72
|
+
readonly error: never;
|
|
73
|
+
};
|
|
74
|
+
export type UseAllAvail<TAvail extends ServiceRecord, TPlugins extends readonly AnyPlugin[]> = UseAllState<TAvail, TPlugins>['avail'];
|
|
75
|
+
type UseAllTupleGuard<TPlugins extends readonly AnyPlugin[]> = number extends TPlugins['length'] ? [
|
|
76
|
+
error: {
|
|
77
|
+
readonly 'DOT: useAll requires a tuple; add `as const` or pass plugins directly in declaration order': TPlugins;
|
|
78
|
+
}
|
|
79
|
+
] : [];
|
|
80
|
+
export type UseAllGuard<TAvail extends ServiceRecord, TPlugins extends readonly AnyPlugin[]> = [
|
|
81
|
+
UseAllState<TAvail, TPlugins>['error']
|
|
82
|
+
] extends [never] ? UseAllTupleGuard<TPlugins> : [error: UseAllState<TAvail, TPlugins>['error']];
|
|
57
83
|
/**
|
|
58
84
|
* Public DotApp surface. The internal `DotAppImpl` implements this; consumers
|
|
59
85
|
* see only these members.
|
|
@@ -64,7 +90,7 @@ export type DotApp<TServices extends ServiceRecord> = {
|
|
|
64
90
|
/** Current lifecycle state. */
|
|
65
91
|
readonly state: DotLifecycleState;
|
|
66
92
|
/**
|
|
67
|
-
* Services published by booted
|
|
93
|
+
* Services published by booted plugins, keyed by wire key.
|
|
68
94
|
* Empty before `boot()` succeeds.
|
|
69
95
|
*/
|
|
70
96
|
readonly services: TServices;
|
|
@@ -121,16 +147,22 @@ export type DotAppConfigured<TServices extends ServiceRecord> = {
|
|
|
121
147
|
/**
|
|
122
148
|
* Builder produced by `defineApp(name)`.
|
|
123
149
|
*
|
|
124
|
-
* `.use(
|
|
150
|
+
* `.use(plugin)` is type-tracking in both directions: the plugin's `needs` must
|
|
125
151
|
* be satisfied by the services accumulated so far, and its `provides`
|
|
126
152
|
* merge into the accumulated record for the next `.use()`.
|
|
127
153
|
*/
|
|
128
154
|
export type DotAppBuilder<TAvail extends ServiceRecord> = {
|
|
129
155
|
/**
|
|
130
|
-
* Register a
|
|
156
|
+
* Register a plugin. Compile error when the plugin's needs are unsatisfied
|
|
131
157
|
* or its provides collide with existing wire keys.
|
|
132
158
|
*/
|
|
133
|
-
use<TNeeds extends ServiceRecord, TProvides extends ServiceRecord>(
|
|
159
|
+
use<TNeeds extends ServiceRecord, TProvides extends ServiceRecord>(plugin: Plugin<TNeeds, TProvides>, ...guard: UseGuard<TAvail, TNeeds, NormalizeProvides<TProvides>>): DotAppBuilder<TAvail & NormalizeProvides<TProvides>>;
|
|
160
|
+
/**
|
|
161
|
+
* Register a tuple of plugins in declaration order. This is type-equivalent
|
|
162
|
+
* to calling `.use()` for each item and keeps the same ordering/collision
|
|
163
|
+
* guard across the whole tuple.
|
|
164
|
+
*/
|
|
165
|
+
useAll<const TPlugins extends readonly AnyPlugin[]>(plugins: TPlugins, ...guard: UseAllGuard<TAvail, TPlugins>): DotAppBuilder<UseAllAvail<TAvail, TPlugins>>;
|
|
134
166
|
/** Run the configure phase synchronously. Throws on configure failure. */
|
|
135
167
|
configure(): DotAppConfigured<TAvail>;
|
|
136
168
|
/** Run configure + boot. Throws on configure or boot failure. */
|
|
@@ -143,8 +175,8 @@ export type DotAppBuilder<TAvail extends ServiceRecord> = {
|
|
|
143
175
|
*
|
|
144
176
|
* @example
|
|
145
177
|
* const app = await defineApp('my-app')
|
|
146
|
-
* .use(
|
|
147
|
-
* .use(
|
|
178
|
+
* .use(dbPlugin)
|
|
179
|
+
* .use(billingPlugin) // billing's needs must be satisfied by now
|
|
148
180
|
* .boot();
|
|
149
181
|
*
|
|
150
182
|
* await app.start();
|
|
@@ -165,7 +197,7 @@ export declare function defineApp(name: string, options?: {
|
|
|
165
197
|
/**
|
|
166
198
|
* Watchdog budget (ms) for each async hook invocation (`boot`, `start`,
|
|
167
199
|
* `stop`, `dispose` — `configure` is sync). A hook exceeding the budget
|
|
168
|
-
* fails with `DOT_LIFECYCLE_E015` naming the
|
|
200
|
+
* fails with `DOT_LIFECYCLE_E015` naming the plugin and hook, and the
|
|
169
201
|
* kernel applies its normal failure rules (boot rollback, teardown
|
|
170
202
|
* aggregation). The hook's promise itself cannot be cancelled — the
|
|
171
203
|
* watchdog makes the hang *visible*, it does not kill it. Default:
|
package/dist/define-app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-app.d.ts","sourceRoot":"","sources":["../src/define-app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"define-app.d.ts","sourceRoot":"","sources":["../src/define-app.ts"],"names":[],"mappings":"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"}
|