@haneinfo/app-tooling 0.2.0 → 0.3.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 CHANGED
@@ -1,9 +1,37 @@
1
1
  # @haneinfo/app-tooling
2
2
 
3
- Run `haneinfo-app check` from an App repository to verify generated plugin artifacts, integration contract runtime files, enum documentation and translations, domain event subscriber wiring, and ScopeGuard scope coverage. `haneinfo-app check plugins`, `integrations`, `enums`, `subscribers`, or `scopes` runs one gate. Use `--root <path>` to check another App and `--json` for machine-readable results. Missing enum translations and documentation fail; orphaned translation keys are warnings.
3
+ Run `haneinfo-app check` from an App repository to verify generated plugin artifacts, integration contract runtime files, enum documentation and translations, domain event subscriber wiring, ScopeGuard scope coverage, and data dictionary drift. `haneinfo-app check plugins`, `integrations`, `enums`, `subscribers`, `scopes`, or `dictionary` runs one gate. Use `--root <path>` to check another App and `--json` for machine-readable results. Missing enum translations and documentation fail; orphaned translation keys are warnings.
4
4
 
5
5
  This package owns App-level checks. The `scripts/lint-specs.mjs` file remains in each repository under the shared specs governance rule.
6
6
 
7
+ ## Data dictionary drift
8
+
9
+ `haneinfo-app check dictionary` compares `docs/data-dictionary.md` with the consuming App's
10
+ `@haneinfo/metadata-schema` renderer in memory. It ignores only the generated header date,
11
+ UTF-8 BOM and line endings. Models, enum values, fields, descriptions, relationships and dates
12
+ inside the document still participate in comparison. Missing documentation and renderer failures
13
+ are failing diagnostics, not a successful skipped check. Drift diagnostics identify the file and
14
+ first differing line. `check all` includes this gate; `check enums` remains a separate contract.
15
+
16
+ The App must already have a fresh generated Prisma client. The gate compares its embedded
17
+ `schema.prisma` with the App source before rendering, detecting stale clients when fields,
18
+ attributes, enum values or `///` documentation differ. The schema fingerprint ignores formatting whitespace,
19
+ ordinary comments and top-level block order; it retains schema tokens, field order and `///`
20
+ documentation. It is a text-consistency check, not a replacement for Prisma schema validation.
21
+ Unknown or malformed declarations fail explicitly.
22
+
23
+ Supported schema locations are `backend/prisma/schema` (including nested `.prisma` files),
24
+ `backend/prisma/schema.prisma`, or the path in `backend/package.json`'s `prisma.schema`. Multiple
25
+ default locations need an explicit path. Executable `prisma.config.*` and non-default client
26
+ outputs are not evaluated or guessed; unsupported configuration/client layout fails with a
27
+ diagnostic. This is the Prisma 6 / default `@prisma/client` layout used by current Haneinfo Apps.
28
+
29
+ Rendering runs in an isolated Node process with the App backend as cwd, using that App's installed
30
+ metadata package and client. Checking several Apps in one process does not share their DMMF cache.
31
+ The checker requires no database connection, does not execute App bootstrap/generator scripts,
32
+ and never writes source, clients or documentation. After reviewing changes, run the App's
33
+ `prisma:generate` and `schema:docs` commands explicitly, then repeat the check.
34
+
7
35
  ## Scope coverage
8
36
 
