@powerhousedao/codegen 6.2.2-dev.42 → 6.2.2-dev.44
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/dist/{file-builders-DaV8C_6p.mjs → file-builders-B4QZXx5u.mjs} +448 -38
- package/dist/file-builders-B4QZXx5u.mjs.map +1 -0
- package/dist/{index-DyhHw5PG.d.mts → index-DSucUSbm.d.mts} +41 -2
- package/dist/index-DSucUSbm.d.mts.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +296 -89
- package/dist/index.mjs.map +1 -1
- package/dist/src/file-builders/index.d.mts +2 -2
- package/dist/src/file-builders/index.mjs +2 -2
- package/dist/src/name-builders/index.d.mts +1 -1
- package/dist/src/name-builders/index.mjs +1 -1
- package/dist/src/templates/index.d.mts +17 -2
- package/dist/src/templates/index.d.mts.map +1 -1
- package/dist/src/templates/index.mjs +1 -1
- package/dist/src/utils/index.d.mts +1 -1
- package/dist/src/utils/index.mjs +1 -1
- package/package.json +3 -3
- package/dist/file-builders-DaV8C_6p.mjs.map +0 -1
- package/dist/index-DyhHw5PG.d.mts.map +0 -1
|
@@ -17,8 +17,8 @@ import { writeJsonFile } from "write-json-file";
|
|
|
17
17
|
import { stripVTControlCharacters } from "node:util";
|
|
18
18
|
import path$1, { join as join$1, relative } from "node:path";
|
|
19
19
|
import { generate } from "@graphql-codegen/cli";
|
|
20
|
-
import { generatorTypeDefs, validationSchema } from "@powerhousedao/document-engineering/graphql";
|
|
21
|
-
import { Kind, parse } from "graphql";
|
|
20
|
+
import { generatorTypeDefs, getPHCustomScalarByTypeName, validationSchema } from "@powerhousedao/document-engineering/graphql";
|
|
21
|
+
import { Kind, parse, print } from "graphql";
|
|
22
22
|
import { realpathSync } from "node:fs";
|
|
23
23
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
24
24
|
function isEOL(c) {
|
|
@@ -5185,36 +5185,88 @@ ${buildCreatorsExports(v.specification.modules, v.camelCaseDocumentType)}
|
|
|
5185
5185
|
`.raw;
|
|
5186
5186
|
//#endregion
|
|
5187
5187
|
//#region src/templates/document-model/gen/document-schema.ts
|
|
5188
|
-
|
|
5188
|
+
function priorVersions(versions, currentVersion) {
|
|
5189
|
+
return versions.filter((k) => k < currentVersion);
|
|
5190
|
+
}
|
|
5191
|
+
function makeOlderStateSchemaImports(versions, currentVersion, phStateName) {
|
|
5192
|
+
return priorVersions(versions, currentVersion).map((k) => `import { ${phStateName}Schema as ${phStateName}SchemaV${k} } from "../../v${k}/gen/document-schema.js";`).join("\n");
|
|
5193
|
+
}
|
|
5194
|
+
function makeStateSchemasByVersion(versions, currentVersion, phStateName) {
|
|
5195
|
+
return `{ ${versions.filter((k) => k <= currentVersion).map((k) => {
|
|
5196
|
+
return `${k}: ${k === currentVersion ? `${phStateName}Schema` : `${phStateName}SchemaV${k}`}`;
|
|
5197
|
+
}).join(", ")} }`;
|
|
5198
|
+
}
|
|
5199
|
+
function makeDocumentSchemasByVersion(versions, currentVersion, v) {
|
|
5200
|
+
return `{ ${versions.filter((k) => k <= currentVersion).map((k) => {
|
|
5201
|
+
if (k === currentVersion) return `${k}: ${v.phDocumentSchemaName}`;
|
|
5202
|
+
return `${k}: z.object({ header: ${v.phDocumentTypeName}HeaderSchema, state: ${v.phStateName}SchemaV${k}, initialState: ${v.phStateName}SchemaV${k} })`;
|
|
5203
|
+
}).join(", ")} }`;
|
|
5204
|
+
}
|
|
5189
5205
|
/**
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
import { ${v.documentTypeVariableName} } from "./document-type.js";
|
|
5199
|
-
import { ${v.stateSchemaName} } from "./schema/zod.js";
|
|
5200
|
-
import type { ${v.phDocumentTypeName}, ${v.phStateName} } from "./types.js";
|
|
5206
|
+
* Version-aware validators are only emitted for versions with released
|
|
5207
|
+
* predecessors: a document is validated against the schema of the version it
|
|
5208
|
+
* is stamped with, so a later version may add non-nullable fields without
|
|
5209
|
+
* rejecting documents that have not been upgraded yet.
|
|
5210
|
+
*/
|
|
5211
|
+
function makeVersionAwareValidators(v) {
|
|
5212
|
+
return `
|
|
5213
|
+
const ${v.phStateName}SchemasByVersion: Record<number, z.ZodType> = ${makeStateSchemasByVersion(v.versions, v.version, v.phStateName)};
|
|
5201
5214
|
|
|
5202
|
-
|
|
5203
|
-
export const ${v.phDocumentTypeName}HeaderSchema = BaseDocumentHeaderSchema.extend({
|
|
5204
|
-
documentType: z.literal(${v.documentTypeVariableName}),
|
|
5205
|
-
});
|
|
5215
|
+
const ${v.phDocumentSchemaName}sByVersion: Record<number, z.ZodType> = ${makeDocumentSchemasByVersion(v.versions, v.version, v)};
|
|
5206
5216
|
|
|
5207
|
-
/**
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
});
|
|
5217
|
+
/** The document model version stamped in a state's document scope. States stamped with 0 or nothing predate versioning and are treated as version 1. */
|
|
5218
|
+
function stampedDocumentModelVersion(state: unknown): number {
|
|
5219
|
+
if (typeof state !== "object" || state === null) return 1;
|
|
5220
|
+
const documentScope = (state as { document?: unknown }).document;
|
|
5221
|
+
if (typeof documentScope !== "object" || documentScope === null) return 1;
|
|
5222
|
+
const version = (documentScope as { version?: unknown }).version;
|
|
5223
|
+
return normalizeDocumentModelVersion(typeof version === "number" ? version : undefined);
|
|
5224
|
+
}
|
|
5211
5225
|
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5226
|
+
function resolve${v.phStateName}Schema(state: unknown): z.ZodType {
|
|
5227
|
+
const schema = ${v.phStateName}SchemasByVersion[stampedDocumentModelVersion(state)];
|
|
5228
|
+
return schema ?? ${v.phStateName}Schema;
|
|
5229
|
+
}
|
|
5230
|
+
|
|
5231
|
+
function resolve${v.phDocumentSchemaName}(document: unknown): z.ZodType {
|
|
5232
|
+
const state = typeof document === "object" && document !== null
|
|
5233
|
+
? (document as { state?: unknown }).state
|
|
5234
|
+
: undefined;
|
|
5235
|
+
const schema = ${v.phDocumentSchemaName}sByVersion[stampedDocumentModelVersion(state)];
|
|
5236
|
+
return schema ?? ${v.phDocumentSchemaName};
|
|
5237
|
+
}
|
|
5238
|
+
|
|
5239
|
+
/** Simple helper function to check if a state object is a ${v.pascalCaseDocumentType} document state object. Validates against the schema of the version the state is stamped with. */
|
|
5240
|
+
export function ${v.isPhStateOfTypeFunctionName}(
|
|
5241
|
+
state: unknown,
|
|
5242
|
+
): state is ${v.phStateName} {
|
|
5243
|
+
return resolve${v.phStateName}Schema(state).safeParse(state).success;
|
|
5244
|
+
}
|
|
5245
|
+
|
|
5246
|
+
/** Simple helper function to assert that a document state object is a ${v.pascalCaseDocumentType} document state object. Validates against the schema of the version the state is stamped with. */
|
|
5247
|
+
export function ${v.assertIsPhStateOfTypeFunctionName}(
|
|
5248
|
+
state: unknown,
|
|
5249
|
+
): asserts state is ${v.phStateName} {
|
|
5250
|
+
resolve${v.phStateName}Schema(state).parse(state);
|
|
5251
|
+
}
|
|
5252
|
+
|
|
5253
|
+
/** Simple helper function to check if a document is a ${v.pascalCaseDocumentType} document. Validates against the schema of the version the document is stamped with, so documents on older versions remain valid until they are upgraded. */
|
|
5254
|
+
export function ${v.isPhDocumentOfTypeFunctionName}(
|
|
5255
|
+
document: unknown,
|
|
5256
|
+
): document is ${v.phDocumentTypeName} {
|
|
5257
|
+
return resolve${v.phDocumentSchemaName}(document).safeParse(document).success;
|
|
5258
|
+
}
|
|
5217
5259
|
|
|
5260
|
+
/** Simple helper function to assert that a document is a ${v.pascalCaseDocumentType} document. Validates against the schema of the version the document is stamped with, so documents on older versions remain valid until they are upgraded. */
|
|
5261
|
+
export function ${v.assertIsPhDocumentOfTypeFunctionName}(
|
|
5262
|
+
document: unknown,
|
|
5263
|
+
): asserts document is ${v.phDocumentTypeName} {
|
|
5264
|
+
resolve${v.phDocumentSchemaName}(document).parse(document);
|
|
5265
|
+
}
|
|
5266
|
+
`;
|
|
5267
|
+
}
|
|
5268
|
+
function makeSingleVersionValidators(v) {
|
|
5269
|
+
return `
|
|
5218
5270
|
/** Simple helper function to check if a state object is a ${v.pascalCaseDocumentType} document state object */
|
|
5219
5271
|
export function ${v.isPhStateOfTypeFunctionName}(
|
|
5220
5272
|
state: unknown,
|
|
@@ -5242,7 +5294,42 @@ export function ${v.assertIsPhDocumentOfTypeFunctionName}(
|
|
|
5242
5294
|
): asserts document is ${v.phDocumentTypeName} {
|
|
5243
5295
|
${v.phDocumentSchemaName}.parse(document);
|
|
5244
5296
|
}
|
|
5245
|
-
|
|
5297
|
+
`;
|
|
5298
|
+
}
|
|
5299
|
+
const documentModelDocumentSchemaFileTemplate = (v) => {
|
|
5300
|
+
const olderImports = makeOlderStateSchemaImports(v.versions, v.version, v.phStateName);
|
|
5301
|
+
const hasPriorVersions = olderImports.length > 0;
|
|
5302
|
+
return ts$1`
|
|
5303
|
+
/**
|
|
5304
|
+
* WARNING: DO NOT EDIT
|
|
5305
|
+
* This file is auto-generated and updated by codegen
|
|
5306
|
+
*/
|
|
5307
|
+
import {
|
|
5308
|
+
BaseDocumentHeaderSchema,
|
|
5309
|
+
BaseDocumentStateSchema,${hasPriorVersions ? "\n normalizeDocumentModelVersion," : ""}
|
|
5310
|
+
} from "document-model";
|
|
5311
|
+
import { z } from "zod";
|
|
5312
|
+
import { ${v.documentTypeVariableName} } from "./document-type.js";
|
|
5313
|
+
import { ${v.stateSchemaName} } from "./schema/zod.js";
|
|
5314
|
+
import type { ${v.phDocumentTypeName}, ${v.phStateName} } from "./types.js";
|
|
5315
|
+
${hasPriorVersions ? olderImports + "\n" : ""}
|
|
5316
|
+
/** Schema for validating the header object of a ${v.pascalCaseDocumentType} document */
|
|
5317
|
+
export const ${v.phDocumentTypeName}HeaderSchema = BaseDocumentHeaderSchema.extend({
|
|
5318
|
+
documentType: z.literal(${v.documentTypeVariableName}),
|
|
5319
|
+
});
|
|
5320
|
+
|
|
5321
|
+
/** Schema for validating the state object of a ${v.pascalCaseDocumentType} document */
|
|
5322
|
+
export const ${v.phStateName}Schema = BaseDocumentStateSchema.extend({
|
|
5323
|
+
global: ${v.stateSchemaName}(),
|
|
5324
|
+
});
|
|
5325
|
+
|
|
5326
|
+
export const ${v.phDocumentSchemaName} = z.object({
|
|
5327
|
+
header: ${v.phDocumentTypeName}HeaderSchema,
|
|
5328
|
+
state: ${v.phStateName}Schema,
|
|
5329
|
+
initialState: ${v.phStateName}Schema,
|
|
5330
|
+
});
|
|
5331
|
+
${hasPriorVersions ? makeVersionAwareValidators(v) : makeSingleVersionValidators(v)}`.raw;
|
|
5332
|
+
};
|
|
5246
5333
|
//#endregion
|
|
5247
5334
|
//#region src/templates/document-model/gen/document-type.ts
|
|
5248
5335
|
const documentModelDocumentTypeTemplate = (v) => ts$1`
|
|
@@ -6231,11 +6318,66 @@ const upgradeManifestTemplate = (v) => ts$1`
|
|
|
6231
6318
|
`.raw;
|
|
6232
6319
|
//#endregion
|
|
6233
6320
|
//#region src/templates/document-model/upgrades/upgrade-transition.ts
|
|
6234
|
-
|
|
6321
|
+
/**
|
|
6322
|
+
* The generated v{N}.ts upgrade transition. Written once and never
|
|
6323
|
+
* overwritten, so hand edits survive regeneration.
|
|
6324
|
+
*
|
|
6325
|
+
* For mechanical schema changes the migration is derived: fields added in
|
|
6326
|
+
* the new version are initialized (from the new version's initial value or
|
|
6327
|
+
* the schema's zero value) and existing data is preserved. When the change
|
|
6328
|
+
* cannot be derived — a field changed type, a nested type changed shape —
|
|
6329
|
+
* the reducer throws until the migration is hand-written: silently running
|
|
6330
|
+
* a no-op migration would stamp documents with a version whose schema their
|
|
6331
|
+
* state does not satisfy, crashing every consumer that validates them.
|
|
6332
|
+
*/
|
|
6333
|
+
const upgradeTransitionTemplate = (v) => {
|
|
6334
|
+
const body = v.plan.kind === "manual" ? manualReducer(v, v.plan.reason) : fillReducer(v, v.plan.fills);
|
|
6335
|
+
return ts$1`
|
|
6336
|
+
/**
|
|
6337
|
+
* WARNING: DO NOT EDIT
|
|
6338
|
+
* This file is auto-generated and updated by codegen
|
|
6339
|
+
*/
|
|
6235
6340
|
import type { Action, PHDocument, UpgradeTransition } from "document-model";
|
|
6236
6341
|
import type { ${v.phStateName} as StateV${v.version - 1} } from "${v.documentModelImportPath}/v${v.version - 1}";
|
|
6237
6342
|
import type { ${v.phStateName} as StateV${v.version} } from "${v.documentModelImportPath}/v${v.version}";
|
|
6238
6343
|
|
|
6344
|
+
${body}
|
|
6345
|
+
|
|
6346
|
+
export const v${v.version}: UpgradeTransition = {
|
|
6347
|
+
toVersion: ${v.version},
|
|
6348
|
+
upgradeReducer,
|
|
6349
|
+
description: "",
|
|
6350
|
+
};
|
|
6351
|
+
`.raw;
|
|
6352
|
+
};
|
|
6353
|
+
function manualReducer(v, reason) {
|
|
6354
|
+
const message = `The ${v.documentModelState.id} v${v.version} migration is not implemented: ${reason}. Implement it in document-models/${v.documentModelDirName}/upgrades/v${v.version}.ts.`;
|
|
6355
|
+
return `
|
|
6356
|
+
/*
|
|
6357
|
+
* This migration could not be derived automatically: ${reason}.
|
|
6358
|
+
* Implement it (migrate BOTH state and initialState), then remove the throw.
|
|
6359
|
+
*/
|
|
6360
|
+
function upgradeReducer(
|
|
6361
|
+
document: PHDocument<StateV${v.version - 1}>,
|
|
6362
|
+
action: Action,
|
|
6363
|
+
): PHDocument<StateV${v.version}> {
|
|
6364
|
+
throw new Error(${JSON.stringify(message)});
|
|
6365
|
+
}
|
|
6366
|
+
`;
|
|
6367
|
+
}
|
|
6368
|
+
function fillReducer(v, fills) {
|
|
6369
|
+
const fillConsts = [];
|
|
6370
|
+
const scopeLines = (source) => ["global", "local"].filter((scope) => fills[scope]).map((scope) => ` ${scope}: { ...added${capitalize$1(scope)}Fields, ...document.${source}.${scope} },`).join("\n");
|
|
6371
|
+
for (const scope of ["global", "local"]) {
|
|
6372
|
+
const fill = fills[scope];
|
|
6373
|
+
if (!fill) continue;
|
|
6374
|
+
fillConsts.push(`const added${capitalize$1(scope)}Fields = ${JSON.stringify(fill, null, 2)} satisfies Partial<StateV${v.version}["${scope}"]>;`);
|
|
6375
|
+
}
|
|
6376
|
+
if (fillConsts.length === 0) return `
|
|
6377
|
+
/*
|
|
6378
|
+
* No fields were added between v${v.version - 1} and v${v.version}, so existing state
|
|
6379
|
+
* carries over unchanged.
|
|
6380
|
+
*/
|
|
6239
6381
|
function upgradeReducer(
|
|
6240
6382
|
document: PHDocument<StateV${v.version - 1}>,
|
|
6241
6383
|
action: Action,
|
|
@@ -6244,13 +6386,37 @@ function upgradeReducer(
|
|
|
6244
6386
|
...document,
|
|
6245
6387
|
};
|
|
6246
6388
|
}
|
|
6389
|
+
`;
|
|
6390
|
+
return `
|
|
6391
|
+
${fillConsts.join("\n\n")}
|
|
6247
6392
|
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6393
|
+
/*
|
|
6394
|
+
* Fields added in v${v.version} are initialized from the new version's initial
|
|
6395
|
+
* value (or the schema's zero value); existing data wins for every field
|
|
6396
|
+
* that already existed. Both state and initialState are migrated so a
|
|
6397
|
+
* rebuild from the operation log converges with the stored state.
|
|
6398
|
+
*/
|
|
6399
|
+
function upgradeReducer(
|
|
6400
|
+
document: PHDocument<StateV${v.version - 1}>,
|
|
6401
|
+
action: Action,
|
|
6402
|
+
): PHDocument<StateV${v.version}> {
|
|
6403
|
+
return {
|
|
6404
|
+
...document,
|
|
6405
|
+
state: {
|
|
6406
|
+
...document.state,
|
|
6407
|
+
${scopeLines("state")}
|
|
6408
|
+
},
|
|
6409
|
+
initialState: {
|
|
6410
|
+
...document.initialState,
|
|
6411
|
+
${scopeLines("initialState")}
|
|
6412
|
+
},
|
|
6413
|
+
};
|
|
6414
|
+
}
|
|
6415
|
+
`;
|
|
6416
|
+
}
|
|
6417
|
+
function capitalize$1(value) {
|
|
6418
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
6419
|
+
}
|
|
6254
6420
|
//#endregion
|
|
6255
6421
|
//#region src/templates/document-model/utils.ts
|
|
6256
6422
|
const documentModelUtilsTemplate = ({ phStateName, pascalCaseDocumentType }) => ts$1`
|
|
@@ -8052,13 +8218,253 @@ async function makeDocumentModelTestFile(args) {
|
|
|
8052
8218
|
await formatSourceFileWithPrettier(sourceFile);
|
|
8053
8219
|
}
|
|
8054
8220
|
//#endregion
|
|
8221
|
+
//#region src/file-builders/document-model/upgrade-migration.ts
|
|
8222
|
+
/**
|
|
8223
|
+
* Derives the migration between two consecutive spec versions. Mechanical
|
|
8224
|
+
* changes — field additions on the scope's state type (initialized from the
|
|
8225
|
+
* new version's initial value, falling back to the schema's zero value) and
|
|
8226
|
+
* field removals — produce a "fill" plan. Anything else (changed field
|
|
8227
|
+
* types, edits to nested types that pre-existing documents reference,
|
|
8228
|
+
* additions codegen cannot synthesize a value for) produces a "manual" plan.
|
|
8229
|
+
*/
|
|
8230
|
+
function buildMigrationPlan(args) {
|
|
8231
|
+
const { previousSpec, specification, stateName, localStateName } = args;
|
|
8232
|
+
if (!previousSpec) return {
|
|
8233
|
+
kind: "manual",
|
|
8234
|
+
reason: "the previous specification version is not available"
|
|
8235
|
+
};
|
|
8236
|
+
const fills = {};
|
|
8237
|
+
const scopes = [{
|
|
8238
|
+
scope: "global",
|
|
8239
|
+
typeName: stateName
|
|
8240
|
+
}, {
|
|
8241
|
+
scope: "local",
|
|
8242
|
+
typeName: localStateName
|
|
8243
|
+
}];
|
|
8244
|
+
for (const { scope, typeName } of scopes) {
|
|
8245
|
+
const oldState = previousSpec.state[scope];
|
|
8246
|
+
const newState = specification.state[scope];
|
|
8247
|
+
const analysis = analyzeScope({
|
|
8248
|
+
oldSchema: oldState?.schema ?? "",
|
|
8249
|
+
newSchema: newState?.schema ?? "",
|
|
8250
|
+
newInitialValue: newState?.initialValue ?? "",
|
|
8251
|
+
typeName,
|
|
8252
|
+
scope
|
|
8253
|
+
});
|
|
8254
|
+
if (analysis.kind === "manual") return analysis;
|
|
8255
|
+
if (analysis.fill && Object.keys(analysis.fill).length > 0) fills[scope] = analysis.fill;
|
|
8256
|
+
}
|
|
8257
|
+
return {
|
|
8258
|
+
kind: "fill",
|
|
8259
|
+
fills
|
|
8260
|
+
};
|
|
8261
|
+
}
|
|
8262
|
+
function analyzeScope(args) {
|
|
8263
|
+
const { oldSchema, newSchema, newInitialValue, typeName, scope } = args;
|
|
8264
|
+
const oldDoc = safeParseSdl(oldSchema);
|
|
8265
|
+
const newDoc = safeParseSdl(newSchema);
|
|
8266
|
+
if (oldSchema.trim() && !oldDoc) return {
|
|
8267
|
+
kind: "manual",
|
|
8268
|
+
reason: `the previous ${scope} state schema could not be parsed`
|
|
8269
|
+
};
|
|
8270
|
+
if (newSchema.trim() && !newDoc) return {
|
|
8271
|
+
kind: "manual",
|
|
8272
|
+
reason: `the new ${scope} state schema could not be parsed`
|
|
8273
|
+
};
|
|
8274
|
+
const oldType = oldDoc ? findObjectType(oldDoc, typeName) : void 0;
|
|
8275
|
+
const newType = newDoc ? findObjectType(newDoc, typeName) : void 0;
|
|
8276
|
+
if (!newType || !newDoc) return {
|
|
8277
|
+
kind: "fill",
|
|
8278
|
+
fill: void 0
|
|
8279
|
+
};
|
|
8280
|
+
if (oldType && oldDoc) {
|
|
8281
|
+
const oldReachable = collectReachableTypes(oldDoc, typeName);
|
|
8282
|
+
for (const [name, oldDefinition] of oldReachable) {
|
|
8283
|
+
if (name === typeName) continue;
|
|
8284
|
+
const newDefinition = findTypeDefinition(newDoc, name);
|
|
8285
|
+
if (!newDefinition) continue;
|
|
8286
|
+
if (print(oldDefinition) !== print(newDefinition)) return {
|
|
8287
|
+
kind: "manual",
|
|
8288
|
+
reason: `the ${scope} state type "${name}" changed between versions`
|
|
8289
|
+
};
|
|
8290
|
+
}
|
|
8291
|
+
}
|
|
8292
|
+
const oldFields = new Map((oldType?.fields ?? []).map((field) => [field.name.value, field]));
|
|
8293
|
+
const newFields = newType.fields ?? [];
|
|
8294
|
+
const initialValueObject = safeParseJsonRecord(newInitialValue);
|
|
8295
|
+
const fill = {};
|
|
8296
|
+
for (const field of newFields) {
|
|
8297
|
+
const fieldName = field.name.value;
|
|
8298
|
+
const oldField = oldFields.get(fieldName);
|
|
8299
|
+
if (oldField) {
|
|
8300
|
+
if (print(oldField.type) !== print(field.type)) return {
|
|
8301
|
+
kind: "manual",
|
|
8302
|
+
reason: `the ${scope} state field "${fieldName}" changed type between versions`
|
|
8303
|
+
};
|
|
8304
|
+
continue;
|
|
8305
|
+
}
|
|
8306
|
+
if (initialValueObject && fieldName in initialValueObject) {
|
|
8307
|
+
fill[fieldName] = initialValueObject[fieldName];
|
|
8308
|
+
continue;
|
|
8309
|
+
}
|
|
8310
|
+
const zero = zeroValueForType(field.type, newDoc, /* @__PURE__ */ new Set());
|
|
8311
|
+
if (!zero.ok) return {
|
|
8312
|
+
kind: "manual",
|
|
8313
|
+
reason: `no initial value could be derived for the added ${scope} state field "${fieldName}"`
|
|
8314
|
+
};
|
|
8315
|
+
fill[fieldName] = zero.value;
|
|
8316
|
+
}
|
|
8317
|
+
return {
|
|
8318
|
+
kind: "fill",
|
|
8319
|
+
fill
|
|
8320
|
+
};
|
|
8321
|
+
}
|
|
8322
|
+
function zeroValueForType(typeNode, schemaDoc, visitedTypes) {
|
|
8323
|
+
if (typeNode.kind !== Kind.NON_NULL_TYPE) return {
|
|
8324
|
+
ok: true,
|
|
8325
|
+
value: null
|
|
8326
|
+
};
|
|
8327
|
+
const inner = typeNode.type;
|
|
8328
|
+
if (inner.kind === Kind.LIST_TYPE) return {
|
|
8329
|
+
ok: true,
|
|
8330
|
+
value: []
|
|
8331
|
+
};
|
|
8332
|
+
const name = inner.name.value;
|
|
8333
|
+
switch (name) {
|
|
8334
|
+
case "String":
|
|
8335
|
+
case "ID": return {
|
|
8336
|
+
ok: true,
|
|
8337
|
+
value: ""
|
|
8338
|
+
};
|
|
8339
|
+
case "Int":
|
|
8340
|
+
case "Float": return {
|
|
8341
|
+
ok: true,
|
|
8342
|
+
value: 0
|
|
8343
|
+
};
|
|
8344
|
+
case "Boolean": return {
|
|
8345
|
+
ok: true,
|
|
8346
|
+
value: false
|
|
8347
|
+
};
|
|
8348
|
+
}
|
|
8349
|
+
const definition = findTypeDefinition(schemaDoc, name);
|
|
8350
|
+
if (!definition) {
|
|
8351
|
+
const defaultValue = getPHCustomScalarByTypeName(name)?.getDefaultValue?.();
|
|
8352
|
+
if (defaultValue !== void 0) return {
|
|
8353
|
+
ok: true,
|
|
8354
|
+
value: defaultValue
|
|
8355
|
+
};
|
|
8356
|
+
return { ok: false };
|
|
8357
|
+
}
|
|
8358
|
+
if (definition.kind === Kind.ENUM_TYPE_DEFINITION) return zeroValueForEnum(definition);
|
|
8359
|
+
if (definition.kind === Kind.OBJECT_TYPE_DEFINITION) {
|
|
8360
|
+
if (visitedTypes.has(name)) return { ok: false };
|
|
8361
|
+
visitedTypes.add(name);
|
|
8362
|
+
const value = {};
|
|
8363
|
+
for (const field of definition.fields ?? []) {
|
|
8364
|
+
const fieldZero = zeroValueForType(field.type, schemaDoc, visitedTypes);
|
|
8365
|
+
if (!fieldZero.ok) return { ok: false };
|
|
8366
|
+
value[field.name.value] = fieldZero.value;
|
|
8367
|
+
}
|
|
8368
|
+
visitedTypes.delete(name);
|
|
8369
|
+
return {
|
|
8370
|
+
ok: true,
|
|
8371
|
+
value
|
|
8372
|
+
};
|
|
8373
|
+
}
|
|
8374
|
+
if (definition.kind === Kind.SCALAR_TYPE_DEFINITION) {
|
|
8375
|
+
const defaultValue = getPHCustomScalarByTypeName(name)?.getDefaultValue?.();
|
|
8376
|
+
if (defaultValue !== void 0) return {
|
|
8377
|
+
ok: true,
|
|
8378
|
+
value: defaultValue
|
|
8379
|
+
};
|
|
8380
|
+
return { ok: false };
|
|
8381
|
+
}
|
|
8382
|
+
return { ok: false };
|
|
8383
|
+
}
|
|
8384
|
+
function zeroValueForEnum(definition) {
|
|
8385
|
+
const first = definition.values?.[0]?.name.value;
|
|
8386
|
+
if (first === void 0) return { ok: false };
|
|
8387
|
+
return {
|
|
8388
|
+
ok: true,
|
|
8389
|
+
value: first
|
|
8390
|
+
};
|
|
8391
|
+
}
|
|
8392
|
+
function collectReachableTypes(schemaDoc, rootTypeName) {
|
|
8393
|
+
const reachable = /* @__PURE__ */ new Map();
|
|
8394
|
+
const queue = [rootTypeName];
|
|
8395
|
+
while (queue.length > 0) {
|
|
8396
|
+
const name = queue.shift();
|
|
8397
|
+
if (reachable.has(name)) continue;
|
|
8398
|
+
const definition = findTypeDefinition(schemaDoc, name);
|
|
8399
|
+
if (!definition) continue;
|
|
8400
|
+
reachable.set(name, definition);
|
|
8401
|
+
if (definition.kind === Kind.OBJECT_TYPE_DEFINITION) for (const field of definition.fields ?? []) queue.push(namedTypeOf(field.type));
|
|
8402
|
+
else if (definition.kind === Kind.UNION_TYPE_DEFINITION) for (const member of definition.types ?? []) queue.push(member.name.value);
|
|
8403
|
+
}
|
|
8404
|
+
return reachable;
|
|
8405
|
+
}
|
|
8406
|
+
function namedTypeOf(typeNode) {
|
|
8407
|
+
let node = typeNode;
|
|
8408
|
+
while (node.kind !== Kind.NAMED_TYPE) node = node.type;
|
|
8409
|
+
return node.name.value;
|
|
8410
|
+
}
|
|
8411
|
+
function findObjectType(schemaDoc, name) {
|
|
8412
|
+
const definition = findTypeDefinition(schemaDoc, name);
|
|
8413
|
+
return definition?.kind === Kind.OBJECT_TYPE_DEFINITION ? definition : void 0;
|
|
8414
|
+
}
|
|
8415
|
+
function findTypeDefinition(schemaDoc, name) {
|
|
8416
|
+
for (const definition of schemaDoc.definitions) switch (definition.kind) {
|
|
8417
|
+
case Kind.OBJECT_TYPE_DEFINITION:
|
|
8418
|
+
case Kind.ENUM_TYPE_DEFINITION:
|
|
8419
|
+
case Kind.SCALAR_TYPE_DEFINITION:
|
|
8420
|
+
case Kind.UNION_TYPE_DEFINITION:
|
|
8421
|
+
case Kind.INTERFACE_TYPE_DEFINITION:
|
|
8422
|
+
case Kind.INPUT_OBJECT_TYPE_DEFINITION: if (definition.name.value === name) return definition;
|
|
8423
|
+
}
|
|
8424
|
+
}
|
|
8425
|
+
function safeParseSdl(sdl) {
|
|
8426
|
+
if (!sdl.trim()) return null;
|
|
8427
|
+
try {
|
|
8428
|
+
return parse(sdl);
|
|
8429
|
+
} catch {
|
|
8430
|
+
return null;
|
|
8431
|
+
}
|
|
8432
|
+
}
|
|
8433
|
+
function safeParseJsonRecord(json) {
|
|
8434
|
+
if (!json.trim()) return null;
|
|
8435
|
+
try {
|
|
8436
|
+
const parsed = JSON.parse(json);
|
|
8437
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed;
|
|
8438
|
+
return null;
|
|
8439
|
+
} catch {
|
|
8440
|
+
return null;
|
|
8441
|
+
}
|
|
8442
|
+
}
|
|
8443
|
+
/**
|
|
8444
|
+
* Serializes a fill value to TypeScript source. Fill values come from JSON
|
|
8445
|
+
* (initial values) or the zero-value synthesizer, so JSON serialization is
|
|
8446
|
+
* sufficient.
|
|
8447
|
+
*/
|
|
8448
|
+
function fillToTsLiteral(fill) {
|
|
8449
|
+
return JSON.stringify(fill, null, 2);
|
|
8450
|
+
}
|
|
8451
|
+
//#endregion
|
|
8055
8452
|
//#region src/file-builders/document-model/upgrades-dir.ts
|
|
8056
8453
|
async function makeUpgradeFile(args) {
|
|
8057
8454
|
const { project, version, upgradesDirPath } = args;
|
|
8058
8455
|
if (version < 2) return;
|
|
8059
8456
|
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(upgradesDirPath, `v${version}.ts`));
|
|
8060
8457
|
if (alreadyExists) return;
|
|
8061
|
-
const
|
|
8458
|
+
const plan = buildMigrationPlan({
|
|
8459
|
+
previousSpec: args.documentModelState.specifications.find((specification) => specification.version === version - 1),
|
|
8460
|
+
specification: args.specification,
|
|
8461
|
+
stateName: args.stateName,
|
|
8462
|
+
localStateName: args.localStateName
|
|
8463
|
+
});
|
|
8464
|
+
const template = upgradeTransitionTemplate({
|
|
8465
|
+
...args,
|
|
8466
|
+
plan
|
|
8467
|
+
});
|
|
8062
8468
|
sourceFile.replaceWithText(template);
|
|
8063
8469
|
await formatSourceFileWithPrettier(sourceFile);
|
|
8064
8470
|
}
|
|
@@ -8340,6 +8746,10 @@ async function makeDocumentModelsIndexFile(args) {
|
|
|
8340
8746
|
moduleSpecifier
|
|
8341
8747
|
});
|
|
8342
8748
|
}));
|
|
8749
|
+
sourceFile.addExportDeclaration({
|
|
8750
|
+
namedExports: ["upgradeManifests"],
|
|
8751
|
+
moduleSpecifier: "./upgrade-manifests.js"
|
|
8752
|
+
});
|
|
8343
8753
|
await formatSourceFileWithPrettier(sourceFile);
|
|
8344
8754
|
}
|
|
8345
8755
|
/** Writes a json file derived from a `documentModelState` */
|
|
@@ -8718,6 +9128,6 @@ async function makeSubgraphsIndexFile(args) {
|
|
|
8718
9128
|
await formatSourceFileWithPrettier(sourceFile);
|
|
8719
9129
|
}
|
|
8720
9130
|
//#endregion
|
|
8721
|
-
export {
|
|
9131
|
+
export { getStringArrayPropertyElements as $, editorsIndexTemplate as $n, documentModelSchemaIndexTemplate as $t, writeGeneratedDocumentModelsFiles as A, subgraphsIndexTemplate as An, processorsIndexTemplate as At, makeEditorsIndexFile as B, npmrcTemplate as Bn, upgradeManifestTemplate as Bt, makeCliDocsFromHelp as C, documentModelRootActionsFileTemplate as Cn, subgraphLibFileTemplate as Ct, writeAiConfigFiles as D, vitestConfigTemplate as Dn, relationalDbMigrationsTemplate as Dt, applyProjectCustomizations as E, docsFromCliHelpTemplate as En, relationalDbProcessorTemplate as Et, writeModuleFiles as F, packageJsonExportsTemplate as Fn, analyticsFactoryTemplate as Ft, buildTsMorphProject as G, indexTsTemplate as Gn, documentModelTestFileTemplate as Gt, updateVersionedImports as H, mainTsxTemplate as Hn, makeOperationImportNames as Ht, writeProjectRootFiles as I, packageJsonScriptsTemplate as In, parseFilterValues as It, getAllImportNames as J, gitIgnoreTemplate as Jn, documentModelModuleFileTemplate as Jt, getDefaultProjectOptions as K, legacyIndexHtmlTemplate as Kn, documentModelSrcUtilsTemplate as Kt, tsMorphGenerateApp as L, pnpmWorkspaceTemplate as Ln, renderProcessorFilter as Lt, writeGeneratedProcessorsFiles as M, readmeTemplate as Mn, factoryBuildersTemplate as Mt, writeGeneratedProjectRootFiles as N, ManifestTemplate as Nn, analyticsProcessorTemplate as Nt, writeAllGeneratedProjectFiles as O, tsConfigTemplate as On, relationalDbIndexTemplate as Ot, writeGeneratedSubgraphsFiles as P, buildPowerhouseConfigTemplate as Pn, analyticsIndexTemplate as Pt, getProperyAssignmentByName as Q, oxlintConfigTemplate as Qn, documentModelGenTypesTemplate as Qt, makeEditorModuleFile as R, exportsTemplate as Rn, documentModelUtilsTemplate as Rt, getCommandsHelpInfo as S, documentModelGenActionsFileTemplate as Sn, customSubgraphSchemaTemplate as St, buildBoilerplatePackageJson as T, documentEditorEditorFileTemplate as Tn, relationalDbSchemaTemplate as Tt, getInitialStates as U, licenseTemplate as Un, makeOperationsImports as Ut, validateDocumentModelState as V, mcpTemplate as Vn, documentModelOperationsModuleTestFileTemplate as Vt, DEFAULT_PROJECT_OPTIONS as W, reactorTsTemplate as Wn, makeTestCaseForOperation as Wt, getObjectLiteral as X, geminiSettingsTemplate as Xn, documentModelHooksFileTemplate as Xt, getBooleanPropertyValue as Y, syncAndPublishWorkflowTemplate as Yn, documentModelIndexTemplate as Yt, getObjectProperty as Z, oxfmtConfigTemplate as Zn, documentModelGenUtilsTemplate as Zt, getMockOverrideFieldNames as _, documentModelGenIndexFileTemplate as _n, emptyStateFileTemplate as _r, documentModelDocumentTypeMetadata as _t, getOrCreateManifestFile as a, documentModelOperationModuleActionsFileTemplate as an, nginxConfTemplate as ar, ensureDirectoriesExist as at, tsMorphGenerateDocumentEditor as b, documentModelGenCreatorsFileTemplate as bn, createDocumentFileTemplate as br, parseConfig as bt, operationHasEmptyInput as c, getDocumentModelSpecByVersionNumber as cn, cursorMcpTemplate as cr, getPreviousVersionSourceFile as ct, buildMigrationPlan as d, getLatestDocumentModelSpec as dn, appEditorFileTemplate as dr, getAppMetadata as dt, documentModelGenReducerFileTemplate as en, editorsTemplate as er, getStringPropertyValue as et, fillToTsLiteral as f, getLatestDocumentModelSpecVersionNumber as fn, appConfigFileTemplate as fr, getEditorMetadata as ft, getInputFieldNames as g, getActionTypeName as gn, appFilesFileTemplate as gr, getDocumentTypeMetadata as gt, getDateLikeFieldNames as h, getActionType as hn, appFoldersFileTemplate as hr, runOxfmt as ht, createOrUpdateManifest as i, documentModelOperationsModuleCreatorsFileTemplate as in, switchboardEntrypointTemplate as ir, buildStringLiteral as it, writeGeneratedEditorsFiles as j, styleTemplate as jn, processorsFactoryTemplate as jt, writeCIFiles as k, tsconfigPathsTemplate as kn, relationalDbFactoryTemplate as kt, operationHasInput as l, getDocumentModelVariableNames as ln, claudeSettingsLocalTemplate as lr, getSubgraphMetadata as lt, generateTypesAndZodSchemasFromGraphql as m, getActionInputTypeNames as mn, folderTreeFileTemplate as mr, formatSourceFileWithPrettier as mt, tsMorphGenerateSubgraph as n, documentModelOperationsModuleOperationsFileTemplate as nn, documentModelsIndexTemplate as nr, loadDocumentModelInDir as nt, pruneManifestSection as o, getModuleExportType as on, dockerfileTemplate as or, getOrCreateDirectory as ot, generateDocumentModelZodSchemas as p, getActionInputName as pn, driveExplorerNavigationBreadcrumbsFileTemplate as pr, formatSafe as pt, getAllImportModuleSpecifiers as q, indexHtmlTemplate as qn, documentModelSrcIndexFileTemplate as qt, tsMorphGenerateProcessor as r, documentModelOperationsModuleErrorFileTemplate as rn, documentModelsTemplate as rr, buildObjectLiteral as rt, makeModulesIndexFile as s, getDocumentModelDirName as sn, connectEntrypointTemplate as sr, getOrCreateSourceFile as st, makeSubgraphsIndexFile as t, documentModelPhFactoriesFileTemplate as tn, upgradeManifestsTemplate as tr, getVariableDeclarationByTypeName as tt, tsMorphGenerateDocumentModel as u, getEditorVariableNames as un, agentsTemplate as ur, getProcessorMetadata as ut, scalars as v, documentModelDocumentTypeTemplate as vn, driveExplorerFileTemplate as vr, configSpec as vt, writeCliDocsMarkdownFile as w, documentEditorModuleFileTemplate as wn, subgraphIndexFileTemplate as wt, getCommandHelpInfo as x, documentModelGenControllerFileTemplate as xn, customSubgraphResolversTemplate as xt, scalarsValidation as y, documentModelDocumentSchemaFileTemplate as yn, appDriveContentsFileTemplate as yr, parseArgs as yt, makeEditorsFile as z, packageJsonTemplate as zn, upgradeTransitionTemplate as zt };
|
|
8722
9132
|
|
|
8723
|
-
//# sourceMappingURL=file-builders-
|
|
9133
|
+
//# sourceMappingURL=file-builders-B4QZXx5u.mjs.map
|