@cms0/cms0 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -3
- package/dist/cjs/custom-types/registry.cjs +250 -5
- package/dist/cjs/index.cjs +342 -18
- package/dist/cjs/libs/cli/descriptor-builder-alt.cjs +237 -5
- package/dist/cjs/seo.cjs +226 -0
- package/dist/esm/custom-types/registry.js +250 -5
- package/dist/esm/index.js +338 -19
- package/dist/esm/libs/cli/descriptor-builder-alt.js +237 -5
- package/dist/esm/seo.js +220 -0
- package/dist/types/custom-types/index.d.ts +38 -0
- package/dist/types/custom-types/index.d.ts.map +1 -1
- package/dist/types/custom-types/registry.d.ts +19 -1
- package/dist/types/custom-types/registry.d.ts.map +1 -1
- package/dist/types/index.d.ts +39 -13
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/libs/cli/descriptor-builder-alt.d.ts.map +1 -1
- package/dist/types/seo.d.ts +18 -0
- package/dist/types/seo.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { schemaDescriptor } from "@cms0/cms0/schema-descriptors";
|
|
2
|
-
import { buildZodSchemasFromDescriptor, } from "@cms0/shared";
|
|
2
|
+
import { buildZodSchemasFromDescriptor, decodeTaggedUnionValue, getUnionBranchKeys, } from "@cms0/shared";
|
|
3
3
|
import { getCustomInlineTypeMetadata } from "./custom-types/registry.js";
|
|
4
4
|
const DEFAULT_MODEL_NORMALIZATION_CONCURRENCY = 8;
|
|
5
5
|
const COLLECTION_SHAPE_ERROR = "Invalid collection response. Expected array or { items, total }.";
|
|
@@ -105,6 +105,9 @@ function snakeCaseModelIdKey(modelName) {
|
|
|
105
105
|
.toLowerCase();
|
|
106
106
|
return `${snake}_id`;
|
|
107
107
|
}
|
|
108
|
+
function isUuidLikeId(value) {
|
|
109
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
110
|
+
}
|
|
108
111
|
function extractModelRefId(raw, modelName, options) {
|
|
109
112
|
if (typeof raw === "string")
|
|
110
113
|
return raw;
|
|
@@ -145,6 +148,15 @@ function extractModelRefId(raw, modelName, options) {
|
|
|
145
148
|
function isPrimitiveDescriptor(desc) {
|
|
146
149
|
return desc.kind === "primitive";
|
|
147
150
|
}
|
|
151
|
+
function isEnumDescriptor(desc) {
|
|
152
|
+
return desc.kind === "enum" && Array.isArray(desc.values);
|
|
153
|
+
}
|
|
154
|
+
function isUnionDescriptor(desc) {
|
|
155
|
+
return desc.kind === "union" && Array.isArray(desc.anyOf);
|
|
156
|
+
}
|
|
157
|
+
function isScalarDescriptor(desc) {
|
|
158
|
+
return isPrimitiveDescriptor(desc) || isEnumDescriptor(desc) || isUnionDescriptor(desc);
|
|
159
|
+
}
|
|
148
160
|
function isModelRefDescriptor(desc) {
|
|
149
161
|
return desc.kind === "modelRef";
|
|
150
162
|
}
|
|
@@ -162,7 +174,7 @@ function attachIdIfObject(value, id) {
|
|
|
162
174
|
}
|
|
163
175
|
return value;
|
|
164
176
|
}
|
|
165
|
-
function
|
|
177
|
+
function attachIdForScalarDescriptor(descriptor, value, id) {
|
|
166
178
|
const withId = attachIdIfObject(value, id);
|
|
167
179
|
if (!withId || typeof withId !== "object" || Array.isArray(withId)) {
|
|
168
180
|
return withId;
|
|
@@ -358,6 +370,23 @@ function coerceLocalizedRichTextValue(value, locale, defaultLocale) {
|
|
|
358
370
|
}
|
|
359
371
|
return projectLocalizedByLocale(normalized, locale);
|
|
360
372
|
}
|
|
373
|
+
function coerceSeoValue(value) {
|
|
374
|
+
if (value == null)
|
|
375
|
+
return value;
|
|
376
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
377
|
+
return {};
|
|
378
|
+
}
|
|
379
|
+
const source = value;
|
|
380
|
+
const keys = Object.keys(source).filter((key) => key !== "id");
|
|
381
|
+
if (keys.length === 1 &&
|
|
382
|
+
keys[0] === "value" &&
|
|
383
|
+
source.value &&
|
|
384
|
+
typeof source.value === "object" &&
|
|
385
|
+
!Array.isArray(source.value)) {
|
|
386
|
+
return source.value;
|
|
387
|
+
}
|
|
388
|
+
return source;
|
|
389
|
+
}
|
|
361
390
|
function coerceCustomTypeValue(descriptor, value, options) {
|
|
362
391
|
const customType = descriptor.customType;
|
|
363
392
|
if (!customType)
|
|
@@ -373,8 +402,81 @@ function coerceCustomTypeValue(descriptor, value, options) {
|
|
|
373
402
|
if (customType === "LocalizedRichText") {
|
|
374
403
|
return coerceLocalizedRichTextValue(value, options?.locale, options?.defaultLocale);
|
|
375
404
|
}
|
|
405
|
+
if (customType === "Seo") {
|
|
406
|
+
return coerceSeoValue(value);
|
|
407
|
+
}
|
|
408
|
+
return value;
|
|
409
|
+
}
|
|
410
|
+
function coercePrimitiveValueByType(type, value) {
|
|
411
|
+
if (type === "string") {
|
|
412
|
+
if (value == null)
|
|
413
|
+
return "";
|
|
414
|
+
return typeof value === "string" ? value : String(value);
|
|
415
|
+
}
|
|
416
|
+
if (type === "number") {
|
|
417
|
+
if (typeof value === "number")
|
|
418
|
+
return Number.isFinite(value) ? value : null;
|
|
419
|
+
const parsed = Number(value);
|
|
420
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
421
|
+
}
|
|
422
|
+
if (type === "boolean") {
|
|
423
|
+
if (typeof value === "boolean")
|
|
424
|
+
return value;
|
|
425
|
+
if (value === "true" || value === "1" || value === 1)
|
|
426
|
+
return true;
|
|
427
|
+
if (value === "false" || value === "0" || value === 0)
|
|
428
|
+
return false;
|
|
429
|
+
return Boolean(value);
|
|
430
|
+
}
|
|
376
431
|
return value;
|
|
377
432
|
}
|
|
433
|
+
function coerceEnumValue(descriptor, value) {
|
|
434
|
+
const valueType = (descriptor.valueType ?? "string");
|
|
435
|
+
const coerced = coercePrimitiveValueByType(valueType, value);
|
|
436
|
+
const values = Array.isArray(descriptor.values)
|
|
437
|
+
? descriptor.values
|
|
438
|
+
: [];
|
|
439
|
+
if (!values.length)
|
|
440
|
+
return coerced;
|
|
441
|
+
if (values.some((entry) => Object.is(entry, coerced))) {
|
|
442
|
+
return coerced;
|
|
443
|
+
}
|
|
444
|
+
return values[0];
|
|
445
|
+
}
|
|
446
|
+
function decodeUnionEnvelope(descriptor, raw) {
|
|
447
|
+
const decoded = decodeTaggedUnionValue(raw);
|
|
448
|
+
if (!decoded)
|
|
449
|
+
return null;
|
|
450
|
+
const branches = Array.isArray(descriptor.anyOf)
|
|
451
|
+
? descriptor.anyOf
|
|
452
|
+
: [];
|
|
453
|
+
if (!branches.length)
|
|
454
|
+
return null;
|
|
455
|
+
const branchKeys = getUnionBranchKeys(descriptor);
|
|
456
|
+
const branchIndex = branchKeys.findIndex((key) => key === decoded.branchKey);
|
|
457
|
+
if (branchIndex < 0 || branchIndex >= branches.length)
|
|
458
|
+
return null;
|
|
459
|
+
const branchDescriptor = branches[branchIndex];
|
|
460
|
+
if (!branchDescriptor)
|
|
461
|
+
return null;
|
|
462
|
+
return {
|
|
463
|
+
branchDescriptor,
|
|
464
|
+
branchValue: decoded.value,
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
function decodeUnionValueFromRawField(descriptor, raw) {
|
|
468
|
+
const direct = decodeUnionEnvelope(descriptor, raw);
|
|
469
|
+
if (direct) {
|
|
470
|
+
return { ...direct, rowId: extractId(raw) };
|
|
471
|
+
}
|
|
472
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && "value" in raw) {
|
|
473
|
+
const nested = decodeUnionEnvelope(descriptor, raw.value);
|
|
474
|
+
if (nested) {
|
|
475
|
+
return { ...nested, rowId: extractId(raw) };
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
378
480
|
function ensureCollectionEnvelope(data, path) {
|
|
379
481
|
if (Array.isArray(data)) {
|
|
380
482
|
return { items: data, total: data.length };
|
|
@@ -446,12 +548,8 @@ async function normalizeObjectField(descriptor, path, raw, context, trail, isCol
|
|
|
446
548
|
const source = raw && typeof raw === "object" ? raw : {};
|
|
447
549
|
const output = {};
|
|
448
550
|
for (const [propertyName, propertyDescriptor] of Object.entries(descriptor.properties)) {
|
|
449
|
-
if (
|
|
450
|
-
output[propertyName] =
|
|
451
|
-
locale: context.options.locale,
|
|
452
|
-
defaultLocale: context.options.defaultLocale,
|
|
453
|
-
assetUrlBuilder: context.options.assetUrlBuilder,
|
|
454
|
-
});
|
|
551
|
+
if (isScalarDescriptor(propertyDescriptor)) {
|
|
552
|
+
output[propertyName] = await normalizeField(propertyDescriptor, `${path}/${propertyName}`, source[propertyName], context, trail, false);
|
|
455
553
|
continue;
|
|
456
554
|
}
|
|
457
555
|
if (isModelRefDescriptor(propertyDescriptor)) {
|
|
@@ -539,16 +637,14 @@ async function normalizeObjectField(descriptor, path, raw, context, trail, isCol
|
|
|
539
637
|
async function normalizeArrayField(descriptor, path, raw, context, trail) {
|
|
540
638
|
const envelope = ensureCollectionEnvelope(raw, path);
|
|
541
639
|
const itemDescriptor = descriptor.items;
|
|
542
|
-
if (
|
|
543
|
-
return envelope.items.
|
|
544
|
-
const
|
|
545
|
-
? row.value
|
|
546
|
-
: row;
|
|
640
|
+
if (isScalarDescriptor(itemDescriptor)) {
|
|
641
|
+
return mapWithConcurrency(envelope.items, context.options.modelNormalizationConcurrency, async (row) => {
|
|
642
|
+
const normalizedValue = await normalizeField(itemDescriptor, path, row, context, trail, true);
|
|
547
643
|
if (context.options.includeIdMode !== "all") {
|
|
548
|
-
return
|
|
644
|
+
return normalizedValue;
|
|
549
645
|
}
|
|
550
646
|
const id = extractId(row);
|
|
551
|
-
const valueWithId =
|
|
647
|
+
const valueWithId = attachIdForScalarDescriptor(itemDescriptor, normalizedValue, id);
|
|
552
648
|
const isObjectValue = valueWithId && typeof valueWithId === "object" && !Array.isArray(valueWithId);
|
|
553
649
|
if (!id) {
|
|
554
650
|
return valueWithId;
|
|
@@ -579,6 +675,60 @@ async function normalizeArrayField(descriptor, path, raw, context, trail) {
|
|
|
579
675
|
}
|
|
580
676
|
return envelope.items;
|
|
581
677
|
}
|
|
678
|
+
async function normalizeInlineField(descriptor, raw, context, trail, isCollectionItem) {
|
|
679
|
+
if (isPrimitiveDescriptor(descriptor)) {
|
|
680
|
+
return coerceCustomTypeValue(descriptor, raw, {
|
|
681
|
+
locale: context.options.locale,
|
|
682
|
+
defaultLocale: context.options.defaultLocale,
|
|
683
|
+
assetUrlBuilder: context.options.assetUrlBuilder,
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
if (isEnumDescriptor(descriptor)) {
|
|
687
|
+
return coerceEnumValue(descriptor, raw);
|
|
688
|
+
}
|
|
689
|
+
if (isUnionDescriptor(descriptor)) {
|
|
690
|
+
if (raw == null)
|
|
691
|
+
return raw;
|
|
692
|
+
const decoded = decodeUnionEnvelope(descriptor, raw);
|
|
693
|
+
if (!decoded) {
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
return normalizeInlineField(decoded.branchDescriptor, decoded.branchValue, context, trail, isCollectionItem);
|
|
697
|
+
}
|
|
698
|
+
if (isModelRefDescriptor(descriptor)) {
|
|
699
|
+
const refId = extractModelRefId(raw, descriptor.model, {
|
|
700
|
+
allowObjectIdFallback: true,
|
|
701
|
+
});
|
|
702
|
+
if (!refId) {
|
|
703
|
+
return missingModelRefValue(descriptor);
|
|
704
|
+
}
|
|
705
|
+
return normalizeModelRef(descriptor.model, refId, context, trail, isCollectionItem, raw);
|
|
706
|
+
}
|
|
707
|
+
if (isArrayDescriptor(descriptor)) {
|
|
708
|
+
const source = Array.isArray(raw) ? raw : [];
|
|
709
|
+
const normalized = await mapWithConcurrency(source, context.options.modelNormalizationConcurrency, async (entry) => normalizeInlineField(descriptor.items, entry, context, trail, true));
|
|
710
|
+
return coerceCustomTypeValue(descriptor, normalized, {
|
|
711
|
+
locale: context.options.locale,
|
|
712
|
+
defaultLocale: context.options.defaultLocale,
|
|
713
|
+
assetUrlBuilder: context.options.assetUrlBuilder,
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
if (isObjectDescriptor(descriptor)) {
|
|
717
|
+
const source = raw && typeof raw === "object" && !Array.isArray(raw)
|
|
718
|
+
? raw
|
|
719
|
+
: {};
|
|
720
|
+
const output = {};
|
|
721
|
+
for (const [propertyName, propertyDescriptor] of Object.entries(descriptor.properties)) {
|
|
722
|
+
output[propertyName] = await normalizeInlineField(propertyDescriptor, source[propertyName], context, trail, false);
|
|
723
|
+
}
|
|
724
|
+
return coerceCustomTypeValue(descriptor, output, {
|
|
725
|
+
locale: context.options.locale,
|
|
726
|
+
defaultLocale: context.options.defaultLocale,
|
|
727
|
+
assetUrlBuilder: context.options.assetUrlBuilder,
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
return raw;
|
|
731
|
+
}
|
|
582
732
|
async function normalizeField(descriptor, path, raw, context, trail, isCollectionItem) {
|
|
583
733
|
if (isPrimitiveDescriptor(descriptor)) {
|
|
584
734
|
const value = raw && typeof raw === "object" && "value" in raw
|
|
@@ -591,10 +741,33 @@ async function normalizeField(descriptor, path, raw, context, trail, isCollectio
|
|
|
591
741
|
});
|
|
592
742
|
if (shouldIncludeObjectId(context.options.includeIdMode, isCollectionItem)) {
|
|
593
743
|
const id = extractId(raw);
|
|
594
|
-
coerced =
|
|
744
|
+
coerced = attachIdForScalarDescriptor(descriptor, coerced, id);
|
|
745
|
+
}
|
|
746
|
+
return coerced;
|
|
747
|
+
}
|
|
748
|
+
if (isEnumDescriptor(descriptor)) {
|
|
749
|
+
const value = raw && typeof raw === "object" && "value" in raw
|
|
750
|
+
? raw.value
|
|
751
|
+
: raw;
|
|
752
|
+
let coerced = coerceEnumValue(descriptor, value);
|
|
753
|
+
if (shouldIncludeObjectId(context.options.includeIdMode, isCollectionItem)) {
|
|
754
|
+
const id = extractId(raw);
|
|
755
|
+
coerced = attachIdForScalarDescriptor(descriptor, coerced, id);
|
|
595
756
|
}
|
|
596
757
|
return coerced;
|
|
597
758
|
}
|
|
759
|
+
if (isUnionDescriptor(descriptor)) {
|
|
760
|
+
const decoded = decodeUnionValueFromRawField(descriptor, raw);
|
|
761
|
+
if (!decoded) {
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
let normalized = await normalizeInlineField(decoded.branchDescriptor, decoded.branchValue, context, trail, isCollectionItem);
|
|
765
|
+
if (shouldIncludeObjectId(context.options.includeIdMode, isCollectionItem)) {
|
|
766
|
+
const id = decoded.rowId ?? extractId(raw);
|
|
767
|
+
normalized = attachIdForScalarDescriptor(descriptor, normalized, id);
|
|
768
|
+
}
|
|
769
|
+
return normalized;
|
|
770
|
+
}
|
|
598
771
|
if (isModelRefDescriptor(descriptor)) {
|
|
599
772
|
const inlineModelDescriptor = context.modelDescriptors.get(descriptor.model);
|
|
600
773
|
const inlineModel = inlineModelDescriptor
|
|
@@ -694,6 +867,140 @@ function buildSearchParams(query) {
|
|
|
694
867
|
}
|
|
695
868
|
return params;
|
|
696
869
|
}
|
|
870
|
+
function isPlainObject(value) {
|
|
871
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
872
|
+
}
|
|
873
|
+
function cloneValue(value) {
|
|
874
|
+
if (Array.isArray(value)) {
|
|
875
|
+
return value.map((item) => cloneValue(item));
|
|
876
|
+
}
|
|
877
|
+
if (isPlainObject(value)) {
|
|
878
|
+
const out = {};
|
|
879
|
+
for (const [key, child] of Object.entries(value)) {
|
|
880
|
+
out[key] = cloneValue(child);
|
|
881
|
+
}
|
|
882
|
+
return out;
|
|
883
|
+
}
|
|
884
|
+
return value;
|
|
885
|
+
}
|
|
886
|
+
function normalizeProjectionPaths(input) {
|
|
887
|
+
if (!input)
|
|
888
|
+
return [];
|
|
889
|
+
const values = Array.isArray(input) ? input : [input];
|
|
890
|
+
const unique = new Set();
|
|
891
|
+
for (const raw of values) {
|
|
892
|
+
for (const candidate of raw.split(",")) {
|
|
893
|
+
const path = candidate.trim();
|
|
894
|
+
if (!path)
|
|
895
|
+
continue;
|
|
896
|
+
const normalized = path
|
|
897
|
+
.split(".")
|
|
898
|
+
.map((part) => part.trim())
|
|
899
|
+
.filter(Boolean)
|
|
900
|
+
.join(".");
|
|
901
|
+
if (!normalized)
|
|
902
|
+
continue;
|
|
903
|
+
unique.add(normalized);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return Array.from(unique).map((path) => path.split("."));
|
|
907
|
+
}
|
|
908
|
+
function mergeProjectedValue(existing, incoming) {
|
|
909
|
+
if (incoming === undefined)
|
|
910
|
+
return existing;
|
|
911
|
+
if (existing === undefined)
|
|
912
|
+
return cloneValue(incoming);
|
|
913
|
+
if (Array.isArray(existing) && Array.isArray(incoming)) {
|
|
914
|
+
const max = Math.max(existing.length, incoming.length);
|
|
915
|
+
const out = [];
|
|
916
|
+
for (let index = 0; index < max; index++) {
|
|
917
|
+
const next = mergeProjectedValue(existing[index], incoming[index]);
|
|
918
|
+
if (next !== undefined)
|
|
919
|
+
out.push(next);
|
|
920
|
+
}
|
|
921
|
+
return out;
|
|
922
|
+
}
|
|
923
|
+
if (isPlainObject(existing) && isPlainObject(incoming)) {
|
|
924
|
+
const out = { ...existing };
|
|
925
|
+
for (const [key, child] of Object.entries(incoming)) {
|
|
926
|
+
out[key] = mergeProjectedValue(out[key], child);
|
|
927
|
+
}
|
|
928
|
+
return out;
|
|
929
|
+
}
|
|
930
|
+
return cloneValue(incoming);
|
|
931
|
+
}
|
|
932
|
+
function projectValueByPath(value, tokens) {
|
|
933
|
+
if (!tokens.length)
|
|
934
|
+
return cloneValue(value);
|
|
935
|
+
if (Array.isArray(value)) {
|
|
936
|
+
const projectedItems = value
|
|
937
|
+
.map((item) => projectValueByPath(item, tokens))
|
|
938
|
+
.filter((item) => item !== undefined);
|
|
939
|
+
return projectedItems.length ? projectedItems : undefined;
|
|
940
|
+
}
|
|
941
|
+
if (!isPlainObject(value))
|
|
942
|
+
return undefined;
|
|
943
|
+
const [head, ...rest] = tokens;
|
|
944
|
+
if (!head || !(head in value))
|
|
945
|
+
return undefined;
|
|
946
|
+
const child = projectValueByPath(value[head], rest);
|
|
947
|
+
if (child === undefined)
|
|
948
|
+
return undefined;
|
|
949
|
+
return { [head]: child };
|
|
950
|
+
}
|
|
951
|
+
function excludeValueByPath(value, tokens) {
|
|
952
|
+
if (!tokens.length)
|
|
953
|
+
return undefined;
|
|
954
|
+
if (Array.isArray(value)) {
|
|
955
|
+
return value.map((item) => excludeValueByPath(item, tokens));
|
|
956
|
+
}
|
|
957
|
+
if (!isPlainObject(value))
|
|
958
|
+
return value;
|
|
959
|
+
const [head, ...rest] = tokens;
|
|
960
|
+
if (!head || !(head in value))
|
|
961
|
+
return cloneValue(value);
|
|
962
|
+
const out = { ...value };
|
|
963
|
+
if (!rest.length) {
|
|
964
|
+
delete out[head];
|
|
965
|
+
return out;
|
|
966
|
+
}
|
|
967
|
+
const next = excludeValueByPath(out[head], rest);
|
|
968
|
+
if (next === undefined) {
|
|
969
|
+
delete out[head];
|
|
970
|
+
}
|
|
971
|
+
else {
|
|
972
|
+
out[head] = next;
|
|
973
|
+
}
|
|
974
|
+
return out;
|
|
975
|
+
}
|
|
976
|
+
function applyFieldProjection(value, fields, exclude) {
|
|
977
|
+
const includePaths = normalizeProjectionPaths(fields);
|
|
978
|
+
const excludePaths = normalizeProjectionPaths(exclude);
|
|
979
|
+
let projected = value;
|
|
980
|
+
if (includePaths.length) {
|
|
981
|
+
let included = undefined;
|
|
982
|
+
for (const pathTokens of includePaths) {
|
|
983
|
+
const partial = projectValueByPath(value, pathTokens);
|
|
984
|
+
included = mergeProjectedValue(included, partial);
|
|
985
|
+
}
|
|
986
|
+
projected =
|
|
987
|
+
included === undefined
|
|
988
|
+
? Array.isArray(value)
|
|
989
|
+
? []
|
|
990
|
+
: isPlainObject(value)
|
|
991
|
+
? {}
|
|
992
|
+
: undefined
|
|
993
|
+
: included;
|
|
994
|
+
}
|
|
995
|
+
if (excludePaths.length) {
|
|
996
|
+
let excluded = projected;
|
|
997
|
+
for (const pathTokens of excludePaths) {
|
|
998
|
+
excluded = excludeValueByPath(excluded, pathTokens);
|
|
999
|
+
}
|
|
1000
|
+
projected = excluded;
|
|
1001
|
+
}
|
|
1002
|
+
return projected;
|
|
1003
|
+
}
|
|
697
1004
|
async function requestJson(baseUrl, apiKey, path, options) {
|
|
698
1005
|
const params = buildSearchParams(options?.query);
|
|
699
1006
|
const url = `${baseUrl}/${path}${params.toString() ? `?${params.toString()}` : ""}`;
|
|
@@ -755,6 +1062,16 @@ async function runResource(resource, descriptor, baseUrl, apiKey, defaultLocale,
|
|
|
755
1062
|
const query = {
|
|
756
1063
|
...(options?.query ?? {}),
|
|
757
1064
|
};
|
|
1065
|
+
if (options?.fields !== undefined && query.fields === undefined) {
|
|
1066
|
+
query.fields = Array.isArray(options.fields)
|
|
1067
|
+
? options.fields.join(",")
|
|
1068
|
+
: options.fields;
|
|
1069
|
+
}
|
|
1070
|
+
if (options?.exclude !== undefined && query.exclude === undefined) {
|
|
1071
|
+
query.exclude = Array.isArray(options.exclude)
|
|
1072
|
+
? options.exclude.join(",")
|
|
1073
|
+
: options.exclude;
|
|
1074
|
+
}
|
|
758
1075
|
const shouldNormalize = responseMode !== "raw";
|
|
759
1076
|
if (shouldNormalize && query.raw === undefined) {
|
|
760
1077
|
query.raw = 1;
|
|
@@ -804,7 +1121,7 @@ async function runResource(resource, descriptor, baseUrl, apiKey, defaultLocale,
|
|
|
804
1121
|
});
|
|
805
1122
|
}
|
|
806
1123
|
if (!shouldNormalize) {
|
|
807
|
-
return rawData;
|
|
1124
|
+
return applyFieldProjection(rawData, options?.fields, options?.exclude);
|
|
808
1125
|
}
|
|
809
1126
|
const modelDescriptors = new Map();
|
|
810
1127
|
for (const modelName of Object.keys(descriptor.models ?? {})) {
|
|
@@ -839,9 +1156,10 @@ async function runResource(resource, descriptor, baseUrl, apiKey, defaultLocale,
|
|
|
839
1156
|
};
|
|
840
1157
|
const normalizedItems = await normalizeArrayField(descriptorForCollection, resource.path, envelope, context, new Set());
|
|
841
1158
|
if (responseMode === "envelope") {
|
|
1159
|
+
const projectedItems = applyFieldProjection(normalizedItems, options?.fields, options?.exclude);
|
|
842
1160
|
validateResult(resource, normalizedItems, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
|
|
843
1161
|
return {
|
|
844
|
-
items: normalizedItems,
|
|
1162
|
+
items: Array.isArray(projectedItems) ? projectedItems : normalizedItems,
|
|
845
1163
|
total: envelope.total,
|
|
846
1164
|
};
|
|
847
1165
|
}
|
|
@@ -850,7 +1168,7 @@ async function runResource(resource, descriptor, baseUrl, apiKey, defaultLocale,
|
|
|
850
1168
|
}
|
|
851
1169
|
const normalized = await normalizeField(resource.descriptor, normalizePath, rawData, context, new Set(), false);
|
|
852
1170
|
validateResult(resource, normalized, descriptor, includeIdMode, zodSchemas, modelZodSchemas);
|
|
853
|
-
return normalized;
|
|
1171
|
+
return applyFieldProjection(normalized, options?.fields, options?.exclude);
|
|
854
1172
|
}
|
|
855
1173
|
export function createCmsClient(descriptor, config) {
|
|
856
1174
|
const baseUrl = normalizeBaseUrl(config.apiConfig?.baseUrl);
|
|
@@ -913,3 +1231,4 @@ export function createCmsClient(descriptor, config) {
|
|
|
913
1231
|
export function cms0(config) {
|
|
914
1232
|
return createCmsClient(schemaDescriptor, config);
|
|
915
1233
|
}
|
|
1234
|
+
export { resolveLocalized, toNextMetadata, toOpenGraph, toTwitter, } from "./seo.js";
|