@adminiumjs/engine 0.1.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.
Files changed (94) hide show
  1. package/LICENSE +661 -0
  2. package/dist/adapter-registry.d.ts +62 -0
  3. package/dist/adapter-registry.d.ts.map +1 -0
  4. package/dist/adapter-registry.js +75 -0
  5. package/dist/adapter-registry.js.map +1 -0
  6. package/dist/adapter.d.ts +384 -0
  7. package/dist/adapter.d.ts.map +1 -0
  8. package/dist/adapter.js +54 -0
  9. package/dist/adapter.js.map +1 -0
  10. package/dist/capabilities.d.ts +57 -0
  11. package/dist/capabilities.d.ts.map +1 -0
  12. package/dist/capabilities.js +131 -0
  13. package/dist/capabilities.js.map +1 -0
  14. package/dist/classify/columns.d.ts +57 -0
  15. package/dist/classify/columns.d.ts.map +1 -0
  16. package/dist/classify/columns.js +535 -0
  17. package/dist/classify/columns.js.map +1 -0
  18. package/dist/classify/index.d.ts +29 -0
  19. package/dist/classify/index.d.ts.map +1 -0
  20. package/dist/classify/index.js +44 -0
  21. package/dist/classify/index.js.map +1 -0
  22. package/dist/classify/names.d.ts +11 -0
  23. package/dist/classify/names.d.ts.map +1 -0
  24. package/dist/classify/names.js +19 -0
  25. package/dist/classify/names.js.map +1 -0
  26. package/dist/classify/pii.d.ts +29 -0
  27. package/dist/classify/pii.d.ts.map +1 -0
  28. package/dist/classify/pii.js +55 -0
  29. package/dist/classify/pii.js.map +1 -0
  30. package/dist/classify/tables.d.ts +64 -0
  31. package/dist/classify/tables.d.ts.map +1 -0
  32. package/dist/classify/tables.js +303 -0
  33. package/dist/classify/tables.js.map +1 -0
  34. package/dist/config-schema/envelope.d.ts +83 -0
  35. package/dist/config-schema/envelope.d.ts.map +1 -0
  36. package/dist/config-schema/envelope.js +87 -0
  37. package/dist/config-schema/envelope.js.map +1 -0
  38. package/dist/config-schema/index.d.ts +14 -0
  39. package/dist/config-schema/index.d.ts.map +1 -0
  40. package/dist/config-schema/index.js +15 -0
  41. package/dist/config-schema/index.js.map +1 -0
  42. package/dist/config-schema/migrations.d.ts +44 -0
  43. package/dist/config-schema/migrations.d.ts.map +1 -0
  44. package/dist/config-schema/migrations.js +62 -0
  45. package/dist/config-schema/migrations.js.map +1 -0
  46. package/dist/generate/archetype.d.ts +76 -0
  47. package/dist/generate/archetype.d.ts.map +1 -0
  48. package/dist/generate/archetype.js +250 -0
  49. package/dist/generate/archetype.js.map +1 -0
  50. package/dist/generate/crud.d.ts +36 -0
  51. package/dist/generate/crud.d.ts.map +1 -0
  52. package/dist/generate/crud.js +45 -0
  53. package/dist/generate/crud.js.map +1 -0
  54. package/dist/generate/dashboard.d.ts +43 -0
  55. package/dist/generate/dashboard.d.ts.map +1 -0
  56. package/dist/generate/dashboard.js +61 -0
  57. package/dist/generate/dashboard.js.map +1 -0
  58. package/dist/generate/domains.d.ts +29 -0
  59. package/dist/generate/domains.d.ts.map +1 -0
  60. package/dist/generate/domains.js +145 -0
  61. package/dist/generate/domains.js.map +1 -0
  62. package/dist/generate/index.d.ts +78 -0
  63. package/dist/generate/index.d.ts.map +1 -0
  64. package/dist/generate/index.js +301 -0
  65. package/dist/generate/index.js.map +1 -0
  66. package/dist/generate/util.d.ts +46 -0
  67. package/dist/generate/util.d.ts.map +1 -0
  68. package/dist/generate/util.js +123 -0
  69. package/dist/generate/util.js.map +1 -0
  70. package/dist/index.d.ts +8 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +8 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/schema-model.d.ts +1853 -0
  75. package/dist/schema-model.d.ts.map +1 -0
  76. package/dist/schema-model.js +463 -0
  77. package/dist/schema-model.js.map +1 -0
  78. package/dist/snapshot/diff.d.ts +258 -0
  79. package/dist/snapshot/diff.d.ts.map +1 -0
  80. package/dist/snapshot/diff.js +151 -0
  81. package/dist/snapshot/diff.js.map +1 -0
  82. package/dist/snapshot/hash.d.ts +23 -0
  83. package/dist/snapshot/hash.d.ts.map +1 -0
  84. package/dist/snapshot/hash.js +47 -0
  85. package/dist/snapshot/hash.js.map +1 -0
  86. package/dist/snapshot/index.d.ts +28 -0
  87. package/dist/snapshot/index.d.ts.map +1 -0
  88. package/dist/snapshot/index.js +26 -0
  89. package/dist/snapshot/index.js.map +1 -0
  90. package/dist/snapshot/sha256.d.ts +14 -0
  91. package/dist/snapshot/sha256.d.ts.map +1 -0
  92. package/dist/snapshot/sha256.js +99 -0
  93. package/dist/snapshot/sha256.js.map +1 -0
  94. package/package.json +37 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../src/generate/crud.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AAIpC;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,iFAAiF;IACjF,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACzC;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,mBAAmB,EAC1B,GAAG,EAAE,gBAAgB,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsBzB"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * `page-crud` envelope generation — one per included table (research/
