@cms0/cms0 0.2.16 → 0.2.18

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toTwitter = exports.toOpenGraph = exports.toNextMetadata = exports.resolveLocalized = exports.unwrapCms0CanvasTransportValue = exports.restoreCms0CanvasTransportMetadata = exports.readCms0ProvenanceValueMeta = exports.readCms0LiveRoots = exports.registerCms0CollectionItemIdentity = exports.registerCms0LiveRoot = exports.readCms0CollectionItemIdentity = exports.readCms0CanvasTransportCollectionItemId = exports.enableCms0ProvenanceTracking = exports.captureCms0Provenance = exports.attachCms0ProvenanceRoot = exports.activateCms0CanvasTransport = void 0;
3
+ exports.toTwitter = exports.toOpenGraph = exports.toNextMetadata = exports.resolveLocalized = exports.unwrapCms0CanvasTransportValue = exports.restoreCms0CanvasTransportMetadata = exports.readCms0ProvenanceValueMeta = exports.readCms0LiveRoots = exports.registerCms0CollectionItemIdentity = exports.registerCms0LiveRoot = exports.readCms0CollectionItemIdentity = exports.readCms0CanvasTransportCollectionItemId = exports.enableCms0ProvenanceTracking = exports.dehydrateCms0CanvasVisibleValue = exports.dehydrateCms0CanvasTransportValue = exports.captureCms0Provenance = exports.attachCms0ProvenanceRoot = exports.activateCms0CanvasTransport = void 0;
4
4
  exports.createCmsClient = createCmsClient;
5
5
  exports.cms0 = cms0;
6
6
  const provenance_1 = require("@cms0/cms0/provenance");
@@ -552,7 +552,7 @@ async function readCanvasModelRefCollectionIdentities(path, descriptor, context)
552
552
  cache.set(cacheKey, pending);
553
553
  return pending;
554
554
  }
