@byline/core 0.9.3
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/LICENSE +373 -0
- package/README.md +17 -0
- package/dist/@types/admin-types.d.ts +275 -0
- package/dist/@types/admin-types.d.ts.map +1 -0
- package/dist/@types/admin-types.js +18 -0
- package/dist/@types/admin-types.js.map +1 -0
- package/dist/@types/collection-types.d.ts +816 -0
- package/dist/@types/collection-types.d.ts.map +1 -0
- package/dist/@types/collection-types.js +217 -0
- package/dist/@types/collection-types.js.map +1 -0
- package/dist/@types/db-types.d.ts +463 -0
- package/dist/@types/db-types.d.ts.map +1 -0
- package/dist/@types/db-types.js +2 -0
- package/dist/@types/db-types.js.map +1 -0
- package/dist/@types/field-data-types.d.ts +147 -0
- package/dist/@types/field-data-types.d.ts.map +1 -0
- package/dist/@types/field-data-types.js +38 -0
- package/dist/@types/field-data-types.js.map +1 -0
- package/dist/@types/field-types.d.ts +579 -0
- package/dist/@types/field-types.d.ts.map +1 -0
- package/dist/@types/field-types.js +32 -0
- package/dist/@types/field-types.js.map +1 -0
- package/dist/@types/index.d.ts +18 -0
- package/dist/@types/index.d.ts.map +1 -0
- package/dist/@types/index.js +18 -0
- package/dist/@types/index.js.map +1 -0
- package/dist/@types/populate-types.d.ts +54 -0
- package/dist/@types/populate-types.d.ts.map +1 -0
- package/dist/@types/populate-types.js +9 -0
- package/dist/@types/populate-types.js.map +1 -0
- package/dist/@types/query-predicate.d.ts +74 -0
- package/dist/@types/query-predicate.d.ts.map +1 -0
- package/dist/@types/query-predicate.js +9 -0
- package/dist/@types/query-predicate.js.map +1 -0
- package/dist/@types/site-config.d.ts +212 -0
- package/dist/@types/site-config.d.ts.map +1 -0
- package/dist/@types/site-config.js +9 -0
- package/dist/@types/site-config.js.map +1 -0
- package/dist/@types/storage-types.d.ts +86 -0
- package/dist/@types/storage-types.d.ts.map +1 -0
- package/dist/@types/storage-types.js +9 -0
- package/dist/@types/storage-types.js.map +1 -0
- package/dist/@types/store-types.d.ts +134 -0
- package/dist/@types/store-types.d.ts.map +1 -0
- package/dist/@types/store-types.js +24 -0
- package/dist/@types/store-types.js.map +1 -0
- package/dist/@types/type-utils.d.ts +17 -0
- package/dist/@types/type-utils.d.ts.map +1 -0
- package/dist/@types/type-utils.js +9 -0
- package/dist/@types/type-utils.js.map +1 -0
- package/dist/auth/apply-before-read.d.ts +36 -0
- package/dist/auth/apply-before-read.d.ts.map +1 -0
- package/dist/auth/apply-before-read.js +68 -0
- package/dist/auth/apply-before-read.js.map +1 -0
- package/dist/auth/apply-before-read.test.node.d.ts +9 -0
- package/dist/auth/apply-before-read.test.node.d.ts.map +1 -0
- package/dist/auth/apply-before-read.test.node.js +144 -0
- package/dist/auth/apply-before-read.test.node.js.map +1 -0
- package/dist/auth/assert-actor-can-perform.d.ts +39 -0
- package/dist/auth/assert-actor-can-perform.d.ts.map +1 -0
- package/dist/auth/assert-actor-can-perform.js +64 -0
- package/dist/auth/assert-actor-can-perform.js.map +1 -0
- package/dist/auth/assert-actor-can-perform.test.node.d.ts +9 -0
- package/dist/auth/assert-actor-can-perform.test.node.d.ts.map +1 -0
- package/dist/auth/assert-actor-can-perform.test.node.js +119 -0
- package/dist/auth/assert-actor-can-perform.test.node.js.map +1 -0
- package/dist/auth/index.d.ts +11 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/register-collection-abilities.d.ts +40 -0
- package/dist/auth/register-collection-abilities.d.ts.map +1 -0
- package/dist/auth/register-collection-abilities.js +87 -0
- package/dist/auth/register-collection-abilities.js.map +1 -0
- package/dist/auth/register-collection-abilities.test.node.d.ts +9 -0
- package/dist/auth/register-collection-abilities.test.node.d.ts.map +1 -0
- package/dist/auth/register-collection-abilities.test.node.js +124 -0
- package/dist/auth/register-collection-abilities.test.node.js.map +1 -0
- package/dist/config/config.d.ts +10 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +108 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/routes.d.ts +16 -0
- package/dist/config/routes.d.ts.map +1 -0
- package/dist/config/routes.js +26 -0
- package/dist/config/routes.js.map +1 -0
- package/dist/config/validate-admin-configs.d.ts +33 -0
- package/dist/config/validate-admin-configs.d.ts.map +1 -0
- package/dist/config/validate-admin-configs.js +250 -0
- package/dist/config/validate-admin-configs.js.map +1 -0
- package/dist/config/validate-admin-configs.test.node.d.ts +9 -0
- package/dist/config/validate-admin-configs.test.node.d.ts.map +1 -0
- package/dist/config/validate-admin-configs.test.node.js +224 -0
- package/dist/config/validate-admin-configs.test.node.js.map +1 -0
- package/dist/config/validate-collections.d.ts +33 -0
- package/dist/config/validate-collections.d.ts.map +1 -0
- package/dist/config/validate-collections.js +70 -0
- package/dist/config/validate-collections.js.map +1 -0
- package/dist/config/validate-collections.test.node.d.ts +9 -0
- package/dist/config/validate-collections.test.node.d.ts.map +1 -0
- package/dist/config/validate-collections.test.node.js +149 -0
- package/dist/config/validate-collections.test.node.js.map +1 -0
- package/dist/core.d.ts +89 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +99 -0
- package/dist/core.js.map +1 -0
- package/dist/defaults/default-values.d.ts +13 -0
- package/dist/defaults/default-values.d.ts.map +1 -0
- package/dist/defaults/default-values.js +60 -0
- package/dist/defaults/default-values.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/errors.d.ts +98 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +134 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/logger.d.ts +62 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +120 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/registry.d.ts +65 -0
- package/dist/lib/registry.d.ts.map +1 -0
- package/dist/lib/registry.js +133 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/logger/index.d.ts +3 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +3 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/patches/apply-patches.d.ts +21 -0
- package/dist/patches/apply-patches.d.ts.map +1 -0
- package/dist/patches/apply-patches.js +357 -0
- package/dist/patches/apply-patches.js.map +1 -0
- package/dist/patches/index.d.ts +3 -0
- package/dist/patches/index.d.ts.map +1 -0
- package/dist/patches/index.js +4 -0
- package/dist/patches/index.js.map +1 -0
- package/dist/patches/patch-types.d.ts +82 -0
- package/dist/patches/patch-types.d.ts.map +1 -0
- package/dist/patches/patch-types.js +3 -0
- package/dist/patches/patch-types.js.map +1 -0
- package/dist/patches/patch.test.node.d.ts +2 -0
- package/dist/patches/patch.test.node.d.ts.map +1 -0
- package/dist/patches/patch.test.node.js +193 -0
- package/dist/patches/patch.test.node.js.map +1 -0
- package/dist/query/parse-where.d.ts +100 -0
- package/dist/query/parse-where.d.ts.map +1 -0
- package/dist/query/parse-where.js +352 -0
- package/dist/query/parse-where.js.map +1 -0
- package/dist/query/parse-where.test.node.d.ts +9 -0
- package/dist/query/parse-where.test.node.d.ts.map +1 -0
- package/dist/query/parse-where.test.node.js +581 -0
- package/dist/query/parse-where.test.node.js.map +1 -0
- package/dist/schemas/zod/builder.d.ts +466 -0
- package/dist/schemas/zod/builder.d.ts.map +1 -0
- package/dist/schemas/zod/builder.js +276 -0
- package/dist/schemas/zod/builder.js.map +1 -0
- package/dist/schemas/zod/cache.d.ts +14 -0
- package/dist/schemas/zod/cache.d.ts.map +1 -0
- package/dist/schemas/zod/cache.js +40 -0
- package/dist/schemas/zod/cache.js.map +1 -0
- package/dist/schemas/zod/index.d.ts +4 -0
- package/dist/schemas/zod/index.d.ts.map +1 -0
- package/dist/schemas/zod/index.js +4 -0
- package/dist/schemas/zod/index.js.map +1 -0
- package/dist/schemas/zod/types.d.ts +13 -0
- package/dist/schemas/zod/types.d.ts.map +1 -0
- package/dist/schemas/zod/types.js +2 -0
- package/dist/schemas/zod/types.js.map +1 -0
- package/dist/services/collection-bootstrap.d.ts +46 -0
- package/dist/services/collection-bootstrap.d.ts.map +1 -0
- package/dist/services/collection-bootstrap.js +108 -0
- package/dist/services/collection-bootstrap.js.map +1 -0
- package/dist/services/collection-bootstrap.test.node.d.ts +9 -0
- package/dist/services/collection-bootstrap.test.node.d.ts.map +1 -0
- package/dist/services/collection-bootstrap.test.node.js +208 -0
- package/dist/services/collection-bootstrap.test.node.js.map +1 -0
- package/dist/services/document-lifecycle.d.ts +245 -0
- package/dist/services/document-lifecycle.d.ts.map +1 -0
- package/dist/services/document-lifecycle.js +481 -0
- package/dist/services/document-lifecycle.js.map +1 -0
- package/dist/services/document-lifecycle.test.node.d.ts +9 -0
- package/dist/services/document-lifecycle.test.node.d.ts.map +1 -0
- package/dist/services/document-lifecycle.test.node.js +781 -0
- package/dist/services/document-lifecycle.test.node.js.map +1 -0
- package/dist/services/document-read.d.ts +26 -0
- package/dist/services/document-read.d.ts.map +1 -0
- package/dist/services/document-read.js +60 -0
- package/dist/services/document-read.js.map +1 -0
- package/dist/services/field-upload.d.ts +100 -0
- package/dist/services/field-upload.d.ts.map +1 -0
- package/dist/services/field-upload.js +328 -0
- package/dist/services/field-upload.js.map +1 -0
- package/dist/services/field-upload.test.node.d.ts +9 -0
- package/dist/services/field-upload.test.node.d.ts.map +1 -0
- package/dist/services/field-upload.test.node.js +337 -0
- package/dist/services/field-upload.test.node.js.map +1 -0
- package/dist/services/index.d.ts +10 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +11 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/populate.d.ts +299 -0
- package/dist/services/populate.d.ts.map +1 -0
- package/dist/services/populate.js +484 -0
- package/dist/services/populate.js.map +1 -0
- package/dist/services/populate.test.node.d.ts +9 -0
- package/dist/services/populate.test.node.d.ts.map +1 -0
- package/dist/services/populate.test.node.js +910 -0
- package/dist/services/populate.test.node.js.map +1 -0
- package/dist/services/relation-projection.d.ts +52 -0
- package/dist/services/relation-projection.d.ts.map +1 -0
- package/dist/services/relation-projection.js +81 -0
- package/dist/services/relation-projection.js.map +1 -0
- package/dist/services/richtext-populate.d.ts +87 -0
- package/dist/services/richtext-populate.d.ts.map +1 -0
- package/dist/services/richtext-populate.js +189 -0
- package/dist/services/richtext-populate.js.map +1 -0
- package/dist/services/richtext-populate.test.node.d.ts +9 -0
- package/dist/services/richtext-populate.test.node.d.ts.map +1 -0
- package/dist/services/richtext-populate.test.node.js +197 -0
- package/dist/services/richtext-populate.test.node.js.map +1 -0
- package/dist/storage/collection-fingerprint.d.ts +21 -0
- package/dist/storage/collection-fingerprint.d.ts.map +1 -0
- package/dist/storage/collection-fingerprint.js +172 -0
- package/dist/storage/collection-fingerprint.js.map +1 -0
- package/dist/storage/collection-fingerprint.test.node.d.ts +9 -0
- package/dist/storage/collection-fingerprint.test.node.d.ts.map +1 -0
- package/dist/storage/collection-fingerprint.test.node.js +256 -0
- package/dist/storage/collection-fingerprint.test.node.js.map +1 -0
- package/dist/storage/field-store-map.d.ts +59 -0
- package/dist/storage/field-store-map.d.ts.map +1 -0
- package/dist/storage/field-store-map.js +75 -0
- package/dist/storage/field-store-map.js.map +1 -0
- package/dist/storage/field-store-map.test.node.d.ts +9 -0
- package/dist/storage/field-store-map.test.node.d.ts.map +1 -0
- package/dist/storage/field-store-map.test.node.js +117 -0
- package/dist/storage/field-store-map.test.node.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +10 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/utils/normalise-dates.d.ts +15 -0
- package/dist/utils/normalise-dates.d.ts.map +1 -0
- package/dist/utils/normalise-dates.js +22 -0
- package/dist/utils/normalise-dates.js.map +1 -0
- package/dist/utils/slugify.d.ts +56 -0
- package/dist/utils/slugify.d.ts.map +1 -0
- package/dist/utils/slugify.js +91 -0
- package/dist/utils/slugify.js.map +1 -0
- package/dist/utils/slugify.test.node.d.ts +9 -0
- package/dist/utils/slugify.test.node.d.ts.map +1 -0
- package/dist/utils/slugify.test.node.js +86 -0
- package/dist/utils/slugify.test.node.js.map +1 -0
- package/dist/utils/storage-utils.d.ts +36 -0
- package/dist/utils/storage-utils.d.ts.map +1 -0
- package/dist/utils/storage-utils.js +38 -0
- package/dist/utils/storage-utils.js.map +1 -0
- package/dist/utils/utils.general.d.ts +64 -0
- package/dist/utils/utils.general.d.ts.map +1 -0
- package/dist/utils/utils.general.js +219 -0
- package/dist/utils/utils.general.js.map +1 -0
- package/dist/validation/index.d.ts +9 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +9 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/shared.d.ts +36 -0
- package/dist/validation/shared.d.ts.map +1 -0
- package/dist/validation/shared.js +42 -0
- package/dist/validation/shared.js.map +1 -0
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +3 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/workflow.d.ts +40 -0
- package/dist/workflow/workflow.d.ts.map +1 -0
- package/dist/workflow/workflow.js +96 -0
- package/dist/workflow/workflow.js.map +1 -0
- package/dist/workflow/workflow.test.node.d.ts +2 -0
- package/dist/workflow/workflow.test.node.d.ts.map +1 -0
- package/dist/workflow/workflow.test.node.js +198 -0
- package/dist/workflow/workflow.test.node.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import { REQUIRED_WORKFLOW_STATUSES } from '../../@types/index.js';
|
|
3
|
+
import { getCollectionDefinition } from '../../config/config.js';
|
|
4
|
+
// Helper function to apply custom validation rules
|
|
5
|
+
const applyValidationRules = (schema, rules) => {
|
|
6
|
+
return rules.reduce((acc, rule) => {
|
|
7
|
+
switch (rule.type) {
|
|
8
|
+
case 'email':
|
|
9
|
+
return acc.describe(rule.message || 'Invalid email address');
|
|
10
|
+
case 'url':
|
|
11
|
+
return acc.describe(rule.message || 'Invalid URL');
|
|
12
|
+
case 'pattern':
|
|
13
|
+
return acc.regex(new RegExp(rule.value), rule.message);
|
|
14
|
+
case 'custom':
|
|
15
|
+
return acc.refine(rule.value, { message: rule.message });
|
|
16
|
+
default:
|
|
17
|
+
return acc;
|
|
18
|
+
}
|
|
19
|
+
}, schema);
|
|
20
|
+
};
|
|
21
|
+
// Helper function to apply text field validation
|
|
22
|
+
const applyTextValidation = (schema, field) => {
|
|
23
|
+
let validatedSchema = schema;
|
|
24
|
+
if (field.validation?.minLength) {
|
|
25
|
+
validatedSchema = validatedSchema.min(field.validation.minLength);
|
|
26
|
+
}
|
|
27
|
+
if (field.validation?.maxLength) {
|
|
28
|
+
validatedSchema = validatedSchema.max(field.validation.maxLength);
|
|
29
|
+
}
|
|
30
|
+
if (field.validation?.pattern) {
|
|
31
|
+
validatedSchema = validatedSchema.regex(new RegExp(field.validation.pattern));
|
|
32
|
+
}
|
|
33
|
+
return validatedSchema;
|
|
34
|
+
};
|
|
35
|
+
// Helper function to apply datetime validation
|
|
36
|
+
const _applyDateTimeValidation = (schema, _field) => {
|
|
37
|
+
// TODO: Implement specific datetime validation if needed
|
|
38
|
+
const validatedSchema = schema;
|
|
39
|
+
return validatedSchema;
|
|
40
|
+
};
|
|
41
|
+
// Convert a single field to a Zod schema.
|
|
42
|
+
// When strict=true (write operations: create/update), field.optional is
|
|
43
|
+
// respected (required fields are actually required).
|
|
44
|
+
// When strict=false (read operations: list/get/history), all fields are
|
|
45
|
+
// nullable+optional regardless — this means adding a required field to an
|
|
46
|
+
// existing collection never breaks reads of older documents that were
|
|
47
|
+
// stored before the field existed.
|
|
48
|
+
export const fieldToZodSchema = (field, strict = true) => {
|
|
49
|
+
let schema;
|
|
50
|
+
switch (field.type) {
|
|
51
|
+
case 'array':
|
|
52
|
+
schema = z.any().array();
|
|
53
|
+
break;
|
|
54
|
+
case 'text': {
|
|
55
|
+
let textSchema = z.string();
|
|
56
|
+
textSchema = applyTextValidation(textSchema, field);
|
|
57
|
+
if (field.validation?.rules) {
|
|
58
|
+
textSchema = applyValidationRules(textSchema, field.validation.rules);
|
|
59
|
+
}
|
|
60
|
+
schema = textSchema;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case 'boolean':
|
|
64
|
+
case 'checkbox':
|
|
65
|
+
schema = z.boolean();
|
|
66
|
+
break;
|
|
67
|
+
case 'select':
|
|
68
|
+
if (field.options && field.options.length > 0) {
|
|
69
|
+
const values = field.options.map((opt) => opt.value);
|
|
70
|
+
schema = z.enum(values);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
schema = z.string();
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
case 'datetime': {
|
|
77
|
+
const dateSchema = z.preprocess((val) => (val === '' || val == null ? null : val), z.coerce.date().refine((val) => val.toString() !== 'Invalid Date', {
|
|
78
|
+
message: 'Invalid date',
|
|
79
|
+
}));
|
|
80
|
+
// TODO: Implement specific datetime validation if needed
|
|
81
|
+
// dateSchema = applyDateTimeValidation(dateTimeSchema, field)
|
|
82
|
+
schema = dateSchema;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case 'richText': {
|
|
86
|
+
const richTextSchema = z.any();
|
|
87
|
+
// TODO: Implement rich text validation if needed
|
|
88
|
+
// if (field.validation?.minLength || field.validation?.maxLength) {
|
|
89
|
+
// // Convert to string for validation if needed
|
|
90
|
+
// richTextSchema = z.string()
|
|
91
|
+
// if (field.validation.minLength) {
|
|
92
|
+
// richTextSchema = (richTextSchema as z.ZodString).min(field.validation.minLength)
|
|
93
|
+
// }
|
|
94
|
+
// if (field.validation.maxLength) {
|
|
95
|
+
// richTextSchema = (richTextSchema as z.ZodString).max(field.validation.maxLength)
|
|
96
|
+
// }
|
|
97
|
+
// }
|
|
98
|
+
schema = richTextSchema;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case 'textArea': {
|
|
102
|
+
let textAreaSchema = z.string();
|
|
103
|
+
if (field.validation?.minLength) {
|
|
104
|
+
textAreaSchema = textAreaSchema.min(field.validation.minLength);
|
|
105
|
+
}
|
|
106
|
+
if (field.validation?.maxLength) {
|
|
107
|
+
textAreaSchema = textAreaSchema.max(field.validation.maxLength);
|
|
108
|
+
}
|
|
109
|
+
schema = textAreaSchema;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'integer':
|
|
113
|
+
schema = z.number().int();
|
|
114
|
+
break;
|
|
115
|
+
case 'float':
|
|
116
|
+
case 'decimal':
|
|
117
|
+
schema = z.number();
|
|
118
|
+
break;
|
|
119
|
+
case 'image':
|
|
120
|
+
case 'file': {
|
|
121
|
+
// StoredFileValue — the object written by the upload endpoint and
|
|
122
|
+
// stored in the typed store_* tables. Use .passthrough() so schema
|
|
123
|
+
// evolution (new fields) doesn't break existing documents.
|
|
124
|
+
schema = z
|
|
125
|
+
.object({
|
|
126
|
+
fileId: z.string(),
|
|
127
|
+
filename: z.string(),
|
|
128
|
+
originalFilename: z.string(),
|
|
129
|
+
mimeType: z.string(),
|
|
130
|
+
fileSize: z.string(),
|
|
131
|
+
storageProvider: z.string(),
|
|
132
|
+
storagePath: z.string(),
|
|
133
|
+
storageUrl: z.string().nullable().optional(),
|
|
134
|
+
fileHash: z.string().nullable().optional(),
|
|
135
|
+
imageWidth: z.number().nullable().optional(),
|
|
136
|
+
imageHeight: z.number().nullable().optional(),
|
|
137
|
+
imageFormat: z.string().nullable().optional(),
|
|
138
|
+
processingStatus: z.enum(['pending', 'processing', 'complete', 'failed']),
|
|
139
|
+
thumbnailGenerated: z.boolean().optional(),
|
|
140
|
+
})
|
|
141
|
+
.passthrough();
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case 'blocks':
|
|
145
|
+
schema = z.any().array();
|
|
146
|
+
break;
|
|
147
|
+
case 'group':
|
|
148
|
+
// Group fields are complex nested structures validated at the
|
|
149
|
+
// field-renderer level. The shape depends on the group's child fields
|
|
150
|
+
// (recursive) and is not constrained here.
|
|
151
|
+
schema = z.any();
|
|
152
|
+
break;
|
|
153
|
+
case 'relation':
|
|
154
|
+
// Relation values are `RelatedDocumentValue` objects:
|
|
155
|
+
// { targetDocumentId, targetCollectionId,
|
|
156
|
+
// relationshipType?, cascadeDelete? }
|
|
157
|
+
// Values come from the picker (UUIDs) or from DB reads (also UUIDs),
|
|
158
|
+
// but tests may use shorter strings — keep the schema shape-strict
|
|
159
|
+
// without enforcing UUID format so synthetic fixtures still validate.
|
|
160
|
+
//
|
|
161
|
+
// Populated responses (depth > 0) skip this schema in the route layer
|
|
162
|
+
// because the tree then contains nested documents, not bare refs.
|
|
163
|
+
schema = z
|
|
164
|
+
.object({
|
|
165
|
+
targetDocumentId: z.string(),
|
|
166
|
+
targetCollectionId: z.string(),
|
|
167
|
+
relationshipType: z.string().optional(),
|
|
168
|
+
cascadeDelete: z.boolean().optional(),
|
|
169
|
+
})
|
|
170
|
+
.nullable();
|
|
171
|
+
break;
|
|
172
|
+
default:
|
|
173
|
+
schema = z.string();
|
|
174
|
+
}
|
|
175
|
+
// In strict mode respect field.optional; in lenient mode always allow null/undefined so reads
|
|
176
|
+
// never fail on schema-evolved documents.
|
|
177
|
+
return strict && !field.optional ? schema : schema.nullable().optional();
|
|
178
|
+
};
|
|
179
|
+
// Create the base schema that all collections share.
|
|
180
|
+
// When a collection defines a workflow, status is constrained to its status names;
|
|
181
|
+
// otherwise it falls back to the required statuses (draft, published, archived).
|
|
182
|
+
export const createBaseSchema = (collection) => {
|
|
183
|
+
const statuses = collection?.workflow?.statuses?.map((s) => s.name) ??
|
|
184
|
+
[...REQUIRED_WORKFLOW_STATUSES];
|
|
185
|
+
// z.enum requires a non-empty tuple [string, ...string[]]
|
|
186
|
+
const statusEnum = z.enum([statuses[0], ...statuses.slice(1)]);
|
|
187
|
+
return z.object({
|
|
188
|
+
id: z.uuid(),
|
|
189
|
+
versionId: z.uuid().optional(),
|
|
190
|
+
path: z.string().optional(),
|
|
191
|
+
status: statusEnum,
|
|
192
|
+
hasPublishedVersion: z.boolean().optional(),
|
|
193
|
+
createdAt: z.iso.datetime(),
|
|
194
|
+
updatedAt: z.iso.datetime(),
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
// Create field schemas for a collection.
|
|
198
|
+
// strict=true → required fields are non-nullable (write / validation use)
|
|
199
|
+
// strict=false → all fields are nullable+optional (read / serialisation use)
|
|
200
|
+
export const createFieldsSchema = (fields, strict = true) => {
|
|
201
|
+
// Use ZodType<any> so the inferred object output is { [x: string]: any }
|
|
202
|
+
// rather than { [x: string]: unknown } (Zod v4 defaults ZodType to <unknown>).
|
|
203
|
+
// This keeps the schema assignable through TanStack Start's serialisation boundary.
|
|
204
|
+
const fieldsSchemaShape = {};
|
|
205
|
+
for (const field of fields) {
|
|
206
|
+
fieldsSchemaShape[field.name] = fieldToZodSchema(field, strict);
|
|
207
|
+
}
|
|
208
|
+
return z.object(fieldsSchemaShape);
|
|
209
|
+
};
|
|
210
|
+
// Create pagination/list metadata schema
|
|
211
|
+
export const createListMetaSchema = () => z.object({
|
|
212
|
+
page: z.number().int().positive(),
|
|
213
|
+
pageSize: z.number().int().positive(),
|
|
214
|
+
total: z.number().int().nonnegative(),
|
|
215
|
+
totalPages: z.number().int().nonnegative(),
|
|
216
|
+
order: z.string().optional(),
|
|
217
|
+
desc: z.boolean().optional(),
|
|
218
|
+
});
|
|
219
|
+
// Create collection metadata schema
|
|
220
|
+
export const createCollectionMetaSchema = (collection) => z.object({
|
|
221
|
+
id: z.string(),
|
|
222
|
+
labels: z.object({
|
|
223
|
+
singular: z.string(),
|
|
224
|
+
plural: z.string(),
|
|
225
|
+
}),
|
|
226
|
+
path: z.literal(collection.path),
|
|
227
|
+
});
|
|
228
|
+
// Helper function to get collection definition before calling createCollectionSchemas
|
|
229
|
+
export const createCollectionSchemasForPath = (path) => {
|
|
230
|
+
const collectionDefinition = getCollectionDefinition(path);
|
|
231
|
+
if (collectionDefinition == null) {
|
|
232
|
+
throw new Error(`Collection not found for path: ${path}`);
|
|
233
|
+
}
|
|
234
|
+
return createCollectionSchemas(collectionDefinition);
|
|
235
|
+
};
|
|
236
|
+
// Main function to create all schemas for a collection
|
|
237
|
+
export const createCollectionSchemas = (collection) => {
|
|
238
|
+
const baseSchema = createBaseSchema(collection);
|
|
239
|
+
// Strict (write) — required fields are enforced.
|
|
240
|
+
const fieldsSchema = createFieldsSchema(collection.fields, true);
|
|
241
|
+
// Lenient (read) — all fields are nullable+optional so that older
|
|
242
|
+
// documents missing a newly-added required field never cause a parse
|
|
243
|
+
// error in list / get / history responses.
|
|
244
|
+
const fieldsSchemaLenient = createFieldsSchema(collection.fields, false);
|
|
245
|
+
const fullSchema = z.object({
|
|
246
|
+
...baseSchema.shape,
|
|
247
|
+
fields: fieldsSchema,
|
|
248
|
+
});
|
|
249
|
+
const fullSchemaLenient = z.object({
|
|
250
|
+
...baseSchema.shape,
|
|
251
|
+
fields: fieldsSchemaLenient,
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
base: baseSchema,
|
|
255
|
+
fields: fieldsSchema,
|
|
256
|
+
full: fullSchema,
|
|
257
|
+
list: z.object({
|
|
258
|
+
docs: z.array(fullSchemaLenient),
|
|
259
|
+
meta: createListMetaSchema(),
|
|
260
|
+
included: z.object({
|
|
261
|
+
collection: createCollectionMetaSchema(collection),
|
|
262
|
+
}),
|
|
263
|
+
}),
|
|
264
|
+
history: z.object({
|
|
265
|
+
docs: z.array(fullSchemaLenient),
|
|
266
|
+
meta: createListMetaSchema(),
|
|
267
|
+
}),
|
|
268
|
+
create: fieldsSchema,
|
|
269
|
+
get: fullSchemaLenient,
|
|
270
|
+
update: fieldsSchema.partial(),
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
// Aliases for consistency
|
|
274
|
+
export const createTypedCollectionSchemas = createCollectionSchemas;
|
|
275
|
+
export const createTypedCollectionSchemasForPath = createCollectionSchemasForPath;
|
|
276
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/schemas/zod/builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createTypedCollectionSchemas } from './builder.js';
|
|
2
|
+
import type { CollectionDefinition } from '../../@types/index.js';
|
|
3
|
+
type TypedSchemaSet = ReturnType<typeof createTypedCollectionSchemas>;
|
|
4
|
+
export declare const getCollectionSchemasForPath: (path: string) => TypedSchemaSet;
|
|
5
|
+
export declare const getCollectionSchemas: (collection: CollectionDefinition) => TypedSchemaSet;
|
|
6
|
+
export declare const getTypedCollectionSchemasForPath: (path: string) => TypedSchemaSet;
|
|
7
|
+
export declare const getTypedCollectionSchemas: (collection: CollectionDefinition) => TypedSchemaSet;
|
|
8
|
+
export declare const clearSchemaCache: (collectionPath?: string) => void;
|
|
9
|
+
export declare const getCacheStats: () => {
|
|
10
|
+
size: number;
|
|
11
|
+
keys: string[];
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/schemas/zod/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAEjE,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAIrE,eAAO,MAAM,2BAA2B,GAAI,MAAM,MAAM,KAAG,cAM1D,CAAA;AAGD,eAAO,MAAM,oBAAoB,GAAI,YAAY,oBAAoB,KAAG,cAQvE,CAAA;AAGD,eAAO,MAAM,gCAAgC,SApBK,MAAM,KAAG,cAoBgB,CAAA;AAC3E,eAAO,MAAM,yBAAyB,eAZW,oBAAoB,KAAG,cAYX,CAAA;AAG7D,eAAO,MAAM,gBAAgB,GAAI,iBAAiB,MAAM,KAAG,IAU1D,CAAA;AAGD,eAAO,MAAM,aAAa;;;CAGxB,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getCollectionDefinition } from '../../config/config.js';
|
|
2
|
+
import { createTypedCollectionSchemas } from './builder.js';
|
|
3
|
+
const schemaCache = new Map();
|
|
4
|
+
export const getCollectionSchemasForPath = (path) => {
|
|
5
|
+
const collectionDefinition = getCollectionDefinition(path);
|
|
6
|
+
if (collectionDefinition == null) {
|
|
7
|
+
throw new Error(`Collection not found for path: ${path}`);
|
|
8
|
+
}
|
|
9
|
+
return getCollectionSchemas(collectionDefinition);
|
|
10
|
+
};
|
|
11
|
+
// Get schemas for a collection (with caching)
|
|
12
|
+
export const getCollectionSchemas = (collection) => {
|
|
13
|
+
const cacheKey = collection.path;
|
|
14
|
+
if (schemaCache.has(cacheKey) === false) {
|
|
15
|
+
schemaCache.set(cacheKey, createTypedCollectionSchemas(collection));
|
|
16
|
+
}
|
|
17
|
+
return schemaCache.get(cacheKey) || createTypedCollectionSchemas(collection);
|
|
18
|
+
};
|
|
19
|
+
// Aliases for consistency (these are the same as above now)
|
|
20
|
+
export const getTypedCollectionSchemasForPath = getCollectionSchemasForPath;
|
|
21
|
+
export const getTypedCollectionSchemas = getCollectionSchemas;
|
|
22
|
+
// Clear cache for a specific collection or all collections
|
|
23
|
+
export const clearSchemaCache = (collectionPath) => {
|
|
24
|
+
if (collectionPath) {
|
|
25
|
+
for (const key of schemaCache.keys()) {
|
|
26
|
+
if (key === collectionPath) {
|
|
27
|
+
schemaCache.delete(key);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
schemaCache.clear();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
// Get cache statistics
|
|
36
|
+
export const getCacheStats = () => ({
|
|
37
|
+
size: schemaCache.size,
|
|
38
|
+
keys: Array.from(schemaCache.keys()),
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/schemas/zod/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAA;AAK3D,MAAM,WAAW,GAAG,IAAI,GAAG,EAA0B,CAAA;AAErD,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAY,EAAkB,EAAE;IAC1E,MAAM,oBAAoB,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IAC1D,IAAI,oBAAoB,IAAI,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAA;IAC3D,CAAC;IACD,OAAO,oBAAoB,CAAC,oBAAoB,CAAC,CAAA;AACnD,CAAC,CAAA;AAED,8CAA8C;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAgC,EAAkB,EAAE;IACvF,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAA;IAEhC,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,EAAE,CAAC;QACxC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAA;IACrE,CAAC;IAED,OAAO,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,4BAA4B,CAAC,UAAU,CAAC,CAAA;AAC9E,CAAC,CAAA;AAED,4DAA4D;AAC5D,MAAM,CAAC,MAAM,gCAAgC,GAAG,2BAA2B,CAAA;AAC3E,MAAM,CAAC,MAAM,yBAAyB,GAAG,oBAAoB,CAAA;AAE7D,2DAA2D;AAC3D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,cAAuB,EAAQ,EAAE;IAChE,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACrC,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;gBAC3B,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;AACH,CAAC,CAAA;AAED,uBAAuB;AACvB,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,CAAC;IAClC,IAAI,EAAE,WAAW,CAAC,IAAI;IACtB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;CACrC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/schemas/zod/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/schemas/zod/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { getCollectionSchemasForPath } from './cache.js';
|
|
3
|
+
export type CollectionSchemaTypes<T extends ReturnType<typeof getCollectionSchemasForPath>> = {
|
|
4
|
+
BaseType: z.infer<T['base']>;
|
|
5
|
+
FullType: z.infer<T['full']>;
|
|
6
|
+
ListType: z.infer<T['list']>;
|
|
7
|
+
HistoryType: z.infer<T['history']>;
|
|
8
|
+
CreateType: z.infer<T['create']>;
|
|
9
|
+
GetType: z.infer<T['get']>;
|
|
10
|
+
UpdateType: z.infer<T['update']>;
|
|
11
|
+
};
|
|
12
|
+
export type AnyCollectionSchemaTypes = CollectionSchemaTypes<ReturnType<typeof getCollectionSchemasForPath>>;
|
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/schemas/zod/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAG7D,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,UAAU,CAAC,OAAO,2BAA2B,CAAC,IAAI;IAC5F,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;IAClC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;CACjC,CAAA;AAGD,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,CAC1D,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAC/C,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/schemas/zod/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
import type { CollectionDefinition, IDbAdapter } from '../@types/index.js';
|
|
9
|
+
import type { BylineLogger } from '../lib/logger.js';
|
|
10
|
+
/**
|
|
11
|
+
* Snapshot of a collection's current registration: the DB row id, the
|
|
12
|
+
* schema version stamped on new `documentVersions` rows, and the fingerprint
|
|
13
|
+
* that was recorded the last time the bootstrap ran. Cached on the core
|
|
14
|
+
* instance for the lifetime of the process.
|
|
15
|
+
*/
|
|
16
|
+
export interface CollectionRecord {
|
|
17
|
+
collectionId: string;
|
|
18
|
+
version: number;
|
|
19
|
+
schemaHash: string;
|
|
20
|
+
}
|
|
21
|
+
export interface EnsureCollectionsInput {
|
|
22
|
+
definitions: CollectionDefinition[];
|
|
23
|
+
db: IDbAdapter;
|
|
24
|
+
logger?: BylineLogger;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Reconcile every registered `CollectionDefinition` with its row in the
|
|
28
|
+
* `collections` table. Runs once at startup from `initBylineCore()`.
|
|
29
|
+
*
|
|
30
|
+
* Behaviour per collection:
|
|
31
|
+
* 1. Compute the data-shape fingerprint.
|
|
32
|
+
* 2. If no row exists: insert with `version = definition.version ?? 1`
|
|
33
|
+
* and the fingerprint.
|
|
34
|
+
* 3. If a row exists and the fingerprint matches: no-op.
|
|
35
|
+
* 4. If a row exists and the fingerprint differs:
|
|
36
|
+
* - `definition.version` pinned explicitly and `> stored.version` → use it
|
|
37
|
+
* - `definition.version` pinned explicitly and `<= stored.version` → throw
|
|
38
|
+
* - otherwise → auto-bump to `stored.version + 1`
|
|
39
|
+
* Then write back `{ config, version, schema_hash, updated_at }`.
|
|
40
|
+
*
|
|
41
|
+
* Returns a `Map<path, CollectionRecord>` to be cached on the core instance
|
|
42
|
+
* so downstream callers (lifecycle, upload, client handle) can resolve
|
|
43
|
+
* `(collectionId, collectionVersion)` without another DB round-trip.
|
|
44
|
+
*/
|
|
45
|
+
export declare function ensureCollections({ definitions, db, logger, }: EnsureCollectionsInput): Promise<Map<string, CollectionRecord>>;
|
|
46
|
+
//# sourceMappingURL=collection-bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-bootstrap.d.ts","sourceRoot":"","sources":["../../src/services/collection-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,oBAAoB,EAAE,CAAA;IACnC,EAAE,EAAE,UAAU,CAAA;IACd,MAAM,CAAC,EAAE,YAAY,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,WAAW,EACX,EAAE,EACF,MAAM,GACP,EAAE,sBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAcjE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
import { fingerprintCollection } from '../storage/collection-fingerprint.js';
|
|
9
|
+
/**
|
|
10
|
+
* Reconcile every registered `CollectionDefinition` with its row in the
|
|
11
|
+
* `collections` table. Runs once at startup from `initBylineCore()`.
|
|
12
|
+
*
|
|
13
|
+
* Behaviour per collection:
|
|
14
|
+
* 1. Compute the data-shape fingerprint.
|
|
15
|
+
* 2. If no row exists: insert with `version = definition.version ?? 1`
|
|
16
|
+
* and the fingerprint.
|
|
17
|
+
* 3. If a row exists and the fingerprint matches: no-op.
|
|
18
|
+
* 4. If a row exists and the fingerprint differs:
|
|
19
|
+
* - `definition.version` pinned explicitly and `> stored.version` → use it
|
|
20
|
+
* - `definition.version` pinned explicitly and `<= stored.version` → throw
|
|
21
|
+
* - otherwise → auto-bump to `stored.version + 1`
|
|
22
|
+
* Then write back `{ config, version, schema_hash, updated_at }`.
|
|
23
|
+
*
|
|
24
|
+
* Returns a `Map<path, CollectionRecord>` to be cached on the core instance
|
|
25
|
+
* so downstream callers (lifecycle, upload, client handle) can resolve
|
|
26
|
+
* `(collectionId, collectionVersion)` without another DB round-trip.
|
|
27
|
+
*/
|
|
28
|
+
export async function ensureCollections({ definitions, db, logger, }) {
|
|
29
|
+
// Each collection reconciles independently (separate rows, independent
|
|
30
|
+
// SELECT/UPDATE paths), so we fan out with Promise.all. At 20+ collections
|
|
31
|
+
// or higher DB latency this turns linear round-trips into one concurrent
|
|
32
|
+
// batch.
|
|
33
|
+
const reconciled = await Promise.all(definitions.map((definition) => reconcileCollection(definition, db, logger)));
|
|
34
|
+
const records = new Map();
|
|
35
|
+
for (const entry of reconciled) {
|
|
36
|
+
records.set(entry.path, entry.record);
|
|
37
|
+
}
|
|
38
|
+
return records;
|
|
39
|
+
}
|
|
40
|
+
async function reconcileCollection(definition, db, logger) {
|
|
41
|
+
const fingerprint = await fingerprintCollection(definition);
|
|
42
|
+
const existing = await db.queries.collections.getCollectionByPath(definition.path);
|
|
43
|
+
if (existing == null) {
|
|
44
|
+
const initialVersion = definition.version ?? 1;
|
|
45
|
+
const inserted = await db.commands.collections.create(definition.path, definition, {
|
|
46
|
+
version: initialVersion,
|
|
47
|
+
schemaHash: fingerprint,
|
|
48
|
+
});
|
|
49
|
+
const row = Array.isArray(inserted) ? inserted[0] : inserted;
|
|
50
|
+
const collectionId = row?.id;
|
|
51
|
+
if (!collectionId) {
|
|
52
|
+
throw new Error(`ensureCollections: insert for '${definition.path}' did not return a row id`);
|
|
53
|
+
}
|
|
54
|
+
logger?.info({ collectionPath: definition.path, version: initialVersion }, 'collection registered');
|
|
55
|
+
return {
|
|
56
|
+
path: definition.path,
|
|
57
|
+
record: { collectionId, version: initialVersion, schemaHash: fingerprint },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const collectionId = existing.id;
|
|
61
|
+
const storedVersion = (existing.version ?? 1) | 0;
|
|
62
|
+
const storedHash = existing.schema_hash ?? null;
|
|
63
|
+
// Unchanged — stored hash matches. We trust the hash and skip the write
|
|
64
|
+
// even if `definition.version` was pinned to something higher; the hash
|
|
65
|
+
// is the source of truth for "did the shape change?".
|
|
66
|
+
if (storedHash === fingerprint) {
|
|
67
|
+
return {
|
|
68
|
+
path: definition.path,
|
|
69
|
+
record: { collectionId, version: storedVersion, schemaHash: fingerprint },
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Hash differs (or was never recorded) — decide the next version.
|
|
73
|
+
let nextVersion;
|
|
74
|
+
if (definition.version !== undefined) {
|
|
75
|
+
if (definition.version < storedVersion) {
|
|
76
|
+
throw new Error(`ensureCollections: collection '${definition.path}' pins version ` +
|
|
77
|
+
`${definition.version} but the database already records version ${storedVersion}. ` +
|
|
78
|
+
`Pinning backwards is not allowed.`);
|
|
79
|
+
}
|
|
80
|
+
nextVersion = definition.version;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// First-run after Phase-1 migration: schema_hash was NULL, so this
|
|
84
|
+
// looks like a change. Don't bump — just backfill the hash at the
|
|
85
|
+
// same version the DB already holds.
|
|
86
|
+
nextVersion = storedHash === null ? storedVersion : storedVersion + 1;
|
|
87
|
+
}
|
|
88
|
+
await db.commands.collections.update(collectionId, {
|
|
89
|
+
config: definition,
|
|
90
|
+
version: nextVersion,
|
|
91
|
+
schemaHash: fingerprint,
|
|
92
|
+
});
|
|
93
|
+
if (nextVersion !== storedVersion) {
|
|
94
|
+
logger?.info({
|
|
95
|
+
collectionPath: definition.path,
|
|
96
|
+
previousVersion: storedVersion,
|
|
97
|
+
version: nextVersion,
|
|
98
|
+
}, 'collection schema version bumped');
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
logger?.debug({ collectionPath: definition.path, version: storedVersion }, 'collection schema hash backfilled');
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
path: definition.path,
|
|
105
|
+
record: { collectionId, version: nextVersion, schemaHash: fingerprint },
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=collection-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-bootstrap.js","sourceRoot":"","sources":["../../src/services/collection-bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=collection-bootstrap.test.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-bootstrap.test.node.d.ts","sourceRoot":"","sources":["../../src/services/collection-bootstrap.test.node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|