@metaobjectsdev/codegen-ts 0.24.5 → 1.0.0-rc.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/README.md +37 -12
- package/dist/api-surface.d.ts +29 -0
- package/dist/api-surface.d.ts.map +1 -1
- package/dist/api-surface.js +47 -0
- package/dist/api-surface.js.map +1 -1
- package/dist/column-mapper.d.ts +12 -0
- package/dist/column-mapper.d.ts.map +1 -1
- package/dist/column-mapper.js +1 -0
- package/dist/column-mapper.js.map +1 -1
- package/dist/constants.d.ts +24 -11
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +54 -19
- package/dist/constants.js.map +1 -1
- package/dist/db-emitting.d.ts +6 -0
- package/dist/db-emitting.d.ts.map +1 -0
- package/dist/db-emitting.js +26 -0
- package/dist/db-emitting.js.map +1 -0
- package/dist/generator-registry.d.ts.map +1 -1
- package/dist/generator-registry.js +14 -1
- package/dist/generator-registry.js.map +1 -1
- package/dist/generator.d.ts +5 -0
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js.map +1 -1
- package/dist/generators/agent-docs-file.d.ts +19 -0
- package/dist/generators/agent-docs-file.d.ts.map +1 -0
- package/dist/generators/agent-docs-file.js +257 -0
- package/dist/generators/agent-docs-file.js.map +1 -0
- package/dist/generators/agent-requirements-page.d.ts +22 -0
- package/dist/generators/agent-requirements-page.d.ts.map +1 -0
- package/dist/generators/agent-requirements-page.js +175 -0
- package/dist/generators/agent-requirements-page.js.map +1 -0
- package/dist/generators/agent-schema-input.d.ts +69 -0
- package/dist/generators/agent-schema-input.d.ts.map +1 -0
- package/dist/generators/agent-schema-input.js +23 -0
- package/dist/generators/agent-schema-input.js.map +1 -0
- package/dist/generators/agent-schema-page.d.ts +21 -0
- package/dist/generators/agent-schema-page.d.ts.map +1 -0
- package/dist/generators/agent-schema-page.js +241 -0
- package/dist/generators/agent-schema-page.js.map +1 -0
- package/dist/generators/agent-ui-page.d.ts +22 -0
- package/dist/generators/agent-ui-page.d.ts.map +1 -0
- package/dist/generators/agent-ui-page.js +253 -0
- package/dist/generators/agent-ui-page.js.map +1 -0
- package/dist/generators/api-docs-file.d.ts.map +1 -1
- package/dist/generators/api-docs-file.js +13 -6
- package/dist/generators/api-docs-file.js.map +1 -1
- package/dist/generators/api-model.d.ts +6 -0
- package/dist/generators/api-model.d.ts.map +1 -1
- package/dist/generators/api-model.js +54 -35
- package/dist/generators/api-model.js.map +1 -1
- package/dist/generators/callable-file.js +1 -1
- package/dist/generators/callable-file.js.map +1 -1
- package/dist/generators/docs-data-builder.d.ts.map +1 -1
- package/dist/generators/docs-data-builder.js +47 -2
- package/dist/generators/docs-data-builder.js.map +1 -1
- package/dist/generators/docs-data.d.ts +6 -2
- package/dist/generators/docs-data.d.ts.map +1 -1
- package/dist/generators/index.d.ts +3 -8
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +19 -14
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/names-file.d.ts +17 -0
- package/dist/generators/names-file.d.ts.map +1 -0
- package/dist/generators/names-file.js +95 -0
- package/dist/generators/names-file.js.map +1 -0
- package/dist/generators/requirements-markdown.d.ts +18 -1
- package/dist/generators/requirements-markdown.d.ts.map +1 -1
- package/dist/generators/requirements-markdown.js +11 -9
- package/dist/generators/requirements-markdown.js.map +1 -1
- package/dist/generators/routes-file-hono.d.ts +17 -2
- package/dist/generators/routes-file-hono.d.ts.map +1 -1
- package/dist/generators/routes-file-hono.js +9 -11
- package/dist/generators/routes-file-hono.js.map +1 -1
- package/dist/generators/routes-file.d.ts +17 -2
- package/dist/generators/routes-file.d.ts.map +1 -1
- package/dist/generators/routes-file.js +10 -8
- package/dist/generators/routes-file.js.map +1 -1
- package/dist/generators/template-generator.d.ts.map +1 -1
- package/dist/generators/template-generator.js +20 -6
- package/dist/generators/template-generator.js.map +1 -1
- package/dist/index.d.ts +20 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -4
- package/dist/index.js.map +1 -1
- package/dist/metaobjects-config.d.ts +38 -1
- package/dist/metaobjects-config.d.ts.map +1 -1
- package/dist/metaobjects-config.js +9 -1
- package/dist/metaobjects-config.js.map +1 -1
- package/dist/names.d.ts +275 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +433 -0
- package/dist/names.js.map +1 -0
- package/dist/overwrite-policy.d.ts.map +1 -1
- package/dist/overwrite-policy.js +15 -3
- package/dist/overwrite-policy.js.map +1 -1
- package/dist/projection/extract-view-spec.d.ts +25 -1
- package/dist/projection/extract-view-spec.d.ts.map +1 -1
- package/dist/projection/extract-view-spec.js +79 -6
- package/dist/projection/extract-view-spec.js.map +1 -1
- package/dist/reference-templates.d.ts +1 -1
- package/dist/reference-templates.d.ts.map +1 -1
- package/dist/reference-templates.js +1 -1
- package/dist/reference-templates.js.map +1 -1
- package/dist/render-context.d.ts +12 -1
- package/dist/render-context.d.ts.map +1 -1
- package/dist/render-context.js +1 -0
- package/dist/render-context.js.map +1 -1
- package/dist/retired-codegen-attrs.d.ts +32 -0
- package/dist/retired-codegen-attrs.d.ts.map +1 -0
- package/dist/retired-codegen-attrs.js +47 -0
- package/dist/retired-codegen-attrs.js.map +1 -0
- package/dist/routes-expose.d.ts +63 -0
- package/dist/routes-expose.d.ts.map +1 -0
- package/dist/routes-expose.js +57 -0
- package/dist/routes-expose.js.map +1 -0
- package/dist/runner.d.ts +18 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +109 -7
- package/dist/runner.js.map +1 -1
- package/dist/templates/callable-file.d.ts +7 -2
- package/dist/templates/callable-file.d.ts.map +1 -1
- package/dist/templates/callable-file.js +54 -9
- package/dist/templates/callable-file.js.map +1 -1
- package/dist/templates/drizzle-schema.d.ts.map +1 -1
- package/dist/templates/drizzle-schema.js +236 -65
- package/dist/templates/drizzle-schema.js.map +1 -1
- package/dist/templates/entity-constants.d.ts +15 -6
- package/dist/templates/entity-constants.d.ts.map +1 -1
- package/dist/templates/entity-constants.js +85 -161
- package/dist/templates/entity-constants.js.map +1 -1
- package/dist/templates/entity-file.d.ts.map +1 -1
- package/dist/templates/entity-file.js +38 -4
- package/dist/templates/entity-file.js.map +1 -1
- package/dist/templates/entity-meta-file.d.ts +15 -1
- package/dist/templates/entity-meta-file.d.ts.map +1 -1
- package/dist/templates/entity-meta-file.js +12 -2
- package/dist/templates/entity-meta-file.js.map +1 -1
- package/dist/templates/entity-ui-descriptor.d.ts +112 -0
- package/dist/templates/entity-ui-descriptor.d.ts.map +1 -0
- package/dist/templates/entity-ui-descriptor.js +238 -0
- package/dist/templates/entity-ui-descriptor.js.map +1 -0
- package/dist/templates/field-meta.d.ts +46 -9
- package/dist/templates/field-meta.d.ts.map +1 -1
- package/dist/templates/field-meta.js +95 -21
- package/dist/templates/field-meta.js.map +1 -1
- package/dist/templates/names-decl.d.ts +38 -0
- package/dist/templates/names-decl.d.ts.map +1 -0
- package/dist/templates/names-decl.js +104 -0
- package/dist/templates/names-decl.js.map +1 -0
- package/dist/templates/projection-decl.d.ts +21 -0
- package/dist/templates/projection-decl.d.ts.map +1 -1
- package/dist/templates/projection-decl.js +53 -29
- package/dist/templates/projection-decl.js.map +1 -1
- package/dist/templates/queries-file.d.ts.map +1 -1
- package/dist/templates/queries-file.js +17 -2
- package/dist/templates/queries-file.js.map +1 -1
- package/dist/templates/requirement-test.d.ts.map +1 -1
- package/dist/templates/requirement-test.js +13 -2
- package/dist/templates/requirement-test.js.map +1 -1
- package/dist/templates/routes-file-hono.d.ts +2 -1
- package/dist/templates/routes-file-hono.d.ts.map +1 -1
- package/dist/templates/routes-file-hono.js +11 -2
- package/dist/templates/routes-file-hono.js.map +1 -1
- package/dist/templates/routes-file.d.ts +2 -1
- package/dist/templates/routes-file.d.ts.map +1 -1
- package/dist/templates/routes-file.js +54 -21
- package/dist/templates/routes-file.js.map +1 -1
- package/dist/templates/value-object-file.d.ts.map +1 -1
- package/dist/templates/value-object-file.js +15 -1
- package/dist/templates/value-object-file.js.map +1 -1
- package/dist/templates/view-decl.d.ts +37 -1
- package/dist/templates/view-decl.d.ts.map +1 -1
- package/dist/templates/view-decl.js +27 -3
- package/dist/templates/view-decl.js.map +1 -1
- package/dist/templates/zod-validators.d.ts +21 -0
- package/dist/templates/zod-validators.d.ts.map +1 -1
- package/dist/templates/zod-validators.js +40 -5
- package/dist/templates/zod-validators.js.map +1 -1
- package/dist/view-context.d.ts +24 -0
- package/dist/view-context.d.ts.map +1 -0
- package/dist/view-context.js +81 -0
- package/dist/view-context.js.map +1 -0
- package/package.json +6 -6
- package/src/api-surface.ts +53 -0
- package/src/column-mapper.ts +13 -0
- package/src/constants.ts +91 -16
- package/src/db-emitting.ts +31 -0
- package/src/generator-registry.ts +14 -4
- package/src/generator.ts +5 -0
- package/src/generators/agent-docs-file.ts +297 -0
- package/src/generators/agent-requirements-page.ts +199 -0
- package/src/generators/agent-schema-input.ts +88 -0
- package/src/generators/agent-schema-page.ts +297 -0
- package/src/generators/agent-ui-page.ts +290 -0
- package/src/generators/api-docs-file.ts +13 -6
- package/src/generators/api-model.ts +63 -34
- package/src/generators/callable-file.ts +1 -1
- package/src/generators/docs-data-builder.ts +46 -2
- package/src/generators/docs-data.ts +6 -2
- package/src/generators/index.ts +25 -14
- package/src/generators/names-file.ts +98 -0
- package/src/generators/requirements-markdown.ts +36 -2
- package/src/generators/routes-file-hono.ts +19 -10
- package/src/generators/routes-file.ts +20 -7
- package/src/generators/template-generator.ts +20 -6
- package/src/index.ts +64 -4
- package/src/metaobjects-config.ts +48 -2
- package/src/names.ts +629 -0
- package/src/overwrite-policy.ts +15 -3
- package/src/projection/extract-view-spec.ts +85 -6
- package/src/reference/entity.ts +21 -2
- package/src/reference/names.ts +125 -0
- package/src/reference/queries.ts +19 -3
- package/src/reference/routes-hono.ts +19 -9
- package/src/reference/routes.ts +25 -9
- package/src/reference-templates.ts +1 -1
- package/src/render-context.ts +13 -1
- package/src/retired-codegen-attrs.ts +52 -0
- package/src/routes-expose.ts +86 -0
- package/src/runner.ts +122 -11
- package/src/templates/callable-file.ts +60 -8
- package/src/templates/drizzle-schema.ts +248 -60
- package/src/templates/entity-constants.ts +95 -184
- package/src/templates/entity-file.ts +46 -4
- package/src/templates/entity-meta-file.ts +16 -3
- package/src/templates/entity-ui-descriptor.ts +305 -0
- package/src/templates/field-meta.ts +100 -19
- package/src/templates/names-decl.ts +165 -0
- package/src/templates/projection-decl.ts +72 -31
- package/src/templates/queries-file.ts +17 -2
- package/src/templates/requirement-test.ts +13 -2
- package/src/templates/routes-file-hono.ts +14 -2
- package/src/templates/routes-file.ts +69 -24
- package/src/templates/value-object-file.ts +15 -1
- package/src/templates/view-decl.ts +53 -3
- package/src/templates/zod-validators.ts +41 -5
- package/src/view-context.ts +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-docs-file.d.ts","sourceRoot":"","sources":["../../src/generators/agent-docs-file.ts"],"names":[],"mappings":"AA6DA,OAAO,KAAK,EAAE,oBAAoB,EAAyB,MAAM,0BAA0B,CAAC;AAC5F,OAAO,KAAK,EAA0B,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAKhE,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAuHD,eAAO,MAAM,aAAa,EA0FrB,gBAAgB,CAAC,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// agentDocsFile() — the `agent` docs surface.
|
|
2
|
+
//
|
|
3
|
+
// Three pages under `agent/`, each one an agent reads BEFORE touching a tier:
|
|
4
|
+
//
|
|
5
|
+
// • `agent/schema.md` — before touching persistence
|
|
6
|
+
// • `agent/ui.md` — before touching a form or a grid
|
|
7
|
+
// • `agent/requirements.md` — before adding a capability
|
|
8
|
+
//
|
|
9
|
+
// (`api/AGENT-API.md`, the fourth file the always-on pointer names, is the api surface's
|
|
10
|
+
// and is emitted by `apiDocsFile()`. It is not duplicated here.)
|
|
11
|
+
//
|
|
12
|
+
// EVERY PAGE IS DERIVED FROM AN EXISTING BUILDER, and that is the design constraint
|
|
13
|
+
// rather than an implementation detail. A documentation surface an agent is told to
|
|
14
|
+
// TRUST has to be true, and the only way to keep three more pages true is to give them
|
|
15
|
+
// no derivation of their own:
|
|
16
|
+
//
|
|
17
|
+
// schema ← the expected-schema snapshot `meta migrate` diffs and emits from
|
|
18
|
+
// (injected; see agent-schema-input.ts for why codegen-ts refuses to
|
|
19
|
+
// compute it) + `resolveObjectNames`, the field→column resolver the
|
|
20
|
+
// names artifact and the DDL already share
|
|
21
|
+
// ui ← `buildEntityUiDescriptor`, the same derivation emitted as the
|
|
22
|
+
// `<Entity>` const that `useEntityForm` reads at runtime
|
|
23
|
+
// requirements ← `walkRequirements` + `requirementRows`, the same walk the ledger
|
|
24
|
+
// surface and the generated test stubs are built on
|
|
25
|
+
//
|
|
26
|
+
// CONFIG-GATED, like the api surface. Physical names, the dialect and view dispatch all
|
|
27
|
+
// depend on the gen config, so `meta docs` only selects this surface when it has one.
|
|
28
|
+
// The NEUTRAL model surface stays neutral (ADR-0020); this is a different surface with a
|
|
29
|
+
// different contract, not a relaxation of that one.
|
|
30
|
+
//
|
|
31
|
+
// AN EMPTY PAGE IS NO FILE. Each renderer returns "" when its tier has nothing to
|
|
32
|
+
// describe — no physical schema, no UI, no ledger — and an empty render emits nothing.
|
|
33
|
+
// That is what makes the surface safe to leave on: a headless project with no ledger sees
|
|
34
|
+
// no `agent/` directory rather than three pages of headings.
|
|
35
|
+
//
|
|
36
|
+
// These files are READ, never imported. There is no three-way merge and no hand-edit
|
|
37
|
+
// preservation to think about: regenerate and the page is current.
|
|
38
|
+
import { CARDINALITY_MANY, CARDINALITY_ONE, FIELD_SUBTYPE_ENUM, ORIGIN_AGGREGATE_ATTR_AGG, ORIGIN_AGGREGATE_ATTR_OF, ORIGIN_AGGREGATE_ATTR_VIA, ORIGIN_ATTR_ORDER_BY, ORIGIN_PASSTHROUGH_ATTR_FROM, ORIGIN_PASSTHROUGH_ATTR_VIA, ORIGIN_SUBTYPE_AGGREGATE, ORIGIN_SUBTYPE_COMPUTED, ORIGIN_SUBTYPE_FIRST, ORIGIN_SUBTYPE_PASSTHROUGH, RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF, RELATIONSHIP_ATTR_ON_DELETE, RELATIONSHIP_ATTR_THROUGH, PHYSICAL_NAME_ATTR_BY_KIND, SOURCE_ROLE_PRIMARY, TYPE_ORIGIN, resolveColumnName, } from "@metaobjectsdev/metadata";
|
|
39
|
+
import { resolveObjectNames } from "../names.js";
|
|
40
|
+
import { isAbstract } from "../instance-artifacts.js";
|
|
41
|
+
import { enumValues, intValueMapOf } from "../enum-meta.js";
|
|
42
|
+
import { renderAgentSchemaPage } from "./agent-schema-page.js";
|
|
43
|
+
import { renderAgentUiPage } from "./agent-ui-page.js";
|
|
44
|
+
import { renderAgentRequirementsPage } from "./agent-requirements-page.js";
|
|
45
|
+
/** All three pages live here, under the docs root. */
|
|
46
|
+
const DEFAULT_AGENT_DIR = "agent";
|
|
47
|
+
/** One `origin.*` child rendered as a lineage phrase. `origin.*` NEVER inherits, so the
|
|
48
|
+
* own-accessor read here is the correct one rather than an ADR-0039 slip. */
|
|
49
|
+
function lineageOf(field) {
|
|
50
|
+
const origin = field.ownChildren().find((c) => c.type === TYPE_ORIGIN);
|
|
51
|
+
if (origin === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
const str = (name) => {
|
|
54
|
+
const v = origin.attr(name);
|
|
55
|
+
return typeof v === "string" && v !== "" ? v : undefined;
|
|
56
|
+
};
|
|
57
|
+
switch (origin.subType) {
|
|
58
|
+
case ORIGIN_SUBTYPE_PASSTHROUGH: {
|
|
59
|
+
const from = str(ORIGIN_PASSTHROUGH_ATTR_FROM);
|
|
60
|
+
const via = str(ORIGIN_PASSTHROUGH_ATTR_VIA);
|
|
61
|
+
return `passthrough from \`${from ?? "?"}\`${via === undefined ? "" : ` via \`${via}\``}`;
|
|
62
|
+
}
|
|
63
|
+
case ORIGIN_SUBTYPE_AGGREGATE: {
|
|
64
|
+
const agg = str(ORIGIN_AGGREGATE_ATTR_AGG) ?? "?";
|
|
65
|
+
const of = str(ORIGIN_AGGREGATE_ATTR_OF);
|
|
66
|
+
const via = str(ORIGIN_AGGREGATE_ATTR_VIA);
|
|
67
|
+
return `\`${agg}\`${of === undefined ? "" : ` of \`${of}\``}${via === undefined ? "" : ` via \`${via}\``}`;
|
|
68
|
+
}
|
|
69
|
+
case ORIGIN_SUBTYPE_FIRST: {
|
|
70
|
+
const of = str(ORIGIN_AGGREGATE_ATTR_OF);
|
|
71
|
+
const via = str(ORIGIN_AGGREGATE_ATTR_VIA);
|
|
72
|
+
const order = str(ORIGIN_ATTR_ORDER_BY);
|
|
73
|
+
return `first${of === undefined ? "" : ` \`${of}\``}${via === undefined ? "" : ` via \`${via}\``}` +
|
|
74
|
+
`${order === undefined ? "" : ` ordered by \`${order}\``}`;
|
|
75
|
+
}
|
|
76
|
+
case ORIGIN_SUBTYPE_COMPUTED:
|
|
77
|
+
// The @expr tree is structured; naming it is enough to route a reader to the
|
|
78
|
+
// declaration, and rendering a tree into a cell would be a second SQL lowering.
|
|
79
|
+
return "computed from a declared `@expr`";
|
|
80
|
+
default:
|
|
81
|
+
return `\`origin.${origin.subType}\``;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The cardinality phrase, from the DECLARING object's side.
|
|
86
|
+
*
|
|
87
|
+
* `@cardinality: one` does NOT mean one-to-one. It means this object holds the foreign
|
|
88
|
+
* key — many rows of it point at one target row — which is what `relation-resolver.ts`
|
|
89
|
+
* builds a belongs-to `one()` relation from. Rendering it as "one-to-one" told a reader
|
|
90
|
+
* the target row is claimed by at most one row here, which is the direction that makes
|
|
91
|
+
* someone write a lookup expecting a single result.
|
|
92
|
+
*
|
|
93
|
+
* `@cardinality` is OPTIONAL vocabulary (min 0), and ABSENT is its own answer: no
|
|
94
|
+
* navigation is generated at all. Folding that into "one-to-one" invented a shape the
|
|
95
|
+
* model never declared.
|
|
96
|
+
*/
|
|
97
|
+
function cardinalityPhrase(cardinality, through) {
|
|
98
|
+
if (cardinality === CARDINALITY_MANY) {
|
|
99
|
+
return typeof through === "string" && through !== "" ? "many-to-many" : "one-to-many";
|
|
100
|
+
}
|
|
101
|
+
if (cardinality === CARDINALITY_ONE)
|
|
102
|
+
return "many-to-one";
|
|
103
|
+
return "cardinality not declared";
|
|
104
|
+
}
|
|
105
|
+
/** `- \`Order.lines\` — one-to-many → \`OrderLine\`` */
|
|
106
|
+
function relationshipLines(objects) {
|
|
107
|
+
const out = [];
|
|
108
|
+
for (const obj of objects) {
|
|
109
|
+
for (const rel of obj.relationships()) {
|
|
110
|
+
const cardinality = rel.attr(RELATIONSHIP_ATTR_CARDINALITY);
|
|
111
|
+
const target = rel.attr(RELATIONSHIP_ATTR_OBJECT_REF);
|
|
112
|
+
const through = rel.attr(RELATIONSHIP_ATTR_THROUGH);
|
|
113
|
+
const onDelete = rel.attr(RELATIONSHIP_ATTR_ON_DELETE);
|
|
114
|
+
// The FQN, not the short name: this line is an ADDRESS a reader searches for.
|
|
115
|
+
const parts = [`\`${obj.resolutionKey()}.${rel.name}\``, `\`${rel.subType}\``];
|
|
116
|
+
parts.push(`${cardinalityPhrase(cardinality, through)} → \`${String(target ?? "?")}\``);
|
|
117
|
+
if (typeof through === "string" && through !== "")
|
|
118
|
+
parts.push(`through \`${through}\``);
|
|
119
|
+
if (typeof onDelete === "string" && onDelete !== "")
|
|
120
|
+
parts.push(`on delete \`${onDelete}\``);
|
|
121
|
+
out.push(`- ${parts.join(" · ")}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* `| \`Order.status\` | OPEN, CLOSED | string-backed |`
|
|
128
|
+
*
|
|
129
|
+
* `objects` IS ONLY THE TABLE-BACKED SUBSET OF THE MODEL — the caller scopes it to the
|
|
130
|
+
* objects the snapshot actually holds as tables. This section sits on the SCHEMA page, so
|
|
131
|
+
* every row it prints is read as a statement about a column. Walking every loaded object
|
|
132
|
+
* printed rows for abstract bases, for `object.value`s that have no column anywhere, and
|
|
133
|
+
* for projections whose "column" is a view expression — three kinds of thing the physical
|
|
134
|
+
* schema does not contain.
|
|
135
|
+
*
|
|
136
|
+
* It also says nothing about a `CHECK`. Whether the database constrains the members is
|
|
137
|
+
* `table.checks`, which is already on this page from the snapshot, and an `@isArray`
|
|
138
|
+
* enum deliberately gets none (`migrate-ts` skips it) — so asserting one here was a
|
|
139
|
+
* SECOND derivation of a fact the page already carries correctly, in the direction that
|
|
140
|
+
* promises the database will refuse a value it will accept.
|
|
141
|
+
*/
|
|
142
|
+
function enumLines(objects) {
|
|
143
|
+
const rows = [];
|
|
144
|
+
for (const obj of objects) {
|
|
145
|
+
for (const field of obj.fields()) {
|
|
146
|
+
if (field.subType !== FIELD_SUBTYPE_ENUM)
|
|
147
|
+
continue;
|
|
148
|
+
const members = enumValues(field);
|
|
149
|
+
if (members === undefined || members.length === 0)
|
|
150
|
+
continue;
|
|
151
|
+
const intMap = intValueMapOf(field);
|
|
152
|
+
const backing = intMap === undefined
|
|
153
|
+
? "string-backed"
|
|
154
|
+
: `int-backed (${members.map((m) => `${m}=${intMap[m]}`).join(", ")})`;
|
|
155
|
+
rows.push(`| \`${obj.resolutionKey()}.${field.name}\` | ${members.map((m) => `\`${m}\``).join(", ")} | ${backing} |`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (rows.length === 0)
|
|
159
|
+
return [];
|
|
160
|
+
return ["| Field | Members | Storage |", "|---|---|---|", ...rows];
|
|
161
|
+
}
|
|
162
|
+
export const agentDocsFile = function agentDocsFile(opts) {
|
|
163
|
+
const dir = (opts?.subDir ?? DEFAULT_AGENT_DIR).replace(/\/$/, "");
|
|
164
|
+
const generator = {
|
|
165
|
+
name: "agent-docs",
|
|
166
|
+
generate(ctx) {
|
|
167
|
+
const objects = ctx.loadedRoot.objects();
|
|
168
|
+
const files = [];
|
|
169
|
+
// ---- schema.md
|
|
170
|
+
if (opts?.schema !== undefined) {
|
|
171
|
+
const schema = opts.schema;
|
|
172
|
+
// The qualified names the snapshot actually holds. An object whose physical name
|
|
173
|
+
// is not one of these contributes nothing to the physical schema (an abstract
|
|
174
|
+
// base, a sourceless value, an `@unmanaged` object) and must not appear on a page
|
|
175
|
+
// describing it — `buildExpectedSchema`'s Pass 1 owns those skip rules and this
|
|
176
|
+
// reads its answer rather than re-deriving them.
|
|
177
|
+
const tableNames = new Set(schema.tables.map((t) => schema.qualify(t)));
|
|
178
|
+
const viewNames = new Set(schema.views.map((v) => schema.qualify(v)));
|
|
179
|
+
// The objects backed by a TABLE in the snapshot — the enum section's scope, since
|
|
180
|
+
// a row there is read as a statement about a column.
|
|
181
|
+
const tableBacked = [];
|
|
182
|
+
// column → declaring field, per qualified table name. `resolveObjectNames` is the
|
|
183
|
+
// ONE field→column resolver — the same one the names artifact and the DDL use —
|
|
184
|
+
// so this mapping cannot disagree with the column it labels.
|
|
185
|
+
const declaredBy = new Map();
|
|
186
|
+
const viewLineage = new Map();
|
|
187
|
+
for (const obj of objects) {
|
|
188
|
+
const names = resolveObjectNames(obj, opts.columnNamingStrategy);
|
|
189
|
+
// The PRIMARY source's physical name and schema — `names.name` is the object's
|
|
190
|
+
// metamodel name since 0.25.0, which would match nothing in the snapshot.
|
|
191
|
+
const primary = names?.sources[SOURCE_ROLE_PRIMARY];
|
|
192
|
+
const physical = primary === undefined
|
|
193
|
+
? undefined
|
|
194
|
+
: primary[(PHYSICAL_NAME_ATTR_BY_KIND.get(primary.kind) ?? "")];
|
|
195
|
+
if (typeof physical !== "string")
|
|
196
|
+
continue;
|
|
197
|
+
const key = schema.qualify({ name: physical, schema: primary?.schema });
|
|
198
|
+
const isTable = tableNames.has(key);
|
|
199
|
+
if (!isTable && !viewNames.has(key))
|
|
200
|
+
continue;
|
|
201
|
+
// ABSTRACT BASES ARE EXCLUDED, and being in the snapshot does not exempt them:
|
|
202
|
+
// an abstract base that declares the `source.rdb` its concrete child inherits
|
|
203
|
+
// resolves to that child's table, so the qualified-name test admits it and the
|
|
204
|
+
// page printed the base's enum a second time under a different owner.
|
|
205
|
+
// `buildExpectedSchema`'s Pass 1 skips abstracts; this reads the same rule.
|
|
206
|
+
if (isTable && !isAbstract(obj))
|
|
207
|
+
tableBacked.push(obj);
|
|
208
|
+
let map = declaredBy.get(key);
|
|
209
|
+
if (map === undefined) {
|
|
210
|
+
map = new Map();
|
|
211
|
+
declaredBy.set(key, map);
|
|
212
|
+
}
|
|
213
|
+
const lineage = [];
|
|
214
|
+
for (const field of obj.fields()) {
|
|
215
|
+
const column = resolveColumnName(field, opts.columnNamingStrategy);
|
|
216
|
+
// A TPH base and its subtypes share one table: first writer wins, so the
|
|
217
|
+
// base's own column keeps its label rather than being relabelled by whichever
|
|
218
|
+
// subtype was walked last.
|
|
219
|
+
if (!map.has(column)) {
|
|
220
|
+
map.set(column, { field: field.name, type: `${field.type}.${field.subType}` });
|
|
221
|
+
}
|
|
222
|
+
const line = lineageOf(field);
|
|
223
|
+
if (line !== undefined)
|
|
224
|
+
lineage.push(`| \`${column}\` | ${line} |`);
|
|
225
|
+
}
|
|
226
|
+
if (lineage.length > 0)
|
|
227
|
+
viewLineage.set(key, lineage);
|
|
228
|
+
}
|
|
229
|
+
const content = renderAgentSchemaPage(schema, {
|
|
230
|
+
declaredBy,
|
|
231
|
+
viewLineage,
|
|
232
|
+
relationships: relationshipLines(objects),
|
|
233
|
+
enums: enumLines(tableBacked),
|
|
234
|
+
});
|
|
235
|
+
if (content !== "")
|
|
236
|
+
files.push({ path: `${dir}/schema.md`, content });
|
|
237
|
+
}
|
|
238
|
+
// ---- ui.md
|
|
239
|
+
// The apiPrefix is the project's, from the render context the runner built — the
|
|
240
|
+
// same value `routes-file.ts` emits as the SERVER mount prefix. Without it the page
|
|
241
|
+
// names an address nothing serves. (The client descriptor no longer carries it: a
|
|
242
|
+
// browser's base URL is supplied at runtime by the provider's `baseUrl`.)
|
|
243
|
+
const ui = renderAgentUiPage(ctx.loadedRoot, ctx.renderContext?.apiPrefix ?? "");
|
|
244
|
+
if (ui !== "")
|
|
245
|
+
files.push({ path: `${dir}/ui.md`, content: ui });
|
|
246
|
+
// ---- requirements.md
|
|
247
|
+
const requirements = renderAgentRequirementsPage(ctx.loadedRoot);
|
|
248
|
+
if (requirements !== "")
|
|
249
|
+
files.push({ path: `${dir}/requirements.md`, content: requirements });
|
|
250
|
+
return files;
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
if (opts?.target)
|
|
254
|
+
generator.target = opts.target;
|
|
255
|
+
return generator;
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=agent-docs-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-docs-file.js","sourceRoot":"","sources":["../../src/generators/agent-docs-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MetaData } from "@metaobjectsdev/metadata";
|
|
2
|
+
interface NodeIndexEntry {
|
|
3
|
+
readonly address: string;
|
|
4
|
+
readonly concern: string;
|
|
5
|
+
readonly claims: {
|
|
6
|
+
path: string;
|
|
7
|
+
subType: string;
|
|
8
|
+
level: number | undefined;
|
|
9
|
+
status: string | undefined;
|
|
10
|
+
statement: string | undefined;
|
|
11
|
+
}[];
|
|
12
|
+
}
|
|
13
|
+
/** Invert the walk: claimed node → the requirements that claim it. */
|
|
14
|
+
export declare function buildNodeIndex(root: MetaData): NodeIndexEntry[];
|
|
15
|
+
/**
|
|
16
|
+
* Render the page. Returns "" for a model declaring no requirements — the same contract
|
|
17
|
+
* `requirementsFile()` keeps, and the only reason a surface that is on by default is a
|
|
18
|
+
* no-op for a project without a ledger.
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderAgentRequirementsPage(root: MetaData): string;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=agent-requirements-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-requirements-page.d.ts","sourceRoot":"","sources":["../../src/generators/agent-requirements-page.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAiCzD,UAAU,cAAc;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,EAAE,CAAC;CAC5I;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,EAAE,CAqB/D;AAWD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAsFlE"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// `agent/requirements.md` — the ledger, plus the index that answers the question an agent
|
|
2
|
+
// actually asks.
|
|
3
|
+
//
|
|
4
|
+
// The `requirements` docs surface is REQUIREMENT-KEYED: it lists entries and, under each,
|
|
5
|
+
// what the entry claims. That is the right shape for reading a ledger and the wrong shape
|
|
6
|
+
// for the question that arises while editing code — *"I am about to change this node; does
|
|
7
|
+
// anything claim it?"* Answering that from the requirement-keyed page means reading all of
|
|
8
|
+
// it, which for this repository's own ledger is 175 rows.
|
|
9
|
+
//
|
|
10
|
+
// So this page carries the same index PLUS a NODE index: every claimed node → the
|
|
11
|
+
// requirements claiming it, at every grain. It is an inversion of `walkRequirements`, not
|
|
12
|
+
// a second walk — the same resolution, read the other way, so the two indexes cannot
|
|
13
|
+
// disagree about what resolves.
|
|
14
|
+
//
|
|
15
|
+
// LITERAL FQNs ON EVERY LINE, deliberately and even where it is repetitive. An agent
|
|
16
|
+
// retrieving over a long context finds a node by matching the token it is holding; a row
|
|
17
|
+
// that says "the field above" is unreachable to it. This is also why the node index is
|
|
18
|
+
// FLAT rather than nested under its owning object.
|
|
19
|
+
//
|
|
20
|
+
// A CLAIM THAT DOES NOT RESOLVE IS OMITTED, silently, exactly as `walkRequirements` omits
|
|
21
|
+
// it. Resolution severity depends on `@status` and belongs to `meta verify`; a docs page
|
|
22
|
+
// that rendered a dangling reference as though it pointed somewhere would be asserting
|
|
23
|
+
// the opposite of what the gate says.
|
|
24
|
+
//
|
|
25
|
+
// THE LEDGER IS EMBEDDED BELOW THE INDEX, and that duplication is deliberate rather than
|
|
26
|
+
// an oversight — the same content also lives at `requirements.md` when that surface is on.
|
|
27
|
+
// The node index alone would omit exactly the entries the mechanism is MEASURED on: a
|
|
28
|
+
// `retired` capability may carry no `@implementedBy` at all (FR-039 forbids it), so it
|
|
29
|
+
// resolves to no node and appears in no node index. The one controlled finding behind this
|
|
30
|
+
// whole vocabulary is that a retired capability goes unnoticed without a ledger — 0 of 24
|
|
31
|
+
// against 19 of 40 — and the page an agent is told to read *before adding a capability* is
|
|
32
|
+
// the last place to drop it. The cost is bytes on a large estate; the alternative is a page
|
|
33
|
+
// that silently loses the only part with evidence behind it.
|
|
34
|
+
import { REQUIREMENT_ATTR_STATEMENT } from "@metaobjectsdev/metadata";
|
|
35
|
+
import { GENERATED_HEADER } from "../constants.js";
|
|
36
|
+
import { concernOf, walkRequirements } from "../requirement-walk.js";
|
|
37
|
+
import { requirementRows } from "./requirements-view.js";
|
|
38
|
+
import { renderRequirementsMarkdown } from "./requirements-markdown.js";
|
|
39
|
+
const GENERATED_MARKER = `<!-- ${GENERATED_HEADER} — DO NOT EDIT. -->`;
|
|
40
|
+
/**
|
|
41
|
+
* The address of any claimed node: the ROOT node's `resolutionKey()` (which carries the
|
|
42
|
+
* effective package), then the child-name path down to it.
|
|
43
|
+
*
|
|
44
|
+
* Built by walking parents rather than read off the node, because only a root-level node
|
|
45
|
+
* has a resolution key — a claimed FIELD has a bare name, and `Subscriber.status` and
|
|
46
|
+
* `Order.status` would collide in this index if the owner were dropped.
|
|
47
|
+
*/
|
|
48
|
+
function nodeAddress(node) {
|
|
49
|
+
const segments = [];
|
|
50
|
+
let cur = node;
|
|
51
|
+
while (cur !== undefined) {
|
|
52
|
+
const parent = cur.parent;
|
|
53
|
+
// The last node with a parent is the root-level one; the metadata ROOT itself has no
|
|
54
|
+
// name worth printing, so the walk stops when the next step would leave the model.
|
|
55
|
+
if (parent === undefined || parent.parent === undefined) {
|
|
56
|
+
segments.push(cur.resolutionKey());
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
segments.push(cur.name);
|
|
60
|
+
cur = parent;
|
|
61
|
+
}
|
|
62
|
+
return segments.reverse().join(".");
|
|
63
|
+
}
|
|
64
|
+
/** Invert the walk: claimed node → the requirements that claim it. */
|
|
65
|
+
export function buildNodeIndex(root) {
|
|
66
|
+
const byAddress = new Map();
|
|
67
|
+
for (const walked of walkRequirements(root)) {
|
|
68
|
+
const statement = walked.node.attr(REQUIREMENT_ATTR_STATEMENT);
|
|
69
|
+
for (const target of walked.targets) {
|
|
70
|
+
const address = nodeAddress(target.node);
|
|
71
|
+
let entry = byAddress.get(address);
|
|
72
|
+
if (entry === undefined) {
|
|
73
|
+
entry = { address, concern: concernOf(target.node), claims: [] };
|
|
74
|
+
byAddress.set(address, entry);
|
|
75
|
+
}
|
|
76
|
+
entry.claims.push({
|
|
77
|
+
path: walked.view.path,
|
|
78
|
+
subType: walked.view.subType,
|
|
79
|
+
level: walked.view.level,
|
|
80
|
+
status: walked.view.status,
|
|
81
|
+
statement: typeof statement === "string" && statement !== "" ? statement : undefined,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return [...byAddress.values()].sort((a, b) => a.address.localeCompare(b.address));
|
|
86
|
+
}
|
|
87
|
+
function mdCell(text) {
|
|
88
|
+
return text.replace(/\|/g, "\\|");
|
|
89
|
+
}
|
|
90
|
+
/** Collapse to one line — a statement with a newline in it would end the table row. */
|
|
91
|
+
function oneLine(text) {
|
|
92
|
+
return text.replace(/\s+/g, " ").trim();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Render the page. Returns "" for a model declaring no requirements — the same contract
|
|
96
|
+
* `requirementsFile()` keeps, and the only reason a surface that is on by default is a
|
|
97
|
+
* no-op for a project without a ledger.
|
|
98
|
+
*/
|
|
99
|
+
export function renderAgentRequirementsPage(root) {
|
|
100
|
+
const rows = requirementRows(root);
|
|
101
|
+
if (rows.length === 0)
|
|
102
|
+
return "";
|
|
103
|
+
const index = buildNodeIndex(root);
|
|
104
|
+
const out = [];
|
|
105
|
+
out.push(GENERATED_MARKER);
|
|
106
|
+
out.push("");
|
|
107
|
+
out.push("# Requirements");
|
|
108
|
+
out.push("");
|
|
109
|
+
out.push("Read this before adding a capability, and before extending anything that looks like " +
|
|
110
|
+
"it already does what you were asked for.");
|
|
111
|
+
out.push("");
|
|
112
|
+
out.push("- A requirement is **prescriptive**: it states what should be true, never what " +
|
|
113
|
+
"happened. `status: retired` means the capability was BUILT and deliberately " +
|
|
114
|
+
"REMOVED — that entry is a prohibition, not history, and the right response to it " +
|
|
115
|
+
"is to stop, not to rebuild.");
|
|
116
|
+
out.push("- The **node index** below answers *\"does anything claim the thing I am about to " +
|
|
117
|
+
"change?\"*. Match the literal FQN.");
|
|
118
|
+
out.push("- **The ledger under it is not the same list.** A retired capability carries no " +
|
|
119
|
+
"`@implementedBy` — there is nothing left to point at — so it appears there and " +
|
|
120
|
+
"in no index. Read it before you conclude a capability does not exist yet.");
|
|
121
|
+
out.push("");
|
|
122
|
+
if (index.length > 0) {
|
|
123
|
+
out.push("## Node index");
|
|
124
|
+
out.push("");
|
|
125
|
+
out.push("| Node | Kind | Claimed by |");
|
|
126
|
+
out.push("|---|---|---|");
|
|
127
|
+
for (const entry of index) {
|
|
128
|
+
const claims = entry.claims
|
|
129
|
+
.map((c) => {
|
|
130
|
+
const level = c.level === undefined ? "" : ` L${c.level}`;
|
|
131
|
+
const status = c.status === undefined ? "" : ` (${c.status})`;
|
|
132
|
+
return `\`${c.path}\`${level}${status}`;
|
|
133
|
+
})
|
|
134
|
+
.join("<br>");
|
|
135
|
+
out.push(`| \`${entry.address}\` | \`${entry.concern}\` | ${claims} |`);
|
|
136
|
+
}
|
|
137
|
+
out.push("");
|
|
138
|
+
// The statements ride below the table: they are prose, they repeat across nodes a
|
|
139
|
+
// shared architectural entry claims, and putting one in a cell forces the table wide.
|
|
140
|
+
const stated = new Map();
|
|
141
|
+
for (const entry of index) {
|
|
142
|
+
for (const c of entry.claims) {
|
|
143
|
+
if (c.statement !== undefined)
|
|
144
|
+
stated.set(c.path, { subType: c.subType, statement: c.statement });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (stated.size > 0) {
|
|
148
|
+
out.push("### What those requirements say");
|
|
149
|
+
out.push("");
|
|
150
|
+
for (const [path, { subType, statement }] of [...stated.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
151
|
+
out.push(`- \`${path}\` (\`${subType}\`) — ${mdCell(oneLine(statement))}`);
|
|
152
|
+
}
|
|
153
|
+
out.push("");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
out.push("## Node index");
|
|
158
|
+
out.push("");
|
|
159
|
+
out.push("No requirement resolves to a model node. The common reason is the ordinary one: an " +
|
|
160
|
+
"entry at L4 or L5 that simply declares no `@implementedBy` yet, which is legal " +
|
|
161
|
+
"and is what a `planned` entry looks like. The others are an entry sitting ABOVE " +
|
|
162
|
+
"the L4 link floor (where a claim is not permitted), a `retired` entry (where it " +
|
|
163
|
+
"is forbidden outright), and a claim that names a node nothing resolves — " +
|
|
164
|
+
"`meta verify` is what says which.");
|
|
165
|
+
out.push("");
|
|
166
|
+
}
|
|
167
|
+
out.push("## The ledger");
|
|
168
|
+
out.push("");
|
|
169
|
+
// The SAME renderer the `requirements` surface uses. A second rendering of the ledger
|
|
170
|
+
// would be a second thing to keep true. `embedded` drops its own H1 and demotes every
|
|
171
|
+
// heading one level, so the entries nest under this section instead of escaping it.
|
|
172
|
+
out.push(renderRequirementsMarkdown(rows, { embedded: true }).replace(/\n+$/, ""));
|
|
173
|
+
return `${out.join("\n").replace(/\n+$/, "")}\n`;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=agent-requirements-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-requirements-page.js","sourceRoot":"","sources":["../../src/generators/agent-requirements-page.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** A canonical SQL type as `migrate-ts` models it. Opaque here — only `columnType` reads it. */
|
|
2
|
+
export interface SchemaColumnLike {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly nullable: boolean;
|
|
5
|
+
readonly default?: {
|
|
6
|
+
readonly kind: "literal" | "expr";
|
|
7
|
+
readonly value: string;
|
|
8
|
+
} | undefined;
|
|
9
|
+
readonly identity?: "increment" | "uuid" | undefined;
|
|
10
|
+
/** Threaded from the field's `@description` — the business semantics beside the column. */
|
|
11
|
+
readonly description?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface SchemaIndexLike {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly columns: readonly string[];
|
|
16
|
+
readonly unique: boolean;
|
|
17
|
+
readonly where?: string | undefined;
|
|
18
|
+
readonly expr?: string | undefined;
|
|
19
|
+
readonly using?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface SchemaFkLike {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly columns: readonly string[];
|
|
24
|
+
readonly refTable: string;
|
|
25
|
+
readonly refColumns: readonly string[];
|
|
26
|
+
readonly onDelete?: string | undefined;
|
|
27
|
+
readonly onUpdate?: string | undefined;
|
|
28
|
+
}
|
|
29
|
+
export interface SchemaCheckLike {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly expression: string;
|
|
32
|
+
}
|
|
33
|
+
export interface SchemaTableLike {
|
|
34
|
+
readonly name: string;
|
|
35
|
+
readonly schema?: string | undefined;
|
|
36
|
+
readonly columns: readonly SchemaColumnLike[];
|
|
37
|
+
readonly indexes: readonly SchemaIndexLike[];
|
|
38
|
+
readonly foreignKeys: readonly SchemaFkLike[];
|
|
39
|
+
readonly checks: readonly SchemaCheckLike[];
|
|
40
|
+
readonly primaryKey: readonly string[];
|
|
41
|
+
/** Threaded from the entity's `@description`. */
|
|
42
|
+
readonly description?: string | undefined;
|
|
43
|
+
}
|
|
44
|
+
export interface SchemaViewLike {
|
|
45
|
+
readonly name: string;
|
|
46
|
+
readonly schema?: string | undefined;
|
|
47
|
+
readonly columns?: readonly {
|
|
48
|
+
readonly name: string;
|
|
49
|
+
}[] | undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Everything `agent/schema.md` renders from, plus the two resolvers it refuses to own.
|
|
53
|
+
*/
|
|
54
|
+
export interface AgentSchemaInput {
|
|
55
|
+
/** `postgres` | `sqlite` | `d1` — named on the page so a reader knows which SQL they are reading. */
|
|
56
|
+
readonly dialect: string;
|
|
57
|
+
readonly tables: readonly SchemaTableLike[];
|
|
58
|
+
readonly views: readonly SchemaViewLike[];
|
|
59
|
+
/** Qualified physical name → the declaring object's `resolutionKey()`. */
|
|
60
|
+
readonly provenance: ReadonlyMap<string, string>;
|
|
61
|
+
/** `migrate-ts`'s `columnTypeSql`, bound to `dialect`. */
|
|
62
|
+
readonly columnType: (column: SchemaColumnLike) => string;
|
|
63
|
+
/** `migrate-ts`'s `qualifiedDbName` — the ONE key the provenance map is built with. */
|
|
64
|
+
readonly qualify: (obj: {
|
|
65
|
+
name: string;
|
|
66
|
+
schema?: string | undefined;
|
|
67
|
+
}) => string;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=agent-schema-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-schema-input.d.ts","sourceRoot":"","sources":["../../src/generators/agent-schema-input.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// The `agent/schema.md` surface's INPUT contract — the physical schema, supplied by
|
|
2
|
+
// whoever owns it.
|
|
3
|
+
//
|
|
4
|
+
// codegen-ts does not compute any of this and must not. The expected schema, the
|
|
5
|
+
// dialect SQL type of a column, and the qualified name a table is keyed by are all
|
|
6
|
+
// `@metaobjectsdev/migrate-ts`'s answers: it builds the snapshot the diff compares, it
|
|
7
|
+
// renders the DDL, and its `qualifiedDbName` is the one key three separate suppression
|
|
8
|
+
// sets already agree on. Re-deriving any of them here would give an adopter a page
|
|
9
|
+
// describing a schema the tool does not produce — and the disagreement would be
|
|
10
|
+
// invisible, because a documentation page looks authoritative and nothing compares it
|
|
11
|
+
// to the migration.
|
|
12
|
+
//
|
|
13
|
+
// So the surface takes the schema as an ARGUMENT, with the resolvers injected. The
|
|
14
|
+
// types below are structural on purpose: `migrate-ts`'s own `SchemaSnapshot`,
|
|
15
|
+
// `TableDescriptor` and `ColumnDescriptor` satisfy them without codegen-ts taking a
|
|
16
|
+
// dependency on that package (it has none today, and the docs surface is not a reason
|
|
17
|
+
// to add one — `meta docs` in the CLI depends on both and is where they meet).
|
|
18
|
+
//
|
|
19
|
+
// ABSENT INPUT IS A SUPPORTED STATE, not a failure. `meta docs` runs without a gen
|
|
20
|
+
// config, and a project with no dialect has no physical schema to describe; the surface
|
|
21
|
+
// then emits nothing rather than a page full of unknowns.
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=agent-schema-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-schema-input.js","sourceRoot":"","sources":["../../src/generators/agent-schema-input.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,mBAAmB;AACnB,EAAE;AACF,iFAAiF;AACjF,mFAAmF;AACnF,uFAAuF;AACvF,uFAAuF;AACvF,mFAAmF;AACnF,gFAAgF;AAChF,sFAAsF;AACtF,oBAAoB;AACpB,EAAE;AACF,mFAAmF;AACnF,8EAA8E;AAC9E,oFAAoF;AACpF,sFAAsF;AACtF,+EAA+E;AAC/E,EAAE;AACF,mFAAmF;AACnF,wFAAwF;AACxF,0DAA0D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AgentSchemaInput } from "./agent-schema-input.js";
|
|
2
|
+
export interface AgentSchemaPageOptions {
|
|
3
|
+
/** Column → declaring field, per QUALIFIED table name. Supplied by the generator, which
|
|
4
|
+
* holds the loaded model; see `agentDocsFile`. */
|
|
5
|
+
readonly declaredBy: ReadonlyMap<string, ReadonlyMap<string, {
|
|
6
|
+
field: string;
|
|
7
|
+
type: string;
|
|
8
|
+
}>>;
|
|
9
|
+
/** Per-projection lineage lines, keyed by QUALIFIED view name. */
|
|
10
|
+
readonly viewLineage: ReadonlyMap<string, readonly string[]>;
|
|
11
|
+
/** Relationship lines, already rendered from the model. */
|
|
12
|
+
readonly relationships: readonly string[];
|
|
13
|
+
/** Enum lines, already rendered from the model. */
|
|
14
|
+
readonly enums: readonly string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Render the whole page. Returns "" when there is no physical schema at all, which is
|
|
18
|
+
* what lets the surface emit no FILE rather than a page describing nothing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderAgentSchemaPage(input: AgentSchemaInput, opts: AgentSchemaPageOptions): string;
|
|
21
|
+
//# sourceMappingURL=agent-schema-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-schema-page.d.ts","sourceRoot":"","sources":["../../src/generators/agent-schema-page.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,gBAAgB,EAKjB,MAAM,yBAAyB,CAAC;AAsIjC,MAAM,WAAW,sBAAsB;IACrC;uDACmD;IACnD,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/F,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC7D,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,sBAAsB,GAC3B,MAAM,CAiHR"}
|