9
37
  `haneinfo-app check scopes` parses App-owned `backend/src/**/*.ts` / `*.tsx` (excluding
package/dist/checks.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type CheckIssue } from './integration-contracts';
2
- export type CheckTarget = 'all' | 'plugins' | 'integrations' | 'enums' | 'subscribers' | 'scopes';
2
+ export type CheckTarget = 'all' | 'plugins' | 'integrations' | 'enums' | 'subscribers' | 'scopes' | 'dictionary';
3
3
  export interface CheckReport {
4
4
  target: CheckTarget;
5
5
  issues: CheckIssue[];
@@ -1 +1 @@
1
- {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAsC,MAAM,yBAAyB,CAAC;AAI9F,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,cAAc,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAC;AAElG,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;CACjB;AA4BD,uFAAuF;AACvF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,WAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBjG"}
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAsC,MAAM,yBAAyB,CAAC;AAI9F,MAAM,MAAM,WAAW,GACnB,KAAK,GACL,SAAS,GACT,cAAc,GACd,OAAO,GACP,aAAa,GACb,QAAQ,GACR,YAAY,CAAC;AAEjB,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;CACjB;AA4BD,uFAAuF;AACvF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,WAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,CAuBjG"}
package/dist/checks.js CHANGED
@@ -7,6 +7,7 @@ exports.checkApp = checkApp;
7
7
  const node_fs_1 = require("node:fs");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const plugin_cli_1 = require("@haneinfo/plugin-cli");
10
+ const dictionary_1 = require("./dictionary");
10
11
  const enums_1 = require("./enums");
11
12
  const integration_contracts_1 = require("./integration-contracts");
12
13
  const scopes_1 = require("./scopes");
@@ -59,6 +60,8 @@ async function checkApp(appRoot, target = 'all') {
59
60
  issues.push(...(0, subscriber_wiring_1.checkDomainEventSubscribers)(repositoryRoot));
60
61
  if (target === 'all' || target === 'scopes')
61
62
  issues.push(...(0, scopes_1.checkScopeCoverage)(repositoryRoot));
63
+ if (target === 'all' || target === 'dictionary')
64
+ issues.push(...(0, dictionary_1.checkDataDictionary)(repositoryRoot));
62
65
  return { target, issues, warnings, passed: issues.length === 0 };
63
66
  }
64
67
  //# sourceMappingURL=checks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":";;;;;AA4CA,4BAqBC;AAjED,qCAAmD;AACnD,0DAA6B;AAC7B,qDAAkF;AAClF,mCAAqC;AACrC,mEAA8F;AAC9F,qCAA8C;AAC9C,2DAAkE;AAWlE,SAAS,gBAAgB;IACvB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QAClE,OAAQ,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAA0B,CAAC,OAAO,IAAI,SAAS,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAe;IACzC,MAAM,MAAM,GAAkB,MAAM,yBAAY,CAAC,OAAO,CAAC;QACvD,OAAO;QACP,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE;QAC9E,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE;QAC9D,OAAO,EAAE,gBAAgB,EAAE;KAC5B,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,QAAQ,KAAK,qBAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IAC/C,OAAO,MAAM,CAAC,WAAW;SACtB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC;SAC7C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,uBAAuB;QAC3C,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAC,CAAC;AACR,CAAC;AAED,uFAAuF;AAChF,KAAK,UAAU,QAAQ,CAAC,OAAe,EAAE,SAAsB,KAAK;IACzE,MAAM,IAAI,GAAG,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,cAAc,GAClB,mBAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,IAAA,oBAAU,EAAC,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;QACvF,CAAC,CAAC,mBAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,WAAW,GAAG,mBAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IACzD,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAChG,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,cAAc;QAC/C,MAAM,CAAC,IAAI,CAAC,GAAG,IAAA,0DAAkC,EAAC,cAAc,CAAC,CAAC,CAAC;IACrE,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAA,kBAAU,EAAC,cAAc,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,aAAa;QAC9C,MAAM,CAAC,IAAI,CAAC,GAAG,IAAA,+CAA2B,EAAC,cAAc,CAAC,CAAC,CAAC;IAC9D,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAA,2BAAkB,EAAC,cAAc,CAAC,CAAC,CAAC;IAChG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAKlG,6FAA6F;AAC7F,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CAgDjB"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAKlG,6FAA6F;AAC7F,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CAkDjB"}
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ exports.runAppToolingCli = runAppToolingCli;
4
4
  const node_util_1 = require("node:util");
5
5
  const checks_1 = require("./checks");
6
6
  const scaffold_1 = require("./scaffold");
7
- const USAGE = 'Usage: haneinfo-app check [all|plugins|integrations|enums|subscribers|scopes] [--root <app-root>] [--json]\n haneinfo-app scaffold --name <kebab-case> --display-name <text> --db-port <port> --backend-port <port> --frontend-port <port> [--description <text>] [--ports-registry <file>] [--root <template-root>] [--dry-run]';
7
+ const USAGE = 'Usage: haneinfo-app check [all|plugins|integrations|enums|subscribers|scopes|dictionary] [--root <app-root>] [--json]\n haneinfo-app scaffold --name <kebab-case> --display-name <text> --db-port <port> --backend-port <port> --frontend-port <port> [--description <text>] [--ports-registry <file>] [--root <template-root>] [--dry-run]';
8
8
  /** Exit codes: 0 passed, 1 verification failed, 2 invalid invocation, 3 unexpected error. */
9
9
  async function runAppToolingCli(argv, cwd, output) {
10
10
  if (argv[0] === 'scaffold')
@@ -29,7 +29,7 @@ async function runAppToolingCli(argv, cwd, output) {
29
29
  const [command, requested = 'all', ...extra] = parsed.positionals;
30
30
  if (command !== 'check' ||
31
31
  extra.length > 0 ||
32
- !['all', 'plugins', 'integrations', 'enums', 'subscribers', 'scopes'].includes(requested)) {
32
+ !['all', 'plugins', 'integrations', 'enums', 'subscribers', 'scopes', 'dictionary'].includes(requested)) {
33
33
  output.stderr(USAGE);
34
34
  return 2;
35
35
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Block order can change when Prisma flattens a schema folder; field/doc order cannot. */
2
+ export declare function schemaFingerprint(sources: string[]): string;
3
+ /** Verify the same default Prisma client that @haneinfo/common selects from the App cwd. */
4
+ export declare function verifyDictionarySchema(backendRoot: string): void;
5
+ //# sourceMappingURL=dictionary-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionary-schema.d.ts","sourceRoot":"","sources":["../src/dictionary-schema.ts"],"names":[],"mappings":"AAmDA,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CA6B3D;AAcD,4FAA4F;AAC5F,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CA+ChE"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.schemaFingerprint = schemaFingerprint;
7
+ exports.verifyDictionarySchema = verifyDictionarySchema;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_module_1 = require("node:module");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ /** Compare schema text without depending on Prisma's formatter or losing /// metadata. */
12
+ function tokens(source) {
13
+ const result = [];
14
+ let offset = 0;
15
+ while (offset < source.length) {
16
+ const remaining = source.slice(offset);
17
+ const whitespace = /^\s+/u.exec(remaining);
18
+ if (whitespace) {
19
+ offset += whitespace[0].length;
20
+ continue;
21
+ }
22
+ if (remaining.startsWith('//')) {
23
+ const end = remaining.indexOf('\n');
24
+ const line = end < 0 ? remaining : remaining.slice(0, end);
25
+ if (line.startsWith('///'))
26
+ result.push({ kind: 'doc', text: line.slice(3).replace(/\r$/u, '').replace(/^ ?/u, '') });
27
+ offset += line.length;
28
+ continue;
29
+ }
30
+ if (remaining.startsWith('/*')) {
31
+ const end = remaining.indexOf('*/', 2);
32
+ if (end < 0 || remaining.slice(2, end).includes('/*'))
33
+ throw new Error('unsupported unterminated/nested schema comment');
34
+ offset += end + 2;
35
+ continue;
36
+ }
37
+ if (remaining.startsWith('"')) {
38
+ const value = /^"(?:\\.|[^"\\])*"/u.exec(remaining);
39
+ if (!value)
40
+ throw new Error('unterminated schema string');
41
+ result.push({ kind: 'string', text: value[0] });
42
+ offset += value[0].length;
43
+ continue;
44
+ }
45
+ const word = /^[A-Za-z_][A-Za-z0-9_]*/u.exec(remaining);
46
+ if (word) {
47
+ result.push({ kind: 'word', text: word[0] });
48
+ offset += word[0].length;
49
+ continue;
50
+ }
51
+ result.push({ kind: 'symbol', text: remaining[0] });
52
+ offset++;
53
+ }
54
+ return result;
55
+ }
56
+ /** Block order can change when Prisma flattens a schema folder; field/doc order cannot. */
57
+ function schemaFingerprint(sources) {
58
+ const blocks = new Map();
59
+ for (const source of sources) {
60
+ const input = tokens(source);
61
+ let offset = 0;
62
+ while (offset < input.length) {
63
+ const block = [];
64
+ while (input[offset]?.kind === 'doc')
65
+ block.push(input[offset++]);
66
+ const kind = input[offset++];
67
+ const name = input[offset++];
68
+ const open = input[offset++];
69
+ if (kind?.kind !== 'word' || name?.kind !== 'word' || open?.text !== '{')
70
+ throw new Error('unsupported schema declaration; expected a named block');
71
+ block.push(kind, name, open);
72
+ let depth = 1;
73
+ while (depth > 0 && offset < input.length) {
74
+ const token = input[offset++];
75
+ block.push(token);
76
+ if (token.kind === 'symbol' && token.text === '{')
77
+ depth++;
78
+ if (token.kind === 'symbol' && token.text === '}')
79
+ depth--;
80
+ }
81
+ if (depth !== 0)
82
+ throw new Error(`unterminated ${kind.text} ${name.text} schema block`);
83
+ const key = `${kind.text}:${name.text}`;
84
+ if (blocks.has(key))
85
+ throw new Error(`duplicate ${kind.text} ${name.text} schema block`);
86
+ blocks.set(key, block);
87
+ }
88
+ }
89
+ if (blocks.size === 0)
90
+ throw new Error('schema contains no named blocks');
91
+ return JSON.stringify([...blocks.entries()].sort(([a], [b]) => a.localeCompare(b)));
92
+ }
93
+ function schemaFiles(file) {
94
+ if (!(0, node_fs_1.statSync)(file).isDirectory())
95
+ return [file];
96
+ return (0, node_fs_1.readdirSync)(file, { withFileTypes: true })
97
+ .flatMap((entry) => {
98
+ const child = node_path_1.default.join(file, entry.name);
99
+ if (entry.isDirectory())
100
+ return ['migrations', 'node_modules'].includes(entry.name) ? [] : schemaFiles(child);
101
+ return entry.name.endsWith('.prisma') ? [child] : [];
102
+ })
103
+ .sort();
104
+ }
105
+ /** Verify the same default Prisma client that @haneinfo/common selects from the App cwd. */
106
+ function verifyDictionarySchema(backendRoot) {
107
+ const manifest = node_path_1.default.join(backendRoot, 'package.json');
108
+ const pkg = JSON.parse((0, node_fs_1.readFileSync)(manifest, 'utf8'));
109
+ const configured = pkg.prisma?.schema;
110
+ if (configured !== undefined && (typeof configured !== 'string' || !configured.trim()))
111
+ throw new Error('package.json prisma.schema must be a non-empty path');
112
+ const configs = [
113
+ 'prisma.config.ts',
114
+ 'prisma.config.js',
115
+ 'prisma.config.mjs',
116
+ 'prisma.config.cjs',
117
+ 'prisma.config.mts',
118
+ 'prisma.config.cts',
119
+ ];
120
+ if (configs.some((name) => (0, node_fs_1.existsSync)(node_path_1.default.join(backendRoot, name))))
121
+ throw new Error('prisma.config.* cannot be evaluated safely by this checker; this schema configuration is unsupported');
122
+ const defaults = [
123
+ node_path_1.default.join(backendRoot, 'prisma', 'schema'),
124
+ node_path_1.default.join(backendRoot, 'prisma', 'schema.prisma'),
125
+ ].filter(node_fs_1.existsSync);
126
+ if (!configured && defaults.length > 1)
127
+ throw new Error('multiple schema locations exist; declare the schema used by prisma:generate in package.json prisma.schema');
128
+ const schema = typeof configured === 'string' ? node_path_1.default.resolve(backendRoot, configured) : defaults[0];
129
+ if (!schema || !(0, node_fs_1.existsSync)(schema))
130
+ throw new Error('active Prisma schema is missing; expected prisma/schema or prisma/schema.prisma');
131
+ const source = schemaFingerprint(schemaFiles(schema).map((file) => (0, node_fs_1.readFileSync)(file, 'utf8')));
132
+ const appRequire = (0, node_module_1.createRequire)(manifest);
133
+ const clientRequire = (0, node_module_1.createRequire)(appRequire.resolve('@prisma/client/package.json'));
134
+ const generated = clientRequire.resolve('.prisma/client/schema.prisma');
135
+ const embedded = schemaFingerprint([(0, node_fs_1.readFileSync)(generated, 'utf8')]);
136
+ if (source !== embedded) {
137
+ const active = new Map(JSON.parse(source));
138
+ const client = new Map(JSON.parse(embedded));
139
+ const changed = [...new Set([...active.keys(), ...client.keys()])].filter((key) => JSON.stringify(active.get(key)) !== JSON.stringify(client.get(key)));
140
+ throw new Error(`generated Prisma client differs from the active schema in ${changed.join(', ')} (including /// documentation); run the App prisma:generate command before checking or generating docs`);
141
+ }
142
+ }
143
+ //# sourceMappingURL=dictionary-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionary-schema.js","sourceRoot":"","sources":["../src/dictionary-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dictionary-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionary-worker.d.ts","sourceRoot":"","sources":["../src/dictionary-worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_module_1 = require("node:module");
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ // Import in the consuming App's cwd so @haneinfo/common selects that App's Prisma DMMF.
9
+ const appRequire = (0, node_module_1.createRequire)(node_path_1.default.join(process.cwd(), 'package.json'));
10
+ const api = appRequire('@haneinfo/metadata-schema');
11
+ if (typeof api.renderDataDictionary !== 'function')
12
+ throw new Error('App metadata-schema package does not export renderDataDictionary');
13
+ const markdown = api.renderDataDictionary(new api.MetaService().buildMeta());
14
+ if (typeof markdown !== 'string')
15
+ throw new Error('renderDataDictionary must return Markdown text');
16
+ process.stdout.write(JSON.stringify({ markdown }));
17
+ //# sourceMappingURL=dictionary-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionary-worker.js","sourceRoot":"","sources":["../src/dictionary-worker.ts"],"names":[],"mappings":";;;;;AAAA,6CAA4C;AAC5C,0DAA6B;AAE7B,wFAAwF;AACxF,MAAM,UAAU,GAAG,IAAA,2BAAa,EAAC,mBAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;AAC3E,MAAM,GAAG,GAAG,UAAU,CAAC,2BAA2B,CAGjD,CAAC;AACF,IAAI,OAAO,GAAG,CAAC,oBAAoB,KAAK,UAAU;IAChD,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;AACtF,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7E,IAAI,OAAO,QAAQ,KAAK,QAAQ;IAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;AACpG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { CheckIssue } from './integration-contracts';
2
+ declare function renderFromApp(backendRoot: string): string;
3
+ /** Ignore the renderer's volatile header date, BOM and platform line endings only. */
4
+ export declare function normalizeDataDictionary(markdown: string): string;
5
+ /** Compare in memory. This gate never generates a client or writes the dictionary. */
6
+ export declare function checkDataDictionary(appRoot: string, renderer?: typeof renderFromApp): CheckIssue[];
7
+ export {};
8
+ //# sourceMappingURL=dictionary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionary.d.ts","sourceRoot":"","sources":["../src/dictionary.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,iBAAS,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAalD;AAED,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,uBAAgB,GAAG,UAAU,EAAE,CAoD3F"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.normalizeDataDictionary = normalizeDataDictionary;
7
+ exports.checkDataDictionary = checkDataDictionary;
8
+ const node_child_process_1 = require("node:child_process");
9
+ const node_fs_1 = require("node:fs");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const dictionary_schema_1 = require("./dictionary-schema");
12
+ function renderFromApp(backendRoot) {
13
+ const result = (0, node_child_process_1.spawnSync)(process.execPath, [node_path_1.default.join(__dirname, 'dictionary-worker.js')], {
14
+ cwd: backendRoot,
15
+ encoding: 'utf8',
16
+ timeout: 30_000,
17
+ maxBuffer: 16 * 1024 * 1024,
18
+ });
19
+ if (result.error || result.status !== 0)
20
+ throw new Error(result.error?.message ?? (result.stderr.trim() || 'dictionary worker failed'));
21
+ const rendered = JSON.parse(result.stdout);
22
+ if (typeof rendered.markdown !== 'string')
23
+ throw new Error('dictionary worker returned invalid Markdown');
24
+ return rendered.markdown;
25
+ }
26
+ /** Ignore the renderer's volatile header date, BOM and platform line endings only. */
27
+ function normalizeDataDictionary(markdown) {
28
+ return markdown
29
+ .replace(/^\uFEFF/u, '')
30
+ .replace(/\r\n?/gu, '\n')
31
+ .replace(/^(# Data Dictionary\n\n)> Auto-generated from Prisma schema on \d{4}-\d{2}-\d{2}\.\n/u, '$1> Auto-generated from Prisma schema on <date>.\n');
32
+ }
33
+ /** Compare in memory. This gate never generates a client or writes the dictionary. */
34
+ function checkDataDictionary(appRoot, renderer = renderFromApp) {
35
+ const file = node_path_1.default.join(appRoot, 'docs', 'data-dictionary.md');
36
+ if (!(0, node_fs_1.existsSync)(file))
37
+ return [
38
+ {
39
+ code: 'dictionary-missing',
40
+ path: file,
41
+ message: 'data dictionary is missing; run the App prisma:generate and schema:docs commands',
42
+ },
43
+ ];
44
+ const backendRoot = node_path_1.default.join(appRoot, 'backend');
45
+ try {
46
+ (0, dictionary_schema_1.verifyDictionarySchema)(backendRoot);
47
+ }
48
+ catch (error) {
49
+ return [
50
+ {
51
+ code: 'dictionary-schema-unverified',
52
+ path: node_path_1.default.join(backendRoot, 'prisma'),
53
+ message: error instanceof Error ? error.message : String(error),
54
+ },
55
+ ];
56
+ }
57
+ let expected;
58
+ try {
59
+ const rendered = normalizeDataDictionary(renderer(backendRoot));
60
+ if (!rendered.startsWith('# Data Dictionary\n\n'))
61
+ throw new Error('metadata renderer returned an unrecognized data dictionary header');
62
+ expected = rendered;
63
+ }
64
+ catch (error) {
65
+ return [
66
+ {
67
+ code: 'dictionary-render-failed',
68
+ path: file,
69
+ message: error instanceof Error ? error.message : String(error),
70
+ },
71
+ ];
72
+ }
73
+ const actual = normalizeDataDictionary((0, node_fs_1.readFileSync)(file, 'utf8'));
74
+ if (expected === actual)
75
+ return [];
76
+ const expectedLines = expected.split('\n');
77
+ const actualLines = actual.split('\n');
78
+ const line = Array.from({ length: Math.max(expectedLines.length, actualLines.length) }, (_, i) => i).find((i) => expectedLines[i] !== actualLines[i]) ?? 0;
79
+ return [
80
+ {
81
+ code: 'dictionary-drift',
82
+ path: `${file}:${line + 1}:1`,
83
+ message: `dictionary differs from the App metadata renderer; run schema:docs after reviewing schema changes. Expected ${JSON.stringify((expectedLines[line] ?? '<end>').slice(0, 180))}, found ${JSON.stringify((actualLines[line] ?? '<end>').slice(0, 180))}`,
84
+ },
85
+ ];
86
+ }
87
+ //# sourceMappingURL=dictionary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionary.js","sourceRoot":"","sources":["../src/dictionary.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './checks';
2
2
  export * from './cli';
3
+ export * from './dictionary';
3
4
  export * from './enums';
4
5
  export * from './integration-contracts';
5
6
  export * from './scaffold';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./checks"), exports);
18
18
  __exportStar(require("./cli"), exports);
19
+ __exportStar(require("./dictionary"), exports);
19
20
  __exportStar(require("./enums"), exports);
20
21
  __exportStar(require("./integration-contracts"), exports);
21
22
  __exportStar(require("./scaffold"), exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,wCAAsB;AACtB,0CAAwB;AACxB,0DAAwC;AACxC,6CAA2B;AAC3B,2CAAyB;AACzB,sDAAoC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,wCAAsB;AACtB,+CAA6B;AAC7B,0CAAwB;AACxB,0DAAwC;AACxC,6CAA2B;AAC3B,2CAAyB;AACzB,sDAAoC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haneinfo/app-tooling",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "description": "Shared Haneinfo App checks and scaffold tooling",