@postxl/schema 0.0.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/LICENSE +50 -0
- package/README.md +320 -0
- package/dist/enum/enum.brands.d.ts +11 -0
- package/dist/enum/enum.brands.js +19 -0
- package/dist/enum/enum.d.ts +49 -0
- package/dist/enum/enum.defaults.d.ts +41 -0
- package/dist/enum/enum.defaults.js +105 -0
- package/dist/enum/enum.js +6 -0
- package/dist/enum/enum.json-decoder.d.ts +61 -0
- package/dist/enum/enum.json-decoder.js +51 -0
- package/dist/enum/enum.transformer.d.ts +12 -0
- package/dist/enum/enum.transformer.js +76 -0
- package/dist/enum/enum.types.d.ts +14 -0
- package/dist/enum/enum.types.js +2 -0
- package/dist/enum/index.d.ts +6 -0
- package/dist/enum/index.js +22 -0
- package/dist/field/defaults.d.ts +12 -0
- package/dist/field/defaults.js +78 -0
- package/dist/field/discriminated-union.d.ts +125 -0
- package/dist/field/discriminated-union.js +207 -0
- package/dist/field/enum.d.ts +65 -0
- package/dist/field/enum.js +111 -0
- package/dist/field/field.d.ts +483 -0
- package/dist/field/field.js +68 -0
- package/dist/field/id.d.ts +152 -0
- package/dist/field/id.js +104 -0
- package/dist/field/index.d.ts +11 -0
- package/dist/field/index.js +27 -0
- package/dist/field/relation.d.ts +88 -0
- package/dist/field/relation.js +138 -0
- package/dist/field/scalar.d.ts +179 -0
- package/dist/field/scalar.js +197 -0
- package/dist/field/shared/brands.d.ts +38 -0
- package/dist/field/shared/brands.js +109 -0
- package/dist/field/shared/decoders.d.ts +17 -0
- package/dist/field/shared/decoders.js +88 -0
- package/dist/field/shared/seed.d.ts +32 -0
- package/dist/field/shared/seed.js +63 -0
- package/dist/field/shared/types.d.ts +73 -0
- package/dist/field/shared/types.js +2 -0
- package/dist/field/shared/utils.d.ts +26 -0
- package/dist/field/shared/utils.js +52 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +25 -0
- package/dist/model/index.d.ts +5 -0
- package/dist/model/index.js +21 -0
- package/dist/model/model.brands.d.ts +7 -0
- package/dist/model/model.brands.js +10 -0
- package/dist/model/model.defaults.d.ts +28 -0
- package/dist/model/model.defaults.js +304 -0
- package/dist/model/model.json-decoder.d.ts +94 -0
- package/dist/model/model.json-decoder.js +107 -0
- package/dist/model/model.transformer.d.ts +93 -0
- package/dist/model/model.transformer.js +183 -0
- package/dist/model/model.types.d.ts +37 -0
- package/dist/model/model.types.js +2 -0
- package/dist/project-schema/project-schema.brands.d.ts +10 -0
- package/dist/project-schema/project-schema.brands.js +17 -0
- package/dist/project-schema/project-schema.defaults.d.ts +16 -0
- package/dist/project-schema/project-schema.defaults.js +53 -0
- package/dist/project-schema/project-schema.json-decoder.d.ts +285 -0
- package/dist/project-schema/project-schema.json-decoder.js +145 -0
- package/dist/project-schema/project-schema.transformer.d.ts +284 -0
- package/dist/project-schema/project-schema.transformer.js +444 -0
- package/dist/project-schema/project-schema.types.d.ts +77 -0
- package/dist/project-schema/project-schema.types.js +2 -0
- package/dist/samples/la.schema.json +2055 -0
- package/dist/samples/mca.schema.json +830 -0
- package/dist/samples/ring.schema.json +879 -0
- package/dist/samples/sample-schemas.d.ts +1896 -0
- package/dist/samples/sample-schemas.js +20 -0
- package/dist/samples/simple.schema.json +250 -0
- package/dist/samples/subex.schema.json +1188 -0
- package/dist/samples/usp-msm.schema.json +2515 -0
- package/package.json +57 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const zModelNameJSON: z.ZodEffects<z.ZodString, string, string>;
|
|
3
|
+
export declare const zModelJSON: z.ZodEffects<z.ZodObject<{
|
|
4
|
+
name: z.ZodEffects<z.ZodString, string, string>;
|
|
5
|
+
description: z.ZodOptional<z.ZodString>;
|
|
6
|
+
isReadonly: z.ZodOptional<z.ZodBoolean>;
|
|
7
|
+
schema: z.ZodOptional<z.ZodString>;
|
|
8
|
+
databaseName: z.ZodOptional<z.ZodString>;
|
|
9
|
+
excelName: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
|
|
10
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
13
|
+
name: z.ZodString;
|
|
14
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
15
|
+
name: z.ZodString;
|
|
16
|
+
}, z.ZodTypeAny, "passthrough">>, "many">>;
|
|
17
|
+
standardFields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
18
|
+
defaultField: z.ZodOptional<z.ZodString>;
|
|
19
|
+
labelField: z.ZodOptional<z.ZodString>;
|
|
20
|
+
indexes: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodBranded<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, "PXL.FieldName">, "many">, "many">>;
|
|
21
|
+
seed: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
|
|
22
|
+
source: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
23
|
+
faker: z.ZodOptional<z.ZodObject<{
|
|
24
|
+
items: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
seed: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
seed?: number | undefined;
|
|
28
|
+
items?: number | undefined;
|
|
29
|
+
}, {
|
|
30
|
+
seed?: number | undefined;
|
|
31
|
+
items?: number | undefined;
|
|
32
|
+
}>>;
|
|
33
|
+
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
name: string;
|
|
35
|
+
description?: string | undefined;
|
|
36
|
+
schema?: string | undefined;
|
|
37
|
+
databaseName?: string | undefined;
|
|
38
|
+
excelName?: string | undefined;
|
|
39
|
+
isReadonly?: boolean | undefined;
|
|
40
|
+
faker?: {
|
|
41
|
+
seed?: number | undefined;
|
|
42
|
+
items?: number | undefined;
|
|
43
|
+
} | undefined;
|
|
44
|
+
seed?: any[] | undefined;
|
|
45
|
+
fields?: z.objectOutputType<{
|
|
46
|
+
name: z.ZodString;
|
|
47
|
+
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
48
|
+
standardFields?: string[] | undefined;
|
|
49
|
+
defaultField?: string | undefined;
|
|
50
|
+
labelField?: string | undefined;
|
|
51
|
+
indexes?: (string & z.BRAND<"PXL.FieldName">)[][] | undefined;
|
|
52
|
+
source?: Record<string, unknown> | undefined;
|
|
53
|
+
}, {
|
|
54
|
+
name: string;
|
|
55
|
+
description?: string | undefined;
|
|
56
|
+
schema?: string | undefined;
|
|
57
|
+
databaseName?: string | undefined;
|
|
58
|
+
excelName?: string | undefined;
|
|
59
|
+
isReadonly?: boolean | undefined;
|
|
60
|
+
faker?: {
|
|
61
|
+
seed?: number | undefined;
|
|
62
|
+
items?: number | undefined;
|
|
63
|
+
} | undefined;
|
|
64
|
+
seed?: any[] | undefined;
|
|
65
|
+
fields?: z.objectInputType<{
|
|
66
|
+
name: z.ZodString;
|
|
67
|
+
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
68
|
+
standardFields?: string[] | undefined;
|
|
69
|
+
defaultField?: string | undefined;
|
|
70
|
+
labelField?: string | undefined;
|
|
71
|
+
indexes?: string[][] | undefined;
|
|
72
|
+
source?: Record<string, unknown> | undefined;
|
|
73
|
+
}>, {
|
|
74
|
+
name: string;
|
|
75
|
+
description?: string | undefined;
|
|
76
|
+
schema?: string | undefined;
|
|
77
|
+
databaseName?: string | undefined;
|
|
78
|
+
excelName?: string | undefined;
|
|
79
|
+
isReadonly?: boolean | undefined;
|
|
80
|
+
faker?: {
|
|
81
|
+
seed?: number | undefined;
|
|
82
|
+
items?: number | undefined;
|
|
83
|
+
} | undefined;
|
|
84
|
+
seed?: any[] | undefined;
|
|
85
|
+
fields?: z.objectOutputType<{
|
|
86
|
+
name: z.ZodString;
|
|
87
|
+
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
88
|
+
standardFields?: string[] | undefined;
|
|
89
|
+
defaultField?: string | undefined;
|
|
90
|
+
labelField?: string | undefined;
|
|
91
|
+
indexes?: (string & z.BRAND<"PXL.FieldName">)[][] | undefined;
|
|
92
|
+
source?: Record<string, unknown> | undefined;
|
|
93
|
+
}, unknown>;
|
|
94
|
+
export type ModelJSON = z.infer<typeof zModelJSON>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.zModelJSON = exports.zModelNameJSON = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const utils_1 = require("@postxl/utils");
|
|
6
|
+
const brands_1 = require("../field/shared/brands");
|
|
7
|
+
exports.zModelNameJSON = zod_1.z
|
|
8
|
+
//
|
|
9
|
+
.string()
|
|
10
|
+
.min(1, 'Name of the model must not be empty')
|
|
11
|
+
.refine((name) => name !== (0, utils_1.pluralize)(name), (name) => ({
|
|
12
|
+
message: `Model ${name} must not be pluralized!`,
|
|
13
|
+
}))
|
|
14
|
+
.describe('Name of the model.');
|
|
15
|
+
exports.zModelJSON = zod_1.z.preprocess((input) => {
|
|
16
|
+
if (typeof input === 'object' && input !== null) {
|
|
17
|
+
const original = input;
|
|
18
|
+
const result = { ...original, source: { ...original } };
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
return input;
|
|
22
|
+
}, zod_1.z.object({
|
|
23
|
+
name: exports.zModelNameJSON,
|
|
24
|
+
description: zod_1.z
|
|
25
|
+
//
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('A helpful description of the model.'),
|
|
29
|
+
isReadonly: zod_1.z
|
|
30
|
+
//
|
|
31
|
+
.boolean()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe(`Indicates if the model is readonly. To be used for system models that should not be editable through actions (e.g. Mutation, Action).`),
|
|
34
|
+
//
|
|
35
|
+
schema: zod_1.z
|
|
36
|
+
//
|
|
37
|
+
.string()
|
|
38
|
+
.min(1, 'Schema of the model must not be empty')
|
|
39
|
+
.optional().describe(`The database schema that the model belongs to.
|
|
40
|
+
If not provided, the default data schema is assumed.`),
|
|
41
|
+
databaseName: zod_1.z
|
|
42
|
+
.string()
|
|
43
|
+
.optional()
|
|
44
|
+
.describe('Mapping of the model to a database table name. If not provided, we use the snakecase of `name` field.'),
|
|
45
|
+
excelName: zod_1.z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.refine((name) => name === undefined || name === (0, utils_1.toExcelTableName)(name), (name) => ({
|
|
49
|
+
message: `Excel table name "${(0, utils_1.red)(name ?? '')}" is not a valid Excel table name. It must start with a letter or underscore and can only contain letters, numbers, and underscores.`,
|
|
50
|
+
}))
|
|
51
|
+
.describe('Mapping of the model to an Excel table name. If not provided, we use the `name` field.'),
|
|
52
|
+
fields: zod_1.z
|
|
53
|
+
//
|
|
54
|
+
.array(
|
|
55
|
+
// We decode the fields only to `Array<{name: string & object}>` for now, as we need to know the model names and enum names
|
|
56
|
+
zod_1.z.object({ name: zod_1.z.string() }).passthrough())
|
|
57
|
+
.optional()
|
|
58
|
+
.describe('The fields of the model.'),
|
|
59
|
+
standardFields: zod_1.z
|
|
60
|
+
//
|
|
61
|
+
.array(zod_1.z.string())
|
|
62
|
+
.optional().describe(`Names of standard fields that should be included in the model.
|
|
63
|
+
Currently, the following fields are supported: id, createdAt, updatedAt, name.
|
|
64
|
+
If not provided, all fields are included by default.
|
|
65
|
+
|
|
66
|
+
If any of the standard fields are also provided in the \`fields\` array, the custom fields will take precedence.`),
|
|
67
|
+
defaultField: zod_1.z
|
|
68
|
+
//
|
|
69
|
+
.string()
|
|
70
|
+
.optional().describe(`Identifies one of the fields as the default field.
|
|
71
|
+
The default field must be a boolean field and have exactly one entry set to \`true\`.
|
|
72
|
+
The entity with this will be exposed as the default entity.
|
|
73
|
+
|
|
74
|
+
Example use case: default language, root region in region tree.`),
|
|
75
|
+
labelField: zod_1.z
|
|
76
|
+
//
|
|
77
|
+
.string()
|
|
78
|
+
.optional().describe(`The name of the field that is used in the UI as the label of the entity.
|
|
79
|
+
The label field must be a string field. If not provided, the \`name\` field is used as the label.`),
|
|
80
|
+
indexes: zod_1.z
|
|
81
|
+
//
|
|
82
|
+
.array(zod_1.z.array(brands_1.zFieldName).min(2))
|
|
83
|
+
.optional()
|
|
84
|
+
.describe('Each entry is an array of field names that are used to create an index.'),
|
|
85
|
+
seed: zod_1.z
|
|
86
|
+
.array(zod_1.z.any())
|
|
87
|
+
.optional()
|
|
88
|
+
.describe(`The seed data for the model. This must be a valid JSON object that corresponds to the model.`),
|
|
89
|
+
source: zod_1.z
|
|
90
|
+
.record(zod_1.z.string(), zod_1.z.unknown())
|
|
91
|
+
.optional()
|
|
92
|
+
.describe(`Contains the source definition of the model before any transformation or validation. This way, custom generators can extract/define additional information from the model.`),
|
|
93
|
+
faker: zod_1.z
|
|
94
|
+
.object({
|
|
95
|
+
items: zod_1.z
|
|
96
|
+
.number()
|
|
97
|
+
.int()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe('The number of items to generate for the model. If nothing is provided, we default to 10 - unless a seed is provided, then we default to 0'),
|
|
100
|
+
seed: zod_1.z
|
|
101
|
+
.number()
|
|
102
|
+
.int()
|
|
103
|
+
.optional()
|
|
104
|
+
.describe('The seed value used to generate the data. Can be modified to generate different data.'),
|
|
105
|
+
})
|
|
106
|
+
.optional(),
|
|
107
|
+
}));
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ModelJSON } from './model.json-decoder';
|
|
3
|
+
export declare function modelJSONTransformer(input: ModelJSON, ctx: z.RefinementCtx): {
|
|
4
|
+
fields: Record<string & z.BRAND<"PXL.FieldName">, unknown>;
|
|
5
|
+
/**
|
|
6
|
+
* We also provide a list of field names to keep the original order
|
|
7
|
+
*/
|
|
8
|
+
fieldNames: (string & z.BRAND<"PXL.FieldName">)[];
|
|
9
|
+
name: string & z.BRAND<"PXL.ModelName">;
|
|
10
|
+
schema: (string & z.BRAND<"PXL.DatabaseSchemaName">) | undefined;
|
|
11
|
+
databaseName: string & z.BRAND<"PXL.DatabaseModelName">;
|
|
12
|
+
defaultFieldName: (string & z.BRAND<"PXL.FieldName">) | undefined;
|
|
13
|
+
labelFieldName: (string & z.BRAND<"PXL.FieldName">) | undefined;
|
|
14
|
+
isReadonly: boolean;
|
|
15
|
+
excelName: string;
|
|
16
|
+
description: string;
|
|
17
|
+
indexes: (string & z.BRAND<"PXL.FieldName">)[][];
|
|
18
|
+
seed: any[];
|
|
19
|
+
faker: {
|
|
20
|
+
seed: number;
|
|
21
|
+
items: number;
|
|
22
|
+
};
|
|
23
|
+
source?: Record<string, unknown> | undefined;
|
|
24
|
+
};
|
|
25
|
+
export type ModelEnriched = ReturnType<typeof modelJSONTransformer>;
|
|
26
|
+
declare function addDefaults({ description, fields, standardFields, seed, faker, ...input }: ModelJSON): {
|
|
27
|
+
isReadonly: boolean;
|
|
28
|
+
databaseName: string;
|
|
29
|
+
excelName: string;
|
|
30
|
+
description: string;
|
|
31
|
+
fields: z.objectOutputType<{
|
|
32
|
+
name: z.ZodString;
|
|
33
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
34
|
+
standardFields: string[];
|
|
35
|
+
indexes: (string & z.BRAND<"PXL.FieldName">)[][];
|
|
36
|
+
seed: any[];
|
|
37
|
+
faker: {
|
|
38
|
+
seed: number;
|
|
39
|
+
items: number;
|
|
40
|
+
};
|
|
41
|
+
name: string;
|
|
42
|
+
schema?: string | undefined;
|
|
43
|
+
defaultField?: string | undefined;
|
|
44
|
+
labelField?: string | undefined;
|
|
45
|
+
source?: Record<string, unknown> | undefined;
|
|
46
|
+
};
|
|
47
|
+
type WithDefaults = ReturnType<typeof addDefaults>;
|
|
48
|
+
declare function brandModel({ name, schema, databaseName, standardFields, defaultField, labelField, ...input }: WithDefaults): {
|
|
49
|
+
name: string & z.BRAND<"PXL.ModelName">;
|
|
50
|
+
schema: (string & z.BRAND<"PXL.DatabaseSchemaName">) | undefined;
|
|
51
|
+
databaseName: string & z.BRAND<"PXL.DatabaseModelName">;
|
|
52
|
+
standardFields: (string & z.BRAND<"PXL.FieldName">)[];
|
|
53
|
+
defaultFieldName: (string & z.BRAND<"PXL.FieldName">) | undefined;
|
|
54
|
+
labelFieldName: (string & z.BRAND<"PXL.FieldName">) | undefined;
|
|
55
|
+
isReadonly: boolean;
|
|
56
|
+
excelName: string;
|
|
57
|
+
description: string;
|
|
58
|
+
fields: z.objectOutputType<{
|
|
59
|
+
name: z.ZodString;
|
|
60
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
61
|
+
indexes: (string & z.BRAND<"PXL.FieldName">)[][];
|
|
62
|
+
seed: any[];
|
|
63
|
+
faker: {
|
|
64
|
+
seed: number;
|
|
65
|
+
items: number;
|
|
66
|
+
};
|
|
67
|
+
source?: Record<string, unknown> | undefined;
|
|
68
|
+
};
|
|
69
|
+
type BrandedModel = ReturnType<typeof brandModel>;
|
|
70
|
+
declare function combineFields({ fields, standardFields, ...model }: BrandedModel, ctx: z.RefinementCtx): {
|
|
71
|
+
fields: Record<string & z.BRAND<"PXL.FieldName">, unknown>;
|
|
72
|
+
/**
|
|
73
|
+
* We also provide a list of field names to keep the original order
|
|
74
|
+
*/
|
|
75
|
+
fieldNames: (string & z.BRAND<"PXL.FieldName">)[];
|
|
76
|
+
name: string & z.BRAND<"PXL.ModelName">;
|
|
77
|
+
schema: (string & z.BRAND<"PXL.DatabaseSchemaName">) | undefined;
|
|
78
|
+
databaseName: string & z.BRAND<"PXL.DatabaseModelName">;
|
|
79
|
+
defaultFieldName: (string & z.BRAND<"PXL.FieldName">) | undefined;
|
|
80
|
+
labelFieldName: (string & z.BRAND<"PXL.FieldName">) | undefined;
|
|
81
|
+
isReadonly: boolean;
|
|
82
|
+
excelName: string;
|
|
83
|
+
description: string;
|
|
84
|
+
indexes: (string & z.BRAND<"PXL.FieldName">)[][];
|
|
85
|
+
seed: any[];
|
|
86
|
+
faker: {
|
|
87
|
+
seed: number;
|
|
88
|
+
items: number;
|
|
89
|
+
};
|
|
90
|
+
source?: Record<string, unknown> | undefined;
|
|
91
|
+
};
|
|
92
|
+
export type CombinedFields = ReturnType<typeof combineFields>;
|
|
93
|
+
export {};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.modelJSONTransformer = modelJSONTransformer;
|
|
37
|
+
const zod_1 = require("zod");
|
|
38
|
+
const utils_1 = require("@postxl/utils");
|
|
39
|
+
const Field = __importStar(require("../field"));
|
|
40
|
+
const project_schema_brands_1 = require("../project-schema/project-schema.brands");
|
|
41
|
+
const model_brands_1 = require("./model.brands");
|
|
42
|
+
function modelJSONTransformer(input, ctx) {
|
|
43
|
+
const withDefaults = addDefaults(input);
|
|
44
|
+
const withBranded = brandModel(withDefaults);
|
|
45
|
+
const withCombinedFields = combineFields(withBranded, ctx);
|
|
46
|
+
validateIndexes(withCombinedFields, ctx);
|
|
47
|
+
validateSeedData(withCombinedFields, ctx);
|
|
48
|
+
return withCombinedFields;
|
|
49
|
+
}
|
|
50
|
+
function addDefaults({ description, fields, standardFields, seed, faker, ...input }) {
|
|
51
|
+
return {
|
|
52
|
+
...input,
|
|
53
|
+
isReadonly: input.isReadonly ?? false,
|
|
54
|
+
databaseName: input.databaseName ?? (0, utils_1.toSnakeCase)(input.name),
|
|
55
|
+
excelName: input.excelName ?? (0, utils_1.toExcelColumnName)((0, utils_1.toPascalCase)((0, utils_1.pluralize)(input.name))),
|
|
56
|
+
description: description ?? '',
|
|
57
|
+
fields: fields ?? [],
|
|
58
|
+
standardFields: standardFields ?? Field.standardFieldNames,
|
|
59
|
+
indexes: input.indexes ?? [],
|
|
60
|
+
seed: seed ?? [],
|
|
61
|
+
faker: {
|
|
62
|
+
seed: faker?.seed ?? 0,
|
|
63
|
+
// We use the provided number of faker items - if nothing is provided, we default to 10 - unless a seed is provided, then we default to 0
|
|
64
|
+
items: faker?.items ?? (seed !== undefined ? 0 : 10),
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function brandModel({ name, schema, databaseName, standardFields, defaultField, labelField, ...input }) {
|
|
69
|
+
return {
|
|
70
|
+
...input,
|
|
71
|
+
name: (0, model_brands_1.toModelName)(name),
|
|
72
|
+
schema: schema ? (0, project_schema_brands_1.toDatabaseSchemaName)(schema) : undefined,
|
|
73
|
+
databaseName: (0, model_brands_1.toDatabaseModelName)(databaseName),
|
|
74
|
+
standardFields: standardFields.map((f) => Field.toFieldName(f)),
|
|
75
|
+
defaultFieldName: defaultField ? Field.toFieldName(defaultField) : undefined,
|
|
76
|
+
labelFieldName: labelField ? Field.toFieldName(labelField) : undefined,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function combineFields({ fields, standardFields, ...model }, ctx) {
|
|
80
|
+
const standardFieldsSelected = [];
|
|
81
|
+
for (const standardFieldName of standardFields) {
|
|
82
|
+
if (fields.find((f) => f.name === standardFieldName)) {
|
|
83
|
+
// A more specific field has been defined, we skip the standard field
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const standardFieldInput = Field.standardFields[standardFieldName];
|
|
87
|
+
if (!standardFieldInput) {
|
|
88
|
+
ctx.addIssue({
|
|
89
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
90
|
+
message: `Standard field ${standardFieldName} is not defined! Can only be one of "${Field.standardFieldNames.join('", "')}"!`,
|
|
91
|
+
});
|
|
92
|
+
return zod_1.z.NEVER;
|
|
93
|
+
}
|
|
94
|
+
standardFieldsSelected.push(standardFieldInput);
|
|
95
|
+
}
|
|
96
|
+
const fieldsRecord = {};
|
|
97
|
+
const fieldNames = [];
|
|
98
|
+
for (const field of [...standardFieldsSelected, ...fields]) {
|
|
99
|
+
const fieldName = Field.toFieldName(field.name);
|
|
100
|
+
if (fieldsRecord[fieldName] !== undefined) {
|
|
101
|
+
ctx.addIssue({
|
|
102
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
103
|
+
message: `Field ${fieldName} is defined multiple times in model ${model.name}!`,
|
|
104
|
+
});
|
|
105
|
+
return zod_1.z.NEVER;
|
|
106
|
+
}
|
|
107
|
+
fieldsRecord[fieldName] = field;
|
|
108
|
+
fieldNames.push(fieldName);
|
|
109
|
+
}
|
|
110
|
+
if (Object.keys(fieldsRecord).length === 0) {
|
|
111
|
+
ctx.addIssue({
|
|
112
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
113
|
+
message: `Model ${model.name} has no fields! At least one field is required, either by standard fields or by custom fields.`,
|
|
114
|
+
});
|
|
115
|
+
return zod_1.z.NEVER;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
...model,
|
|
119
|
+
fields: fieldsRecord,
|
|
120
|
+
/**
|
|
121
|
+
* We also provide a list of field names to keep the original order
|
|
122
|
+
*/
|
|
123
|
+
fieldNames,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function validateIndexes({ fields, indexes, ...model }, ctx) {
|
|
127
|
+
const checkedIndexes = new Set();
|
|
128
|
+
for (const index of indexes) {
|
|
129
|
+
for (const fieldName of index) {
|
|
130
|
+
if (!fields[fieldName]) {
|
|
131
|
+
ctx.addIssue({
|
|
132
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
133
|
+
message: `Index [${index.join(',')} ]in model ${model.name} references unknown field ${fieldName}!`,
|
|
134
|
+
});
|
|
135
|
+
return zod_1.z.NEVER;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const indexName = index.toSorted((a, b) => a.localeCompare(b)).join(',');
|
|
139
|
+
if (checkedIndexes.has(indexName)) {
|
|
140
|
+
ctx.addIssue({
|
|
141
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
142
|
+
message: `Index ${indexName} in model ${model.name} is defined multiple times!`,
|
|
143
|
+
});
|
|
144
|
+
return zod_1.z.NEVER;
|
|
145
|
+
}
|
|
146
|
+
checkedIndexes.add(indexName);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function validateSeedData({ seed, fields, ...model }, ctx) {
|
|
150
|
+
if (seed.length === 0) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const fieldNames = Object.keys(fields);
|
|
154
|
+
let index = 0;
|
|
155
|
+
let hasError = false;
|
|
156
|
+
for (const seedEntry of seed) {
|
|
157
|
+
index++;
|
|
158
|
+
const entryName = seedEntry.id ? `id "${seedEntry.id}" (row ${index})` : `row #${index}`;
|
|
159
|
+
for (const fieldName of Object.keys(seedEntry)) {
|
|
160
|
+
if (!fieldNames.includes(fieldName)) {
|
|
161
|
+
ctx.addIssue({
|
|
162
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
163
|
+
message: `Seed entry ${entryName} in model ${model.name} references unknown field "${fieldName}"!`,
|
|
164
|
+
});
|
|
165
|
+
hasError = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const [fieldName, field] of Object.entries(fields)) {
|
|
169
|
+
const { type, isCreatedAt, isUpdatedAt } = field;
|
|
170
|
+
const isRequired = !type.endsWith('?') && !isCreatedAt && !isUpdatedAt;
|
|
171
|
+
if (isRequired && !(fieldName in seedEntry)) {
|
|
172
|
+
ctx.addIssue({
|
|
173
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
174
|
+
message: `Seed entry ${entryName} in model ${model.name} lacks required field "${fieldName}"!`,
|
|
175
|
+
});
|
|
176
|
+
hasError = true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (hasError) {
|
|
181
|
+
return zod_1.z.NEVER;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as Field from '../field';
|
|
2
|
+
import { DatabaseSchemaName } from '../project-schema/project-schema.brands';
|
|
3
|
+
import * as Branded from './model.brands';
|
|
4
|
+
export type Models = Map<Branded.ModelName, Model>;
|
|
5
|
+
export type Model = {
|
|
6
|
+
name: Branded.ModelName;
|
|
7
|
+
description: string;
|
|
8
|
+
isReadonly: boolean;
|
|
9
|
+
databaseSchema: DatabaseSchemaName;
|
|
10
|
+
databaseName: string;
|
|
11
|
+
excelName: string;
|
|
12
|
+
fields: Field.Fields;
|
|
13
|
+
idField: Field.FieldId;
|
|
14
|
+
defaultField: Field.FieldDatabaseNative | undefined;
|
|
15
|
+
labelField: Field.FieldDatabaseNative;
|
|
16
|
+
indexes: ModelIndex[];
|
|
17
|
+
seed: Seed[];
|
|
18
|
+
/**
|
|
19
|
+
* The source definition of the model. Provided to allow custom generators to extract/define additional information.
|
|
20
|
+
*/
|
|
21
|
+
source?: Record<string, unknown> | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* The seed data configuration for the model.
|
|
24
|
+
*/
|
|
25
|
+
faker?: {
|
|
26
|
+
/**
|
|
27
|
+
* The seed value used to generate the data. Can be modified to generate different data.
|
|
28
|
+
*/
|
|
29
|
+
seed: number;
|
|
30
|
+
/**
|
|
31
|
+
* The number of items to generate for the model.
|
|
32
|
+
*/
|
|
33
|
+
items: number;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export type ModelIndex = Field.FieldName[];
|
|
37
|
+
export type Seed = Record<string, unknown>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const zProjectSchemaName: z.ZodBranded<z.ZodString, "PXL.ProjectSchemaName">;
|
|
3
|
+
export type ProjectSchemaName = z.infer<typeof zProjectSchemaName>;
|
|
4
|
+
export declare const toProjectSchemaName: (input: string) => string & z.BRAND<"PXL.ProjectSchemaName">;
|
|
5
|
+
export declare const zProjectSlug: z.ZodBranded<z.ZodEffects<z.ZodString, string, string>, "PXL.ProjectSlug">;
|
|
6
|
+
export type ProjectSlug = z.infer<typeof zProjectSlug>;
|
|
7
|
+
export declare const toProjectSlug: (input: string) => string & z.BRAND<"PXL.ProjectSlug">;
|
|
8
|
+
export declare const zDatabaseSchemaName: z.ZodBranded<z.ZodString, "PXL.DatabaseSchemaName">;
|
|
9
|
+
export type DatabaseSchemaName = z.infer<typeof zDatabaseSchemaName>;
|
|
10
|
+
export declare const toDatabaseSchemaName: (input: string) => string & z.BRAND<"PXL.DatabaseSchemaName">;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toDatabaseSchemaName = exports.zDatabaseSchemaName = exports.toProjectSlug = exports.zProjectSlug = exports.toProjectSchemaName = exports.zProjectSchemaName = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const utils_1 = require("@postxl/utils");
|
|
6
|
+
exports.zProjectSchemaName = zod_1.z.string().brand('PXL.ProjectSchemaName');
|
|
7
|
+
const toProjectSchemaName = (input) => exports.zProjectSchemaName.parse(input);
|
|
8
|
+
exports.toProjectSchemaName = toProjectSchemaName;
|
|
9
|
+
exports.zProjectSlug = zod_1.z
|
|
10
|
+
.string()
|
|
11
|
+
.refine(utils_1.isSlug, (s) => ({ message: `Project slug must be a valid slug. Expected ${(0, utils_1.slugify)(s)}, received ${s}` }))
|
|
12
|
+
.brand('PXL.ProjectSlug');
|
|
13
|
+
const toProjectSlug = (input) => exports.zProjectSlug.parse(input);
|
|
14
|
+
exports.toProjectSlug = toProjectSlug;
|
|
15
|
+
exports.zDatabaseSchemaName = zod_1.z.string().brand('PXL.DatabaseSchemaName');
|
|
16
|
+
const toDatabaseSchemaName = (input) => exports.zDatabaseSchemaName.parse(input);
|
|
17
|
+
exports.toDatabaseSchemaName = toDatabaseSchemaName;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The name of the default data schema of the project.
|
|
3
|
+
* This name is used when a model does not specify a schema.
|
|
4
|
+
*/
|
|
5
|
+
export declare const databaseSchemaNameData: string & import("zod").BRAND<"PXL.DatabaseSchemaName">;
|
|
6
|
+
/**
|
|
7
|
+
* The name of the schema that contains the configuration of the project.
|
|
8
|
+
*/
|
|
9
|
+
export declare const databaseSchemaNameConfig: string & import("zod").BRAND<"PXL.DatabaseSchemaName">;
|
|
10
|
+
export declare const defaultSystemUser: {
|
|
11
|
+
id: string;
|
|
12
|
+
sub: null;
|
|
13
|
+
email: string;
|
|
14
|
+
name: string;
|
|
15
|
+
profilePictureUrl: string;
|
|
16
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.defaultSystemUser = exports.databaseSchemaNameConfig = exports.databaseSchemaNameData = void 0;
|
|
37
|
+
const Branded = __importStar(require("./project-schema.brands"));
|
|
38
|
+
/**
|
|
39
|
+
* The name of the default data schema of the project.
|
|
40
|
+
* This name is used when a model does not specify a schema.
|
|
41
|
+
*/
|
|
42
|
+
exports.databaseSchemaNameData = Branded.toDatabaseSchemaName('Data');
|
|
43
|
+
/**
|
|
44
|
+
* The name of the schema that contains the configuration of the project.
|
|
45
|
+
*/
|
|
46
|
+
exports.databaseSchemaNameConfig = Branded.toDatabaseSchemaName('PXL');
|
|
47
|
+
exports.defaultSystemUser = {
|
|
48
|
+
id: 'root',
|
|
49
|
+
sub: null,
|
|
50
|
+
email: 'admin@postxl.com',
|
|
51
|
+
name: 'Root',
|
|
52
|
+
profilePictureUrl: 'https://postxl.com/images/team/user.png',
|
|
53
|
+
};
|