3
+ * widget-registry.md §14: "Every included table"; 01-architecture.md §6.1
4
+ * fixes the config body shape: `columns[]`, `defaultSort`, `pageSize`,
5
+ * `detail`).
6
+ *
7
+ * The body vocabulary — column selection, tones, form-field mapping — lives in
8
+ * `@adminium/widgets/generate` (`composeCrudBody`; 04 §8: the Registry owns
9
+ * what a generated page contains). This module keeps only what the leaf cannot
10
+ * know: slug/id allocation, nav placement, and the §6.1 envelope wrap. Inputs
11
+ * arrive pre-adapted through `./archetype.ts`'s `toCandidateModel` — the single
12
+ * place the engine and registry vocabularies meet.
13
+ */
14
+ import { composeCrudBody, } from '@adminium/widgets/generate';
15
+ import { humanize, pageIdFor } from './util.js';
16
+ /**
17
+ * The §7.1 rule-7 tone map moved into the leaf with the rest of the body
18
+ * vocabulary; re-exported because the generate surface is public API of the
19
+ * self-host package (`@adminium/engine` root re-exports this module).
20
+ */
21
+ export { enumTones } from '@adminium/widgets/generate';
22
+ /** Build the (unhashed, unvalidated) `page-crud` envelope for one table. */
23
+ export function buildCrudEnvelope(entry, ctx) {
24
+ const { table, classified } = entry;
25
+ const body = composeCrudBody(table, classified, {
26
+ readOnly: ctx.readOnly,
27
+ includedTableIds: ctx.includedTableIds,
28
+ relations: ctx.relations,
29
+ });
30
+ return {
31
+ v: 1,
32
+ kind: 'page',
33
+ id: pageIdFor(ctx.connectionId, ctx.slug),
34
+ template: 'page-crud',
35
+ title: { key: `nav.${ctx.slug}`, fallback: table.label ?? humanize(table.name) },
36
+ source: { connectionId: ctx.connectionId, table: table.id },
37
+ nav: { group: ctx.navGroup, icon: ctx.navIcon, order: ctx.navOrder, slug: ctx.slug },
38
+ access: {
39
+ minRole: 'viewer',
40
+ permissions: [`table:${table.id}:read`],
41
+ },
42
+ config: { ...body },
43
+ };
44
+ }
45
+ //# sourceMappingURL=crud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.js","sourceRoot":"","sources":["../../src/generate/crud.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,eAAe,GAGhB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEhD;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAqB,MAAM,4BAA4B,CAAC;AAgB1E,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAC/B,KAA0B,EAC1B,GAAqB;IAErB,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IACpC,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE;QAC9C,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC,CAAC;IAEH,OAAO;QACL,CAAC,EAAE,CAAC;QACJ,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,CAAC;QACzC,QAAQ,EAAE,WAAW;QACrB,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QAChF,MAAM,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE;QAC3D,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE;QACpF,MAAM,EAAE;YACN,OAAO,EAAE,QAAQ;YACjB,WAAW,EAAE,CAAC,SAAS,KAAK,CAAC,EAAE,OAAO,CAAC;SACxC;QACD,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * `page-dashboard` envelope generation — one per FK-cluster domain, cap 3
3
+ * for v1 (research/widget-registry.md §14 trigger, §15 decision summary).
4
+ *
5
+ * The §15 widget set (4 KPIs, hero `chart-line-area`, `chart-donut`) is
6
+ * assembled by `@adminium/widgets/generate`'s `emitDomainDashboardCandidates`
7
+ * and laid out by `composeTemplate` against the `page-dashboard` manifest —
8
+ * geometry comes from the manifest's v2 slot areas, not hand-stamped x/y/w/h.
9
+ * This module keeps only what the leaf cannot know: the §6.1 envelope wrap,
10
+ * nav placement, and the stored `config.domain` block (`ComposedPage` carries
11
+ * none of them). Domain detection itself stays in `./domains.js`.
12
+ */
13
+ import { type CandidateRelation, type CandidateTableInput, type ComposeWarning } from '@adminium/widgets/generate';
14
+ import type { DatabaseModel, TableModel } from '../schema-model.js';
15
+ import type { Domain } from './domains.js';
16
+ export interface DashboardBuildContext {
17
+ connectionId: string;
18
+ slug: string;
19
+ title: string;
20
+ navOrder: number;
21
+ /** Live registry membership test, threaded to H4 (04 §10). */
22
+ isRegistered?: ((widgetId: string) => boolean) | undefined;
23
+ }
24
+ export interface DashboardBuildResult {
25
+ /**
26
+ * Unhashed, unvalidated envelope — `generatePages` stamps + validates it.
27
+ * `null` ⇔ the domain has no time axis at all (05 §8 trigger requires ≥ 1
28
+ * timestamp) or composition failed — the caller records a warning.
29
+ */
30
+ envelope: Record<string, unknown> | null;
31
+ warnings: readonly ComposeWarning[];
32
+ }
33
+ /**
34
+ * §8 trigger in the pre-migration signature (`DatabaseModel` + `TableModel[]`):
35
+ * a domain can host a dashboard only with ≥ 1 time axis. Kept as public API of
36
+ * the self-host package (the root re-exports this module); `generatePages`
37
+ * itself asks the leaf's `domainHasDashboardSignal` over the shared candidate
38
+ * mirror instead of re-adapting per domain.
39
+ */
40
+ export declare function hasDashboardSignal(model: DatabaseModel, domain: Domain, tables: readonly TableModel[]): boolean;
41
+ /** Build the `page-dashboard` envelope for a domain and wrap it per §6.1. */
42
+ export declare function buildDashboardEnvelope(domain: Domain, model: readonly CandidateTableInput[], relations: readonly CandidateRelation[], ctx: DashboardBuildContext): DashboardBuildResult;
43
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/generate/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;CAC5D;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,UAAU,EAAE,GAC5B,OAAO,CAOT;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,SAAS,EAAE,SAAS,iBAAiB,EAAE,EACvC,GAAG,EAAE,qBAAqB,GACzB,oBAAoB,CAmCtB"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * `page-dashboard` envelope generation — one per FK-cluster domain, cap 3
3
+ * for v1 (research/widget-registry.md §14 trigger, §15 decision summary).
4
+ *
5
+ * The §15 widget set (4 KPIs, hero `chart-line-area`, `chart-donut`) is
6
+ * assembled by `@adminium/widgets/generate`'s `emitDomainDashboardCandidates`
7
+ * and laid out by `composeTemplate` against the `page-dashboard` manifest —
8
+ * geometry comes from the manifest's v2 slot areas, not hand-stamped x/y/w/h.
9
+ * This module keeps only what the leaf cannot know: the §6.1 envelope wrap,
10
+ * nav placement, and the stored `config.domain` block (`ComposedPage` carries
11
+ * none of them). Domain detection itself stays in `./domains.js`.
12
+ */
13
+ import { composeTemplate, domainHasDashboardSignal, emitDomainDashboardCandidates, } from '@adminium/widgets/generate';
14
+ import { classifyModel } from '../classify/index.js';
15
+ import { toCandidateModel } from './archetype.js';
16
+ import { pageIdFor } from './util.js';
17
+ /**
18
+ * §8 trigger in the pre-migration signature (`DatabaseModel` + `TableModel[]`):
19
+ * a domain can host a dashboard only with ≥ 1 time axis. Kept as public API of
20
+ * the self-host package (the root re-exports this module); `generatePages`
21
+ * itself asks the leaf's `domainHasDashboardSignal` over the shared candidate
22
+ * mirror instead of re-adapting per domain.
23
+ */
24
+ export function hasDashboardSignal(model, domain, tables) {
25
+ const classified = new Map(classifyModel(model).tables.map((t) => [t.tableId, t]));
26
+ return domainHasDashboardSignal(domain, toCandidateModel(model, tables, classified), model.relations);
27
+ }
28
+ /** Build the `page-dashboard` envelope for a domain and wrap it per §6.1. */
29
+ export function buildDashboardEnvelope(domain, model, relations, ctx) {
30
+ const candidates = emitDomainDashboardCandidates(domain, model, relations, {
31
+ connectionId: ctx.connectionId,
32
+ });
33
+ if (candidates === null)
34
+ return { envelope: null, warnings: [] };
35
+ const composed = composeTemplate('page-dashboard', candidates, ctx.isRegistered === undefined ? {} : { isRegistered: ctx.isRegistered });
36
+ if (composed.page === null)
37
+ return { envelope: null, warnings: composed.warnings };
38
+ return {
39
+ warnings: composed.warnings,
40
+ envelope: {
41
+ v: 1,
42
+ kind: composed.page.type,
43
+ id: pageIdFor(ctx.connectionId, ctx.slug),
44
+ template: composed.page.template,
45
+ title: { key: `nav.${ctx.slug}`, fallback: ctx.title },
46
+ source: { connectionId: ctx.connectionId, table: null },
47
+ nav: { group: 'workspace', icon: 'layout-dashboard', order: ctx.navOrder, slug: ctx.slug },
48
+ access: { minRole: 'viewer', permissions: [] },
49
+ config: {
50
+ templateVersion: composed.page.templateVersion,
51
+ toolbar: composed.page.toolbar,
52
+ overlays: composed.page.overlays,
53
+ // What the page aggregates — kept on the stored document so the domain
54
+ // membership survives without re-running detection.
55
+ domain: { key: domain.key, label: domain.label, tables: domain.tableIds },
56
+ layout: composed.page.layout,
57
+ },
58
+ },
59
+ };
60
+ }
61
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/generate/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * FK-cluster domain detection — 05-introspection-engine.md §8.3.
3
+ *
4
+ * Domains drive "one `page-dashboard` per domain" (research/widget-registry.md
5
+ * §15): connected components over the relation graph (declared + accepted
6
+ * inferred, confidence ≥ 0.8); singleton tables attach to the component they
7
+ * share a name prefix with, else to a "General" domain. Domain naming: schema
8
+ * name when meaningful, else the most-central (weighted hub) table's plural
9
+ * label.
10
+ */
11
+ import type { DatabaseModel, TableModel } from '../schema-model.js';
12
+ export interface Domain {
13
+ /** Deterministic kebab-case key, e.g. `orders`. */
14
+ key: string;
15
+ /** Human label, e.g. `Orders`. */
16
+ label: string;
17
+ /** All member table ids, sorted. */
18
+ tableIds: string[];
19
+ /** The weighted hub — highest relation degree, ties by row estimate then name. */
20
+ hubTableId: string;
21
+ }
22
+ /**
23
+ * Detect FK-cluster domains over the model's non-system tables. Join tables
24
+ * participate as edges (their relations connect the sides) but are never
25
+ * chosen as hubs. Components larger than 12 tables would split by schema per
26
+ * §8.3 — with a single schema they stay one domain.
27
+ */
28
+ export declare function detectDomains(model: DatabaseModel, tables: readonly TableModel[]): Domain[];
29
+ //# sourceMappingURL=domains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../src/generate/domains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGpE,MAAM,WAAW,MAAM;IACrB,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;CACpB;AAiCD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,EAAE,CAkG3F"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * FK-cluster domain detection — 05-introspection-engine.md §8.3.
3
+ *
4
+ * Domains drive "one `page-dashboard` per domain" (research/widget-registry.md
5
+ * §15): connected components over the relation graph (declared + accepted
6
+ * inferred, confidence ≥ 0.8); singleton tables attach to the component they
7
+ * share a name prefix with, else to a "General" domain. Domain naming: schema
8
+ * name when meaningful, else the most-central (weighted hub) table's plural
9
+ * label.
10
+ */
11
+ import { humanize, pluralizeWord, slugify } from './util.js';
12
+ /** Relations that count as domain edges (§6 thresholds: accepted at ≥ 0.8). */
13
+ const EDGE_CONFIDENCE = 0.8;
14
+ class UnionFind {
15
+ parent = new Map();
16
+ find(x) {
17
+ let root = this.parent.get(x) ?? x;
18
+ if (root !== x) {
19
+ root = this.find(root);
20
+ this.parent.set(x, root);
21
+ }
22
+ return root;
23
+ }
24
+ union(a, b) {
25
+ const ra = this.find(a);
26
+ const rb = this.find(b);
27
+ // Deterministic root selection: smaller id wins.
28
+ if (ra === rb)
29
+ return;
30
+ if (ra < rb)
31
+ this.parent.set(rb, ra);
32
+ else
33
+ this.parent.set(ra, rb);
34
+ }
35
+ }
36
+ function sharedPrefix(a, b) {
37
+ const ta = (a.split('.').pop() ?? a).split('_')[0] ?? '';
38
+ const tb = (b.split('.').pop() ?? b).split('_')[0] ?? '';
39
+ return ta.length >= 3 && ta === tb;
40
+ }
41
+ /**
42
+ * Detect FK-cluster domains over the model's non-system tables. Join tables
43
+ * participate as edges (their relations connect the sides) but are never
44
+ * chosen as hubs. Components larger than 12 tables would split by schema per
45
+ * §8.3 — with a single schema they stay one domain.
46
+ */
47
+ export function detectDomains(model, tables) {
48
+ const ids = new Set(tables.map((t) => t.id));
49
+ const uf = new UnionFind();
50
+ const degree = new Map();
51
+ for (const id of ids)
52
+ degree.set(id, 0);
53
+ for (const relation of model.relations) {
54
+ if (relation.confidence < EDGE_CONFIDENCE)
55
+ continue;
56
+ const { tableId: fromId } = relation.from;
57
+ const { tableId: toId } = relation.to;
58
+ if (!ids.has(fromId) || !ids.has(toId))
59
+ continue;
60
+ uf.union(fromId, toId);
61
+ if (fromId !== toId) {
62
+ degree.set(fromId, (degree.get(fromId) ?? 0) + 1);
63
+ degree.set(toId, (degree.get(toId) ?? 0) + 1);
64
+ }
65
+ }
66
+ const components = new Map();
67
+ const singletons = [];
68
+ for (const table of [...tables].sort((a, b) => a.id.localeCompare(b.id))) {
69
+ const root = uf.find(table.id);
70
+ const members = components.get(root) ?? [];
71
+ members.push(table.id);
72
+ components.set(root, members);
73
+ }
74
+ for (const [root, members] of [...components]) {
75
+ if (members.length === 1) {
76
+ singletons.push(members[0]);
77
+ components.delete(root);
78
+ }
79
+ }
80
+ // Singletons attach to a component sharing a name prefix, else "General".
81
+ const general = [];
82
+ for (const singleton of singletons) {
83
+ let attached = false;
84
+ for (const members of components.values()) {
85
+ if (members.some((member) => sharedPrefix(member, singleton))) {
86
+ members.push(singleton);
87
+ members.sort();
88
+ attached = true;
89
+ break;
90
+ }
91
+ }
92
+ if (!attached)
93
+ general.push(singleton);
94
+ }
95
+ const byId = new Map(tables.map((t) => [t.id, t]));
96
+ const hubOf = (members) => {
97
+ const candidates = members.filter((id) => byId.get(id)?.semantics?.role !== 'join-table');
98
+ const pool = candidates.length > 0 ? candidates : [...members];
99
+ return [...pool].sort((a, b) => {
100
+ const dd = (degree.get(b) ?? 0) - (degree.get(a) ?? 0);
101
+ if (dd !== 0)
102
+ return dd;
103
+ const rr = (byId.get(b)?.rowCountEstimate ?? 0) - (byId.get(a)?.rowCountEstimate ?? 0);
104
+ if (rr !== 0)
105
+ return rr;
106
+ return a.localeCompare(b);
107
+ })[0];
108
+ };
109
+ const named = (members) => {
110
+ const hub = hubOf(members);
111
+ const hubTable = byId.get(hub);
112
+ // Schema name when meaningful (§8.3), else the hub table's plural label.
113
+ const schema = hubTable?.schema ?? 'public';
114
+ const meaningful = schema !== 'public' && schema !== 'main' && schema !== model.name;
115
+ const rawLabel = meaningful ? humanize(schema) : humanize(hub);
116
+ const heuristic = meaningful
117
+ ? rawLabel
118
+ : rawLabel
119
+ .split(' ')
120
+ .map((w, i, all) => (i === all.length - 1 ? pluralizeWord(w) : w))
121
+ .join(' ');
122
+ // A hub table carrying an effective label (Studio remap / accepted LLM
123
+ // rename) names the domain verbatim — it is already human-authored, so it
124
+ // is never pluralized. The KEY stays heuristic-derived: it feeds dashboard
125
+ // slugs and page ids, which must not move when a table is renamed.
126
+ // DELIBERATE asymmetry: in a meaningful (named) schema the SCHEMA names
127
+ // the domain, so renaming the hub table retitles its crud/archetype pages
128
+ // but NOT the '<Domain> Dashboard' — the schema name stays authoritative.
129
+ const label = meaningful ? heuristic : (hubTable?.label ?? heuristic);
130
+ return { key: slugify(heuristic), label, tableIds: members, hubTableId: hub };
131
+ };
132
+ const domains = [...components.values()].map(named);
133
+ if (general.length > 0) {
134
+ domains.push({
135
+ key: 'general',
136
+ label: 'General',
137
+ tableIds: [...general].sort(),
138
+ hubTableId: hubOf(general),
139
+ });
140
+ }
141
+ // Largest first; ties break on key for determinism.
142
+ domains.sort((a, b) => b.tableIds.length - a.tableIds.length || a.key.localeCompare(b.key));
143
+ return domains;
144
+ }
145
+ //# sourceMappingURL=domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/generate/domains.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * `generatePages()` — Generator v1 (M4-T08, 05-introspection-engine.md
3
+ * generation section, research/widget-registry.md §14–§15, 09-generated-app.md
4
+ * §2.2 nav rules, §8.4 intent variants).
5
+ *
6
+ * Pure and deterministic: same classified model + options in, same
7
+ * `PageEnvelope[]` out (05 §9 — regeneration is safe to re-run). Every
8
+ * emitted envelope is validated against `pageEnvelopeSchema` (and dashboard
9
+ * widget instances against `widgetConfigSchema`) before return — outputs
10
+ * cannot drift from the frozen config contract.
11
+ */
12
+ import { z } from 'zod';
13
+ import { type PageEnvelope } from '../config-schema/envelope.js';
14
+ import type { DatabaseModel } from '../schema-model.js';
15
+ export { archetypeSlug, buildArchetypeEnvelope, composeRequestedArchetype, toCandidateModel, type ArchetypeBuildContext, type ArchetypeBuildResult, } from './archetype.js';
16
+ export { buildCrudEnvelope, enumTones, type CrudBuildContext, type CrudEnumTone } from './crud.js';
17
+ export { buildDashboardEnvelope, hasDashboardSignal, type DashboardBuildContext, type DashboardBuildResult, } from './dashboard.js';
18
+ export { detectDomains, type Domain } from './domains.js';
19
+ export { ID_SLUG_BUDGET, MAX_SLUG_LENGTH, hashEnvelope, humanize, pageIdFor, pluralizeWord, slugify, SlugRegistry, } from './util.js';
20
+ /** 09 §8.4 generation intent variants (adminium_connections.settings.intent). */
21
+ export declare const GENERATE_INTENTS: readonly ["full-admin", "read-only-analytics", "crud", "support-console"];
22
+ export declare const generateIntentSchema: z.ZodEnum<{
23
+ "full-admin": "full-admin";
24
+ "read-only-analytics": "read-only-analytics";
25
+ crud: "crud";
26
+ "support-console": "support-console";
27
+ }>;
28
+ export type GenerateIntent = z.infer<typeof generateIntentSchema>;
29
+ /** One `page-dashboard` per major domain, cap 3 for v1. */
30
+ export declare const DASHBOARD_CAP = 3;
31
+ export interface GenerateOptions {
32
+ /** 09 §8.4; default 'full-admin'. */
33
+ intent?: GenerateIntent | undefined;
34
+ /**
35
+ * Connection the pages bind to. Defaults to the model's live-source
36
+ * connection id; import models without one get CRUD pages with a null
37
+ * source connection and no dashboards (descriptors need a connection).
38
+ */
39
+ connectionId?: string | null | undefined;
40
+ /**
41
+ * Widget-registry membership test, threaded into the §14 archetype step
42
+ * (04 §8 H1/H4) so unregistered ids are dropped before they reach a stored
43
+ * page.
44
+ *
45
+ * **Defaults to `isRegisteredWidgetId`** — the checked-in mirror of
46
+ * `widgetRegistry` that `@adminium/widgets/generate` exports (the Engine is
47
+ * Node-only and cannot import the registry map itself, and neither can the
48
+ * server, 01 §2.3). Defaulting rather than requiring is deliberate: this option
49
+ * being *optional and omitted* by the sole production caller is what made every
50
+ * registry filter in the archetype pipeline dead code, persisting chrome ids
51
+ * like `toast-stack`/`date-range-picker` into real page envelopes.
52
+ *
53
+ * Pass an explicit test only to override that catalog — a Studio preview
54
+ * against a marketplace registry, or `() => true` in a unit test driving
55
+ * synthetic widget ids.
56
+ */
57
+ isRegistered?: ((widgetId: string) => boolean) | undefined;
58
+ }
59
+ export interface GenerateResult {
60
+ pages: PageEnvelope[];
61
+ warnings: string[];
62
+ }
63
+ /**
64
+ * Generate the v1 page set for a classified model: one `page-crud` per
65
+ * included table plus one `page-dashboard` per FK-cluster domain (cap
66
+ * {@link DASHBOARD_CAP}), honoring the 09 §8.4 intent. The model should come
67
+ * out of `applyClassification` (snapshots persist that form); classification
68
+ * is recomputed here regardless — `classifyModel` is pure and cheap, and the
69
+ * generator also needs the non-persisted shape/displayColumn outputs. Column
70
+ * stamps with `source: 'llm' | 'override'` still beat the recomputed tags
71
+ * (05 §7, `archetype.ts#toClassifiedInput`); heuristic stamps do not — the
72
+ * recomputed classification of the model as handed in (post `includedTables`
73
+ * filtering) is authoritative.
74
+ */
75
+ export declare function generatePages(model: DatabaseModel, opts?: GenerateOptions): GenerateResult;
76
+ /** Human-readable page label — used by server replies and the demo script. */
77
+ export declare function pageLabel(page: PageEnvelope): string;
78
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generate/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,oBAAoB,CAAC;AAOpE,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AACnG,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,aAAa,EACb,OAAO,EACP,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,2EAKnB,CAAC;AACX,eAAO,MAAM,oBAAoB;;;;;EAA2B,CAAC;AAC7D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,2DAA2D;AAC3D,eAAO,MAAM,aAAa,IAAI,CAAC;AAwB/B,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;CAC5D;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAyID;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,GAAE,eAAoB,GAAG,cAAc,CA+I9F;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEpD"}