555
- async function normalizeModelRef(modelName, id, context, trail, isCollectionItem, inlineValue) {
555
+ async function normalizeModelRef(modelName, id, context, trail, isCollectionItem, inlineValue, projectionPathTokens = []) {
556
556
  if (!id)
557
557
  return null;
558
558
  if (!context.options.resolveModelRefs)
@@ -580,14 +580,29 @@ async function normalizeModelRef(modelName, id, context, trail, isCollectionItem
580
580
  const nextTrail = new Set(trail);
581
581
  nextTrail.add(nodeKey);
582
582
  const promise = (async () => {
583
+ const modelPath = `models/${modelName}/${id}`;
584
+ const resolvedModelPath = `_resolved/models/${encodeURIComponent(modelName)}/${encodeURIComponent(id)}`;
583
585
  const rawModel = inlineModel ??
584
- (await context.requestJson(`models/${modelName}/${id}`, {
585
- query: {
586
+ (await (async () => {
587
+ const query = {
586
588
  raw: 1,
587
589
  ...(context.options.locale ? { locale: context.options.locale } : {}),
588
- },
589
- }));
590
- return normalizeField(modelDescriptor, `models/${modelName}/${encodeURIComponent(id)}`, rawModel, context, nextTrail, isCollectionItem);
590
+ };
591
+ try {
592
+ return await context.requestJson(resolvedModelPath, {
593
+ query: {
594
+ ...query,
595
+ resolveModelRefs: 1,
596
+ },
597
+ });
598
+ }
599
+ catch {
600
+ return context.requestJson(modelPath, {
601
+ query,
602
+ });
603
+ }
604
+ })());
605
+ return normalizeField(modelDescriptor, `models/${modelName}/${encodeURIComponent(id)}`, rawModel, context, nextTrail, isCollectionItem, projectionPathTokens);
591
606
  })();
592
607
  context.modelCache.set(nodeKey, promise);
593
608
  context.sharedModelInflightCache.set(nodeKey, promise);
@@ -607,12 +622,16 @@ function missingModelRefValue(descriptor) {
607
622
  return undefined;
608
623
  return null;
609
624
  }
610
- async function normalizeObjectField(descriptor, path, raw, context, trail, isCollectionItem) {
625
+ async function normalizeObjectField(descriptor, path, raw, context, trail, isCollectionItem, projectionPathTokens = []) {
611
626
  const source = raw && typeof raw === "object" ? raw : {};
612
627
  const output = {};
613
628
  for (const [propertyName, propertyDescriptor] of Object.entries(descriptor.properties)) {
629
+ const childProjectionPathTokens = [...projectionPathTokens, propertyName];
630
+ if (!shouldTraverseProjectionPath(childProjectionPathTokens, context.options.includeProjectionPaths, context.options.excludeProjectionPaths)) {
631
+ continue;
632
+ }
614
633
  if (isScalarDescriptor(propertyDescriptor)) {
615
- output[propertyName] = await normalizeField(propertyDescriptor, `${path}/${propertyName}`, source[propertyName], context, trail, false);
634
+ output[propertyName] = await normalizeField(propertyDescriptor, `${path}/${propertyName}`, source[propertyName], context, trail, false, childProjectionPathTokens);
616
635
  continue;
617
636
  }
618
637
  if (isModelRefDescriptor(propertyDescriptor)) {
@@ -636,7 +655,7 @@ async function normalizeObjectField(descriptor, path, raw, context, trail, isCol
636
655
  }
637
656
  continue;
638
657
  }
639
- output[propertyName] = await normalizeModelRef(propertyDescriptor.model, refId, context, trail, false, inlineValue);
658
+ output[propertyName] = await normalizeModelRef(propertyDescriptor.model, refId, context, trail, false, inlineValue, childProjectionPathTokens);
640
659
  continue;
641
660
  }
642
661
  if (isArrayDescriptor(propertyDescriptor)) {
@@ -654,7 +673,7 @@ async function normalizeObjectField(descriptor, path, raw, context, trail, isCol
654
673
  ...(context.options.locale ? { locale: context.options.locale } : {}),
655
674
  },
656
675
  });
657
- const normalizedChild = await normalizeArrayField(propertyDescriptor, childPath, childRaw, context, trail, inlineChildRaw !== undefined);
676
+ const normalizedChild = await normalizeArrayField(propertyDescriptor, childPath, childRaw, context, trail, inlineChildRaw !== undefined, childProjectionPathTokens);
658
677
  output[propertyName] = coerceCustomTypeValue(propertyDescriptor, normalizedChild, {
659
678
  locale: context.options.locale,
660
679
  defaultLocale: context.options.defaultLocale,
@@ -677,7 +696,7 @@ async function normalizeObjectField(descriptor, path, raw, context, trail, isCol
677
696
  ...(context.options.locale ? { locale: context.options.locale } : {}),
678
697
  },
679
698
  });
680
- const normalizedChild = await normalizeObjectField(propertyDescriptor, childPath, childRaw, context, trail, false);
699
+ const normalizedChild = await normalizeObjectField(propertyDescriptor, childPath, childRaw, context, trail, false, childProjectionPathTokens);
681
700
  output[propertyName] = coerceCustomTypeValue(propertyDescriptor, normalizedChild, {
682
701
  locale: context.options.locale,
683
702
  defaultLocale: context.options.defaultLocale,
@@ -697,12 +716,12 @@ async function normalizeObjectField(descriptor, path, raw, context, trail, isCol
697
716
  }
698
717
  return maybeAttachAssetUrl(output, context.options.assetUrlBuilder);
699
718
  }
700
- async function normalizeArrayField(descriptor, path, raw, context, trail, inlineResolvedItems = false) {
719
+ async function normalizeArrayField(descriptor, path, raw, context, trail, inlineResolvedItems = false, projectionPathTokens = []) {
701
720
  const envelope = ensureCollectionEnvelope(raw, path);
702
721
  const itemDescriptor = descriptor.items;
703
722
  if (isScalarDescriptor(itemDescriptor)) {
704
723
  return mapWithConcurrency(envelope.items, context.options.modelNormalizationConcurrency, async (row) => {
705
- const normalizedValue = await normalizeField(itemDescriptor, path, row, context, trail, true);
724
+ const normalizedValue = await normalizeField(itemDescriptor, path, row, context, trail, true, projectionPathTokens);
706
725
  if (context.options.includeIdMode !== "all") {
707
726
  return normalizedValue;
708
727
  }
@@ -725,7 +744,7 @@ async function normalizeArrayField(descriptor, path, raw, context, trail, inline
725
744
  const refId = extractModelRefId(row, itemDescriptor.model, {
726
745
  allowObjectIdFallback: false,
727
746
  }) ?? (inlineModel ? extractId(inlineModel) : null);
728
- const normalized = await normalizeModelRef(itemDescriptor.model, refId, context, trail, true, row);
747
+ const normalized = await normalizeModelRef(itemDescriptor.model, refId, context, trail, true, row, projectionPathTokens);
729
748
  const collectionItemId = collectionIdentities?.[index]?.relationId ??
730
749
  (inlineResolvedItems ? null : extractId(row));
731
750
  if (!collectionItemId ||
@@ -748,12 +767,12 @@ async function normalizeArrayField(descriptor, path, raw, context, trail, inline
748
767
  const rowPath = rowId
749
768
  ? `${path}/${encodeURIComponent(rowId)}`
750
769
  : path;
751
- return normalizeObjectField(itemDescriptor, rowPath, row, context, trail, true);
770
+ return normalizeObjectField(itemDescriptor, rowPath, row, context, trail, true, projectionPathTokens);
752
771
  });
753
772
  }
754
773
  return envelope.items;
755
774
  }
756
- async function normalizeInlineField(descriptor, raw, context, trail, isCollectionItem) {
775
+ async function normalizeInlineField(descriptor, raw, context, trail, isCollectionItem, projectionPathTokens = []) {
757
776
  if (isPrimitiveDescriptor(descriptor)) {
758
777
  return coerceCustomTypeValue(descriptor, raw, {
759
778
  locale: context.options.locale,
@@ -771,7 +790,7 @@ async function normalizeInlineField(descriptor, raw, context, trail, isCollectio
771
790
  if (!decoded) {
772
791
  return null;
773
792
  }
774
- return normalizeInlineField(decoded.branchDescriptor, decoded.branchValue, context, trail, isCollectionItem);
793
+ return normalizeInlineField(decoded.branchDescriptor, decoded.branchValue, context, trail, isCollectionItem, projectionPathTokens);
775
794
  }
776
795
  if (isModelRefDescriptor(descriptor)) {
777
796
  const refId = extractModelRefId(raw, descriptor.model, {
@@ -780,11 +799,11 @@ async function normalizeInlineField(descriptor, raw, context, trail, isCollectio
780
799
  if (!refId) {
781
800
  return missingModelRefValue(descriptor);
782
801
  }
783
- return normalizeModelRef(descriptor.model, refId, context, trail, isCollectionItem, raw);
802
+ return normalizeModelRef(descriptor.model, refId, context, trail, isCollectionItem, raw, projectionPathTokens);
784
803
  }
785
804
  if (isArrayDescriptor(descriptor)) {
786
805
  const source = Array.isArray(raw) ? raw : [];
787
- const normalized = await mapWithConcurrency(source, context.options.modelNormalizationConcurrency, async (entry) => normalizeInlineField(descriptor.items, entry, context, trail, true));
806
+ const normalized = await mapWithConcurrency(source, context.options.modelNormalizationConcurrency, async (entry) => normalizeInlineField(descriptor.items, entry, context, trail, true, projectionPathTokens));
788
807
  return coerceCustomTypeValue(descriptor, normalized, {
789
808
  locale: context.options.locale,
790
809
  defaultLocale: context.options.defaultLocale,
@@ -797,7 +816,7 @@ async function normalizeInlineField(descriptor, raw, context, trail, isCollectio
797
816
  : {};
798
817
  const output = {};
799
818
  for (const [propertyName, propertyDescriptor] of Object.entries(descriptor.properties)) {
800
- output[propertyName] = await normalizeInlineField(propertyDescriptor, source[propertyName], context, trail, false);
819
+ output[propertyName] = await normalizeInlineField(propertyDescriptor, source[propertyName], context, trail, false, [...projectionPathTokens, propertyName]);
801
820
  }
802
821
  return coerceCustomTypeValue(descriptor, output, {
803
822
  locale: context.options.locale,
@@ -807,7 +826,7 @@ async function normalizeInlineField(descriptor, raw, context, trail, isCollectio
807
826
  }
808
827
  return raw;
809
828
  }
810
- async function normalizeField(descriptor, path, raw, context, trail, isCollectionItem) {
829
+ async function normalizeField(descriptor, path, raw, context, trail, isCollectionItem, projectionPathTokens = []) {
811
830
  if (isPrimitiveDescriptor(descriptor)) {
812
831
  const value = raw && typeof raw === "object" && "value" in raw
813
832
  ? raw.value
@@ -839,7 +858,7 @@ async function normalizeField(descriptor, path, raw, context, trail, isCollectio
839
858
  if (!decoded) {
840
859
  return null;
841
860
  }
842
- let normalized = await normalizeInlineField(decoded.branchDescriptor, decoded.branchValue, context, trail, isCollectionItem);
861
+ let normalized = await normalizeInlineField(decoded.branchDescriptor, decoded.branchValue, context, trail, isCollectionItem, projectionPathTokens);
843
862
  if (shouldIncludeObjectId(context.options.includeIdMode, isCollectionItem)) {
844
863
  const id = decoded.rowId ?? extractId(raw);
845
864
  normalized = attachIdForScalarDescriptor(descriptor, normalized, id);
@@ -860,7 +879,7 @@ async function normalizeField(descriptor, path, raw, context, trail, isCollectio
860
879
  return normalizeModelRef(descriptor.model, refId, context, trail, isCollectionItem, raw);
861
880
  }
862
881
  if (isArrayDescriptor(descriptor)) {
863
- const normalized = await normalizeArrayField(descriptor, path, raw, context, trail);
882
+ const normalized = await normalizeArrayField(descriptor, path, raw, context, trail, false, projectionPathTokens);
864
883
  return coerceCustomTypeValue(descriptor, normalized, {
865
884
  locale: context.options.locale,
866
885
  defaultLocale: context.options.defaultLocale,
@@ -868,7 +887,7 @@ async function normalizeField(descriptor, path, raw, context, trail, isCollectio
868
887
  });
869
888
  }
870
889
  if (isObjectDescriptor(descriptor)) {
871
- const normalized = await normalizeObjectField(descriptor, path, raw, context, trail, isCollectionItem);
890
+ const normalized = await normalizeObjectField(descriptor, path, raw, context, trail, isCollectionItem, projectionPathTokens);
872
891
  return coerceCustomTypeValue(descriptor, normalized, {
873
892
  locale: context.options.locale,
874
893
  defaultLocale: context.options.defaultLocale,
@@ -983,6 +1002,22 @@ function normalizeProjectionPaths(input) {
983
1002
  }
984
1003
  return Array.from(unique).map((path) => path.split("."));
985
1004
  }
1005
+ function isProjectionPathPrefix(prefix, value) {
1006
+ if (prefix.length > value.length)
1007
+ return false;
1008
+ return prefix.every((token, index) => value[index] === token);
1009
+ }
1010
+ function shouldTraverseProjectionPath(childTokens, includePaths, excludePaths) {
1011
+ if (includePaths.length > 0 &&
1012
+ !includePaths.some((pathTokens) => isProjectionPathPrefix(pathTokens, childTokens) ||
1013
+ isProjectionPathPrefix(childTokens, pathTokens))) {
1014
+ return false;
1015
+ }
1016
+ if (excludePaths.some((pathTokens) => isProjectionPathPrefix(pathTokens, childTokens))) {
1017
+ return false;
1018
+ }
1019
+ return true;
1020
+ }
986
1021
  function mergeProjectedValue(existing, incoming) {
987
1022
  if (incoming === undefined)
988
1023
  return existing;
@@ -1143,6 +1178,9 @@ async function runResource(resource, descriptor, baseUrl, apiKey, defaultLocale,
1143
1178
  const responseMode = options?.response ?? "normalized";
1144
1179
  const includeIdMode = resolveIncludeIdMode(options?.includeId, globalIncludeId);
1145
1180
  const resolveModelRefs = options?.resolveModelRefs !== false;
1181
+ const includeProjectionPaths = normalizeProjectionPaths(options?.fields);
1182
+ const excludeProjectionPaths = normalizeProjectionPaths(options?.exclude);
1183
+ const shouldValidateFullResult = includeProjectionPaths.length === 0 && excludeProjectionPaths.length === 0;
1146
1184
  const requestedLocale = options?.locale ??
1147
1185
  (typeof options?.query?.locale === "string"
1148
1186
  ? options.query.locale
@@ -1235,6 +1273,8 @@ async function runResource(resource, descriptor, baseUrl, apiKey, defaultLocale,
1235
1273
  defaultLocale,
1236
1274
  assetUrlBuilder,
1237
1275
  modelNormalizationConcurrency: DEFAULT_MODEL_NORMALIZATION_CONCURRENCY,
1276
+ includeProjectionPaths,
1277
+ excludeProjectionPaths,
1238
1278
  },
1239
1279
  };
1240
1280
  if (resource.isCollection && !byId) {
@@ -1250,17 +1290,23 @@ async function runResource(resource, descriptor, baseUrl, apiKey, defaultLocale,
1250
1290
  const normalizedItems = await normalizeArrayField(descriptorForCollection, resource.path, envelope, context, new Set());
1251
1291
  if (responseMode === "envelope") {
1252
1292
  const projectedItems = applyFieldProjection(normalizedItems, options?.fields, options?.exclude);
1253
- validateResult(resource, normalizedItems, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
1293
+ if (shouldValidateFullResult) {
1294
+ validateResult(resource, normalizedItems, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
1295
+ }
1254
1296
  return {
1255
1297
  items: attachResourceProvenanceWithOptions(resource, Array.isArray(projectedItems) ? projectedItems : normalizedItems, provenanceOptions),
1256
1298
  total: envelope.total,
1257
1299
  };
1258
1300
  }
1259
- validateResult(resource, normalizedItems, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
1301
+ if (shouldValidateFullResult) {
1302
+ validateResult(resource, normalizedItems, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
1303
+ }
1260
1304
  return attachResourceProvenanceWithOptions(resource, normalizedItems, provenanceOptions);
1261
1305
  }
1262
1306
  const normalized = await normalizeField(resource.descriptor, normalizePath, rawData, context, new Set(), false);
1263
- validateResult(resource, normalized, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
1307
+ if (shouldValidateFullResult) {
1308
+ validateResult(resource, normalized, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
1309
+ }
1264
1310
  return attachResourceProvenanceWithOptions(resource, applyFieldProjection(normalized, options?.fields, options?.exclude), provenanceOptions);
1265
1311
  }
1266
1312
  function createCmsClient(descriptor, config) {
@@ -1345,12 +1391,14 @@ function createCmsClient(descriptor, config) {
1345
1391
  return rootProxy;
1346
1392
  }
1347
1393
  function cms0(config) {
1348
- return createCmsClient(schema_descriptors_1.schemaDescriptor, config);
1394
+ return createCmsClient((0, schema_descriptors_1.getActiveSchemaDescriptor)(), config);
1349
1395
  }
1350
1396
  var provenance_js_1 = require("./provenance.cjs");
1351
1397
  Object.defineProperty(exports, "activateCms0CanvasTransport", { enumerable: true, get: function () { return provenance_js_1.activateCms0CanvasTransport; } });
1352
1398
  Object.defineProperty(exports, "attachCms0ProvenanceRoot", { enumerable: true, get: function () { return provenance_js_1.attachCms0ProvenanceRoot; } });
1353
1399
  Object.defineProperty(exports, "captureCms0Provenance", { enumerable: true, get: function () { return provenance_js_1.captureCms0Provenance; } });
1400
+ Object.defineProperty(exports, "dehydrateCms0CanvasTransportValue", { enumerable: true, get: function () { return provenance_js_1.dehydrateCms0CanvasTransportValue; } });
1401
+ Object.defineProperty(exports, "dehydrateCms0CanvasVisibleValue", { enumerable: true, get: function () { return provenance_js_1.dehydrateCms0CanvasVisibleValue; } });
1354
1402
  Object.defineProperty(exports, "enableCms0ProvenanceTracking", { enumerable: true, get: function () { return provenance_js_1.enableCms0ProvenanceTracking; } });
1355
1403
  Object.defineProperty(exports, "readCms0CanvasTransportCollectionItemId", { enumerable: true, get: function () { return provenance_js_1.readCms0CanvasTransportCollectionItemId; } });
1356
1404
  Object.defineProperty(exports, "readCms0CollectionItemIdentity", { enumerable: true, get: function () { return provenance_js_1.readCms0CollectionItemIdentity; } });
@@ -7,7 +7,7 @@ const publisher_js_1 = require("./publisher.cjs");
7
7
  const descriptor_writer_js_1 = require("./descriptor-writer.cjs");
8
8
  function buildOnce(resolved) {
9
9
  const descriptor = (0, descriptor_builder_alt_js_1.buildDescriptorAlt)(resolved);
10
- (0, descriptor_writer_js_1.writeDescriptorFiles)(descriptor);
10
+ (0, descriptor_writer_js_1.writeDescriptorFiles)(resolved, descriptor);
11
11
  (0, publisher_js_1.publishDescriptor)(resolved, descriptor);
12
12
  return descriptor;
13
13
  }
@@ -114,38 +114,20 @@ async function loadUserConfig(configPath) {
114
114
  return { path: resolvedPath, config: JSON.parse(json) };
115
115
  }
116
116
  if (ext === ".ts" || ext === ".mts" || ext === ".cts" || ext === ".tsx") {
117
- // If the enclosing package is ESM, use dynamic import instead of require.
118
117
  const pkgJsonPath = findNearestPackageJson(resolvedPath);
119
118
  const pkgType = pkgJsonPath ? readPackageType(pkgJsonPath) : undefined;
120
119
  const isEsmPkg = pkgType === "module";
121
- if (isEsmPkg) {
122
- const compiledHref = await transpileTsModuleToTemp(resolvedPath);
123
- try {
124
- const imported = (await importByHref(compiledHref));
125
- const config = imported?.default ?? imported?.config ?? imported ?? {};
126
- return { path: resolvedPath, config };
127
- }
128
- finally {
129
- cleanupTempModule(compiledHref);
130
- }
131
- }
132
- const previous = process.env.TS_NODE_COMPILER_OPTIONS;
133
- // register ts-node on demand so TypeScript configs can be required
134
- // eslint-disable-next-line @typescript-eslint/no-var-requires
135
- require("ts-node/register/transpile-only");
120
+ const compiledPath = await transpileTsModuleToTemp(resolvedPath, isEsmPkg ? "esm" : "cjs");
136
121
  try {
137
- // eslint-disable-next-line @typescript-eslint/no-var-requires
138
- const required = require(resolvedPath);
139
- const config = required?.default ?? required?.config ?? required ?? {};
122
+ const imported = isEsmPkg
123
+ ? (await importByHref((0, url_1.pathToFileURL)(compiledPath).href))
124
+ : // eslint-disable-next-line @typescript-eslint/no-var-requires
125
+ require(compiledPath);
126
+ const config = imported?.default ?? imported?.config ?? imported ?? {};
140
127
  return { path: resolvedPath, config };
141
128
  }
142
129
  finally {
143
- if (previous === undefined) {
144
- delete process.env.TS_NODE_COMPILER_OPTIONS;
145
- }
146
- else {
147
- process.env.TS_NODE_COMPILER_OPTIONS = previous;
148
- }
130
+ cleanupTempModule(compiledPath);
149
131
  }
150
132
  }
151
133
  const imported = (await importByHref((0, url_1.pathToFileURL)(resolvedPath).href));
@@ -162,6 +144,10 @@ function resolvePaths(cfgPath, config) {
162
144
  throw new Error("cms0: config.entry is required");
163
145
  }
164
146
  const baseDir = path_1.default.dirname(cfgPath);
147
+ const packageJsonPath = findNearestPackageJson(cfgPath);
148
+ const projectRoot = packageJsonPath
149
+ ? path_1.default.dirname(packageJsonPath)
150
+ : baseDir;
165
151
  const entryFile = path_1.default.resolve(baseDir, config.entry);
166
152
  const tsconfigPath = config.tsconfig
167
153
  ? path_1.default.resolve(baseDir, config.tsconfig)
@@ -171,6 +157,7 @@ function resolvePaths(cfgPath, config) {
171
157
  return {
172
158
  configPath: cfgPath,
173
159
  entryFile,
160
+ projectRoot,
174
161
  tsconfigPath,
175
162
  apiBaseUrl,
176
163
  apiKey,
@@ -190,12 +177,12 @@ function findTsConfig(entryFile) {
190
177
  }
191
178
  return undefined;
192
179
  }
193
- async function transpileTsModuleToTemp(tsPath) {
180
+ async function transpileTsModuleToTemp(tsPath, format) {
194
181
  const ts = await Promise.resolve().then(() => __importStar(require("typescript")));
195
182
  const source = fs_1.default.readFileSync(tsPath, "utf8");
196
183
  const transpiled = ts.transpileModule(source, {
197
184
  compilerOptions: {
198
- module: ts.ModuleKind.ESNext,
185
+ module: format === "esm" ? ts.ModuleKind.ESNext : ts.ModuleKind.CommonJS,
199
186
  target: ts.ScriptTarget.ES2022,
200
187
  esModuleInterop: true,
201
188
  },
@@ -203,16 +190,15 @@ async function transpileTsModuleToTemp(tsPath) {
203
190
  });
204
191
  const hash = crypto_1.default
205
192
  .createHash("sha1")
206
- .update(tsPath + source + Date.now().toString())
193
+ .update(tsPath + format + source + Date.now().toString())
207
194
  .digest("hex");
208
- const outFile = path_1.default.join(path_1.default.dirname(tsPath), `.cms0-config.${hash}.mjs`);
195
+ const outFile = path_1.default.join(path_1.default.dirname(tsPath), `.cms0-config.${hash}.${format === "esm" ? "mjs" : "cjs"}`);
209
196
  fs_1.default.writeFileSync(outFile, transpiled.outputText, "utf8");
210
- return (0, url_1.pathToFileURL)(outFile).href;
197
+ return outFile;
211
198
  }
212
- function cleanupTempModule(tempHref) {
199
+ function cleanupTempModule(tempPath) {
213
200
  try {
214
- const filePath = (0, url_1.fileURLToPath)(tempHref);
215
- fs_1.default.unlinkSync(filePath);
201
+ fs_1.default.unlinkSync(tempPath);
216
202
  }
217
203
  catch {
218
204
  // ignore cleanup failures
@@ -30,10 +30,16 @@ function createEsmOutput(descriptor) {
30
30
  function createCjsOutput(descriptor) {
31
31
  return `// Auto-generated schema descriptor\nexports.schemaDescriptor = ${JSON.stringify(descriptor, null, 2)};\n`;
32
32
  }
33
- function writeDescriptorFiles(descriptor) {
33
+ function createJsonOutput(descriptor) {
34
+ return `${JSON.stringify(descriptor, null, 2)}\n`;
35
+ }
36
+ function writeDescriptorFiles(resolved, descriptor) {
37
+ const localDescriptorOutputPaths = (0, paths_js_1.resolveLocalDescriptorOutputPaths)(resolved.projectRoot);
34
38
  if (fs_1.default.existsSync(path_1.default.resolve(path_1.default.dirname(paths_js_1.descriptorOutputPaths.sourceTs), ".."))) {
35
39
  safeWrite(paths_js_1.descriptorOutputPaths.sourceTs, createSourceTsOutput(descriptor));
36
40
  }
37
41
  safeWrite(paths_js_1.descriptorOutputPaths.esmJs, createEsmOutput(descriptor));
38
42
  safeWrite(paths_js_1.descriptorOutputPaths.cjsJs, createCjsOutput(descriptor));
43
+ safeWrite(localDescriptorOutputPaths.json, createJsonOutput(descriptor));
44
+ safeWrite(localDescriptorOutputPaths.cjsJs, createCjsOutput(descriptor));
39
45
  }
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.packageRoot = exports.descriptorOutputPaths = void 0;
7
+ exports.resolveLocalDescriptorOutputPaths = resolveLocalDescriptorOutputPaths;
7
8
  // Path utilities for locating package-relative outputs.
8
9
  const path_1 = __importDefault(require("path"));
9
10
  const node_fs_1 = __importDefault(require("node:fs"));
@@ -53,3 +54,9 @@ const descriptorOutputPaths = {
53
54
  cjsJs: path_1.default.resolve(packageRoot, "dist/cjs/generated/schema-descriptor.cjs"),
54
55
  };
55
56
  exports.descriptorOutputPaths = descriptorOutputPaths;
57
+ function resolveLocalDescriptorOutputPaths(projectRoot) {
58
+ return {
59
+ json: path_1.default.resolve(projectRoot, ".cms0/generated/schema-descriptor.json"),
60
+ cjsJs: path_1.default.resolve(projectRoot, ".cms0/generated/schema-descriptor.cjs"),
61
+ };
62
+ }
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isCms0CanvasTransportEnabled = isCms0CanvasTransportEnabled;
4
+ exports.dehydrateCms0CanvasTransportValue = dehydrateCms0CanvasTransportValue;
5
+ exports.dehydrateCms0CanvasVisibleValue = dehydrateCms0CanvasVisibleValue;
4
6
  exports.registerCms0LiveRoot = registerCms0LiveRoot;
5
7
  exports.registerCms0CollectionItemIdentity = registerCms0CollectionItemIdentity;
6
8
  exports.readCms0CollectionItemIdentity = readCms0CollectionItemIdentity;
@@ -15,8 +17,7 @@ exports.restoreCms0CanvasTransportMetadata = restoreCms0CanvasTransportMetadata;
15
17
  exports.readCms0LiveRoots = readCms0LiveRoots;
16
18
  exports.captureCms0Provenance = captureCms0Provenance;
17
19
  const schema_descriptors_js_1 = require("./schema-descriptors.cjs");
18
- globalThis.__CMS0_SCHEMA_DESCRIPTOR__ = schema_descriptors_js_1.schemaDescriptor;
19
- globalThis.__CMS0_CANVAS_SCHEMA_DESCRIPTOR__ = schema_descriptors_js_1.schemaDescriptor;
20
+ (0, schema_descriptors_js_1.syncActiveSchemaDescriptorGlobals)();
20
21
  const CAPTURE_STACK = [];
21
22
  const ARRAY_METHOD_NAMES = new Set(Object.getOwnPropertyNames(Array.prototype));
22
23
  const TRACK_IGNORED_OBJECT_KEYS = new Set([
@@ -41,9 +42,26 @@ function isCms0CanvasTransportEnabled() {
41
42
  function isRootRawPath(rawPath) {
42
43
  return rawPath.length > 0 && !rawPath.includes(".") && !rawPath.includes("[#");
43
44
  }
44
- function cloneCanvasTransportValue(value, seen = new WeakMap()) {
45
+ function isWalkableCanvasTransportValue(value) {
46
+ if (!value || typeof value !== "object")
47
+ return false;
48
+ if (Array.isArray(value))
49
+ return true;
50
+ const record = value;
51
+ if ("$$typeof" in record || "__v_isVNode" in record || "_owner" in record) {
52
+ return false;
53
+ }
54
+ if (typeof record.then === "function") {
55
+ return false;
56
+ }
57
+ const prototype = Object.getPrototypeOf(value);
58
+ return prototype === Object.prototype || prototype === null;
59
+ }
60
+ function cloneCanvasTransportValue(value, seen = new WeakMap(), options = {}) {
45
61
  if (!value || typeof value !== "object")
46
62
  return value;
63
+ if (!isWalkableCanvasTransportValue(value))
64
+ return undefined;
47
65
  const cached = seen.get(value);
48
66
  if (cached)
49
67
  return cached;
@@ -51,19 +69,48 @@ function cloneCanvasTransportValue(value, seen = new WeakMap()) {
51
69
  const clone = [];
52
70
  seen.set(value, clone);
53
71
  value.forEach((item, index) => {
54
- clone[index] = cloneCanvasTransportValue(item, seen);
72
+ clone[index] = cloneCanvasTransportValue(item, seen, options);
55
73
  });
74
+ const collectionItemId = readCms0CollectionItemIdentity(value);
75
+ if (collectionItemId) {
76
+ collectionItemIdentity.set(clone, collectionItemId);
77
+ }
78
+ if (options.attachVisibleProvenance) {
79
+ const meta = readCms0ProvenanceValueMeta(value);
80
+ if (meta?.rawPath) {
81
+ const wrapped = attachCms0ProvenanceRoot(clone, meta.rawPath, {
82
+ registerLiveRoot: false,
83
+ transportSerializable: options.transportSerializable,
84
+ });
85
+ seen.set(value, wrapped);
86
+ return wrapped;
87
+ }
88
+ }
56
89
  return clone;
57
90
  }
58
91
  const clone = {};
59
92
  seen.set(value, clone);
60
93
  Object.entries(value).forEach(([key, nested]) => {
61
- clone[key] = cloneCanvasTransportValue(nested, seen);
94
+ clone[key] = cloneCanvasTransportValue(nested, seen, options);
62
95
  });
63
96
  const collectionItemId = readCms0CollectionItemIdentity(value);
64
- if (collectionItemId) {
97
+ if (options.includeCollectionItemId !== false && collectionItemId) {
65
98
  clone[CMS0_CANVAS_COLLECTION_ITEM_ID_KEY] = collectionItemId;
66
99
  }
100
+ if (collectionItemId) {
101
+ collectionItemIdentity.set(clone, collectionItemId);
102
+ }
103
+ if (options.attachVisibleProvenance) {
104
+ const meta = readCms0ProvenanceValueMeta(value);
105
+ if (meta?.rawPath) {
106
+ const wrapped = attachCms0ProvenanceRoot(clone, meta.rawPath, {
107
+ registerLiveRoot: false,
108
+ transportSerializable: options.transportSerializable,
109
+ });
110
+ seen.set(value, wrapped);
111
+ return wrapped;
112
+ }
113
+ }
67
114
  return clone;
68
115
  }
69
116
  function wrapCanvasTransportRoot(value, rootId) {
@@ -75,6 +122,28 @@ function wrapCanvasTransportRoot(value, rootId) {
75
122
  [CMS0_CANVAS_TRANSPORT_DATA_KEY]: cloneCanvasTransportValue(value),
76
123
  };
77
124
  }
125
+ function dehydrateCms0CanvasTransportValue(value) {
126
+ if (!value || typeof value !== "object") {
127
+ return value;
128
+ }
129
+ const meta = readCms0ProvenanceValueMeta(value);
130
+ if (meta?.rawPath) {
131
+ return wrapCanvasTransportRoot(value, meta.rawPath);
132
+ }
133
+ return cloneCanvasTransportValue(value, new WeakMap(), {
134
+ includeCollectionItemId: true,
135
+ });
136
+ }
137
+ function dehydrateCms0CanvasVisibleValue(value) {
138
+ if (!value || typeof value !== "object") {
139
+ return value;
140
+ }
141
+ return cloneCanvasTransportValue(value, new WeakMap(), {
142
+ attachVisibleProvenance: true,
143
+ includeCollectionItemId: false,
144
+ transportSerializable: false,
145
+ });
146
+ }
78
147
  function supportsWeakRef() {
79
148
  return typeof WeakRef !== "undefined";
80
149
  }
@@ -345,7 +414,7 @@ function buildEntityLineage(inheritedEntityIds, rawPath, value) {
345
414
  [rawPath]: entityId,
346
415
  };
347
416
  }
348
- function wrapWithProvenance(value, pathTokens, inheritedEntityIds = {}) {
417
+ function wrapWithProvenance(value, pathTokens, inheritedEntityIds = {}, options = {}) {
349
418
  if (!provenanceEnabled)
350
419
  return value;
351
420
  if (!value || typeof value !== "object")
@@ -360,6 +429,7 @@ function wrapWithProvenance(value, pathTokens, inheritedEntityIds = {}) {
360
429
  const proxy = new Proxy(objectValue, {
361
430
  get(target, property, receiver) {
362
431
  if (property === "toJSON" &&
432
+ options.transportSerializable !== false &&
363
433
  isCanvasTransportEnabled() &&
364
434
  isRootRawPath(pathKey)) {
365
435
  return () => wrapCanvasTransportRoot(target, pathKey);
@@ -371,7 +441,7 @@ function wrapWithProvenance(value, pathTokens, inheritedEntityIds = {}) {
371
441
  if (!trackedToken)
372
442
  return result;
373
443
  const nextPath = [...pathTokens, trackedToken];
374
- const wrappedResult = wrapWithProvenance(result, nextPath, buildEntityLineage(currentEntityIds, nextPath.join("."), result));
444
+ const wrappedResult = wrapWithProvenance(result, nextPath, buildEntityLineage(currentEntityIds, nextPath.join("."), result), options);
375
445
  recordPath(nextPath);
376
446
  recordCapture(nextPath, wrappedResult);
377
447
  return wrappedResult;
@@ -409,7 +479,9 @@ function attachCms0ProvenanceRoot(value, rootId, options) {
409
479
  const normalizedRoot = typeof rootId === "string" ? rootId.trim() : "";
410
480
  if (!normalizedRoot)
411
481
  return value;
412
- const wrapped = wrapWithProvenance(value, [normalizedRoot]);
482
+ const wrapped = wrapWithProvenance(value, [normalizedRoot], {}, {
483
+ transportSerializable: options?.transportSerializable,
484
+ });
413
485
  if (options?.registerLiveRoot !== false &&
414
486
  wrapped &&
415
487
  typeof wrapped === "object") {