@contember/client-content-generator 1.3.0-alpha.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/dist/development/ContemberClientGenerator.cjs +45 -0
- package/dist/development/ContemberClientGenerator.cjs.map +1 -0
- package/dist/development/ContemberClientGenerator.js +45 -0
- package/dist/development/ContemberClientGenerator.js.map +1 -0
- package/dist/development/EntityTypeSchemaGenerator.cjs +171 -0
- package/dist/development/EntityTypeSchemaGenerator.cjs.map +1 -0
- package/dist/development/EntityTypeSchemaGenerator.js +171 -0
- package/dist/development/EntityTypeSchemaGenerator.js.map +1 -0
- package/dist/development/EnumTypeSchemaGenerator.cjs +14 -0
- package/dist/development/EnumTypeSchemaGenerator.cjs.map +1 -0
- package/dist/development/EnumTypeSchemaGenerator.js +14 -0
- package/dist/development/EnumTypeSchemaGenerator.js.map +1 -0
- package/dist/development/NameSchemaGenerator.cjs +38 -0
- package/dist/development/NameSchemaGenerator.cjs.map +1 -0
- package/dist/development/NameSchemaGenerator.js +38 -0
- package/dist/development/NameSchemaGenerator.js.map +1 -0
- package/dist/development/generate.cjs +41 -0
- package/dist/development/generate.cjs.map +1 -0
- package/dist/development/generate.js +23 -0
- package/dist/development/generate.js.map +1 -0
- package/dist/development/index.cjs +11 -0
- package/dist/development/index.cjs.map +1 -0
- package/dist/development/index.js +11 -0
- package/dist/development/index.js.map +1 -0
- package/dist/production/ContemberClientGenerator.cjs +45 -0
- package/dist/production/ContemberClientGenerator.cjs.map +1 -0
- package/dist/production/ContemberClientGenerator.js +45 -0
- package/dist/production/ContemberClientGenerator.js.map +1 -0
- package/dist/production/EntityTypeSchemaGenerator.cjs +171 -0
- package/dist/production/EntityTypeSchemaGenerator.cjs.map +1 -0
- package/dist/production/EntityTypeSchemaGenerator.js +171 -0
- package/dist/production/EntityTypeSchemaGenerator.js.map +1 -0
- package/dist/production/EnumTypeSchemaGenerator.cjs +14 -0
- package/dist/production/EnumTypeSchemaGenerator.cjs.map +1 -0
- package/dist/production/EnumTypeSchemaGenerator.js +14 -0
- package/dist/production/EnumTypeSchemaGenerator.js.map +1 -0
- package/dist/production/NameSchemaGenerator.cjs +38 -0
- package/dist/production/NameSchemaGenerator.cjs.map +1 -0
- package/dist/production/NameSchemaGenerator.js +38 -0
- package/dist/production/NameSchemaGenerator.js.map +1 -0
- package/dist/production/generate.cjs +41 -0
- package/dist/production/generate.cjs.map +1 -0
- package/dist/production/generate.js +23 -0
- package/dist/production/generate.js.map +1 -0
- package/dist/production/index.cjs +11 -0
- package/dist/production/index.cjs.map +1 -0
- package/dist/production/index.js +11 -0
- package/dist/production/index.js.map +1 -0
- package/dist/types/ContemberClientGenerator.d.ts +12 -0
- package/dist/types/ContemberClientGenerator.d.ts.map +1 -0
- package/dist/types/EntityTypeSchemaGenerator.d.ts +8 -0
- package/dist/types/EntityTypeSchemaGenerator.d.ts.map +1 -0
- package/dist/types/EnumTypeSchemaGenerator.d.ts +5 -0
- package/dist/types/EnumTypeSchemaGenerator.d.ts.map +1 -0
- package/dist/types/NameSchemaGenerator.d.ts +6 -0
- package/dist/types/NameSchemaGenerator.d.ts.map +1 -0
- package/dist/types/generate.d.ts +2 -0
- package/dist/types/generate.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +55 -0
- package/src/ContemberClientGenerator.ts +48 -0
- package/src/EntityTypeSchemaGenerator.ts +182 -0
- package/src/EnumTypeSchemaGenerator.ts +12 -0
- package/src/NameSchemaGenerator.ts +41 -0
- package/src/generate.ts +26 -0
- package/src/index.ts +4 -0
- package/src/tsconfig.json +10 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const EnumTypeSchemaGenerator = require("./EnumTypeSchemaGenerator.cjs");
|
|
4
|
+
const EntityTypeSchemaGenerator = require("./EntityTypeSchemaGenerator.cjs");
|
|
5
|
+
const NameSchemaGenerator = require("./NameSchemaGenerator.cjs");
|
|
6
|
+
class ContemberClientGenerator {
|
|
7
|
+
constructor(nameSchemaGenerator = new NameSchemaGenerator.NameSchemaGenerator(), enumTypeSchemaGenerator = new EnumTypeSchemaGenerator.EnumTypeSchemaGenerator(), entityTypeSchemaGenerator = new EntityTypeSchemaGenerator.EntityTypeSchemaGenerator()) {
|
|
8
|
+
this.nameSchemaGenerator = nameSchemaGenerator;
|
|
9
|
+
this.enumTypeSchemaGenerator = enumTypeSchemaGenerator;
|
|
10
|
+
this.entityTypeSchemaGenerator = entityTypeSchemaGenerator;
|
|
11
|
+
}
|
|
12
|
+
generate(model) {
|
|
13
|
+
const nameSchema = this.nameSchemaGenerator.generate(model);
|
|
14
|
+
const enumTypeSchema = this.enumTypeSchemaGenerator.generate(model);
|
|
15
|
+
const entityTypeSchema = this.entityTypeSchemaGenerator.generate(model);
|
|
16
|
+
const namesCode = `import { SchemaNames } from '@contember/client-content'
|
|
17
|
+
export const ContemberClientNames: SchemaNames = ` + JSON.stringify(nameSchema, null, 2);
|
|
18
|
+
const indexCode = `
|
|
19
|
+
import { ContemberClientNames } from './names'
|
|
20
|
+
import { ContemberClientSchema } from './entities'
|
|
21
|
+
import { ContentQueryBuilder, TypedContentQueryBuilder, TypedEntitySelection } from '@contember/client'
|
|
22
|
+
export * from './names'
|
|
23
|
+
export * from './enums'
|
|
24
|
+
export * from './entities'
|
|
25
|
+
|
|
26
|
+
export const queryBuilder = new ContentQueryBuilder(ContemberClientNames) as unknown as TypedContentQueryBuilder<ContemberClientSchema>
|
|
27
|
+
|
|
28
|
+
export type FragmentOf<EntityName extends keyof ContemberClientSchema['entities'] & string, Data = unknown> =
|
|
29
|
+
TypedEntitySelection<ContemberClientSchema, EntityName, ContemberClientSchema['entities'][EntityName], Data>
|
|
30
|
+
|
|
31
|
+
export type FragmentType<T extends TypedEntitySelection<any, any, any, any> = any> =
|
|
32
|
+
T extends TypedEntitySelection<any, any, any, infer TFields>
|
|
33
|
+
? TFields
|
|
34
|
+
: never
|
|
35
|
+
`;
|
|
36
|
+
return {
|
|
37
|
+
"names.ts": namesCode,
|
|
38
|
+
"enums.ts": enumTypeSchema,
|
|
39
|
+
"entities.ts": entityTypeSchema,
|
|
40
|
+
"index.ts": indexCode
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.ContemberClientGenerator = ContemberClientGenerator;
|
|
45
|
+
//# sourceMappingURL=ContemberClientGenerator.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContemberClientGenerator.cjs","sources":["../../src/ContemberClientGenerator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { EnumTypeSchemaGenerator } from './EnumTypeSchemaGenerator'\nimport { EntityTypeSchemaGenerator } from './EntityTypeSchemaGenerator'\nimport { NameSchemaGenerator } from './NameSchemaGenerator'\n\n\nexport class ContemberClientGenerator {\n\tconstructor(\n\t\tprivate readonly nameSchemaGenerator: NameSchemaGenerator = new NameSchemaGenerator(),\n\t\tprivate readonly enumTypeSchemaGenerator: EnumTypeSchemaGenerator = new EnumTypeSchemaGenerator(),\n\t\tprivate readonly entityTypeSchemaGenerator: EntityTypeSchemaGenerator = new EntityTypeSchemaGenerator(),\n\t) {\n\t}\n\n\tgenerate(model: Model.Schema): Record<string, string> {\n\t\tconst nameSchema = this.nameSchemaGenerator.generate(model)\n\t\tconst enumTypeSchema = this.enumTypeSchemaGenerator.generate(model)\n\t\tconst entityTypeSchema = this.entityTypeSchemaGenerator.generate(model)\n\n\t\tconst namesCode = `import { SchemaNames } from '@contember/client-content'\nexport const ContemberClientNames: SchemaNames = ` + JSON.stringify(nameSchema, null, 2)\n\n\t\tconst indexCode = `\nimport { ContemberClientNames } from './names'\nimport { ContemberClientSchema } from './entities'\nimport { ContentQueryBuilder, TypedContentQueryBuilder, TypedEntitySelection } from '@contember/client'\nexport * from './names'\nexport * from './enums'\nexport * from './entities'\n\nexport const queryBuilder = new ContentQueryBuilder(ContemberClientNames) as unknown as TypedContentQueryBuilder<ContemberClientSchema>\n\nexport type FragmentOf<EntityName extends keyof ContemberClientSchema['entities'] & string, Data = unknown> =\nTypedEntitySelection<ContemberClientSchema, EntityName, ContemberClientSchema['entities'][EntityName], Data>\n\nexport type FragmentType<T extends TypedEntitySelection<any, any, any, any> = any> =\nT extends TypedEntitySelection<any, any, any, infer TFields>\n\t? TFields\n\t: never\n`\n\t\treturn {\n\t\t\t'names.ts': namesCode,\n\t\t\t'enums.ts': enumTypeSchema,\n\t\t\t'entities.ts': entityTypeSchema,\n\t\t\t'index.ts': indexCode,\n\t\t}\n\t}\n}\n"],"names":["NameSchemaGenerator","EnumTypeSchemaGenerator","EntityTypeSchemaGenerator"],"mappings":";;;;;AAMO,MAAM,yBAAyB;AAAA,EACrC,YACkB,sBAA2C,IAAIA,oBAAAA,uBAC/C,0BAAmD,IAAIC,wBAAAA,2BACvD,4BAAuD,IAAIC,0BAAAA,6BAC3E;AAHgB,SAAA,sBAAA;AACA,SAAA,0BAAA;AACA,SAAA,4BAAA;AAAA,EAElB;AAAA,EAEA,SAAS,OAA6C;AACrD,UAAM,aAAa,KAAK,oBAAoB,SAAS,KAAK;AAC1D,UAAM,iBAAiB,KAAK,wBAAwB,SAAS,KAAK;AAClE,UAAM,mBAAmB,KAAK,0BAA0B,SAAS,KAAK;AAEtE,UAAM,YAAY;AAAA,qDACiC,KAAK,UAAU,YAAY,MAAM,CAAC;AAErF,UAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBX,WAAA;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,YAAY;AAAA,IAAA;AAAA,EAEd;AACD;;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EnumTypeSchemaGenerator } from "./EnumTypeSchemaGenerator.js";
|
|
2
|
+
import { EntityTypeSchemaGenerator } from "./EntityTypeSchemaGenerator.js";
|
|
3
|
+
import { NameSchemaGenerator } from "./NameSchemaGenerator.js";
|
|
4
|
+
class ContemberClientGenerator {
|
|
5
|
+
constructor(nameSchemaGenerator = new NameSchemaGenerator(), enumTypeSchemaGenerator = new EnumTypeSchemaGenerator(), entityTypeSchemaGenerator = new EntityTypeSchemaGenerator()) {
|
|
6
|
+
this.nameSchemaGenerator = nameSchemaGenerator;
|
|
7
|
+
this.enumTypeSchemaGenerator = enumTypeSchemaGenerator;
|
|
8
|
+
this.entityTypeSchemaGenerator = entityTypeSchemaGenerator;
|
|
9
|
+
}
|
|
10
|
+
generate(model) {
|
|
11
|
+
const nameSchema = this.nameSchemaGenerator.generate(model);
|
|
12
|
+
const enumTypeSchema = this.enumTypeSchemaGenerator.generate(model);
|
|
13
|
+
const entityTypeSchema = this.entityTypeSchemaGenerator.generate(model);
|
|
14
|
+
const namesCode = `import { SchemaNames } from '@contember/client-content'
|
|
15
|
+
export const ContemberClientNames: SchemaNames = ` + JSON.stringify(nameSchema, null, 2);
|
|
16
|
+
const indexCode = `
|
|
17
|
+
import { ContemberClientNames } from './names'
|
|
18
|
+
import { ContemberClientSchema } from './entities'
|
|
19
|
+
import { ContentQueryBuilder, TypedContentQueryBuilder, TypedEntitySelection } from '@contember/client'
|
|
20
|
+
export * from './names'
|
|
21
|
+
export * from './enums'
|
|
22
|
+
export * from './entities'
|
|
23
|
+
|
|
24
|
+
export const queryBuilder = new ContentQueryBuilder(ContemberClientNames) as unknown as TypedContentQueryBuilder<ContemberClientSchema>
|
|
25
|
+
|
|
26
|
+
export type FragmentOf<EntityName extends keyof ContemberClientSchema['entities'] & string, Data = unknown> =
|
|
27
|
+
TypedEntitySelection<ContemberClientSchema, EntityName, ContemberClientSchema['entities'][EntityName], Data>
|
|
28
|
+
|
|
29
|
+
export type FragmentType<T extends TypedEntitySelection<any, any, any, any> = any> =
|
|
30
|
+
T extends TypedEntitySelection<any, any, any, infer TFields>
|
|
31
|
+
? TFields
|
|
32
|
+
: never
|
|
33
|
+
`;
|
|
34
|
+
return {
|
|
35
|
+
"names.ts": namesCode,
|
|
36
|
+
"enums.ts": enumTypeSchema,
|
|
37
|
+
"entities.ts": entityTypeSchema,
|
|
38
|
+
"index.ts": indexCode
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
ContemberClientGenerator
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=ContemberClientGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContemberClientGenerator.js","sources":["../../src/ContemberClientGenerator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { EnumTypeSchemaGenerator } from './EnumTypeSchemaGenerator'\nimport { EntityTypeSchemaGenerator } from './EntityTypeSchemaGenerator'\nimport { NameSchemaGenerator } from './NameSchemaGenerator'\n\n\nexport class ContemberClientGenerator {\n\tconstructor(\n\t\tprivate readonly nameSchemaGenerator: NameSchemaGenerator = new NameSchemaGenerator(),\n\t\tprivate readonly enumTypeSchemaGenerator: EnumTypeSchemaGenerator = new EnumTypeSchemaGenerator(),\n\t\tprivate readonly entityTypeSchemaGenerator: EntityTypeSchemaGenerator = new EntityTypeSchemaGenerator(),\n\t) {\n\t}\n\n\tgenerate(model: Model.Schema): Record<string, string> {\n\t\tconst nameSchema = this.nameSchemaGenerator.generate(model)\n\t\tconst enumTypeSchema = this.enumTypeSchemaGenerator.generate(model)\n\t\tconst entityTypeSchema = this.entityTypeSchemaGenerator.generate(model)\n\n\t\tconst namesCode = `import { SchemaNames } from '@contember/client-content'\nexport const ContemberClientNames: SchemaNames = ` + JSON.stringify(nameSchema, null, 2)\n\n\t\tconst indexCode = `\nimport { ContemberClientNames } from './names'\nimport { ContemberClientSchema } from './entities'\nimport { ContentQueryBuilder, TypedContentQueryBuilder, TypedEntitySelection } from '@contember/client'\nexport * from './names'\nexport * from './enums'\nexport * from './entities'\n\nexport const queryBuilder = new ContentQueryBuilder(ContemberClientNames) as unknown as TypedContentQueryBuilder<ContemberClientSchema>\n\nexport type FragmentOf<EntityName extends keyof ContemberClientSchema['entities'] & string, Data = unknown> =\nTypedEntitySelection<ContemberClientSchema, EntityName, ContemberClientSchema['entities'][EntityName], Data>\n\nexport type FragmentType<T extends TypedEntitySelection<any, any, any, any> = any> =\nT extends TypedEntitySelection<any, any, any, infer TFields>\n\t? TFields\n\t: never\n`\n\t\treturn {\n\t\t\t'names.ts': namesCode,\n\t\t\t'enums.ts': enumTypeSchema,\n\t\t\t'entities.ts': entityTypeSchema,\n\t\t\t'index.ts': indexCode,\n\t\t}\n\t}\n}\n"],"names":[],"mappings":";;;AAMO,MAAM,yBAAyB;AAAA,EACrC,YACkB,sBAA2C,IAAI,uBAC/C,0BAAmD,IAAI,2BACvD,4BAAuD,IAAI,6BAC3E;AAHgB,SAAA,sBAAA;AACA,SAAA,0BAAA;AACA,SAAA,4BAAA;AAAA,EAElB;AAAA,EAEA,SAAS,OAA6C;AACrD,UAAM,aAAa,KAAK,oBAAoB,SAAS,KAAK;AAC1D,UAAM,iBAAiB,KAAK,wBAAwB,SAAS,KAAK;AAClE,UAAM,mBAAmB,KAAK,0BAA0B,SAAS,KAAK;AAEtE,UAAM,YAAY;AAAA,qDACiC,KAAK,UAAU,YAAY,MAAM,CAAC;AAErF,UAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBX,WAAA;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,YAAY;AAAA,IAAA;AAAA,EAEd;AACD;"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const schema = require("@contember/schema");
|
|
4
|
+
const schemaUtils = require("@contember/schema-utils");
|
|
5
|
+
class EntityTypeSchemaGenerator {
|
|
6
|
+
generate(model) {
|
|
7
|
+
let code = "";
|
|
8
|
+
for (const enumName of Object.keys(model.enums)) {
|
|
9
|
+
code += `import type { ${enumName} } from './enums'
|
|
10
|
+
`;
|
|
11
|
+
}
|
|
12
|
+
code += `
|
|
13
|
+
export type JSONPrimitive = string | number | boolean | null
|
|
14
|
+
export type JSONValue = JSONPrimitive | JSONObject | JSONArray
|
|
15
|
+
export type JSONObject = { readonly [K in string]?: JSONValue }
|
|
16
|
+
export type JSONArray = readonly JSONValue[]
|
|
17
|
+
|
|
18
|
+
`;
|
|
19
|
+
for (const entity of Object.values(model.entities)) {
|
|
20
|
+
code += this.generateTypeEntityCode(model, entity);
|
|
21
|
+
}
|
|
22
|
+
code += "\n";
|
|
23
|
+
code += `export type ContemberClientEntities = {
|
|
24
|
+
`;
|
|
25
|
+
for (const entity of Object.values(model.entities)) {
|
|
26
|
+
code += ` ${entity.name}: ${entity.name}
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
code += "}\n\n";
|
|
30
|
+
code += `export type ContemberClientSchema = {
|
|
31
|
+
`;
|
|
32
|
+
code += " entities: ContemberClientEntities\n";
|
|
33
|
+
code += "}\n";
|
|
34
|
+
return code;
|
|
35
|
+
}
|
|
36
|
+
generateTypeEntityCode(model, entity) {
|
|
37
|
+
let code = `export type ${entity.name} = {
|
|
38
|
+
`;
|
|
39
|
+
code += " name: '" + entity.name + "'\n";
|
|
40
|
+
code += " unique:\n";
|
|
41
|
+
code += this.formatUniqueFields(model, entity);
|
|
42
|
+
let columnsCode = "";
|
|
43
|
+
let hasOneCode = "";
|
|
44
|
+
let hasManyCode = "";
|
|
45
|
+
schemaUtils.acceptEveryFieldVisitor(model, entity, {
|
|
46
|
+
visitHasMany: (ctx) => {
|
|
47
|
+
hasManyCode += ` ${ctx.relation.name}: ${ctx.targetEntity.name}
|
|
48
|
+
`;
|
|
49
|
+
},
|
|
50
|
+
visitHasOne: (ctx) => {
|
|
51
|
+
hasOneCode += ` ${ctx.relation.name}: ${ctx.targetEntity.name}
|
|
52
|
+
`;
|
|
53
|
+
},
|
|
54
|
+
visitColumn: (ctx) => {
|
|
55
|
+
columnsCode += ` ${ctx.column.name}: ${columnToTsType(ctx.column)}${ctx.column.nullable ? ` | null` : ""}
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
code += " columns: {\n";
|
|
60
|
+
code += columnsCode;
|
|
61
|
+
code += " }\n";
|
|
62
|
+
code += " hasOne: {\n";
|
|
63
|
+
code += hasOneCode;
|
|
64
|
+
code += " }\n";
|
|
65
|
+
code += " hasMany: {\n";
|
|
66
|
+
code += hasManyCode;
|
|
67
|
+
code += " }\n";
|
|
68
|
+
code += " hasManyBy: {\n";
|
|
69
|
+
code += this.formatReducedFields(model, entity);
|
|
70
|
+
code += " }\n";
|
|
71
|
+
code += "}\n";
|
|
72
|
+
return code;
|
|
73
|
+
}
|
|
74
|
+
formatReducedFields(model, entity) {
|
|
75
|
+
let code = "";
|
|
76
|
+
schemaUtils.acceptEveryFieldVisitor(model, entity, {
|
|
77
|
+
visitOneHasMany: ({ entity: entity2, relation, targetEntity, targetRelation }) => {
|
|
78
|
+
if (!targetRelation) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const uniqueConstraints = getFieldsForUniqueWhere(model, targetEntity);
|
|
82
|
+
const composedUnique = uniqueConstraints.filter((fields) => fields.length === 2).filter((fields) => fields.includes(targetRelation.name)).map((fields) => fields.filter((it) => it !== targetRelation.name)).map((fields) => fields[0]);
|
|
83
|
+
const singleUnique = uniqueConstraints.filter((fields) => fields.length === 1 && fields[0] !== targetEntity.primary).map((fields) => fields[0]).filter((it) => it !== targetRelation.name);
|
|
84
|
+
[...composedUnique, ...singleUnique].forEach((fieldName) => {
|
|
85
|
+
const capitalizeFirstLetter = (value) => {
|
|
86
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
87
|
+
};
|
|
88
|
+
const name = `${relation.name}By${capitalizeFirstLetter(fieldName)}`;
|
|
89
|
+
const targetUnique = targetEntity.fields[fieldName];
|
|
90
|
+
code += ` ${name}: { entity: ${targetEntity.name}; by: {${fieldName}: ${uniqueType(model, targetEntity, targetUnique)}} }
|
|
91
|
+
`;
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
visitColumn: () => {
|
|
95
|
+
},
|
|
96
|
+
visitManyHasManyInverse: () => {
|
|
97
|
+
},
|
|
98
|
+
visitManyHasManyOwning: () => {
|
|
99
|
+
},
|
|
100
|
+
visitManyHasOne: () => {
|
|
101
|
+
},
|
|
102
|
+
visitOneHasOneInverse: () => {
|
|
103
|
+
},
|
|
104
|
+
visitOneHasOneOwning: () => {
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return code;
|
|
108
|
+
}
|
|
109
|
+
formatUniqueFields(model, entity) {
|
|
110
|
+
const fields = getFieldsForUniqueWhere(model, entity);
|
|
111
|
+
let code = "";
|
|
112
|
+
for (const field of fields) {
|
|
113
|
+
code += " | { ";
|
|
114
|
+
code += field.map((it) => `${it}: ${uniqueType(model, entity, entity.fields[it])}`).join(", ");
|
|
115
|
+
code += " }\n";
|
|
116
|
+
}
|
|
117
|
+
return code;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const uniqueType = (model, entity, field) => {
|
|
121
|
+
return schemaUtils.acceptFieldVisitor(model, entity, field, {
|
|
122
|
+
visitColumn: (ctx) => {
|
|
123
|
+
return columnToTsType(ctx.column);
|
|
124
|
+
},
|
|
125
|
+
visitRelation: (ctx) => {
|
|
126
|
+
return ctx.targetEntity.name + `['unique']`;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
const columnToTsType = (column) => {
|
|
131
|
+
switch (column.type) {
|
|
132
|
+
case schema.Model.ColumnType.Enum:
|
|
133
|
+
return column.columnType;
|
|
134
|
+
case schema.Model.ColumnType.String:
|
|
135
|
+
return "string";
|
|
136
|
+
case schema.Model.ColumnType.Int:
|
|
137
|
+
return "number";
|
|
138
|
+
case schema.Model.ColumnType.Double:
|
|
139
|
+
return "number";
|
|
140
|
+
case schema.Model.ColumnType.Bool:
|
|
141
|
+
return "boolean";
|
|
142
|
+
case schema.Model.ColumnType.DateTime:
|
|
143
|
+
return "string";
|
|
144
|
+
case schema.Model.ColumnType.Date:
|
|
145
|
+
return "string";
|
|
146
|
+
case schema.Model.ColumnType.Json:
|
|
147
|
+
return "JSONValue";
|
|
148
|
+
case schema.Model.ColumnType.Uuid:
|
|
149
|
+
return "string";
|
|
150
|
+
default:
|
|
151
|
+
((_) => {
|
|
152
|
+
throw new Error(`Unknown type ${_}`);
|
|
153
|
+
})(column.type);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const getFieldsForUniqueWhere = (schema2, entity) => {
|
|
157
|
+
const relations = Object.values(
|
|
158
|
+
schemaUtils.acceptEveryFieldVisitor(schema2, entity, {
|
|
159
|
+
visitColumn: () => void 0,
|
|
160
|
+
visitManyHasManyInverse: () => void 0,
|
|
161
|
+
visitManyHasManyOwning: () => void 0,
|
|
162
|
+
visitOneHasMany: ({ relation }) => [relation.name],
|
|
163
|
+
visitManyHasOne: () => void 0,
|
|
164
|
+
visitOneHasOneInverse: ({ relation }) => [relation.name],
|
|
165
|
+
visitOneHasOneOwning: ({ relation }) => [relation.name]
|
|
166
|
+
})
|
|
167
|
+
).filter((it) => !!it);
|
|
168
|
+
return [[entity.primary], ...Object.values(entity.unique).map((it) => it.fields), ...relations];
|
|
169
|
+
};
|
|
170
|
+
exports.EntityTypeSchemaGenerator = EntityTypeSchemaGenerator;
|
|
171
|
+
//# sourceMappingURL=EntityTypeSchemaGenerator.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityTypeSchemaGenerator.cjs","sources":["../../src/EntityTypeSchemaGenerator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { acceptEveryFieldVisitor, acceptFieldVisitor } from '@contember/schema-utils'\n\nexport class EntityTypeSchemaGenerator {\n\tgenerate(model: Model.Schema): string {\n\t\tlet code = ''\n\t\tfor (const enumName of Object.keys(model.enums)) {\n\t\t\tcode += `import type { ${enumName} } from './enums'\\n`\n\t\t}\n\n\t\tcode += `\nexport type JSONPrimitive = string | number | boolean | null\nexport type JSONValue = JSONPrimitive | JSONObject | JSONArray\nexport type JSONObject = { readonly [K in string]?: JSONValue }\nexport type JSONArray = readonly JSONValue[]\n\n`\n\n\t\tfor (const entity of Object.values(model.entities)) {\n\t\t\tcode += this.generateTypeEntityCode(model, entity)\n\t\t}\n\t\tcode += '\\n'\n\t\tcode += `export type ContemberClientEntities = {\\n`\n\t\tfor (const entity of Object.values(model.entities)) {\n\t\t\tcode += `\\t${entity.name}: ${entity.name}\\n`\n\t\t}\n\t\tcode += '}\\n\\n'\n\t\tcode += `export type ContemberClientSchema = {\\n`\n\t\tcode += '\\tentities: ContemberClientEntities\\n'\n\t\tcode += '}\\n'\n\t\treturn code\n\t}\n\n\tprivate generateTypeEntityCode(model: Model.Schema, entity: Model.Entity): string {\n\t\tlet code = `export type ${entity.name} = {\\n`\n\t\tcode += '\\tname: \\'' + entity.name + '\\'\\n'\n\t\tcode += '\\tunique:\\n'\n\t\tcode += this.formatUniqueFields(model, entity)\n\t\tlet columnsCode = ''\n\t\tlet hasOneCode = ''\n\t\tlet hasManyCode = ''\n\t\tacceptEveryFieldVisitor(model, entity, {\n\t\t\tvisitHasMany: ctx => {\n\t\t\t\thasManyCode += `\\t\\t${ctx.relation.name}: ${ctx.targetEntity.name}\\n`\n\t\t\t},\n\t\t\tvisitHasOne: ctx => {\n\t\t\t\thasOneCode += `\\t\\t${ctx.relation.name}: ${ctx.targetEntity.name}\\n`\n\t\t\t},\n\t\t\tvisitColumn: ctx => {\n\t\t\t\tcolumnsCode += `\\t\\t${ctx.column.name}: ${columnToTsType(ctx.column)}${ctx.column.nullable ? ` | null` : ''}\\n`\n\t\t\t},\n\t\t})\n\n\t\tcode += '\\tcolumns: {\\n'\n\t\tcode += columnsCode\n\t\tcode += '\\t}\\n'\n\t\tcode += '\\thasOne: {\\n'\n\t\tcode += hasOneCode\n\t\tcode += '\\t}\\n'\n\t\tcode += '\\thasMany: {\\n'\n\t\tcode += hasManyCode\n\t\tcode += '\\t}\\n'\n\t\tcode += '\\thasManyBy: {\\n'\n\t\tcode += this.formatReducedFields(model, entity)\n\t\tcode += '\\t}\\n'\n\t\tcode += '}\\n'\n\t\treturn code\n\t}\n\n\tprivate formatReducedFields(model: Model.Schema, entity: Model.Entity): string {\n\t\tlet code = ''\n\t\tacceptEveryFieldVisitor(model, entity, {\n\t\t\tvisitOneHasMany: ({ entity, relation, targetEntity, targetRelation }) => {\n\t\t\t\tif (!targetRelation) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst uniqueConstraints = getFieldsForUniqueWhere(model, targetEntity)\n\t\t\t\tconst composedUnique = uniqueConstraints\n\t\t\t\t\t.filter(fields => fields.length === 2) //todo support all uniques\n\t\t\t\t\t.filter(fields => fields.includes(targetRelation.name))\n\t\t\t\t\t.map(fields => fields.filter(it => it !== targetRelation.name))\n\t\t\t\t\t.map(fields => fields[0])\n\t\t\t\tconst singleUnique = uniqueConstraints\n\t\t\t\t\t.filter(fields => fields.length === 1 && fields[0] !== targetEntity.primary)\n\t\t\t\t\t.map(fields => fields[0])\n\t\t\t\t\t.filter(it => it !== targetRelation.name)\n\n\t\t\t\t;[...composedUnique, ...singleUnique].forEach(fieldName => {\n\t\t\t\t\tconst capitalizeFirstLetter = (value: string) => {\n\t\t\t\t\t\treturn value.charAt(0).toUpperCase() + value.slice(1)\n\t\t\t\t\t}\n\t\t\t\t\tconst name = `${relation.name}By${capitalizeFirstLetter(fieldName)}`\n\n\t\t\t\t\tconst targetUnique = targetEntity.fields[fieldName]\n\n\t\t\t\t\tcode += `\\t\\t${name}: { entity: ${targetEntity.name}; by: {${fieldName}: ${uniqueType(model, targetEntity, targetUnique)}} }\\n`\n\n\t\t\t\t})\n\t\t\t},\n\t\t\tvisitColumn: () => {\n\t\t\t},\n\t\t\tvisitManyHasManyInverse: () => {\n\t\t\t},\n\t\t\tvisitManyHasManyOwning: () => {\n\t\t\t},\n\t\t\tvisitManyHasOne: () => {\n\t\t\t},\n\t\t\tvisitOneHasOneInverse: () => {\n\t\t\t},\n\t\t\tvisitOneHasOneOwning: () => {\n\t\t\t},\n\t\t})\n\t\treturn code\n\t}\n\n\tprivate formatUniqueFields(model: Model.Schema, entity: Model.Entity): string {\n\t\tconst fields = getFieldsForUniqueWhere(model, entity)\n\t\tlet code = ''\n\t\tfor (const field of fields) {\n\t\t\tcode += '\\t\\t| { '\n\t\t\tcode += field.map(it => `${it}: ${uniqueType(model, entity, entity.fields[it])}`).join(', ')\n\t\t\tcode += ' }\\n'\n\t\t}\n\t\treturn code\n\t}\n}\n\n\nconst uniqueType = (model: Model.Schema, entity: Model.Entity, field: Model.AnyField): string => {\n\treturn acceptFieldVisitor(model, entity, field, {\n\t\tvisitColumn: ctx => {\n\t\t\treturn columnToTsType(ctx.column)\n\t\t},\n\t\tvisitRelation: ctx => {\n\t\t\treturn ctx.targetEntity.name + `['unique']`\n\t\t},\n\t})\n}\n\n\nconst columnToTsType = (column: Model.AnyColumn): string => {\n\tswitch (column.type) {\n\t\tcase Model.ColumnType.Enum:\n\t\t\treturn column.columnType\n\t\tcase Model.ColumnType.String:\n\t\t\treturn 'string'\n\t\tcase Model.ColumnType.Int:\n\t\t\treturn 'number'\n\t\tcase Model.ColumnType.Double:\n\t\t\treturn 'number'\n\t\tcase Model.ColumnType.Bool:\n\t\t\treturn 'boolean'\n\t\tcase Model.ColumnType.DateTime:\n\t\t\treturn 'string'\n\t\tcase Model.ColumnType.Date:\n\t\t\treturn 'string'\n\t\tcase Model.ColumnType.Json:\n\t\t\treturn 'JSONValue'\n\t\tcase Model.ColumnType.Uuid:\n\t\t\treturn 'string'\n\t\tdefault:\n\t\t\t((_: never) => {\n\t\t\t\tthrow new Error(`Unknown type ${_}`)\n\t\t\t})(column.type)\n\t}\n}\n\nconst getFieldsForUniqueWhere = (schema: Model.Schema, entity: Model.Entity): readonly (readonly string[])[] => {\n\tconst relations = Object.values(\n\t\tacceptEveryFieldVisitor<undefined | [string]>(schema, entity, {\n\t\t\tvisitColumn: () => undefined,\n\t\t\tvisitManyHasManyInverse: () => undefined,\n\t\t\tvisitManyHasManyOwning: () => undefined,\n\t\t\tvisitOneHasMany: ({ relation }) => [relation.name],\n\t\t\tvisitManyHasOne: () => undefined,\n\t\t\tvisitOneHasOneInverse: ({ relation }) => [relation.name],\n\t\t\tvisitOneHasOneOwning: ({ relation }) => [relation.name],\n\t\t}),\n\t).filter((it): it is [string] => !!it)\n\n\treturn [[entity.primary], ...Object.values(entity.unique).map(it => it.fields), ...relations]\n}\n"],"names":["acceptEveryFieldVisitor","entity","acceptFieldVisitor","Model","schema"],"mappings":"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"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { Model } from "@contember/schema";
|
|
2
|
+
import { acceptEveryFieldVisitor, acceptFieldVisitor } from "@contember/schema-utils";
|
|
3
|
+
class EntityTypeSchemaGenerator {
|
|
4
|
+
generate(model) {
|
|
5
|
+
let code = "";
|
|
6
|
+
for (const enumName of Object.keys(model.enums)) {
|
|
7
|
+
code += `import type { ${enumName} } from './enums'
|
|
8
|
+
`;
|
|
9
|
+
}
|
|
10
|
+
code += `
|
|
11
|
+
export type JSONPrimitive = string | number | boolean | null
|
|
12
|
+
export type JSONValue = JSONPrimitive | JSONObject | JSONArray
|
|
13
|
+
export type JSONObject = { readonly [K in string]?: JSONValue }
|
|
14
|
+
export type JSONArray = readonly JSONValue[]
|
|
15
|
+
|
|
16
|
+
`;
|
|
17
|
+
for (const entity of Object.values(model.entities)) {
|
|
18
|
+
code += this.generateTypeEntityCode(model, entity);
|
|
19
|
+
}
|
|
20
|
+
code += "\n";
|
|
21
|
+
code += `export type ContemberClientEntities = {
|
|
22
|
+
`;
|
|
23
|
+
for (const entity of Object.values(model.entities)) {
|
|
24
|
+
code += ` ${entity.name}: ${entity.name}
|
|
25
|
+
`;
|
|
26
|
+
}
|
|
27
|
+
code += "}\n\n";
|
|
28
|
+
code += `export type ContemberClientSchema = {
|
|
29
|
+
`;
|
|
30
|
+
code += " entities: ContemberClientEntities\n";
|
|
31
|
+
code += "}\n";
|
|
32
|
+
return code;
|
|
33
|
+
}
|
|
34
|
+
generateTypeEntityCode(model, entity) {
|
|
35
|
+
let code = `export type ${entity.name} = {
|
|
36
|
+
`;
|
|
37
|
+
code += " name: '" + entity.name + "'\n";
|
|
38
|
+
code += " unique:\n";
|
|
39
|
+
code += this.formatUniqueFields(model, entity);
|
|
40
|
+
let columnsCode = "";
|
|
41
|
+
let hasOneCode = "";
|
|
42
|
+
let hasManyCode = "";
|
|
43
|
+
acceptEveryFieldVisitor(model, entity, {
|
|
44
|
+
visitHasMany: (ctx) => {
|
|
45
|
+
hasManyCode += ` ${ctx.relation.name}: ${ctx.targetEntity.name}
|
|
46
|
+
`;
|
|
47
|
+
},
|
|
48
|
+
visitHasOne: (ctx) => {
|
|
49
|
+
hasOneCode += ` ${ctx.relation.name}: ${ctx.targetEntity.name}
|
|
50
|
+
`;
|
|
51
|
+
},
|
|
52
|
+
visitColumn: (ctx) => {
|
|
53
|
+
columnsCode += ` ${ctx.column.name}: ${columnToTsType(ctx.column)}${ctx.column.nullable ? ` | null` : ""}
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
code += " columns: {\n";
|
|
58
|
+
code += columnsCode;
|
|
59
|
+
code += " }\n";
|
|
60
|
+
code += " hasOne: {\n";
|
|
61
|
+
code += hasOneCode;
|
|
62
|
+
code += " }\n";
|
|
63
|
+
code += " hasMany: {\n";
|
|
64
|
+
code += hasManyCode;
|
|
65
|
+
code += " }\n";
|
|
66
|
+
code += " hasManyBy: {\n";
|
|
67
|
+
code += this.formatReducedFields(model, entity);
|
|
68
|
+
code += " }\n";
|
|
69
|
+
code += "}\n";
|
|
70
|
+
return code;
|
|
71
|
+
}
|
|
72
|
+
formatReducedFields(model, entity) {
|
|
73
|
+
let code = "";
|
|
74
|
+
acceptEveryFieldVisitor(model, entity, {
|
|
75
|
+
visitOneHasMany: ({ entity: entity2, relation, targetEntity, targetRelation }) => {
|
|
76
|
+
if (!targetRelation) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const uniqueConstraints = getFieldsForUniqueWhere(model, targetEntity);
|
|
80
|
+
const composedUnique = uniqueConstraints.filter((fields) => fields.length === 2).filter((fields) => fields.includes(targetRelation.name)).map((fields) => fields.filter((it) => it !== targetRelation.name)).map((fields) => fields[0]);
|
|
81
|
+
const singleUnique = uniqueConstraints.filter((fields) => fields.length === 1 && fields[0] !== targetEntity.primary).map((fields) => fields[0]).filter((it) => it !== targetRelation.name);
|
|
82
|
+
[...composedUnique, ...singleUnique].forEach((fieldName) => {
|
|
83
|
+
const capitalizeFirstLetter = (value) => {
|
|
84
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
85
|
+
};
|
|
86
|
+
const name = `${relation.name}By${capitalizeFirstLetter(fieldName)}`;
|
|
87
|
+
const targetUnique = targetEntity.fields[fieldName];
|
|
88
|
+
code += ` ${name}: { entity: ${targetEntity.name}; by: {${fieldName}: ${uniqueType(model, targetEntity, targetUnique)}} }
|
|
89
|
+
`;
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
visitColumn: () => {
|
|
93
|
+
},
|
|
94
|
+
visitManyHasManyInverse: () => {
|
|
95
|
+
},
|
|
96
|
+
visitManyHasManyOwning: () => {
|
|
97
|
+
},
|
|
98
|
+
visitManyHasOne: () => {
|
|
99
|
+
},
|
|
100
|
+
visitOneHasOneInverse: () => {
|
|
101
|
+
},
|
|
102
|
+
visitOneHasOneOwning: () => {
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return code;
|
|
106
|
+
}
|
|
107
|
+
formatUniqueFields(model, entity) {
|
|
108
|
+
const fields = getFieldsForUniqueWhere(model, entity);
|
|
109
|
+
let code = "";
|
|
110
|
+
for (const field of fields) {
|
|
111
|
+
code += " | { ";
|
|
112
|
+
code += field.map((it) => `${it}: ${uniqueType(model, entity, entity.fields[it])}`).join(", ");
|
|
113
|
+
code += " }\n";
|
|
114
|
+
}
|
|
115
|
+
return code;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const uniqueType = (model, entity, field) => {
|
|
119
|
+
return acceptFieldVisitor(model, entity, field, {
|
|
120
|
+
visitColumn: (ctx) => {
|
|
121
|
+
return columnToTsType(ctx.column);
|
|
122
|
+
},
|
|
123
|
+
visitRelation: (ctx) => {
|
|
124
|
+
return ctx.targetEntity.name + `['unique']`;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
const columnToTsType = (column) => {
|
|
129
|
+
switch (column.type) {
|
|
130
|
+
case Model.ColumnType.Enum:
|
|
131
|
+
return column.columnType;
|
|
132
|
+
case Model.ColumnType.String:
|
|
133
|
+
return "string";
|
|
134
|
+
case Model.ColumnType.Int:
|
|
135
|
+
return "number";
|
|
136
|
+
case Model.ColumnType.Double:
|
|
137
|
+
return "number";
|
|
138
|
+
case Model.ColumnType.Bool:
|
|
139
|
+
return "boolean";
|
|
140
|
+
case Model.ColumnType.DateTime:
|
|
141
|
+
return "string";
|
|
142
|
+
case Model.ColumnType.Date:
|
|
143
|
+
return "string";
|
|
144
|
+
case Model.ColumnType.Json:
|
|
145
|
+
return "JSONValue";
|
|
146
|
+
case Model.ColumnType.Uuid:
|
|
147
|
+
return "string";
|
|
148
|
+
default:
|
|
149
|
+
((_) => {
|
|
150
|
+
throw new Error(`Unknown type ${_}`);
|
|
151
|
+
})(column.type);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const getFieldsForUniqueWhere = (schema, entity) => {
|
|
155
|
+
const relations = Object.values(
|
|
156
|
+
acceptEveryFieldVisitor(schema, entity, {
|
|
157
|
+
visitColumn: () => void 0,
|
|
158
|
+
visitManyHasManyInverse: () => void 0,
|
|
159
|
+
visitManyHasManyOwning: () => void 0,
|
|
160
|
+
visitOneHasMany: ({ relation }) => [relation.name],
|
|
161
|
+
visitManyHasOne: () => void 0,
|
|
162
|
+
visitOneHasOneInverse: ({ relation }) => [relation.name],
|
|
163
|
+
visitOneHasOneOwning: ({ relation }) => [relation.name]
|
|
164
|
+
})
|
|
165
|
+
).filter((it) => !!it);
|
|
166
|
+
return [[entity.primary], ...Object.values(entity.unique).map((it) => it.fields), ...relations];
|
|
167
|
+
};
|
|
168
|
+
export {
|
|
169
|
+
EntityTypeSchemaGenerator
|
|
170
|
+
};
|
|
171
|
+
//# sourceMappingURL=EntityTypeSchemaGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityTypeSchemaGenerator.js","sources":["../../src/EntityTypeSchemaGenerator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { acceptEveryFieldVisitor, acceptFieldVisitor } from '@contember/schema-utils'\n\nexport class EntityTypeSchemaGenerator {\n\tgenerate(model: Model.Schema): string {\n\t\tlet code = ''\n\t\tfor (const enumName of Object.keys(model.enums)) {\n\t\t\tcode += `import type { ${enumName} } from './enums'\\n`\n\t\t}\n\n\t\tcode += `\nexport type JSONPrimitive = string | number | boolean | null\nexport type JSONValue = JSONPrimitive | JSONObject | JSONArray\nexport type JSONObject = { readonly [K in string]?: JSONValue }\nexport type JSONArray = readonly JSONValue[]\n\n`\n\n\t\tfor (const entity of Object.values(model.entities)) {\n\t\t\tcode += this.generateTypeEntityCode(model, entity)\n\t\t}\n\t\tcode += '\\n'\n\t\tcode += `export type ContemberClientEntities = {\\n`\n\t\tfor (const entity of Object.values(model.entities)) {\n\t\t\tcode += `\\t${entity.name}: ${entity.name}\\n`\n\t\t}\n\t\tcode += '}\\n\\n'\n\t\tcode += `export type ContemberClientSchema = {\\n`\n\t\tcode += '\\tentities: ContemberClientEntities\\n'\n\t\tcode += '}\\n'\n\t\treturn code\n\t}\n\n\tprivate generateTypeEntityCode(model: Model.Schema, entity: Model.Entity): string {\n\t\tlet code = `export type ${entity.name} = {\\n`\n\t\tcode += '\\tname: \\'' + entity.name + '\\'\\n'\n\t\tcode += '\\tunique:\\n'\n\t\tcode += this.formatUniqueFields(model, entity)\n\t\tlet columnsCode = ''\n\t\tlet hasOneCode = ''\n\t\tlet hasManyCode = ''\n\t\tacceptEveryFieldVisitor(model, entity, {\n\t\t\tvisitHasMany: ctx => {\n\t\t\t\thasManyCode += `\\t\\t${ctx.relation.name}: ${ctx.targetEntity.name}\\n`\n\t\t\t},\n\t\t\tvisitHasOne: ctx => {\n\t\t\t\thasOneCode += `\\t\\t${ctx.relation.name}: ${ctx.targetEntity.name}\\n`\n\t\t\t},\n\t\t\tvisitColumn: ctx => {\n\t\t\t\tcolumnsCode += `\\t\\t${ctx.column.name}: ${columnToTsType(ctx.column)}${ctx.column.nullable ? ` | null` : ''}\\n`\n\t\t\t},\n\t\t})\n\n\t\tcode += '\\tcolumns: {\\n'\n\t\tcode += columnsCode\n\t\tcode += '\\t}\\n'\n\t\tcode += '\\thasOne: {\\n'\n\t\tcode += hasOneCode\n\t\tcode += '\\t}\\n'\n\t\tcode += '\\thasMany: {\\n'\n\t\tcode += hasManyCode\n\t\tcode += '\\t}\\n'\n\t\tcode += '\\thasManyBy: {\\n'\n\t\tcode += this.formatReducedFields(model, entity)\n\t\tcode += '\\t}\\n'\n\t\tcode += '}\\n'\n\t\treturn code\n\t}\n\n\tprivate formatReducedFields(model: Model.Schema, entity: Model.Entity): string {\n\t\tlet code = ''\n\t\tacceptEveryFieldVisitor(model, entity, {\n\t\t\tvisitOneHasMany: ({ entity, relation, targetEntity, targetRelation }) => {\n\t\t\t\tif (!targetRelation) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst uniqueConstraints = getFieldsForUniqueWhere(model, targetEntity)\n\t\t\t\tconst composedUnique = uniqueConstraints\n\t\t\t\t\t.filter(fields => fields.length === 2) //todo support all uniques\n\t\t\t\t\t.filter(fields => fields.includes(targetRelation.name))\n\t\t\t\t\t.map(fields => fields.filter(it => it !== targetRelation.name))\n\t\t\t\t\t.map(fields => fields[0])\n\t\t\t\tconst singleUnique = uniqueConstraints\n\t\t\t\t\t.filter(fields => fields.length === 1 && fields[0] !== targetEntity.primary)\n\t\t\t\t\t.map(fields => fields[0])\n\t\t\t\t\t.filter(it => it !== targetRelation.name)\n\n\t\t\t\t;[...composedUnique, ...singleUnique].forEach(fieldName => {\n\t\t\t\t\tconst capitalizeFirstLetter = (value: string) => {\n\t\t\t\t\t\treturn value.charAt(0).toUpperCase() + value.slice(1)\n\t\t\t\t\t}\n\t\t\t\t\tconst name = `${relation.name}By${capitalizeFirstLetter(fieldName)}`\n\n\t\t\t\t\tconst targetUnique = targetEntity.fields[fieldName]\n\n\t\t\t\t\tcode += `\\t\\t${name}: { entity: ${targetEntity.name}; by: {${fieldName}: ${uniqueType(model, targetEntity, targetUnique)}} }\\n`\n\n\t\t\t\t})\n\t\t\t},\n\t\t\tvisitColumn: () => {\n\t\t\t},\n\t\t\tvisitManyHasManyInverse: () => {\n\t\t\t},\n\t\t\tvisitManyHasManyOwning: () => {\n\t\t\t},\n\t\t\tvisitManyHasOne: () => {\n\t\t\t},\n\t\t\tvisitOneHasOneInverse: () => {\n\t\t\t},\n\t\t\tvisitOneHasOneOwning: () => {\n\t\t\t},\n\t\t})\n\t\treturn code\n\t}\n\n\tprivate formatUniqueFields(model: Model.Schema, entity: Model.Entity): string {\n\t\tconst fields = getFieldsForUniqueWhere(model, entity)\n\t\tlet code = ''\n\t\tfor (const field of fields) {\n\t\t\tcode += '\\t\\t| { '\n\t\t\tcode += field.map(it => `${it}: ${uniqueType(model, entity, entity.fields[it])}`).join(', ')\n\t\t\tcode += ' }\\n'\n\t\t}\n\t\treturn code\n\t}\n}\n\n\nconst uniqueType = (model: Model.Schema, entity: Model.Entity, field: Model.AnyField): string => {\n\treturn acceptFieldVisitor(model, entity, field, {\n\t\tvisitColumn: ctx => {\n\t\t\treturn columnToTsType(ctx.column)\n\t\t},\n\t\tvisitRelation: ctx => {\n\t\t\treturn ctx.targetEntity.name + `['unique']`\n\t\t},\n\t})\n}\n\n\nconst columnToTsType = (column: Model.AnyColumn): string => {\n\tswitch (column.type) {\n\t\tcase Model.ColumnType.Enum:\n\t\t\treturn column.columnType\n\t\tcase Model.ColumnType.String:\n\t\t\treturn 'string'\n\t\tcase Model.ColumnType.Int:\n\t\t\treturn 'number'\n\t\tcase Model.ColumnType.Double:\n\t\t\treturn 'number'\n\t\tcase Model.ColumnType.Bool:\n\t\t\treturn 'boolean'\n\t\tcase Model.ColumnType.DateTime:\n\t\t\treturn 'string'\n\t\tcase Model.ColumnType.Date:\n\t\t\treturn 'string'\n\t\tcase Model.ColumnType.Json:\n\t\t\treturn 'JSONValue'\n\t\tcase Model.ColumnType.Uuid:\n\t\t\treturn 'string'\n\t\tdefault:\n\t\t\t((_: never) => {\n\t\t\t\tthrow new Error(`Unknown type ${_}`)\n\t\t\t})(column.type)\n\t}\n}\n\nconst getFieldsForUniqueWhere = (schema: Model.Schema, entity: Model.Entity): readonly (readonly string[])[] => {\n\tconst relations = Object.values(\n\t\tacceptEveryFieldVisitor<undefined | [string]>(schema, entity, {\n\t\t\tvisitColumn: () => undefined,\n\t\t\tvisitManyHasManyInverse: () => undefined,\n\t\t\tvisitManyHasManyOwning: () => undefined,\n\t\t\tvisitOneHasMany: ({ relation }) => [relation.name],\n\t\t\tvisitManyHasOne: () => undefined,\n\t\t\tvisitOneHasOneInverse: ({ relation }) => [relation.name],\n\t\t\tvisitOneHasOneOwning: ({ relation }) => [relation.name],\n\t\t}),\n\t).filter((it): it is [string] => !!it)\n\n\treturn [[entity.primary], ...Object.values(entity.unique).map(it => it.fields), ...relations]\n}\n"],"names":["entity"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
class EnumTypeSchemaGenerator {
|
|
4
|
+
generate(model) {
|
|
5
|
+
let code = "";
|
|
6
|
+
for (const [enumName, values] of Object.entries(model.enums)) {
|
|
7
|
+
code += `export type ${enumName} = ${values.map((it) => "\n | " + JSON.stringify(it)).join("")}
|
|
8
|
+
`;
|
|
9
|
+
}
|
|
10
|
+
return code || "export {}\n";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.EnumTypeSchemaGenerator = EnumTypeSchemaGenerator;
|
|
14
|
+
//# sourceMappingURL=EnumTypeSchemaGenerator.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnumTypeSchemaGenerator.cjs","sources":["../../src/EnumTypeSchemaGenerator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\n\nexport class EnumTypeSchemaGenerator {\n\tgenerate(model: Model.Schema): string {\n\t\tlet code = ''\n\t\tfor (const [enumName, values] of Object.entries(model.enums)) {\n\t\t\tcode += `export type ${enumName} = ${values.map(it => '\\n\\t | ' + JSON.stringify(it)).join('')}\\n`\n\t\t}\n\n\t\treturn code || 'export {}\\n'\n\t}\n}\n"],"names":[],"mappings":";;AAEO,MAAM,wBAAwB;AAAA,EACpC,SAAS,OAA6B;AACrC,QAAI,OAAO;AACA,eAAA,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQ,MAAM,KAAK,GAAG;AAC7D,cAAQ,eAAe,cAAc,OAAO,IAAI,CAAM,OAAA,WAAY,KAAK,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE;AAAA;AAAA,IAC9F;AAEA,WAAO,QAAQ;AAAA,EAChB;AACD;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class EnumTypeSchemaGenerator {
|
|
2
|
+
generate(model) {
|
|
3
|
+
let code = "";
|
|
4
|
+
for (const [enumName, values] of Object.entries(model.enums)) {
|
|
5
|
+
code += `export type ${enumName} = ${values.map((it) => "\n | " + JSON.stringify(it)).join("")}
|
|
6
|
+
`;
|
|
7
|
+
}
|
|
8
|
+
return code || "export {}\n";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
EnumTypeSchemaGenerator
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=EnumTypeSchemaGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnumTypeSchemaGenerator.js","sources":["../../src/EnumTypeSchemaGenerator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\n\nexport class EnumTypeSchemaGenerator {\n\tgenerate(model: Model.Schema): string {\n\t\tlet code = ''\n\t\tfor (const [enumName, values] of Object.entries(model.enums)) {\n\t\t\tcode += `export type ${enumName} = ${values.map(it => '\\n\\t | ' + JSON.stringify(it)).join('')}\\n`\n\t\t}\n\n\t\treturn code || 'export {}\\n'\n\t}\n}\n"],"names":[],"mappings":"AAEO,MAAM,wBAAwB;AAAA,EACpC,SAAS,OAA6B;AACrC,QAAI,OAAO;AACA,eAAA,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQ,MAAM,KAAK,GAAG;AAC7D,cAAQ,eAAe,cAAc,OAAO,IAAI,CAAM,OAAA,WAAY,KAAK,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE;AAAA;AAAA,IAC9F;AAEA,WAAO,QAAQ;AAAA,EAChB;AACD;"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const schemaUtils = require("@contember/schema-utils");
|
|
4
|
+
class NameSchemaGenerator {
|
|
5
|
+
generate(model) {
|
|
6
|
+
return {
|
|
7
|
+
entities: Object.fromEntries(
|
|
8
|
+
Object.values(model.entities).map((entity) => {
|
|
9
|
+
const fields = {};
|
|
10
|
+
const scalars = [];
|
|
11
|
+
schemaUtils.acceptEveryFieldVisitor(model, entity, {
|
|
12
|
+
visitHasOne: (ctx) => {
|
|
13
|
+
fields[ctx.relation.name] = {
|
|
14
|
+
type: "one",
|
|
15
|
+
entity: ctx.targetEntity.name
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
visitHasMany: (ctx) => {
|
|
19
|
+
fields[ctx.relation.name] = {
|
|
20
|
+
type: "many",
|
|
21
|
+
entity: ctx.targetEntity.name
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
visitColumn: (ctx) => {
|
|
25
|
+
scalars.push(ctx.column.name);
|
|
26
|
+
fields[ctx.column.name] = {
|
|
27
|
+
type: "column"
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return [entity.name, { name: entity.name, fields, scalars }];
|
|
32
|
+
})
|
|
33
|
+
)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.NameSchemaGenerator = NameSchemaGenerator;
|
|
38
|
+
//# sourceMappingURL=NameSchemaGenerator.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NameSchemaGenerator.cjs","sources":["../../src/NameSchemaGenerator.ts"],"sourcesContent":["import { SchemaNames, SchemaEntityNames } from '@contember/client-content'\nimport { Model } from '@contember/schema'\nimport { acceptEveryFieldVisitor } from '@contember/schema-utils'\n\nexport class NameSchemaGenerator {\n\tgenerate(model: Model.Schema): SchemaNames {\n\t\treturn {\n\t\t\tentities: Object.fromEntries(\n\t\t\t\tObject.values(model.entities).map(entity => {\n\t\t\t\t\tconst fields: Record<string, SchemaEntityNames<any>['fields'][string]> = {}\n\t\t\t\t\tconst scalars: string[] = []\n\n\t\t\t\t\tacceptEveryFieldVisitor(model, entity, {\n\t\t\t\t\t\tvisitHasOne: ctx => {\n\t\t\t\t\t\t\tfields[ctx.relation.name] = {\n\t\t\t\t\t\t\t\ttype: 'one',\n\t\t\t\t\t\t\t\tentity: ctx.targetEntity.name,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvisitHasMany: ctx => {\n\t\t\t\t\t\t\tfields[ctx.relation.name] = {\n\t\t\t\t\t\t\t\ttype: 'many',\n\t\t\t\t\t\t\t\tentity: ctx.targetEntity.name,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvisitColumn: ctx => {\n\t\t\t\t\t\t\tscalars.push(ctx.column.name)\n\t\t\t\t\t\t\tfields[ctx.column.name] = {\n\t\t\t\t\t\t\t\ttype: 'column',\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\treturn [entity.name, { name: entity.name, fields, scalars }]\n\t\t\t\t}),\n\t\t\t),\n\t\t}\n\t}\n}\n\n\n"],"names":["acceptEveryFieldVisitor"],"mappings":";;;AAIO,MAAM,oBAAoB;AAAA,EAChC,SAAS,OAAkC;AACnC,WAAA;AAAA,MACN,UAAU,OAAO;AAAA,QAChB,OAAO,OAAO,MAAM,QAAQ,EAAE,IAAI,CAAU,WAAA;AAC3C,gBAAM,SAAmE,CAAA;AACzE,gBAAM,UAAoB,CAAA;AAE1BA,sBAAA,wBAAwB,OAAO,QAAQ;AAAA,YACtC,aAAa,CAAO,QAAA;AACZ,qBAAA,IAAI,SAAS,IAAI,IAAI;AAAA,gBAC3B,MAAM;AAAA,gBACN,QAAQ,IAAI,aAAa;AAAA,cAAA;AAAA,YAE3B;AAAA,YACA,cAAc,CAAO,QAAA;AACb,qBAAA,IAAI,SAAS,IAAI,IAAI;AAAA,gBAC3B,MAAM;AAAA,gBACN,QAAQ,IAAI,aAAa;AAAA,cAAA;AAAA,YAE3B;AAAA,YACA,aAAa,CAAO,QAAA;AACX,sBAAA,KAAK,IAAI,OAAO,IAAI;AACrB,qBAAA,IAAI,OAAO,IAAI,IAAI;AAAA,gBACzB,MAAM;AAAA,cAAA;AAAA,YAER;AAAA,UAAA,CACA;AAEM,iBAAA,CAAC,OAAO,MAAM,EAAE,MAAM,OAAO,MAAM,QAAQ,QAAA,CAAS;AAAA,QAAA,CAC3D;AAAA,MACF;AAAA,IAAA;AAAA,EAEF;AACD;;"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { acceptEveryFieldVisitor } from "@contember/schema-utils";
|
|
2
|
+
class NameSchemaGenerator {
|
|
3
|
+
generate(model) {
|
|
4
|
+
return {
|
|
5
|
+
entities: Object.fromEntries(
|
|
6
|
+
Object.values(model.entities).map((entity) => {
|
|
7
|
+
const fields = {};
|
|
8
|
+
const scalars = [];
|
|
9
|
+
acceptEveryFieldVisitor(model, entity, {
|
|
10
|
+
visitHasOne: (ctx) => {
|
|
11
|
+
fields[ctx.relation.name] = {
|
|
12
|
+
type: "one",
|
|
13
|
+
entity: ctx.targetEntity.name
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
visitHasMany: (ctx) => {
|
|
17
|
+
fields[ctx.relation.name] = {
|
|
18
|
+
type: "many",
|
|
19
|
+
entity: ctx.targetEntity.name
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
visitColumn: (ctx) => {
|
|
23
|
+
scalars.push(ctx.column.name);
|
|
24
|
+
fields[ctx.column.name] = {
|
|
25
|
+
type: "column"
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return [entity.name, { name: entity.name, fields, scalars }];
|
|
30
|
+
})
|
|
31
|
+
)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
NameSchemaGenerator
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=NameSchemaGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NameSchemaGenerator.js","sources":["../../src/NameSchemaGenerator.ts"],"sourcesContent":["import { SchemaNames, SchemaEntityNames } from '@contember/client-content'\nimport { Model } from '@contember/schema'\nimport { acceptEveryFieldVisitor } from '@contember/schema-utils'\n\nexport class NameSchemaGenerator {\n\tgenerate(model: Model.Schema): SchemaNames {\n\t\treturn {\n\t\t\tentities: Object.fromEntries(\n\t\t\t\tObject.values(model.entities).map(entity => {\n\t\t\t\t\tconst fields: Record<string, SchemaEntityNames<any>['fields'][string]> = {}\n\t\t\t\t\tconst scalars: string[] = []\n\n\t\t\t\t\tacceptEveryFieldVisitor(model, entity, {\n\t\t\t\t\t\tvisitHasOne: ctx => {\n\t\t\t\t\t\t\tfields[ctx.relation.name] = {\n\t\t\t\t\t\t\t\ttype: 'one',\n\t\t\t\t\t\t\t\tentity: ctx.targetEntity.name,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvisitHasMany: ctx => {\n\t\t\t\t\t\t\tfields[ctx.relation.name] = {\n\t\t\t\t\t\t\t\ttype: 'many',\n\t\t\t\t\t\t\t\tentity: ctx.targetEntity.name,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvisitColumn: ctx => {\n\t\t\t\t\t\t\tscalars.push(ctx.column.name)\n\t\t\t\t\t\t\tfields[ctx.column.name] = {\n\t\t\t\t\t\t\t\ttype: 'column',\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\treturn [entity.name, { name: entity.name, fields, scalars }]\n\t\t\t\t}),\n\t\t\t),\n\t\t}\n\t}\n}\n\n\n"],"names":[],"mappings":";AAIO,MAAM,oBAAoB;AAAA,EAChC,SAAS,OAAkC;AACnC,WAAA;AAAA,MACN,UAAU,OAAO;AAAA,QAChB,OAAO,OAAO,MAAM,QAAQ,EAAE,IAAI,CAAU,WAAA;AAC3C,gBAAM,SAAmE,CAAA;AACzE,gBAAM,UAAoB,CAAA;AAE1B,kCAAwB,OAAO,QAAQ;AAAA,YACtC,aAAa,CAAO,QAAA;AACZ,qBAAA,IAAI,SAAS,IAAI,IAAI;AAAA,gBAC3B,MAAM;AAAA,gBACN,QAAQ,IAAI,aAAa;AAAA,cAAA;AAAA,YAE3B;AAAA,YACA,cAAc,CAAO,QAAA;AACb,qBAAA,IAAI,SAAS,IAAI,IAAI;AAAA,gBAC3B,MAAM;AAAA,gBACN,QAAQ,IAAI,aAAa;AAAA,cAAA;AAAA,YAE3B;AAAA,YACA,aAAa,CAAO,QAAA;AACX,sBAAA,KAAK,IAAI,OAAO,IAAI;AACrB,qBAAA,IAAI,OAAO,IAAI,IAAI;AAAA,gBACzB,MAAM;AAAA,cAAA;AAAA,YAER;AAAA,UAAA,CACA;AAEM,iBAAA,CAAC,OAAO,MAAM,EAAE,MAAM,OAAO,MAAM,QAAQ,QAAA,CAAS;AAAA,QAAA,CAC3D;AAAA,MACF;AAAA,IAAA;AAAA,EAEF;AACD;"}
|