@blinkk/root-cms 3.0.1-alpha.1 → 3.0.1-beta.2
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/app.js +12 -6
- package/dist/chunk-ATPWU3CU.js +921 -0
- package/dist/chunk-CRK7N6RR.js +298 -0
- package/dist/{chunk-SNZ4S4IC.js → chunk-F4SODS5S.js} +87 -297
- package/dist/{chunk-R4LKO3EZ.js → chunk-MAZA5B27.js} +16 -18
- package/dist/{chunk-UTSL2E2P.js → chunk-TRM4MQHU.js} +270 -11
- package/dist/{chunk-KDXHFMIH.js → chunk-XLX37FRL.js} +3 -0
- package/dist/cli.js +3 -2
- package/dist/{client-DdB4xpM6.d.ts → client-1puwLgNx.d.ts} +194 -10
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -1
- package/dist/core.d.ts +3 -3
- package/dist/core.js +2 -1
- package/dist/functions.js +3 -2
- package/dist/{generate-types-MHWSSOWV.js → generate-types-SPV7I3A5.js} +1 -1
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.js +284 -78
- package/dist/project.d.ts +15 -2
- package/dist/project.js +3 -1
- package/dist/richtext.d.ts +25 -18
- package/dist/richtext.js +98 -43
- package/dist/{schema-rjBOZk-j.d.ts → schema-Db_xODoi.d.ts} +5 -0
- package/dist/ui/signin.css +1 -1
- package/dist/ui/signin.js +3 -3
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +255 -177
- package/dist/ui/ui.js.LEGAL.txt +2 -1
- package/package.json +10 -7
- package/dist/ai-OZY3JXDH.js +0 -19
- package/dist/altText-RDKJNVGH.js +0 -7
- package/dist/chunk-BBOESYH7.js +0 -192
- package/dist/chunk-T5UK2H24.js +0 -419
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateFields
|
|
3
|
+
} from "./chunk-CRK7N6RR.js";
|
|
4
|
+
|
|
1
5
|
// core/client.ts
|
|
2
6
|
import crypto from "crypto";
|
|
3
7
|
import {
|
|
@@ -358,301 +362,6 @@ function buildTranslationsLocaleDocDbPath(options) {
|
|
|
358
362
|
).replace("{mode}", options.mode).replace("{id}", normalizeSlug(options.id)).replace("{locale}", options.locale);
|
|
359
363
|
}
|
|
360
364
|
|
|
361
|
-
// core/validation.ts
|
|
362
|
-
function validateFields(fieldsData, schema) {
|
|
363
|
-
if (fieldsData === null || fieldsData === void 0) {
|
|
364
|
-
return [];
|
|
365
|
-
}
|
|
366
|
-
if (typeof fieldsData !== "object" || Array.isArray(fieldsData)) {
|
|
367
|
-
return [
|
|
368
|
-
{
|
|
369
|
-
path: "",
|
|
370
|
-
message: "Expected object for fields data",
|
|
371
|
-
expected: "object",
|
|
372
|
-
received: getType(fieldsData)
|
|
373
|
-
}
|
|
374
|
-
];
|
|
375
|
-
}
|
|
376
|
-
const errors = [];
|
|
377
|
-
for (const field of schema.fields) {
|
|
378
|
-
if (!field.id) {
|
|
379
|
-
continue;
|
|
380
|
-
}
|
|
381
|
-
if (!(field.id in fieldsData)) {
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
const value = fieldsData[field.id];
|
|
385
|
-
errors.push(...validateValue(value, field, field.id));
|
|
386
|
-
}
|
|
387
|
-
return errors;
|
|
388
|
-
}
|
|
389
|
-
function validateValue(value, field, path) {
|
|
390
|
-
if (value === void 0) {
|
|
391
|
-
return [];
|
|
392
|
-
}
|
|
393
|
-
switch (field.type) {
|
|
394
|
-
case "string":
|
|
395
|
-
case "select":
|
|
396
|
-
if (typeof value !== "string") {
|
|
397
|
-
return [createError(path, "string", value)];
|
|
398
|
-
}
|
|
399
|
-
return [];
|
|
400
|
-
case "number":
|
|
401
|
-
if (typeof value !== "number") {
|
|
402
|
-
return [createError(path, "number", value)];
|
|
403
|
-
}
|
|
404
|
-
if (isNaN(value)) {
|
|
405
|
-
return [createError(path, "number", value)];
|
|
406
|
-
}
|
|
407
|
-
return [];
|
|
408
|
-
case "boolean":
|
|
409
|
-
if (typeof value !== "boolean") {
|
|
410
|
-
return [createError(path, "boolean", value)];
|
|
411
|
-
}
|
|
412
|
-
return [];
|
|
413
|
-
case "date":
|
|
414
|
-
case "datetime": {
|
|
415
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
416
|
-
return [createError(path, "object", value)];
|
|
417
|
-
}
|
|
418
|
-
const errors = [];
|
|
419
|
-
const seconds = value.seconds;
|
|
420
|
-
const nanoseconds = value.nanoseconds;
|
|
421
|
-
if (seconds === void 0) {
|
|
422
|
-
errors.push({
|
|
423
|
-
path: `${path}.seconds`,
|
|
424
|
-
message: "Required",
|
|
425
|
-
expected: "number",
|
|
426
|
-
received: "undefined"
|
|
427
|
-
});
|
|
428
|
-
} else if (typeof seconds !== "number") {
|
|
429
|
-
errors.push(createError(`${path}.seconds`, "number", seconds));
|
|
430
|
-
}
|
|
431
|
-
if (nanoseconds === void 0) {
|
|
432
|
-
errors.push({
|
|
433
|
-
path: `${path}.nanoseconds`,
|
|
434
|
-
message: "Required",
|
|
435
|
-
expected: "number",
|
|
436
|
-
received: "undefined"
|
|
437
|
-
});
|
|
438
|
-
} else if (typeof nanoseconds !== "number") {
|
|
439
|
-
errors.push(createError(`${path}.nanoseconds`, "number", nanoseconds));
|
|
440
|
-
}
|
|
441
|
-
return errors;
|
|
442
|
-
}
|
|
443
|
-
case "multiselect":
|
|
444
|
-
if (!Array.isArray(value)) {
|
|
445
|
-
return [createError(path, "array", value)];
|
|
446
|
-
}
|
|
447
|
-
return value.flatMap((item, index) => {
|
|
448
|
-
if (typeof item !== "string") {
|
|
449
|
-
return [createError(`${path}.${index}`, "string", item)];
|
|
450
|
-
}
|
|
451
|
-
return [];
|
|
452
|
-
});
|
|
453
|
-
case "image":
|
|
454
|
-
case "file": {
|
|
455
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
456
|
-
return [createError(path, "object", value)];
|
|
457
|
-
}
|
|
458
|
-
const errors = [];
|
|
459
|
-
if (value.src === void 0) {
|
|
460
|
-
errors.push({
|
|
461
|
-
path: `${path}.src`,
|
|
462
|
-
message: "Required",
|
|
463
|
-
expected: "string",
|
|
464
|
-
received: "undefined"
|
|
465
|
-
});
|
|
466
|
-
} else if (typeof value.src !== "string") {
|
|
467
|
-
errors.push(createError(`${path}.src`, "string", value.src));
|
|
468
|
-
}
|
|
469
|
-
if (value.alt !== void 0 && typeof value.alt !== "string") {
|
|
470
|
-
errors.push(createError(`${path}.alt`, "string", value.alt));
|
|
471
|
-
}
|
|
472
|
-
return errors;
|
|
473
|
-
}
|
|
474
|
-
case "object": {
|
|
475
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
476
|
-
return [createError(path, "object", value)];
|
|
477
|
-
}
|
|
478
|
-
const objectField = field;
|
|
479
|
-
const errors = [];
|
|
480
|
-
for (const nestedField of objectField.fields) {
|
|
481
|
-
if (!nestedField.id || !(nestedField.id in value)) {
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
errors.push(
|
|
485
|
-
...validateValue(
|
|
486
|
-
value[nestedField.id],
|
|
487
|
-
nestedField,
|
|
488
|
-
`${path}.${nestedField.id}`
|
|
489
|
-
)
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
return errors;
|
|
493
|
-
}
|
|
494
|
-
case "array": {
|
|
495
|
-
if (!Array.isArray(value)) {
|
|
496
|
-
return [createError(path, "array", value)];
|
|
497
|
-
}
|
|
498
|
-
const arrayField = field;
|
|
499
|
-
const itemField = arrayField.of;
|
|
500
|
-
return value.flatMap((item, index) => {
|
|
501
|
-
return validateValue(item, itemField, `${path}.${index}`);
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
case "oneof": {
|
|
505
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
506
|
-
return [createError(path, "object", value)];
|
|
507
|
-
}
|
|
508
|
-
const oneOfField = field;
|
|
509
|
-
const typeName = value._type;
|
|
510
|
-
const typeMap = /* @__PURE__ */ new Map();
|
|
511
|
-
const typeNames = [];
|
|
512
|
-
for (const type of oneOfField.types) {
|
|
513
|
-
if (typeof type === "string") {
|
|
514
|
-
typeNames.push(type);
|
|
515
|
-
continue;
|
|
516
|
-
}
|
|
517
|
-
typeMap.set(type.name, type);
|
|
518
|
-
typeNames.push(type.name);
|
|
519
|
-
}
|
|
520
|
-
if (!typeNames.includes(typeName)) {
|
|
521
|
-
const expectedStr = typeNames.map((t) => `'${t}'`).join(" | ");
|
|
522
|
-
return [
|
|
523
|
-
{
|
|
524
|
-
path: `${path}._type`,
|
|
525
|
-
message: `Invalid discriminator value. Expected ${expectedStr}`,
|
|
526
|
-
expected: "valid discriminator value",
|
|
527
|
-
received: typeName
|
|
528
|
-
}
|
|
529
|
-
];
|
|
530
|
-
}
|
|
531
|
-
const matchedSchema = typeMap.get(typeName);
|
|
532
|
-
if (!matchedSchema) {
|
|
533
|
-
return [];
|
|
534
|
-
}
|
|
535
|
-
const errors = [];
|
|
536
|
-
for (const nestedField of matchedSchema.fields) {
|
|
537
|
-
if (!nestedField.id || !(nestedField.id in value)) {
|
|
538
|
-
continue;
|
|
539
|
-
}
|
|
540
|
-
errors.push(
|
|
541
|
-
...validateValue(
|
|
542
|
-
value[nestedField.id],
|
|
543
|
-
nestedField,
|
|
544
|
-
`${path}.${nestedField.id}`
|
|
545
|
-
)
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
return errors;
|
|
549
|
-
}
|
|
550
|
-
case "richtext": {
|
|
551
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
552
|
-
return [createError(path, "object", value)];
|
|
553
|
-
}
|
|
554
|
-
const errors = [];
|
|
555
|
-
if (value.blocks === void 0) {
|
|
556
|
-
errors.push({
|
|
557
|
-
path: `${path}.blocks`,
|
|
558
|
-
message: "Required",
|
|
559
|
-
expected: "array",
|
|
560
|
-
received: "undefined"
|
|
561
|
-
});
|
|
562
|
-
} else if (!Array.isArray(value.blocks)) {
|
|
563
|
-
errors.push(createError(`${path}.blocks`, "array", value.blocks));
|
|
564
|
-
} else {
|
|
565
|
-
value.blocks.forEach((block, index) => {
|
|
566
|
-
if (typeof block !== "object" || block === null) {
|
|
567
|
-
errors.push(
|
|
568
|
-
createError(`${path}.blocks.${index}`, "object", block)
|
|
569
|
-
);
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
if (block.type === void 0) {
|
|
573
|
-
errors.push({
|
|
574
|
-
path: `${path}.blocks.${index}.type`,
|
|
575
|
-
message: "Required",
|
|
576
|
-
expected: "string",
|
|
577
|
-
received: "undefined"
|
|
578
|
-
});
|
|
579
|
-
} else if (typeof block.type !== "string") {
|
|
580
|
-
errors.push(
|
|
581
|
-
createError(`${path}.blocks.${index}.type`, "string", block.type)
|
|
582
|
-
);
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
return errors;
|
|
587
|
-
}
|
|
588
|
-
case "reference": {
|
|
589
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
590
|
-
return [createError(path, "object", value)];
|
|
591
|
-
}
|
|
592
|
-
const errors = [];
|
|
593
|
-
const requiredFields = ["id", "collection", "slug"];
|
|
594
|
-
for (const req of requiredFields) {
|
|
595
|
-
if (value[req] === void 0) {
|
|
596
|
-
errors.push({
|
|
597
|
-
path: `${path}.${req}`,
|
|
598
|
-
message: "Required",
|
|
599
|
-
expected: "string",
|
|
600
|
-
received: "undefined"
|
|
601
|
-
});
|
|
602
|
-
} else if (typeof value[req] !== "string") {
|
|
603
|
-
errors.push(createError(`${path}.${req}`, "string", value[req]));
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
return errors;
|
|
607
|
-
}
|
|
608
|
-
case "references": {
|
|
609
|
-
if (!Array.isArray(value)) {
|
|
610
|
-
return [createError(path, "array", value)];
|
|
611
|
-
}
|
|
612
|
-
return value.flatMap((item, index) => {
|
|
613
|
-
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
614
|
-
return [createError(`${path}.${index}`, "object", item)];
|
|
615
|
-
}
|
|
616
|
-
const errors = [];
|
|
617
|
-
const requiredFields = ["id", "collection", "slug"];
|
|
618
|
-
for (const req of requiredFields) {
|
|
619
|
-
if (item[req] === void 0) {
|
|
620
|
-
errors.push({
|
|
621
|
-
path: `${path}.${index}.${req}`,
|
|
622
|
-
message: "Required",
|
|
623
|
-
expected: "string",
|
|
624
|
-
received: "undefined"
|
|
625
|
-
});
|
|
626
|
-
} else if (typeof item[req] !== "string") {
|
|
627
|
-
errors.push(
|
|
628
|
-
createError(`${path}.${index}.${req}`, "string", item[req])
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
return errors;
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
default:
|
|
636
|
-
console.warn(`Unknown field type: ${field.type}`);
|
|
637
|
-
return [];
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
function getType(value) {
|
|
641
|
-
if (value === null) return "null";
|
|
642
|
-
if (Array.isArray(value)) return "array";
|
|
643
|
-
if (typeof value === "number" && Number.isNaN(value)) return "nan";
|
|
644
|
-
return typeof value;
|
|
645
|
-
}
|
|
646
|
-
function createError(path, expected, receivedValue) {
|
|
647
|
-
const received = getType(receivedValue);
|
|
648
|
-
return {
|
|
649
|
-
path,
|
|
650
|
-
message: `Expected ${expected}, received ${received}`,
|
|
651
|
-
expected,
|
|
652
|
-
received
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
|
|
656
365
|
// core/values.ts
|
|
657
366
|
function setValueAtPath(obj, path, value) {
|
|
658
367
|
const keys = path.split(".");
|
|
@@ -1501,10 +1210,41 @@ ${errorMessages}`);
|
|
|
1501
1210
|
const docRef = this.db.doc(dbPath);
|
|
1502
1211
|
const doc = await docRef.get();
|
|
1503
1212
|
if (doc.exists) {
|
|
1504
|
-
|
|
1213
|
+
const dataSource = doc.data();
|
|
1214
|
+
if (dataSource.archivedAt) {
|
|
1215
|
+
console.warn(
|
|
1216
|
+
`warning: data source "${dataSourceId}" is archived` + (dataSource.archivedBy ? ` (archived by ${dataSource.archivedBy})` : "")
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
return dataSource;
|
|
1505
1220
|
}
|
|
1506
1221
|
return null;
|
|
1507
1222
|
}
|
|
1223
|
+
/**
|
|
1224
|
+
* Archives a data source. Archived data sources cannot be synced or published.
|
|
1225
|
+
*/
|
|
1226
|
+
async archiveDataSource(dataSourceId, options) {
|
|
1227
|
+
const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}`;
|
|
1228
|
+
const docRef = this.db.doc(dbPath);
|
|
1229
|
+
const archivedBy = options?.archivedBy || "root-cms-client";
|
|
1230
|
+
await docRef.update({
|
|
1231
|
+
archivedAt: Timestamp2.now(),
|
|
1232
|
+
archivedBy
|
|
1233
|
+
});
|
|
1234
|
+
console.log(`archived data source: ${dataSourceId}`);
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Unarchives a data source.
|
|
1238
|
+
*/
|
|
1239
|
+
async unarchiveDataSource(dataSourceId) {
|
|
1240
|
+
const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}`;
|
|
1241
|
+
const docRef = this.db.doc(dbPath);
|
|
1242
|
+
await docRef.update({
|
|
1243
|
+
archivedAt: FieldValue2.delete(),
|
|
1244
|
+
archivedBy: FieldValue2.delete()
|
|
1245
|
+
});
|
|
1246
|
+
console.log(`unarchived data source: ${dataSourceId}`);
|
|
1247
|
+
}
|
|
1508
1248
|
/**
|
|
1509
1249
|
* Syncs a data source to draft state.
|
|
1510
1250
|
*/
|
|
@@ -1513,6 +1253,9 @@ ${errorMessages}`);
|
|
|
1513
1253
|
if (!dataSource) {
|
|
1514
1254
|
throw new Error(`data source not found: ${dataSourceId}`);
|
|
1515
1255
|
}
|
|
1256
|
+
if (dataSource.archivedAt) {
|
|
1257
|
+
throw new Error(`data source is archived: ${dataSourceId}`);
|
|
1258
|
+
}
|
|
1516
1259
|
const result = await this.fetchData(dataSource);
|
|
1517
1260
|
const dataSourceDocRef = this.db.doc(
|
|
1518
1261
|
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
@@ -1545,6 +1288,9 @@ ${errorMessages}`);
|
|
|
1545
1288
|
if (!dataSource) {
|
|
1546
1289
|
throw new Error(`data source not found: ${dataSourceId}`);
|
|
1547
1290
|
}
|
|
1291
|
+
if (dataSource.archivedAt) {
|
|
1292
|
+
throw new Error(`data source is archived: ${dataSourceId}`);
|
|
1293
|
+
}
|
|
1548
1294
|
const dataSourceDocRef = this.db.doc(
|
|
1549
1295
|
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
1550
1296
|
);
|
|
@@ -1578,6 +1324,40 @@ ${errorMessages}`);
|
|
|
1578
1324
|
console.log(`published data ${dataSourceId}`);
|
|
1579
1325
|
console.log(`published by: ${publishedBy}`);
|
|
1580
1326
|
}
|
|
1327
|
+
/**
|
|
1328
|
+
* Unpublishes a data source. Removes the `publishedAt`/`publishedBy`
|
|
1329
|
+
* metadata from the DataSource doc and deletes the `Data/published` doc.
|
|
1330
|
+
*/
|
|
1331
|
+
async unpublishDataSource(dataSourceId) {
|
|
1332
|
+
const dataSource = await this.getDataSource(dataSourceId);
|
|
1333
|
+
if (!dataSource) {
|
|
1334
|
+
throw new Error(`data source not found: ${dataSourceId}`);
|
|
1335
|
+
}
|
|
1336
|
+
const dataSourceDocRef = this.db.doc(
|
|
1337
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
1338
|
+
);
|
|
1339
|
+
const dataDocRefDraft = this.db.doc(
|
|
1340
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}/Data/draft`
|
|
1341
|
+
);
|
|
1342
|
+
const dataDocRefPublished = this.db.doc(
|
|
1343
|
+
`Projects/${this.projectId}/DataSources/${dataSourceId}/Data/published`
|
|
1344
|
+
);
|
|
1345
|
+
const batch = this.db.batch();
|
|
1346
|
+
batch.update(dataSourceDocRef, {
|
|
1347
|
+
publishedAt: FieldValue2.delete(),
|
|
1348
|
+
publishedBy: FieldValue2.delete()
|
|
1349
|
+
});
|
|
1350
|
+
const draftSnapshot = await dataDocRefDraft.get();
|
|
1351
|
+
if (draftSnapshot.exists) {
|
|
1352
|
+
batch.update(dataDocRefDraft, {
|
|
1353
|
+
"dataSource.publishedAt": FieldValue2.delete(),
|
|
1354
|
+
"dataSource.publishedBy": FieldValue2.delete()
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
batch.delete(dataDocRefPublished);
|
|
1358
|
+
await batch.commit();
|
|
1359
|
+
console.log(`unpublished data source: ${dataSourceId}`);
|
|
1360
|
+
}
|
|
1581
1361
|
async publishDataSources(dataSourceIds, options) {
|
|
1582
1362
|
const publishedBy = options?.publishedBy || "root-cms-client";
|
|
1583
1363
|
const batch = options?.batch || this.db.batch();
|
|
@@ -1586,6 +1366,9 @@ ${errorMessages}`);
|
|
|
1586
1366
|
if (!dataSource) {
|
|
1587
1367
|
throw new Error(`data source not found: ${id}`);
|
|
1588
1368
|
}
|
|
1369
|
+
if (dataSource.archivedAt) {
|
|
1370
|
+
throw new Error(`data source is archived: ${id}`);
|
|
1371
|
+
}
|
|
1589
1372
|
const dataSourceDocRef = this.db.doc(
|
|
1590
1373
|
`Projects/${this.projectId}/DataSources/${id}`
|
|
1591
1374
|
);
|
|
@@ -1751,7 +1534,14 @@ ${errorMessages}`);
|
|
|
1751
1534
|
const docRef = this.dbDataSourceDataRef(dataSourceId, { mode });
|
|
1752
1535
|
const doc = await docRef.get();
|
|
1753
1536
|
if (doc.exists) {
|
|
1754
|
-
|
|
1537
|
+
const dataSourceData = doc.data();
|
|
1538
|
+
if (dataSourceData.dataSource?.archivedAt) {
|
|
1539
|
+
const archivedBy = dataSourceData.dataSource.archivedBy;
|
|
1540
|
+
console.warn(
|
|
1541
|
+
`warning: data source "${dataSourceId}" is archived` + (archivedBy ? ` (archived by ${archivedBy})` : "")
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1544
|
+
return dataSourceData;
|
|
1755
1545
|
}
|
|
1756
1546
|
return null;
|
|
1757
1547
|
}
|
|
@@ -55,10 +55,10 @@ function testValidCollectionId(id) {
|
|
|
55
55
|
function isSchemaPattern(value) {
|
|
56
56
|
return typeof value === "object" && value !== null && "_schemaPattern" in value && value._schemaPattern === true;
|
|
57
57
|
}
|
|
58
|
-
function buildSchemaNameMap() {
|
|
58
|
+
function buildSchemaNameMap(schemaModules = SCHEMA_MODULES) {
|
|
59
59
|
const nameMap = {};
|
|
60
|
-
for (const fileId in
|
|
61
|
-
const module =
|
|
60
|
+
for (const fileId in schemaModules) {
|
|
61
|
+
const module = schemaModules[fileId];
|
|
62
62
|
if (module.default && module.default.name) {
|
|
63
63
|
nameMap[module.default.name] = module.default;
|
|
64
64
|
}
|
|
@@ -69,16 +69,16 @@ function globToRegex(pattern) {
|
|
|
69
69
|
const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{DOUBLE_STAR}}").replace(/\*/g, "[^/]*").replace(/\{\{DOUBLE_STAR\}\}/g, ".*");
|
|
70
70
|
return new RegExp(`^${regexStr}$`);
|
|
71
71
|
}
|
|
72
|
-
function resolveSchemaPattern(pattern) {
|
|
72
|
+
function resolveSchemaPattern(pattern, schemaModules = SCHEMA_MODULES) {
|
|
73
73
|
const regex = globToRegex(pattern.pattern);
|
|
74
74
|
const excludeSet = new Set(pattern.exclude || []);
|
|
75
75
|
const names = [];
|
|
76
76
|
const schemas = {};
|
|
77
|
-
for (const fileId in
|
|
77
|
+
for (const fileId in schemaModules) {
|
|
78
78
|
if (!regex.test(fileId)) {
|
|
79
79
|
continue;
|
|
80
80
|
}
|
|
81
|
-
const module =
|
|
81
|
+
const module = schemaModules[fileId];
|
|
82
82
|
if (!module.default || !module.default.name) {
|
|
83
83
|
continue;
|
|
84
84
|
}
|
|
@@ -86,28 +86,25 @@ function resolveSchemaPattern(pattern) {
|
|
|
86
86
|
if (excludeSet.has(schemaName)) {
|
|
87
87
|
continue;
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
const schemaObj = structuredClone(module.default);
|
|
90
90
|
if (pattern.omitFields && pattern.omitFields.length > 0) {
|
|
91
91
|
const omitSet = new Set(pattern.omitFields);
|
|
92
|
-
schemaObj =
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
(f) => !omitSet.has(f.id || "")
|
|
96
|
-
)
|
|
97
|
-
};
|
|
92
|
+
schemaObj.fields = schemaObj.fields.filter(
|
|
93
|
+
(f) => !omitSet.has(f.id || "")
|
|
94
|
+
);
|
|
98
95
|
}
|
|
99
96
|
names.push(schemaName);
|
|
100
97
|
schemas[schemaName] = schemaObj;
|
|
101
98
|
}
|
|
102
99
|
return { names, schemas };
|
|
103
100
|
}
|
|
104
|
-
function convertOneOfTypes(collection) {
|
|
101
|
+
function convertOneOfTypes(collection, schemaModules = SCHEMA_MODULES) {
|
|
105
102
|
const clone = structuredClone(collection);
|
|
106
103
|
const types = clone.types || {};
|
|
107
|
-
const schemaNameMap = buildSchemaNameMap();
|
|
104
|
+
const schemaNameMap = buildSchemaNameMap(schemaModules);
|
|
108
105
|
function handleOneOfField(field) {
|
|
109
106
|
if (isSchemaPattern(field.types)) {
|
|
110
|
-
const resolved = resolveSchemaPattern(field.types);
|
|
107
|
+
const resolved = resolveSchemaPattern(field.types, schemaModules);
|
|
111
108
|
for (const [name, schemaObj] of Object.entries(resolved.schemas)) {
|
|
112
109
|
if (!types[name]) {
|
|
113
110
|
types[name] = schemaObj;
|
|
@@ -124,7 +121,7 @@ function convertOneOfTypes(collection) {
|
|
|
124
121
|
if (typeof sub === "string") {
|
|
125
122
|
names.push(sub);
|
|
126
123
|
if (!types[sub] && schemaNameMap[sub]) {
|
|
127
|
-
const resolvedSchema = schemaNameMap[sub];
|
|
124
|
+
const resolvedSchema = structuredClone(schemaNameMap[sub]);
|
|
128
125
|
types[sub] = resolvedSchema;
|
|
129
126
|
if (resolvedSchema.fields) {
|
|
130
127
|
walk(resolvedSchema);
|
|
@@ -166,5 +163,6 @@ export {
|
|
|
166
163
|
SCHEMA_MODULES,
|
|
167
164
|
getProjectSchemas,
|
|
168
165
|
resolveOneOfPatterns,
|
|
169
|
-
getCollectionSchema
|
|
166
|
+
getCollectionSchema,
|
|
167
|
+
convertOneOfTypes
|
|
170
168
|
};
|