@happyvertical/smrt-core 0.57.45 → 0.57.47
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/AGENTS.md +11 -3
- package/agents/browser-entry.md +16 -0
- package/agents/build-knowledge.md +58 -14
- package/agents/change-feed.md +20 -0
- package/agents/generators.md +69 -3
- package/agents/schema-paths.md +82 -0
- package/dist/_virtual/_rolldown/runtime.js +22 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +2 -2
- package/dist/cascade.d.ts +46 -0
- package/dist/cascade.d.ts.map +1 -1
- package/dist/cascade.js +96 -7
- package/dist/cascade.js.map +1 -1
- package/dist/change-feed.d.ts.map +1 -1
- package/dist/change-feed.js +7 -4
- package/dist/change-feed.js.map +1 -1
- package/dist/class.d.ts.map +1 -1
- package/dist/class.js +3 -3
- package/dist/class.js.map +1 -1
- package/dist/consumer-plugin/index.d.ts +13 -0
- package/dist/consumer-plugin/index.d.ts.map +1 -1
- package/dist/consumer-plugin/index.js +69 -13
- package/dist/consumer-plugin/index.js.map +1 -1
- package/dist/consumer-plugin.js +2 -2
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +3 -3
- package/dist/database.js.map +1 -1
- package/dist/dispatch/bus.d.ts.map +1 -1
- package/dist/dispatch/bus.js +1 -4
- package/dist/dispatch/bus.js.map +1 -1
- package/dist/dispatch/index.d.ts +1 -1
- package/dist/dispatch/index.d.ts.map +1 -1
- package/dist/dispatch/types.d.ts +22 -3
- package/dist/dispatch/types.d.ts.map +1 -1
- package/dist/generators/changes-route.d.ts.map +1 -1
- package/dist/generators/changes-route.js +2 -2
- package/dist/generators/changes-route.js.map +1 -1
- package/dist/generators/custom-action.d.ts +11 -0
- package/dist/generators/custom-action.d.ts.map +1 -1
- package/dist/generators/custom-action.js +23 -4
- package/dist/generators/custom-action.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/lazy-config.d.ts +120 -3
- package/dist/lazy-config.d.ts.map +1 -1
- package/dist/lazy-config.js +81 -10
- package/dist/lazy-config.js.map +1 -1
- package/dist/manifest/generator.d.ts +8 -2
- package/dist/manifest/generator.d.ts.map +1 -1
- package/dist/manifest/generator.js +6 -5
- package/dist/manifest/generator.js.map +1 -1
- package/dist/manifest/index.d.ts +1 -0
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +2 -1
- package/dist/manifest/index.js.map +1 -1
- package/dist/manifest/local-manifest-reader.d.ts +13 -2
- package/dist/manifest/local-manifest-reader.d.ts.map +1 -1
- package/dist/manifest/local-manifest-reader.js +38 -6
- package/dist/manifest/local-manifest-reader.js.map +1 -1
- package/dist/manifest/manifest-loader.d.ts +9 -8
- package/dist/manifest/manifest-loader.d.ts.map +1 -1
- package/dist/manifest/manifest-loader.js +67 -27
- package/dist/manifest/manifest-loader.js.map +1 -1
- package/dist/manifest/object-declarations.d.ts +116 -0
- package/dist/manifest/object-declarations.d.ts.map +1 -0
- package/dist/manifest/object-declarations.js +161 -0
- package/dist/manifest/object-declarations.js.map +1 -0
- package/dist/manifest/static-manifest.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +5 -3
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.d.ts.map +1 -1
- package/dist/manifest/store.js +18 -2
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest/test-artifacts.d.ts +57 -0
- package/dist/manifest/test-artifacts.d.ts.map +1 -0
- package/dist/manifest/test-artifacts.js +111 -0
- package/dist/manifest/test-artifacts.js.map +1 -0
- package/dist/manifest.js +2 -1
- package/dist/manifest.json +5 -3
- package/dist/migrations/differ.d.ts.map +1 -1
- package/dist/migrations/differ.js +11 -3
- package/dist/migrations/differ.js.map +1 -1
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +3 -1
- package/dist/migrations/qualified-name-aliases.d.ts.map +1 -1
- package/dist/migrations/qualified-name-aliases.js +1 -1
- package/dist/migrations/qualified-name-aliases.js.map +1 -1
- package/dist/migrations.js +3 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +2 -2
- package/dist/object.js.map +1 -1
- package/dist/postgres-permissions.d.ts.map +1 -1
- package/dist/postgres-permissions.js +4 -3
- package/dist/postgres-permissions.js.map +1 -1
- package/dist/postgres-timeouts.d.ts +30 -3
- package/dist/postgres-timeouts.d.ts.map +1 -1
- package/dist/postgres-timeouts.js +39 -2
- package/dist/postgres-timeouts.js.map +1 -1
- package/dist/prebuild/index.d.ts.map +1 -1
- package/dist/prebuild/index.js +14 -11
- package/dist/prebuild/index.js.map +1 -1
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +24 -2
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/collection-exposure.d.ts +27 -0
- package/dist/registry/collection-exposure.d.ts.map +1 -1
- package/dist/registry/collection-exposure.js +74 -1
- package/dist/registry/collection-exposure.js.map +1 -1
- package/dist/registry/collection-resolution.d.ts.map +1 -1
- package/dist/registry/collection-resolution.js +1 -0
- package/dist/registry/collection-resolution.js.map +1 -1
- package/dist/registry/framework-base-classes.d.ts.map +1 -1
- package/dist/registry/framework-base-classes.js +5 -0
- package/dist/registry/framework-base-classes.js.map +1 -1
- package/dist/registry/schema-builder.d.ts +8 -1
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +17 -4
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/types.d.ts +12 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts +2 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +30 -10
- package/dist/registry.js.map +1 -1
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +10 -8
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/scanner/types.d.ts +29 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/scanner/types.js.map +1 -1
- package/dist/schema/generator.d.ts +32 -0
- package/dist/schema/generator.d.ts.map +1 -1
- package/dist/schema/generator.js +59 -0
- package/dist/schema/generator.js.map +1 -1
- package/dist/schema/live-parity.d.ts.map +1 -1
- package/dist/schema/live-parity.js +4 -2
- package/dist/schema/live-parity.js.map +1 -1
- package/dist/scripts/browser-unbundled-dev.mjs +90 -0
- package/dist/scripts/generate-test-manifest.js +9 -49
- package/dist/smrt-knowledge.json +16 -16
- package/dist/system/compatibility.d.ts.map +1 -1
- package/dist/system/compatibility.js +12 -4
- package/dist/system/compatibility.js.map +1 -1
- package/dist/system/schema.d.ts +70 -8
- package/dist/system/schema.d.ts.map +1 -1
- package/dist/system/schema.js +231 -24
- package/dist/system/schema.js.map +1 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js +14 -2
- package/dist/testing/database.js.map +1 -1
- package/dist/tools/tool-generator.d.ts.map +1 -1
- package/dist/tools/tool-generator.js +2 -2
- package/dist/tools/tool-generator.js.map +1 -1
- package/dist/utils/import-workspace-module.d.ts.map +1 -1
- package/dist/utils/import-workspace-module.js +23 -0
- package/dist/utils/import-workspace-module.js.map +1 -1
- package/dist/utils/naming.js +5 -3
- package/dist/utils/naming.js.map +1 -1
- package/dist/vendor/pluralize/pluralize.js +421 -0
- package/dist/vendor/pluralize/pluralize.js.map +1 -0
- package/dist/vite-plugin/api-client-entries.d.ts +5 -1
- package/dist/vite-plugin/api-client-entries.d.ts.map +1 -1
- package/dist/vite-plugin/api-client-entries.js +11 -6
- package/dist/vite-plugin/api-client-entries.js.map +1 -1
- package/dist/vite-plugin/consumer-import.d.ts +28 -0
- package/dist/vite-plugin/consumer-import.d.ts.map +1 -0
- package/dist/vite-plugin/consumer-import.js +42 -0
- package/dist/vite-plugin/consumer-import.js.map +1 -0
- package/dist/vite-plugin/dev-plane-route.d.ts +6 -1
- package/dist/vite-plugin/dev-plane-route.d.ts.map +1 -1
- package/dist/vite-plugin/dev-plane-route.js +8 -9
- package/dist/vite-plugin/dev-plane-route.js.map +1 -1
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +12 -9
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/resources-route.d.ts.map +1 -1
- package/dist/vite-plugin/resources-route.js +3 -8
- package/dist/vite-plugin/resources-route.js.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +7 -11
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/dist/vite-plugin/sync-apply-route.d.ts +16 -0
- package/dist/vite-plugin/sync-apply-route.d.ts.map +1 -1
- package/dist/vite-plugin/sync-apply-route.js +48 -6
- package/dist/vite-plugin/sync-apply-route.js.map +1 -1
- package/package.json +12 -12
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
//#region src/manifest/object-declarations.ts
|
|
2
|
+
function compareText(left, right) {
|
|
3
|
+
if (left < right) return -1;
|
|
4
|
+
if (left > right) return 1;
|
|
5
|
+
return 0;
|
|
6
|
+
}
|
|
7
|
+
function normalizeSourcePath(filePath) {
|
|
8
|
+
return filePath.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
|
|
9
|
+
}
|
|
10
|
+
function isAbsoluteSourcePath(filePath) {
|
|
11
|
+
return filePath.startsWith("/") || /^[A-Za-z]:\//.test(filePath);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The value as it survives a manifest JSON round trip. An in-memory scanned
|
|
15
|
+
* listing (Vite plugin) is merged with dependency listings read from
|
|
16
|
+
* `dist/manifest.json`; `undefined`-valued keys exist only in the former, so
|
|
17
|
+
* comparing raw objects would keep the same class apart.
|
|
18
|
+
*/
|
|
19
|
+
function wireShape(value) {
|
|
20
|
+
const json = JSON.stringify(value);
|
|
21
|
+
return json === void 0 ? null : JSON.parse(json);
|
|
22
|
+
}
|
|
23
|
+
/** JSON with object keys sorted at every depth, for structural comparison. */
|
|
24
|
+
function canonicalJson(value) {
|
|
25
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
26
|
+
if (value && typeof value === "object") return `{${Object.keys(value).sort(compareText).map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
|
|
27
|
+
return JSON.stringify(value) ?? "null";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The identity of the class a manifest listing describes.
|
|
31
|
+
*
|
|
32
|
+
* Two listings are the same class only when they name the same class in the
|
|
33
|
+
* same absolute declaring source file AND describe the same fields. A path is
|
|
34
|
+
* only machine-local evidence (separately built packages can share a
|
|
35
|
+
* `/app/src/...` layout), so the field shape the declaration is rendered from
|
|
36
|
+
* must agree too: listings that collapse always render identical
|
|
37
|
+
* declarations, and a stale or unrelated listing stays separate instead of
|
|
38
|
+
* silently supplying (or losing) fields. A relative `filePath` is relative to
|
|
39
|
+
* whichever root scanned it, so two equal relative paths from different
|
|
40
|
+
* packages may be different files; such listings fall back to their qualified
|
|
41
|
+
* name (or manifest key), which keeps them distinct.
|
|
42
|
+
*/
|
|
43
|
+
function objectDeclarationIdentity(manifestKey, obj) {
|
|
44
|
+
const filePath = typeof obj.filePath === "string" ? normalizeSourcePath(obj.filePath) : "";
|
|
45
|
+
if (filePath && isAbsoluteSourcePath(filePath)) return `source\0${filePath}\0${obj.className}\0${canonicalJson(wireShape(obj.fields ?? {}))}`;
|
|
46
|
+
return `listing\0${obj.qualifiedName || manifestKey}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Manifest entries in the deterministic qualified-identity order every
|
|
50
|
+
* declaration emitter shares (#2749): qualified name (or manifest key), then
|
|
51
|
+
* manifest key.
|
|
52
|
+
*/
|
|
53
|
+
function orderedEntries(manifest) {
|
|
54
|
+
return Object.entries(manifest.objects ?? {}).sort(([leftKey, left], [rightKey, right]) => compareText(left.qualifiedName || leftKey, right.qualifiedName || rightKey) || compareText(leftKey, rightKey));
|
|
55
|
+
}
|
|
56
|
+
function declarationPackage(manifestKey, obj) {
|
|
57
|
+
if (obj.packageName) return obj.packageName;
|
|
58
|
+
const qualifiedName = obj.qualifiedName || manifestKey;
|
|
59
|
+
const separator = qualifiedName.lastIndexOf(":");
|
|
60
|
+
return separator > 0 ? qualifiedName.slice(0, separator) : void 0;
|
|
61
|
+
}
|
|
62
|
+
/** `@ergot/market-core` -> `ErgotMarketCore`, a valid identifier prefix. */
|
|
63
|
+
function packageIdentifierPrefix(packageName) {
|
|
64
|
+
if (!packageName) return "";
|
|
65
|
+
const prefix = packageName.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join("");
|
|
66
|
+
return /^[0-9]/.test(prefix) ? `_${prefix}` : prefix;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Select one declaration per class described by the manifest, in deterministic
|
|
70
|
+
* qualified-identity order of each class's first listing, and name each one.
|
|
71
|
+
*
|
|
72
|
+
* Naming follows the qualified identity when simple names collide (#3115): a
|
|
73
|
+
* class whose simple name is unique keeps `${className}Data`; distinct classes
|
|
74
|
+
* sharing a simple name each get a package-qualified name
|
|
75
|
+
* (`@ergot/market-core:LicenseSale` -> `ErgotMarketCoreLicenseSaleData`) and
|
|
76
|
+
* none of them keeps the bare name, which would otherwise silently merge two
|
|
77
|
+
* classes' fields through TypeScript declaration merging. Every simple name
|
|
78
|
+
* is reserved first, and a qualified name that is still taken (or a stem with
|
|
79
|
+
* no known package) gets a stable numeric suffix, so every emitted name is
|
|
80
|
+
* unique and independent of manifest insertion order.
|
|
81
|
+
*
|
|
82
|
+
* The package prefix is the package of the declaration's FIRST listing in
|
|
83
|
+
* qualified-identity order. When one class is relisted by consumer packages
|
|
84
|
+
* (#3296) that is not necessarily the declaring package, and it can change
|
|
85
|
+
* when a relisting dependency is added or removed; the collision warning
|
|
86
|
+
* names every listing so a consumer can tell. A collision group also forms
|
|
87
|
+
* when one class's listings disagree on fields (a stale relisting), which the
|
|
88
|
+
* warning describes as well.
|
|
89
|
+
*/
|
|
90
|
+
function createObjectDeclarationIndex(manifest) {
|
|
91
|
+
const byIdentity = /* @__PURE__ */ new Map();
|
|
92
|
+
const byObject = /* @__PURE__ */ new Map();
|
|
93
|
+
for (const [manifestKey, obj] of orderedEntries(manifest)) {
|
|
94
|
+
const identity = objectDeclarationIdentity(manifestKey, obj);
|
|
95
|
+
const existing = byIdentity.get(identity);
|
|
96
|
+
if (existing) {
|
|
97
|
+
existing.manifestKeys.push(manifestKey);
|
|
98
|
+
byObject.set(obj, existing);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const declaration = {
|
|
102
|
+
interfaceName: `${obj.className}Data`,
|
|
103
|
+
obj,
|
|
104
|
+
manifestKey,
|
|
105
|
+
manifestKeys: [manifestKey]
|
|
106
|
+
};
|
|
107
|
+
byIdentity.set(identity, declaration);
|
|
108
|
+
byObject.set(obj, declaration);
|
|
109
|
+
}
|
|
110
|
+
const declarations = [...byIdentity.values()];
|
|
111
|
+
const byClassName = /* @__PURE__ */ new Map();
|
|
112
|
+
for (const declaration of declarations) {
|
|
113
|
+
const group = byClassName.get(declaration.obj.className) ?? [];
|
|
114
|
+
group.push(declaration);
|
|
115
|
+
byClassName.set(declaration.obj.className, group);
|
|
116
|
+
}
|
|
117
|
+
const used = /* @__PURE__ */ new Set();
|
|
118
|
+
for (const className of byClassName.keys()) used.add(`${className}Data`);
|
|
119
|
+
const collisions = [];
|
|
120
|
+
for (const [className, group] of byClassName) {
|
|
121
|
+
if (group.length === 1) continue;
|
|
122
|
+
for (const declaration of group) {
|
|
123
|
+
const stem = `${packageIdentifierPrefix(declarationPackage(declaration.manifestKey, declaration.obj))}${className}`;
|
|
124
|
+
let interfaceName = `${stem}Data`;
|
|
125
|
+
for (let suffix = 2; used.has(interfaceName); suffix += 1) interfaceName = `${stem}${suffix}Data`;
|
|
126
|
+
used.add(interfaceName);
|
|
127
|
+
declaration.interfaceName = interfaceName;
|
|
128
|
+
}
|
|
129
|
+
collisions.push({
|
|
130
|
+
className,
|
|
131
|
+
declarations: group.map((declaration) => ({
|
|
132
|
+
interfaceName: declaration.interfaceName,
|
|
133
|
+
objectRefs: declaration.manifestKeys.map((key) => manifest.objects[key]?.qualifiedName || key)
|
|
134
|
+
}))
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
declarations,
|
|
139
|
+
collisions,
|
|
140
|
+
interfaceNameFor: (obj) => byObject.get(obj)?.interfaceName ?? `${obj.className}Data`
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Select one declaration per class described by the manifest; see
|
|
145
|
+
* {@link createObjectDeclarationIndex} for identity and naming.
|
|
146
|
+
*/
|
|
147
|
+
function selectObjectDeclarations(manifest) {
|
|
148
|
+
return createObjectDeclarationIndex(manifest).declarations;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Report simple-name collisions once per generation, naming the qualified
|
|
152
|
+
* interface each class was given, so a consumer that referenced the bare
|
|
153
|
+
* name learns which one to use (#3115).
|
|
154
|
+
*/
|
|
155
|
+
function warnObjectDeclarationCollisions(index, log) {
|
|
156
|
+
for (const { className, declarations } of index.collisions) log(`[smrt:types] ${declarations.length} declarations share the class name ${JSON.stringify(className)} (distinct classes, or one class whose listings disagree on fields); generated row types use qualified names instead of ${className}Data: ` + declarations.map(({ interfaceName, objectRefs }) => `${interfaceName} (${objectRefs.join(", ")})`).join("; "));
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
export { createObjectDeclarationIndex, objectDeclarationIdentity, selectObjectDeclarations, warnObjectDeclarationCollisions };
|
|
160
|
+
|
|
161
|
+
//# sourceMappingURL=object-declarations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-declarations.js","names":[],"sources":["../../src/manifest/object-declarations.ts"],"sourcesContent":["/**\n * Manifest -> generated object-type declaration selection.\n *\n * Every emitter of the per-object `XData` row interfaces (the physical\n * `smrt-objects.d.ts` / `smrt-types.d.ts` prebuild files, the Vite ambient\n * `virtual-modules.d.ts`, the `@smrt/types` virtual module in server and client\n * mode, and the consumer fallback module) reads this selection, so they agree\n * on how many declarations exist and in which order.\n *\n * A declaration describes one CLASS, not one manifest listing. An aggregated\n * consumer manifest can list one class several times: when workspace libraries\n * are built, each library that consumes another package's model scans that\n * model's source under its own package name (#3110), so the class appears once\n * under its declaring package and again under every consumer package. Those\n * listings name the same declaring source file and class with the same fields,\n * so they collapse to a single declaration (#3296). Listings without an\n * absolute source path, or whose fields disagree, cannot be proven to be the\n * same class and keep one declaration each.\n *\n * Pure and dependency-free: the scanner, the Vite plugin, the consumer plugin\n * and the prebuild CLI all import it.\n */\n\nimport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types.js';\n\n/** One generated object-type declaration and the listings it describes. */\nexport interface ObjectDeclaration {\n /**\n * Interface name emitted for the class's row payload: `ProductData`, or a\n * package-qualified name when distinct classes share the simple name.\n */\n interfaceName: string;\n /**\n * The listing the declaration is rendered from: the first listing in\n * deterministic qualified-identity order. Every collapsed listing has the\n * same fields, so the choice never changes the declared type (only, at\n * most, the order its properties are written in).\n */\n obj: SmartObjectDefinition;\n /** Manifest key of {@link obj}. */\n manifestKey: string;\n /** Every manifest key that names this class, in qualified-identity order. */\n manifestKeys: string[];\n}\n\nfunction compareText(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\nfunction normalizeSourcePath(filePath: string): string {\n return filePath.replace(/\\\\/g, '/').replace(/\\/{2,}/g, '/');\n}\n\nfunction isAbsoluteSourcePath(filePath: string): boolean {\n return filePath.startsWith('/') || /^[A-Za-z]:\\//.test(filePath);\n}\n\n/**\n * The value as it survives a manifest JSON round trip. An in-memory scanned\n * listing (Vite plugin) is merged with dependency listings read from\n * `dist/manifest.json`; `undefined`-valued keys exist only in the former, so\n * comparing raw objects would keep the same class apart.\n */\nfunction wireShape(value: unknown): unknown {\n const json = JSON.stringify(value);\n return json === undefined ? null : JSON.parse(json);\n}\n\n/** JSON with object keys sorted at every depth, for structural comparison. */\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (value && typeof value === 'object') {\n return `{${Object.keys(value as Record<string, unknown>)\n .sort(compareText)\n .map(\n (key) =>\n `${JSON.stringify(key)}:${canonicalJson((value as Record<string, unknown>)[key])}`,\n )\n .join(',')}}`;\n }\n return JSON.stringify(value) ?? 'null';\n}\n\n/**\n * The identity of the class a manifest listing describes.\n *\n * Two listings are the same class only when they name the same class in the\n * same absolute declaring source file AND describe the same fields. A path is\n * only machine-local evidence (separately built packages can share a\n * `/app/src/...` layout), so the field shape the declaration is rendered from\n * must agree too: listings that collapse always render identical\n * declarations, and a stale or unrelated listing stays separate instead of\n * silently supplying (or losing) fields. A relative `filePath` is relative to\n * whichever root scanned it, so two equal relative paths from different\n * packages may be different files; such listings fall back to their qualified\n * name (or manifest key), which keeps them distinct.\n */\nexport function objectDeclarationIdentity(\n manifestKey: string,\n obj: SmartObjectDefinition,\n): string {\n const filePath =\n typeof obj.filePath === 'string' ? normalizeSourcePath(obj.filePath) : '';\n if (filePath && isAbsoluteSourcePath(filePath)) {\n return `source\\0${filePath}\\0${obj.className}\\0${canonicalJson(wireShape(obj.fields ?? {}))}`;\n }\n return `listing\\0${obj.qualifiedName || manifestKey}`;\n}\n\n/**\n * Manifest entries in the deterministic qualified-identity order every\n * declaration emitter shares (#2749): qualified name (or manifest key), then\n * manifest key.\n */\nfunction orderedEntries(\n manifest: SmartObjectManifest,\n): Array<[string, SmartObjectDefinition]> {\n return Object.entries(manifest.objects ?? {}).sort(\n ([leftKey, left], [rightKey, right]) =>\n compareText(\n left.qualifiedName || leftKey,\n right.qualifiedName || rightKey,\n ) || compareText(leftKey, rightKey),\n );\n}\n\nfunction declarationPackage(\n manifestKey: string,\n obj: SmartObjectDefinition,\n): string | undefined {\n if (obj.packageName) return obj.packageName;\n const qualifiedName = obj.qualifiedName || manifestKey;\n const separator = qualifiedName.lastIndexOf(':');\n return separator > 0 ? qualifiedName.slice(0, separator) : undefined;\n}\n\n/** `@ergot/market-core` -> `ErgotMarketCore`, a valid identifier prefix. */\nfunction packageIdentifierPrefix(packageName: string | undefined): string {\n if (!packageName) return '';\n const prefix = packageName\n .split(/[^A-Za-z0-9]+/)\n .filter(Boolean)\n .map((part) => part[0].toUpperCase() + part.slice(1))\n .join('');\n return /^[0-9]/.test(prefix) ? `_${prefix}` : prefix;\n}\n\n/**\n * Distinct classes that share one simple class name (#3115), with the\n * qualified interface name each was given.\n */\nexport interface ObjectDeclarationCollision {\n className: string;\n /** Each declaration's name and every listing it describes. */\n declarations: Array<{ interfaceName: string; objectRefs: string[] }>;\n}\n\n/** The declaration selection plus a lookup from any listing to its name. */\nexport interface ObjectDeclarationIndex {\n declarations: ObjectDeclaration[];\n collisions: ObjectDeclarationCollision[];\n /**\n * The declared row interface for a listing in this manifest (by object\n * reference). A collection class resolves through the caller to its item\n * listing first; an object outside the manifest falls back to its simple\n * `${className}Data`.\n */\n interfaceNameFor(obj: SmartObjectDefinition): string;\n}\n\n/**\n * Select one declaration per class described by the manifest, in deterministic\n * qualified-identity order of each class's first listing, and name each one.\n *\n * Naming follows the qualified identity when simple names collide (#3115): a\n * class whose simple name is unique keeps `${className}Data`; distinct classes\n * sharing a simple name each get a package-qualified name\n * (`@ergot/market-core:LicenseSale` -> `ErgotMarketCoreLicenseSaleData`) and\n * none of them keeps the bare name, which would otherwise silently merge two\n * classes' fields through TypeScript declaration merging. Every simple name\n * is reserved first, and a qualified name that is still taken (or a stem with\n * no known package) gets a stable numeric suffix, so every emitted name is\n * unique and independent of manifest insertion order.\n *\n * The package prefix is the package of the declaration's FIRST listing in\n * qualified-identity order. When one class is relisted by consumer packages\n * (#3296) that is not necessarily the declaring package, and it can change\n * when a relisting dependency is added or removed; the collision warning\n * names every listing so a consumer can tell. A collision group also forms\n * when one class's listings disagree on fields (a stale relisting), which the\n * warning describes as well.\n */\nexport function createObjectDeclarationIndex(\n manifest: SmartObjectManifest,\n): ObjectDeclarationIndex {\n const byIdentity = new Map<string, ObjectDeclaration>();\n const byObject = new Map<SmartObjectDefinition, ObjectDeclaration>();\n for (const [manifestKey, obj] of orderedEntries(manifest)) {\n const identity = objectDeclarationIdentity(manifestKey, obj);\n const existing = byIdentity.get(identity);\n if (existing) {\n existing.manifestKeys.push(manifestKey);\n byObject.set(obj, existing);\n continue;\n }\n const declaration: ObjectDeclaration = {\n interfaceName: `${obj.className}Data`,\n obj,\n manifestKey,\n manifestKeys: [manifestKey],\n };\n byIdentity.set(identity, declaration);\n byObject.set(obj, declaration);\n }\n const declarations = [...byIdentity.values()];\n\n const byClassName = new Map<string, ObjectDeclaration[]>();\n for (const declaration of declarations) {\n const group = byClassName.get(declaration.obj.className) ?? [];\n group.push(declaration);\n byClassName.set(declaration.obj.className, group);\n }\n\n // Every simple name is reserved, including a colliding one: no member of a\n // collision group may keep it, even when its package is unknown and its\n // qualified stem is just the class name.\n const used = new Set<string>();\n for (const className of byClassName.keys()) used.add(`${className}Data`);\n const collisions: ObjectDeclarationCollision[] = [];\n for (const [className, group] of byClassName) {\n if (group.length === 1) continue;\n for (const declaration of group) {\n const stem = `${packageIdentifierPrefix(\n declarationPackage(declaration.manifestKey, declaration.obj),\n )}${className}`;\n let interfaceName = `${stem}Data`;\n for (let suffix = 2; used.has(interfaceName); suffix += 1) {\n interfaceName = `${stem}${suffix}Data`;\n }\n used.add(interfaceName);\n declaration.interfaceName = interfaceName;\n }\n collisions.push({\n className,\n declarations: group.map((declaration) => ({\n interfaceName: declaration.interfaceName,\n objectRefs: declaration.manifestKeys.map(\n (key) => manifest.objects[key]?.qualifiedName || key,\n ),\n })),\n });\n }\n\n return {\n declarations,\n collisions,\n interfaceNameFor: (obj) =>\n byObject.get(obj)?.interfaceName ?? `${obj.className}Data`,\n };\n}\n\n/**\n * Select one declaration per class described by the manifest; see\n * {@link createObjectDeclarationIndex} for identity and naming.\n */\nexport function selectObjectDeclarations(\n manifest: SmartObjectManifest,\n): ObjectDeclaration[] {\n return createObjectDeclarationIndex(manifest).declarations;\n}\n\n/**\n * Report simple-name collisions once per generation, naming the qualified\n * interface each class was given, so a consumer that referenced the bare\n * name learns which one to use (#3115).\n */\nexport function warnObjectDeclarationCollisions(\n index: ObjectDeclarationIndex,\n log: (message: string) => void,\n): void {\n for (const { className, declarations } of index.collisions) {\n log(\n `[smrt:types] ${declarations.length} declarations share the class name ${JSON.stringify(className)} ` +\n '(distinct classes, or one class whose listings disagree on fields); ' +\n `generated row types use qualified names instead of ${className}Data: ` +\n declarations\n .map(\n ({ interfaceName, objectRefs }) =>\n `${interfaceName} (${objectRefs.join(', ')})`,\n )\n .join('; '),\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-manifest.d.ts","sourceRoot":"","sources":["../../src/manifest/static-manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"static-manifest.d.ts","sourceRoot":"","sources":["../../src/manifest/static-manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,eAAO,MAAM,cAAc,EAAE,mBAq1DnB,CAAC;AAEX,eAAe,cAAc,CAAC"}
|
|
@@ -3,7 +3,7 @@ var staticManifest = {
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"timestamp": 0,
|
|
5
5
|
"packageName": "@happyvertical/smrt-core",
|
|
6
|
-
"packageVersion": "0.57.
|
|
6
|
+
"packageVersion": "0.57.47",
|
|
7
7
|
"objects": {
|
|
8
8
|
"@happyvertical/smrt-core:SmrtClass": {
|
|
9
9
|
"name": "smrtclass",
|
|
@@ -921,7 +921,8 @@ var staticManifest = {
|
|
|
921
921
|
{
|
|
922
922
|
"name": "opts",
|
|
923
923
|
"type": "JunctionAttachOptions",
|
|
924
|
-
"optional": true
|
|
924
|
+
"optional": true,
|
|
925
|
+
"resolvedType": "Record<string, unknown>"
|
|
925
926
|
}
|
|
926
927
|
],
|
|
927
928
|
"returnType": "Promise<TItem>",
|
|
@@ -969,7 +970,8 @@ var staticManifest = {
|
|
|
969
970
|
{
|
|
970
971
|
"name": "opts",
|
|
971
972
|
"type": "JunctionAttachOptions",
|
|
972
|
-
"optional": true
|
|
973
|
+
"optional": true,
|
|
974
|
+
"resolvedType": "Record<string, unknown>"
|
|
973
975
|
}
|
|
974
976
|
],
|
|
975
977
|
"returnType": "Promise<void>",
|