@palantir/pack.document-schema.type-gen 0.9.0 → 0.11.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/build/esm/commands/asset/__tests__/buildPrefixRewriteFetch.test.js +85 -0
- package/build/esm/commands/asset/__tests__/buildPrefixRewriteFetch.test.js.map +1 -0
- package/build/esm/commands/asset/assetDeployHandler.js +36 -1
- package/build/esm/commands/asset/assetDeployHandler.js.map +1 -1
- package/build/esm/commands/asset/assetUpdateSchemaHandler.js +84 -0
- package/build/esm/commands/asset/assetUpdateSchemaHandler.js.map +1 -0
- package/build/esm/commands/asset/registerAssetCommands.js +3 -1
- package/build/esm/commands/asset/registerAssetCommands.js.map +1 -1
- package/build/esm/commands/ir/irGenTypesHandler.js +49 -0
- package/build/esm/commands/ir/irGenTypesHandler.js.map +1 -0
- package/build/esm/commands/ir/registerIrCommands.js +2 -0
- package/build/esm/commands/ir/registerIrCommands.js.map +1 -1
- package/build/esm/commands/schema/registerSchemaCommands.js +2 -2
- package/build/esm/commands/schema/registerSchemaCommands.js.map +1 -1
- package/build/esm/commands/schema/schemaIrHandler.js +56 -0
- package/build/esm/commands/schema/schemaIrHandler.js.map +1 -0
- package/build/esm/index.js +0 -6
- package/build/esm/index.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/custom-discriminant.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/custom-discriminant.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/external-refs.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/external-refs.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/simple-record.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/simple-record.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/union-types.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateModelsFromIr/union-types.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/array-and-map-types.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/array-and-map-types.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/boolean-fields.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/boolean-fields.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/custom-discriminant.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/custom-discriminant.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/datetime-fields.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/datetime-fields.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/simple-records.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/simple-records.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/union-before-records.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/union-before-records.js.map +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/union-types.js +1 -1
- package/build/esm/utils/ir/__tests__/__snapshots__/generateZodSchemasFromIr/union-types.js.map +1 -1
- package/build/esm/utils/ir/__tests__/convertIrToWireSchema.test.js +23 -0
- package/build/esm/utils/ir/__tests__/convertIrToWireSchema.test.js.map +1 -1
- package/build/esm/utils/ir/irFieldHelpers.js +383 -0
- package/build/esm/utils/ir/irFieldHelpers.js.map +1 -0
- package/build/esm/utils/schema/__tests__/__snapshots__/generateVersionsFromSchema/single-version.js.map +1 -1
- package/build/esm/utils/schema/__tests__/__snapshots__/generateVersionsFromSchema/three-version-chain.js.map +1 -1
- package/build/esm/utils/schema/__tests__/__snapshots__/generateVersionsFromSchema/two-version.js.map +1 -1
- package/build/esm/utils/schema/__tests__/convertSchemaToSteps.test.js +13 -0
- package/build/esm/utils/schema/__tests__/convertSchemaToSteps.test.js.map +1 -1
- package/build/esm/utils/schema/__tests__/fixtures.js +78 -13
- package/build/esm/utils/schema/__tests__/fixtures.js.map +1 -1
- package/build/esm/utils/schema/__tests__/generateInternalFromSchema.test.js +19 -7
- package/build/esm/utils/schema/__tests__/generateInternalFromSchema.test.js.map +1 -1
- package/build/esm/utils/schema/__tests__/generateModelMetadataFromSchema.test.js +12 -7
- package/build/esm/utils/schema/__tests__/generateModelMetadataFromSchema.test.js.map +1 -1
- package/build/esm/utils/schema/__tests__/generateScopeFromSchema.test.js +6 -5
- package/build/esm/utils/schema/__tests__/generateScopeFromSchema.test.js.map +1 -1
- package/build/esm/utils/schema/__tests__/generateVersionedTypesFromSchema.test.js +19 -10
- package/build/esm/utils/schema/__tests__/generateVersionedTypesFromSchema.test.js.map +1 -1
- package/build/esm/utils/schema/__tests__/generateVersionedZodFromSchema.test.js +15 -10
- package/build/esm/utils/schema/__tests__/generateVersionedZodFromSchema.test.js.map +1 -1
- package/build/esm/utils/schema/__tests__/generateVersionsFromSchema.test.js +6 -5
- package/build/esm/utils/schema/__tests__/generateVersionsFromSchema.test.js.map +1 -1
- package/build/esm/utils/schema/__tests__/snapshotUtils.js +3 -0
- package/build/esm/utils/schema/__tests__/snapshotUtils.js.map +1 -1
- package/build/esm/utils/schema/convertSchemaToSteps.js +6 -0
- package/build/esm/utils/schema/convertSchemaToSteps.js.map +1 -1
- package/build/esm/utils/schema/generateIndexFromSchema.js +21 -14
- package/build/esm/utils/schema/generateIndexFromSchema.js.map +1 -1
- package/build/esm/utils/schema/generateInternalFromSchema.js +202 -191
- package/build/esm/utils/schema/generateInternalFromSchema.js.map +1 -1
- package/build/esm/utils/schema/generateModelMetadataFromSchema.js +89 -80
- package/build/esm/utils/schema/generateModelMetadataFromSchema.js.map +1 -1
- package/build/esm/utils/schema/generateScopeFromSchema.js +29 -33
- package/build/esm/utils/schema/generateScopeFromSchema.js.map +1 -1
- package/build/esm/utils/schema/generateTypesFromSchema.js +9 -1
- package/build/esm/utils/schema/generateTypesFromSchema.js.map +1 -1
- package/build/esm/utils/schema/generateVersionedTypesFromSchema.js +61 -155
- package/build/esm/utils/schema/generateVersionedTypesFromSchema.js.map +1 -1
- package/build/esm/utils/schema/generateVersionedZodFromSchema.js +58 -94
- package/build/esm/utils/schema/generateVersionedZodFromSchema.js.map +1 -1
- package/build/esm/utils/schema/generateVersionsFromSchema.js +7 -5
- package/build/esm/utils/schema/generateVersionsFromSchema.js.map +1 -1
- package/build/esm/utils/schema/loadSchemaModule.js +53 -0
- package/build/esm/utils/schema/loadSchemaModule.js.map +1 -0
- package/build/esm/utils/schema/resolveSchemaChain.js +68 -9
- package/build/esm/utils/schema/resolveSchemaChain.js.map +1 -1
- package/build/esm/utils/schema/runtimeSchema.js +3 -27
- package/build/esm/utils/schema/runtimeSchema.js.map +1 -1
- package/build/esm/utils/schema/writeAllSdkFiles.js +113 -0
- package/build/esm/utils/schema/writeAllSdkFiles.js.map +1 -0
- package/build/esm/utils/steps/__tests__/__snapshots__/types/arrayFields.js.map +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/customDiscriminant.js +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/customDiscriminant.js.map +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/generateTypeScriptInterfaces.js +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/generateTypeScriptInterfaces.js.map +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/refTypes.js.map +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/simpleRecord.js.map +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/simpleSteps.js +1 -1
- package/build/esm/utils/steps/__tests__/__snapshots__/types/simpleSteps.js.map +1 -1
- package/build/esm/utils/steps/__tests__/convertStepsToIr.test.js +93 -1
- package/build/esm/utils/steps/__tests__/convertStepsToIr.test.js.map +1 -1
- package/build/esm/utils/steps/convertStepsToIr.js +43 -35
- package/build/esm/utils/steps/convertStepsToIr.js.map +1 -1
- package/build/types/commands/asset/__tests__/buildPrefixRewriteFetch.test.d.ts +2 -0
- package/build/types/commands/asset/__tests__/buildPrefixRewriteFetch.test.d.ts.map +1 -0
- package/build/types/commands/asset/assetDeployHandler.d.ts +15 -0
- package/build/types/commands/asset/assetDeployHandler.d.ts.map +1 -1
- package/build/types/commands/asset/assetUpdateSchemaHandler.d.ts +12 -0
- package/build/types/commands/asset/assetUpdateSchemaHandler.d.ts.map +1 -0
- package/build/types/commands/asset/registerAssetCommands.d.ts.map +1 -1
- package/build/types/commands/ir/irGenTypesHandler.d.ts +8 -0
- package/build/types/commands/ir/irGenTypesHandler.d.ts.map +1 -0
- package/build/types/commands/ir/registerIrCommands.d.ts.map +1 -1
- package/build/types/commands/schema/registerSchemaCommands.d.ts.map +1 -1
- package/build/types/commands/schema/schemaIrHandler.d.ts +19 -0
- package/build/types/commands/schema/schemaIrHandler.d.ts.map +1 -0
- package/build/types/index.d.ts +1 -6
- package/build/types/index.d.ts.map +1 -1
- package/build/types/utils/ir/irFieldHelpers.d.ts +36 -0
- package/build/types/utils/ir/irFieldHelpers.d.ts.map +1 -0
- package/build/types/utils/schema/__tests__/fixtures.d.ts +10 -1
- package/build/types/utils/schema/__tests__/fixtures.d.ts.map +1 -1
- package/build/types/utils/schema/__tests__/snapshotUtils.d.ts +2 -0
- package/build/types/utils/schema/__tests__/snapshotUtils.d.ts.map +1 -1
- package/build/types/utils/schema/convertSchemaToSteps.d.ts.map +1 -1
- package/build/types/utils/schema/generateIndexFromSchema.d.ts +5 -3
- package/build/types/utils/schema/generateIndexFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/generateInternalFromSchema.d.ts +6 -7
- package/build/types/utils/schema/generateInternalFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/generateModelMetadataFromSchema.d.ts +3 -8
- package/build/types/utils/schema/generateModelMetadataFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/generateScopeFromSchema.d.ts +2 -2
- package/build/types/utils/schema/generateScopeFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/generateTypesFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/generateVersionedTypesFromSchema.d.ts +4 -7
- package/build/types/utils/schema/generateVersionedTypesFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/generateVersionedZodFromSchema.d.ts +3 -7
- package/build/types/utils/schema/generateVersionedZodFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/generateVersionsFromSchema.d.ts +3 -3
- package/build/types/utils/schema/generateVersionsFromSchema.d.ts.map +1 -1
- package/build/types/utils/schema/loadSchemaModule.d.ts +14 -0
- package/build/types/utils/schema/loadSchemaModule.d.ts.map +1 -0
- package/build/types/utils/schema/resolveSchemaChain.d.ts +29 -8
- package/build/types/utils/schema/resolveSchemaChain.d.ts.map +1 -1
- package/build/types/utils/schema/runtimeSchema.d.ts +2 -32
- package/build/types/utils/schema/runtimeSchema.d.ts.map +1 -1
- package/build/types/utils/schema/writeAllSdkFiles.d.ts +8 -0
- package/build/types/utils/schema/writeAllSdkFiles.d.ts.map +1 -0
- package/build/types/utils/steps/convertStepsToIr.d.ts +3 -3
- package/build/types/utils/steps/convertStepsToIr.d.ts.map +1 -1
- package/package.json +4 -4
- package/build/esm/commands/schema/schemaGenTypesHandler.js +0 -147
- package/build/esm/commands/schema/schemaGenTypesHandler.js.map +0 -1
- package/build/types/commands/schema/schemaGenTypesHandler.d.ts +0 -8
- package/build/types/commands/schema/schemaGenTypesHandler.d.ts.map +0 -1
|
@@ -15,109 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { GENERATED_FILE_HEADER } from "../generatedFileHeader.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
/**
|
|
21
|
-
* Convert a schema field type to TypeScript string for internal types.
|
|
22
|
-
*/
|
|
23
|
-
function convertTypeToTypeScript(fieldType) {
|
|
24
|
-
switch (fieldType.type) {
|
|
25
|
-
case TypeKind.ARRAY:
|
|
26
|
-
{
|
|
27
|
-
if (fieldType.items == null) {
|
|
28
|
-
throw new Error("Array field is missing items type");
|
|
29
|
-
}
|
|
30
|
-
const inner = convertTypeToTypeScript(fieldType.items);
|
|
31
|
-
// Wrap compound types (unions, other arrays) in parens before appending []
|
|
32
|
-
const needsParens = inner.includes("|") || inner.startsWith("readonly ");
|
|
33
|
-
const wrapped = needsParens ? `(${inner})` : inner;
|
|
34
|
-
return `readonly ${wrapped}[]`;
|
|
35
|
-
}
|
|
36
|
-
case TypeKind.BOOLEAN:
|
|
37
|
-
return "boolean";
|
|
38
|
-
case TypeKind.DOC_REF:
|
|
39
|
-
return "string";
|
|
40
|
-
case TypeKind.DOUBLE:
|
|
41
|
-
return "number";
|
|
42
|
-
case TypeKind.MEDIA_REF:
|
|
43
|
-
return "string";
|
|
44
|
-
case TypeKind.OBJECT_REF:
|
|
45
|
-
return "string";
|
|
46
|
-
case TypeKind.OPTIONAL:
|
|
47
|
-
if (fieldType.item == null) {
|
|
48
|
-
throw new Error("Optional field is missing inner type");
|
|
49
|
-
}
|
|
50
|
-
return `(${convertTypeToTypeScript(fieldType.item)} | undefined)`;
|
|
51
|
-
case TypeKind.REF:
|
|
52
|
-
return "unknown";
|
|
53
|
-
case TypeKind.STRING:
|
|
54
|
-
return "string";
|
|
55
|
-
case TypeKind.USER_REF:
|
|
56
|
-
return "string";
|
|
57
|
-
default:
|
|
58
|
-
throw new Error(`Unknown schema field type: ${fieldType.type}`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Convert a schema field type to a FieldTypeDescriptor source string.
|
|
64
|
-
*/
|
|
65
|
-
function convertTypeToFieldTypeDescriptor(fieldType, schema) {
|
|
66
|
-
switch (fieldType.type) {
|
|
67
|
-
case TypeKind.ARRAY:
|
|
68
|
-
if (fieldType.items == null) {
|
|
69
|
-
throw new Error("Array field is missing items type");
|
|
70
|
-
}
|
|
71
|
-
return `{ kind: "array", element: ${convertTypeToFieldTypeDescriptor(fieldType.items, schema)} }`;
|
|
72
|
-
case TypeKind.OPTIONAL:
|
|
73
|
-
if (fieldType.item == null) {
|
|
74
|
-
throw new Error("Optional field is missing inner type");
|
|
75
|
-
}
|
|
76
|
-
return `{ kind: "optional", inner: ${convertTypeToFieldTypeDescriptor(fieldType.item, schema)} }`;
|
|
77
|
-
case TypeKind.REF:
|
|
78
|
-
{
|
|
79
|
-
if (fieldType.name == null) {
|
|
80
|
-
throw new Error("Ref field is missing a name");
|
|
81
|
-
}
|
|
82
|
-
const exportKey = fieldType.refType === "record" ? findRecordExportName(fieldType.name, schema) ?? fieldType.name : fieldType.name;
|
|
83
|
-
return `{ kind: "modelRef", model: "${exportKey}" }`;
|
|
84
|
-
}
|
|
85
|
-
default:
|
|
86
|
-
return `{ kind: "primitive" }`;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Convert a schema field type to a Zod schema string.
|
|
92
|
-
*/
|
|
93
|
-
function convertTypeToZodSchema(fieldType) {
|
|
94
|
-
switch (fieldType.type) {
|
|
95
|
-
case TypeKind.ARRAY:
|
|
96
|
-
if (fieldType.items == null) {
|
|
97
|
-
throw new Error("Array field is missing items type");
|
|
98
|
-
}
|
|
99
|
-
return `z.array(${convertTypeToZodSchema(fieldType.items)})`;
|
|
100
|
-
case TypeKind.BOOLEAN:
|
|
101
|
-
return "z.boolean()";
|
|
102
|
-
case TypeKind.DOC_REF:
|
|
103
|
-
case TypeKind.MEDIA_REF:
|
|
104
|
-
case TypeKind.OBJECT_REF:
|
|
105
|
-
case TypeKind.STRING:
|
|
106
|
-
case TypeKind.USER_REF:
|
|
107
|
-
return "z.string()";
|
|
108
|
-
case TypeKind.DOUBLE:
|
|
109
|
-
return "z.number()";
|
|
110
|
-
case TypeKind.OPTIONAL:
|
|
111
|
-
if (fieldType.item == null) {
|
|
112
|
-
throw new Error("Optional field is missing inner type");
|
|
113
|
-
}
|
|
114
|
-
return `${convertTypeToZodSchema(fieldType.item)}.optional()`;
|
|
115
|
-
case TypeKind.REF:
|
|
116
|
-
return "z.unknown()";
|
|
117
|
-
default:
|
|
118
|
-
throw new Error(`Unknown schema field type: ${fieldType.type}`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
18
|
+
import { convertFieldTypeToDescriptor, convertFieldTypeToInternalTypeScript, convertFieldTypeToInternalZod } from "../ir/irFieldHelpers.js";
|
|
19
|
+
import { chainHasDerivedFields } from "./resolveSchemaChain.js";
|
|
121
20
|
|
|
122
21
|
/** Collected info about all fields for a model across all versions. */
|
|
123
22
|
|
|
@@ -141,30 +40,35 @@ function collectRecordModels(chain) {
|
|
|
141
40
|
// Initialize models from all versions
|
|
142
41
|
for (const {
|
|
143
42
|
version,
|
|
144
|
-
|
|
43
|
+
ir
|
|
145
44
|
} of chain) {
|
|
146
|
-
for (const [
|
|
147
|
-
if (
|
|
148
|
-
if (!allRecordModels.has(
|
|
149
|
-
allRecordModels.set(
|
|
45
|
+
for (const [modelKey, modelDef] of Object.entries(ir.models)) {
|
|
46
|
+
if (modelDef.type !== "record") continue;
|
|
47
|
+
if (!allRecordModels.has(modelKey)) {
|
|
48
|
+
allRecordModels.set(modelKey, {
|
|
150
49
|
allFields: new Map(),
|
|
151
50
|
steps: []
|
|
152
51
|
});
|
|
153
52
|
}
|
|
154
|
-
const model = allRecordModels.get(
|
|
155
|
-
for (const
|
|
156
|
-
const existing = model.allFields.get(
|
|
53
|
+
const model = allRecordModels.get(modelKey);
|
|
54
|
+
for (const field of modelDef.record.fields) {
|
|
55
|
+
const existing = model.allFields.get(field.key);
|
|
157
56
|
if (existing == null) {
|
|
158
|
-
model.allFields.set(
|
|
159
|
-
fieldType,
|
|
57
|
+
model.allFields.set(field.key, {
|
|
58
|
+
fieldType: field.fieldType,
|
|
59
|
+
isOptional: field.isOptional === true,
|
|
160
60
|
presentInVersions: new Set([version]),
|
|
161
|
-
alwaysOptional:
|
|
61
|
+
alwaysOptional: field.isOptional === true,
|
|
62
|
+
everOptional: field.isOptional === true
|
|
162
63
|
});
|
|
163
64
|
} else {
|
|
164
65
|
existing.presentInVersions.add(version);
|
|
165
|
-
if (
|
|
66
|
+
if (field.isOptional !== true) {
|
|
166
67
|
existing.alwaysOptional = false;
|
|
167
68
|
}
|
|
69
|
+
if (field.isOptional === true) {
|
|
70
|
+
existing.everOptional = true;
|
|
71
|
+
}
|
|
168
72
|
}
|
|
169
73
|
}
|
|
170
74
|
}
|
|
@@ -172,32 +76,30 @@ function collectRecordModels(chain) {
|
|
|
172
76
|
|
|
173
77
|
// Compute upgrade steps from version diffs
|
|
174
78
|
for (let i = 1; i < chain.length; i++) {
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
for (const [
|
|
178
|
-
if (
|
|
179
|
-
const
|
|
180
|
-
if (
|
|
181
|
-
const model = allRecordModels.get(
|
|
79
|
+
const prevEntry = chain[i - 1];
|
|
80
|
+
const currEntry = chain[i];
|
|
81
|
+
for (const [modelKey, currModelDef] of Object.entries(currEntry.ir.models)) {
|
|
82
|
+
if (currModelDef.type !== "record") continue;
|
|
83
|
+
const prevModelDef = prevEntry.ir.models[modelKey];
|
|
84
|
+
if (prevModelDef == null || prevModelDef.type !== "record") continue;
|
|
85
|
+
const model = allRecordModels.get(modelKey);
|
|
182
86
|
if (model == null) continue;
|
|
183
|
-
const prevFields = new Set(
|
|
184
|
-
const currFields = new Set(
|
|
87
|
+
const prevFields = new Set(prevModelDef.record.fields.map(f => f.key));
|
|
88
|
+
const currFields = new Set(currModelDef.record.fields.map(f => f.key));
|
|
185
89
|
|
|
186
90
|
// Fields added in this version
|
|
187
91
|
const addedFields = new Map();
|
|
188
|
-
const recordUpgrades =
|
|
189
|
-
for (const
|
|
190
|
-
if (!prevFields.has(
|
|
191
|
-
const annotation = recordUpgrades?.[
|
|
92
|
+
const recordUpgrades = currEntry.migrations?.[modelKey];
|
|
93
|
+
for (const fieldKey of currFields) {
|
|
94
|
+
if (!prevFields.has(fieldKey)) {
|
|
95
|
+
const annotation = recordUpgrades?.[fieldKey];
|
|
192
96
|
if (annotation != null) {
|
|
193
|
-
addedFields.set(
|
|
194
|
-
derivedFrom: [...annotation.derivedFrom]
|
|
195
|
-
forwardSource: annotation.forward.toString()
|
|
97
|
+
addedFields.set(fieldKey, {
|
|
98
|
+
derivedFrom: [...annotation.derivedFrom]
|
|
196
99
|
});
|
|
197
100
|
} else {
|
|
198
|
-
addedFields.set(
|
|
199
|
-
derivedFrom: []
|
|
200
|
-
forwardSource: "() => undefined"
|
|
101
|
+
addedFields.set(fieldKey, {
|
|
102
|
+
derivedFrom: []
|
|
201
103
|
});
|
|
202
104
|
}
|
|
203
105
|
}
|
|
@@ -205,15 +107,14 @@ function collectRecordModels(chain) {
|
|
|
205
107
|
|
|
206
108
|
// Fields removed in this version
|
|
207
109
|
const removedFields = [];
|
|
208
|
-
for (const
|
|
209
|
-
if (!currFields.has(
|
|
210
|
-
removedFields.push(
|
|
110
|
+
for (const fieldKey of prevFields) {
|
|
111
|
+
if (!currFields.has(fieldKey)) {
|
|
112
|
+
removedFields.push(fieldKey);
|
|
211
113
|
}
|
|
212
114
|
}
|
|
213
115
|
if (addedFields.size > 0 || removedFields.length > 0) {
|
|
214
116
|
model.steps.push({
|
|
215
|
-
|
|
216
|
-
addedInVersion: currVersion.version,
|
|
117
|
+
addedInVersion: currEntry.version,
|
|
217
118
|
fields: addedFields,
|
|
218
119
|
removedFields
|
|
219
120
|
});
|
|
@@ -239,11 +140,11 @@ function collectRecordModels(chain) {
|
|
|
239
140
|
function generateInternalTypes(allRecordModels) {
|
|
240
141
|
let output = GENERATED_FILE_HEADER;
|
|
241
142
|
output += "\n";
|
|
242
|
-
for (const [
|
|
143
|
+
for (const [modelKey, model] of sortedEntries(allRecordModels)) {
|
|
243
144
|
output += `/** Internal representation containing all fields across all schema versions. */\n`;
|
|
244
|
-
output += `export interface ${
|
|
145
|
+
output += `export interface ${modelKey}__Internal {\n`;
|
|
245
146
|
for (const [fieldName, fieldInfo] of sortedEntries(model.allFields)) {
|
|
246
|
-
const tsType =
|
|
147
|
+
const tsType = convertFieldTypeToInternalTypeScript(fieldInfo.fieldType, fieldInfo.isOptional);
|
|
247
148
|
const optional = fieldInfo.alwaysOptional ? "?" : "";
|
|
248
149
|
output += ` readonly ${fieldName}${optional}: ${tsType};\n`;
|
|
249
150
|
}
|
|
@@ -252,32 +153,78 @@ function generateInternalTypes(allRecordModels) {
|
|
|
252
153
|
return output;
|
|
253
154
|
}
|
|
254
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Generate per-version internal interfaces (e.g. `ShapeBox__v1`, `ShapeBox__v2`).
|
|
158
|
+
*
|
|
159
|
+
* Each interface contains only the fields present in that version, with their
|
|
160
|
+
* actual optionality taken straight from that version's IR. The downstream
|
|
161
|
+
* `DocumentUpgradeFns` generator uses these so each upgrade function's
|
|
162
|
+
* parameter can `Pick` the prior version's fields and its return type can
|
|
163
|
+
* index the current version's field type precisely.
|
|
164
|
+
*/
|
|
165
|
+
function generatePerVersionInternalTypes(chain) {
|
|
166
|
+
// Group by model so each model's versions appear together in ascending order.
|
|
167
|
+
const perModelVersions = new Map();
|
|
168
|
+
for (const {
|
|
169
|
+
version,
|
|
170
|
+
ir
|
|
171
|
+
} of chain) {
|
|
172
|
+
for (const [modelKey, modelDef] of Object.entries(ir.models)) {
|
|
173
|
+
if (modelDef.type !== "record") continue;
|
|
174
|
+
let list = perModelVersions.get(modelKey);
|
|
175
|
+
if (list == null) {
|
|
176
|
+
list = [];
|
|
177
|
+
perModelVersions.set(modelKey, list);
|
|
178
|
+
}
|
|
179
|
+
list.push({
|
|
180
|
+
version,
|
|
181
|
+
fields: modelDef.record.fields
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
let output = "";
|
|
186
|
+
const sortedModels = Array.from(perModelVersions.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
187
|
+
for (const [modelKey, versions] of sortedModels) {
|
|
188
|
+
for (const {
|
|
189
|
+
version,
|
|
190
|
+
fields
|
|
191
|
+
} of versions) {
|
|
192
|
+
output += `/** Internal representation of ${modelKey} at schema version ${version}. */\n`;
|
|
193
|
+
output += `export interface ${modelKey}__v${version} {\n`;
|
|
194
|
+
const sortedFields = [...fields].sort((a, b) => a.key.localeCompare(b.key));
|
|
195
|
+
for (const field of sortedFields) {
|
|
196
|
+
const tsType = convertFieldTypeToInternalTypeScript(field.fieldType, field.isOptional === true);
|
|
197
|
+
const optional = field.isOptional === true ? "?" : "";
|
|
198
|
+
output += ` readonly ${field.key}${optional}: ${tsType};\n`;
|
|
199
|
+
}
|
|
200
|
+
output += "}\n\n";
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return output;
|
|
204
|
+
}
|
|
205
|
+
|
|
255
206
|
/**
|
|
256
207
|
* Generate _internal/upgrades.ts content.
|
|
257
208
|
*/
|
|
258
|
-
function generateUpgrades(allRecordModels,
|
|
209
|
+
function generateUpgrades(allRecordModels, latestIr) {
|
|
259
210
|
let output = GENERATED_FILE_HEADER;
|
|
260
211
|
const hasRecords = allRecordModels.size > 0;
|
|
261
|
-
const hasUnions = Object.values(
|
|
212
|
+
const hasUnions = Object.values(latestIr.models).some(m => m.type === "union");
|
|
262
213
|
const imports = [];
|
|
263
214
|
if (hasRecords) imports.push("UpgradeRegistry");
|
|
264
215
|
if (hasUnions) imports.push("UnionUpgradeRegistry");
|
|
265
216
|
if (imports.length > 0) {
|
|
266
217
|
output += `import type { ${imports.join(", ")} } from "@palantir/pack.document-schema.model-types";\n\n`;
|
|
267
218
|
}
|
|
268
|
-
for (const [
|
|
269
|
-
output += `export const ${
|
|
270
|
-
output += ` modelName: "${
|
|
219
|
+
for (const [modelKey, model] of sortedEntries(allRecordModels)) {
|
|
220
|
+
output += `export const ${modelKey}Upgrades: UpgradeRegistry<"${modelKey}"> = {\n`;
|
|
221
|
+
output += ` modelName: "${modelKey}",\n`;
|
|
271
222
|
|
|
272
223
|
// allFields
|
|
273
224
|
output += ` allFields: {\n`;
|
|
274
225
|
for (const [fieldName, fieldInfo] of sortedEntries(model.allFields)) {
|
|
275
|
-
const typeDescriptor =
|
|
276
|
-
|
|
277
|
-
output += ` ${fieldName}: { type: ${typeDescriptor}, default: ${JSON.stringify(fieldInfo.default)} },\n`;
|
|
278
|
-
} else {
|
|
279
|
-
output += ` ${fieldName}: { type: ${typeDescriptor} },\n`;
|
|
280
|
-
}
|
|
226
|
+
const typeDescriptor = convertFieldTypeToDescriptor(fieldInfo.fieldType, fieldInfo.isOptional);
|
|
227
|
+
output += ` ${fieldName}: { type: ${typeDescriptor} },\n`;
|
|
281
228
|
}
|
|
282
229
|
output += ` },\n`;
|
|
283
230
|
|
|
@@ -285,13 +232,11 @@ function generateUpgrades(allRecordModels, latestSchema) {
|
|
|
285
232
|
output += ` steps: [\n`;
|
|
286
233
|
for (const step of model.steps) {
|
|
287
234
|
output += ` {\n`;
|
|
288
|
-
output += ` name: "${step.name}",\n`;
|
|
289
235
|
output += ` addedInVersion: ${step.addedInVersion},\n`;
|
|
290
236
|
output += ` fields: {\n`;
|
|
291
237
|
for (const [fieldName, fieldMeta] of step.fields) {
|
|
292
238
|
output += ` ${fieldName}: {\n`;
|
|
293
239
|
output += ` derivedFrom: [${fieldMeta.derivedFrom.map(d => `"${d}"`).join(", ")}],\n`;
|
|
294
|
-
output += ` forward: ${fieldMeta.forwardSource},\n`;
|
|
295
240
|
if (fieldMeta.default !== undefined) {
|
|
296
241
|
output += ` default: ${JSON.stringify(fieldMeta.default)},\n`;
|
|
297
242
|
}
|
|
@@ -308,19 +253,15 @@ function generateUpgrades(allRecordModels, latestSchema) {
|
|
|
308
253
|
}
|
|
309
254
|
|
|
310
255
|
// Generate UnionUpgradeRegistry entries for union models
|
|
311
|
-
for (const [
|
|
312
|
-
if (
|
|
313
|
-
|
|
314
|
-
output += `
|
|
315
|
-
output += `
|
|
256
|
+
for (const [modelKey, modelDef] of Object.entries(latestIr.models)) {
|
|
257
|
+
if (modelDef.type !== "union") continue;
|
|
258
|
+
const union = modelDef.union;
|
|
259
|
+
output += `export const ${modelKey}Upgrades: UnionUpgradeRegistry<"${modelKey}"> = {\n`;
|
|
260
|
+
output += ` modelName: "${modelKey}",\n`;
|
|
261
|
+
output += ` discriminant: "${union.discriminant}",\n`;
|
|
316
262
|
output += ` variants: {\n`;
|
|
317
|
-
for (const [variantKey,
|
|
318
|
-
|
|
319
|
-
const variantExportName = findRecordExportName(variantField.name, latestSchema);
|
|
320
|
-
if (variantExportName != null) {
|
|
321
|
-
output += ` "${variantKey}": "${variantExportName}",\n`;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
263
|
+
for (const [variantKey, variantModelKey] of Object.entries(union.variants)) {
|
|
264
|
+
output += ` "${variantKey}": "${variantModelKey}",\n`;
|
|
324
265
|
}
|
|
325
266
|
output += ` },\n`;
|
|
326
267
|
output += `};\n\n`;
|
|
@@ -334,21 +275,13 @@ function generateUpgrades(allRecordModels, latestSchema) {
|
|
|
334
275
|
function generateInternalSchemaContent(allRecordModels) {
|
|
335
276
|
let output = GENERATED_FILE_HEADER;
|
|
336
277
|
output += `import { z } from "zod";\n\n`;
|
|
337
|
-
for (const [
|
|
338
|
-
output += `export const ${
|
|
278
|
+
for (const [modelKey, model] of sortedEntries(allRecordModels)) {
|
|
279
|
+
output += `export const ${modelKey}InternalSchema = z.object({\n`;
|
|
339
280
|
for (const [fieldName, fieldInfo] of sortedEntries(model.allFields)) {
|
|
340
|
-
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
if (zodType.endsWith(".optional()")) {
|
|
345
|
-
output += ` ${fieldName}: ${zodType},\n`;
|
|
346
|
-
} else {
|
|
347
|
-
output += ` ${fieldName}: ${zodType}.optional(),\n`;
|
|
348
|
-
}
|
|
349
|
-
} else {
|
|
350
|
-
output += ` ${fieldName}: ${zodType},\n`;
|
|
351
|
-
}
|
|
281
|
+
// Use everOptional: a field optional in ANY version must stay optional
|
|
282
|
+
// in the internal schema because older documents may legitimately omit it.
|
|
283
|
+
const zodType = convertFieldTypeToInternalZod(fieldInfo.fieldType, fieldInfo.alwaysOptional || fieldInfo.everOptional);
|
|
284
|
+
output += ` ${fieldName}: ${zodType},\n`;
|
|
352
285
|
}
|
|
353
286
|
output += `}).passthrough();\n\n`;
|
|
354
287
|
}
|
|
@@ -356,25 +289,103 @@ function generateInternalSchemaContent(allRecordModels) {
|
|
|
356
289
|
}
|
|
357
290
|
|
|
358
291
|
/**
|
|
359
|
-
* Generate _internal/
|
|
360
|
-
*
|
|
292
|
+
* Generate _internal/upgradeFns.ts content: a typed `DocumentUpgradeFns`
|
|
293
|
+
* interface enumerating every upgrade function the app must supply at boot.
|
|
294
|
+
*
|
|
295
|
+
* For every `(modelName, v${version}, fieldName)` triple where `derivedFrom` is
|
|
296
|
+
* non-empty, emit a property typed
|
|
297
|
+
* `(oldFields: Pick<<Model>__v<prior>, derivedFrom[number]>) => <Model>__v<current>[fieldName]`.
|
|
298
|
+
* Additive fields (empty `derivedFrom`) are intentionally absent — they are
|
|
299
|
+
* handled by the structural `default` in `_internal/upgrades.ts`.
|
|
361
300
|
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
301
|
+
* The interface is consumed by the generated `DocumentModel` factory in
|
|
302
|
+
* `models.ts`, which requires it as a parameter when the schema has any
|
|
303
|
+
* derived fields. Schemas without derived fields emit an empty interface
|
|
304
|
+
* (still exported for type-uniformity in downstream code).
|
|
305
|
+
*/
|
|
306
|
+
function generateUpgradeFns(chain, allRecordModels) {
|
|
307
|
+
const perModel = new Map();
|
|
308
|
+
const neededTypes = new Set();
|
|
309
|
+
for (const [modelKey, model] of sortedEntries(allRecordModels)) {
|
|
310
|
+
for (const step of model.steps) {
|
|
311
|
+
const currentIdx = chain.findIndex(c => c.version === step.addedInVersion);
|
|
312
|
+
if (currentIdx <= 0) continue;
|
|
313
|
+
const priorVersion = chain[currentIdx - 1].version;
|
|
314
|
+
const fields = [];
|
|
315
|
+
for (const [fieldName, fieldMeta] of step.fields) {
|
|
316
|
+
if (fieldMeta.derivedFrom.length === 0) continue;
|
|
317
|
+
fields.push({
|
|
318
|
+
fieldName,
|
|
319
|
+
derivedFrom: [...fieldMeta.derivedFrom]
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (fields.length === 0) continue;
|
|
323
|
+
let list = perModel.get(modelKey);
|
|
324
|
+
if (list == null) {
|
|
325
|
+
list = [];
|
|
326
|
+
perModel.set(modelKey, list);
|
|
327
|
+
}
|
|
328
|
+
list.push({
|
|
329
|
+
currentVersion: step.addedInVersion,
|
|
330
|
+
priorVersion,
|
|
331
|
+
fields
|
|
332
|
+
});
|
|
333
|
+
neededTypes.add(`${modelKey}__v${priorVersion}`);
|
|
334
|
+
neededTypes.add(`${modelKey}__v${step.addedInVersion}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
let output = GENERATED_FILE_HEADER;
|
|
338
|
+
output += `\n`;
|
|
339
|
+
if (neededTypes.size > 0) {
|
|
340
|
+
const sorted = Array.from(neededTypes).sort();
|
|
341
|
+
output += `import type { ${sorted.join(", ")} } from "./types.js";\n\n`;
|
|
342
|
+
}
|
|
343
|
+
output += `/**\n`;
|
|
344
|
+
output += ` * Typed upgrade functions the application must supply at boot. Coverage is\n`;
|
|
345
|
+
output += ` * exhaustive: missing or extra entries fail type-check at the \`DocumentModel(...)\`\n`;
|
|
346
|
+
output += ` * call site. Additive fields (empty \`derivedFrom\`) are intentionally absent.\n`;
|
|
347
|
+
output += ` */\n`;
|
|
348
|
+
if (perModel.size === 0) {
|
|
349
|
+
output += `// eslint-disable-next-line @typescript-eslint/no-empty-object-type\n`;
|
|
350
|
+
output += `export interface DocumentUpgradeFns {}\n`;
|
|
351
|
+
} else {
|
|
352
|
+
output += `export interface DocumentUpgradeFns {\n`;
|
|
353
|
+
for (const [modelKey, steps] of Array.from(perModel.entries()).sort(([a], [b]) => a.localeCompare(b))) {
|
|
354
|
+
output += ` ${modelKey}: {\n`;
|
|
355
|
+
for (const step of steps) {
|
|
356
|
+
output += ` v${step.currentVersion}: {\n`;
|
|
357
|
+
for (const f of step.fields) {
|
|
358
|
+
const pickKeys = f.derivedFrom.map(d => `"${d}"`).join(" | ");
|
|
359
|
+
output += ` ${f.fieldName}: (oldFields: Pick<${modelKey}__v${step.priorVersion}, ${pickKeys}>) => ${modelKey}__v${step.currentVersion}["${f.fieldName}"];\n`;
|
|
360
|
+
}
|
|
361
|
+
output += ` };\n`;
|
|
362
|
+
}
|
|
363
|
+
output += ` };\n`;
|
|
364
|
+
}
|
|
365
|
+
output += `}\n`;
|
|
366
|
+
}
|
|
367
|
+
return output;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Generate _internal/types.ts, _internal/upgrades.ts, _internal/schema.ts and
|
|
372
|
+
* _internal/upgradeFns.ts from an already-resolved versioned IR chain.
|
|
364
373
|
*/
|
|
365
|
-
export function
|
|
374
|
+
export function generateInternalFromChain(resolved) {
|
|
366
375
|
const {
|
|
367
376
|
chain
|
|
368
|
-
} =
|
|
369
|
-
const
|
|
377
|
+
} = resolved;
|
|
378
|
+
const latestIr = chain[chain.length - 1].ir;
|
|
370
379
|
const allRecordModels = collectRecordModels(chain);
|
|
371
|
-
const internalTypes = generateInternalTypes(allRecordModels);
|
|
372
|
-
const upgrades = generateUpgrades(allRecordModels,
|
|
380
|
+
const internalTypes = generateInternalTypes(allRecordModels) + (chainHasDerivedFields(chain) ? generatePerVersionInternalTypes(chain) : "");
|
|
381
|
+
const upgrades = generateUpgrades(allRecordModels, latestIr);
|
|
373
382
|
const internalSchema = generateInternalSchemaContent(allRecordModels);
|
|
383
|
+
const internalUpgradeFns = generateUpgradeFns(chain, allRecordModels);
|
|
374
384
|
return {
|
|
375
385
|
internalTypes,
|
|
376
386
|
upgrades,
|
|
377
|
-
internalSchema
|
|
387
|
+
internalSchema,
|
|
388
|
+
internalUpgradeFns
|
|
378
389
|
};
|
|
379
390
|
}
|
|
380
391
|
//# sourceMappingURL=generateInternalFromSchema.js.map
|