@postxl/generator 0.33.4 → 0.35.0
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/generator.js +40 -22
- package/dist/generators/indices/businesslogic-actiontypes.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-actiontypes.generator.js +39 -0
- package/dist/generators/indices/businesslogic-update-index.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-update-index.generator.js +20 -0
- package/dist/generators/indices/businesslogic-update-module.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-update-module.generator.js +69 -0
- package/dist/generators/indices/businesslogic-update-service.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-update-service.generator.js +34 -0
- package/dist/generators/indices/businesslogic-view-index.generator.d.ts +9 -0
- package/dist/generators/indices/businesslogic-view-index.generator.js +19 -0
- package/dist/generators/indices/{businesslogicindex.generator.d.ts → businesslogic-view-module.generator.d.ts} +2 -2
- package/dist/generators/indices/{businesslogicmodule.generator.js → businesslogic-view-module.generator.js} +22 -26
- package/dist/generators/indices/{businesslogicservice.generator.d.ts → businesslogic-view-service.generator.d.ts} +1 -1
- package/dist/generators/indices/{businesslogicservice.generator.js → businesslogic-view-service.generator.js} +9 -10
- package/dist/generators/indices/{datamockmodule.generator.js → datamock-module.generator.js} +8 -16
- package/dist/generators/indices/datamocker.generator.js +3 -7
- package/dist/generators/indices/datamodule.generator.js +7 -13
- package/dist/generators/indices/{businesslogicmodule.generator.d.ts → dispatcher-service.generator.d.ts} +2 -2
- package/dist/generators/indices/dispatcher-service.generator.js +81 -0
- package/dist/generators/indices/seed-migration.generator.d.ts +9 -0
- package/dist/generators/indices/seed-migration.generator.js +35 -0
- package/dist/generators/indices/seed-service.generator.d.ts +1 -1
- package/dist/generators/indices/seed-service.generator.js +327 -123
- package/dist/generators/indices/seed-template-decoder.generator.js +22 -6
- package/dist/generators/indices/{seed.generator.d.ts → seeddata-type.generator.d.ts} +2 -2
- package/dist/generators/indices/seeddata-type.generator.js +42 -0
- package/dist/generators/indices/types.generator.d.ts +1 -1
- package/dist/generators/indices/types.generator.js +8 -6
- package/dist/generators/models/businesslogic-update.generator.d.ts +10 -0
- package/dist/generators/models/businesslogic-update.generator.js +243 -0
- package/dist/generators/models/businesslogic-view.generator.d.ts +10 -0
- package/dist/generators/models/businesslogic-view.generator.js +253 -0
- package/dist/generators/models/react.generator/modals.generator.js +20 -4
- package/dist/generators/models/repository.generator.d.ts +9 -0
- package/dist/generators/models/repository.generator.js +496 -148
- package/dist/generators/models/route.generator.js +45 -54
- package/dist/generators/models/seed.generator.js +6 -2
- package/dist/generators/models/types.generator.js +60 -13
- package/dist/lib/attributes.d.ts +32 -2
- package/dist/lib/imports.d.ts +23 -2
- package/dist/lib/imports.js +19 -1
- package/dist/lib/meta.d.ts +287 -34
- package/dist/lib/meta.js +87 -16
- package/dist/lib/schema/fields.d.ts +7 -4
- package/dist/lib/schema/fields.js +11 -4
- package/dist/lib/schema/schema.d.ts +32 -6
- package/dist/lib/schema/types.d.ts +4 -0
- package/dist/lib/utils/ast.d.ts +29 -0
- package/dist/lib/utils/ast.js +23 -0
- package/dist/lib/utils/jsdoc.d.ts +1 -1
- package/dist/lib/utils/jsdoc.js +8 -5
- package/dist/lib/utils/string.js +2 -1
- package/dist/prisma/attributes.js +45 -26
- package/dist/prisma/parse.js +44 -11
- package/package.json +1 -1
- package/dist/generators/indices/businesslogicindex.generator.js +0 -19
- package/dist/generators/indices/seed.generator.js +0 -17
- package/dist/generators/indices/testdataservice.generator.d.ts +0 -9
- package/dist/generators/indices/testdataservice.generator.js +0 -78
- package/dist/generators/models/businesslogic.generator.d.ts +0 -9
- package/dist/generators/models/businesslogic.generator.js +0 -259
- /package/dist/generators/indices/{datamockmodule.generator.d.ts → datamock-module.generator.d.ts} +0 -0
|
@@ -23,6 +23,10 @@ export type SchemaConfig = {
|
|
|
23
23
|
* If true, data module will not be generated.
|
|
24
24
|
*/
|
|
25
25
|
data: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* If true, actions module will not be generated.
|
|
28
|
+
*/
|
|
29
|
+
actions: boolean;
|
|
26
30
|
/**
|
|
27
31
|
* If true, business logic module will not be generated.
|
|
28
32
|
*/
|
|
@@ -59,6 +63,13 @@ export type SchemaConfig = {
|
|
|
59
63
|
* Path to the directory containing Cypress project.
|
|
60
64
|
*/
|
|
61
65
|
cypressPath: Types.Path;
|
|
66
|
+
/**
|
|
67
|
+
* Path to the directory containing actions.
|
|
68
|
+
*
|
|
69
|
+
* NOTE: Metadata assumes that project is set up so that certain parts of the code
|
|
70
|
+
* may reference actions using `@project/actions` import.
|
|
71
|
+
*/
|
|
72
|
+
actionsPath: Types.Path;
|
|
62
73
|
/**
|
|
63
74
|
* Path to the directory containing business logic.
|
|
64
75
|
*
|
|
@@ -67,12 +78,19 @@ export type SchemaConfig = {
|
|
|
67
78
|
*/
|
|
68
79
|
businessLogicPath: Types.Path;
|
|
69
80
|
/**
|
|
70
|
-
* Path to the directory containing
|
|
81
|
+
* Path to the directory containing seed module.
|
|
71
82
|
*
|
|
72
83
|
* NOTE: Metadata assumes that project is set up so that certain parts of the code
|
|
73
84
|
* may reference mock data using `@project/seed` import.
|
|
74
85
|
*/
|
|
75
|
-
|
|
86
|
+
seedLibPath: Types.Path;
|
|
87
|
+
/**
|
|
88
|
+
* Path to the directory containing mock data samples.
|
|
89
|
+
*
|
|
90
|
+
* NOTE: Metadata assumes that project is set up so that certain parts of the code
|
|
91
|
+
* may reference mock data using `@project/seed-data` import.
|
|
92
|
+
*/
|
|
93
|
+
seedDataPath: Types.Path;
|
|
76
94
|
/**
|
|
77
95
|
* Path to the directory containing React components.
|
|
78
96
|
*
|
|
@@ -89,14 +107,14 @@ export type SchemaConfig = {
|
|
|
89
107
|
*/
|
|
90
108
|
migrationsFolderPath: Types.Path;
|
|
91
109
|
};
|
|
92
|
-
/**
|
|
93
|
-
* Seed to use for random generation.
|
|
94
|
-
*/
|
|
95
|
-
randomSeed: number;
|
|
96
110
|
/**
|
|
97
111
|
* Whether the generator should overwrite existing files.
|
|
98
112
|
*/
|
|
99
113
|
force: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Name of the User type
|
|
116
|
+
*/
|
|
117
|
+
userType: Types.TypeName;
|
|
100
118
|
};
|
|
101
119
|
export type Model = Prettify<ModelCore & ModelFields>;
|
|
102
120
|
/**
|
|
@@ -148,6 +166,14 @@ export type ModelFields = {
|
|
|
148
166
|
* The id field of the model
|
|
149
167
|
*/
|
|
150
168
|
idField: FieldId;
|
|
169
|
+
/**
|
|
170
|
+
* The field of the model that identifies when the entry was created.
|
|
171
|
+
*/
|
|
172
|
+
createdAtField?: FieldScalar;
|
|
173
|
+
/**
|
|
174
|
+
* The field of the model that identifies when the entry was last updated.
|
|
175
|
+
*/
|
|
176
|
+
updatedAtField?: FieldScalar;
|
|
151
177
|
/**
|
|
152
178
|
* The property of the model that identifies the default row.
|
|
153
179
|
*/
|
|
@@ -70,3 +70,7 @@ export type Path = string & {
|
|
|
70
70
|
* Converts a string to a branded FileName.
|
|
71
71
|
*/
|
|
72
72
|
export declare const toPath: (t: string) => Path;
|
|
73
|
+
/**
|
|
74
|
+
* Branded string values that can be used as import statement values in the generators
|
|
75
|
+
*/
|
|
76
|
+
export type ImportableTypes = Fnction | ClassName | TypeName | VariableName;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A collection of utility functions that let you more easily write TypeScript code.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Utility function that lets you easily create a TypeScript switch statement.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createSwitchStatement({ field, cases, defaultBlock, }: {
|
|
8
|
+
/**
|
|
9
|
+
* The variable name to switch on.
|
|
10
|
+
*/
|
|
11
|
+
field: string;
|
|
12
|
+
/**
|
|
13
|
+
* The cases to switch on.
|
|
14
|
+
*/
|
|
15
|
+
cases: {
|
|
16
|
+
/**
|
|
17
|
+
* The value to match.
|
|
18
|
+
*/
|
|
19
|
+
match: string;
|
|
20
|
+
/**
|
|
21
|
+
* The body of the switch case.
|
|
22
|
+
*/
|
|
23
|
+
block: string;
|
|
24
|
+
}[];
|
|
25
|
+
/**
|
|
26
|
+
* The execution block of the default case.
|
|
27
|
+
*/
|
|
28
|
+
defaultBlock?: string;
|
|
29
|
+
}): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A collection of utility functions that let you more easily write TypeScript code.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createSwitchStatement = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Utility function that lets you easily create a TypeScript switch statement.
|
|
9
|
+
*/
|
|
10
|
+
function createSwitchStatement({ field, cases, defaultBlock, }) {
|
|
11
|
+
const _cases = cases.map(_createSwitchCase).join('\n');
|
|
12
|
+
const _default = defaultBlock ? `default: {\n${defaultBlock}\n}` : '';
|
|
13
|
+
return `
|
|
14
|
+
switch (${field}) {
|
|
15
|
+
${_cases}
|
|
16
|
+
${_default}
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
}
|
|
20
|
+
exports.createSwitchStatement = createSwitchStatement;
|
|
21
|
+
function _createSwitchCase({ match, block, }) {
|
|
22
|
+
return `case ${match}: {\n${block}\n}`;
|
|
23
|
+
}
|
package/dist/lib/utils/jsdoc.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.toJsDocComment = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Returns a string of JSDoc comments from an array of lines.
|
|
6
6
|
*/
|
|
7
|
-
function
|
|
8
|
-
|
|
7
|
+
function toJsDocComment(comments) {
|
|
8
|
+
if (!comments || comments.length === 0) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
return `/**${comments
|
|
9
12
|
.filter((c) => c !== '')
|
|
10
13
|
.map((c) => `\n * ${c}`)
|
|
11
|
-
.join('')
|
|
14
|
+
.join('')} \n */`;
|
|
12
15
|
}
|
|
13
|
-
exports.
|
|
16
|
+
exports.toJsDocComment = toJsDocComment;
|
package/dist/lib/utils/string.js
CHANGED
|
@@ -70,8 +70,9 @@ const irregularPlurals = {
|
|
|
70
70
|
* Returns a pluralized version of the given string based on the count.
|
|
71
71
|
*/
|
|
72
72
|
const pluralize = (s, count = 2) => {
|
|
73
|
-
if (count === 1)
|
|
73
|
+
if (count === 1) {
|
|
74
74
|
return s;
|
|
75
|
+
}
|
|
75
76
|
if (s.endsWith('y') &&
|
|
76
77
|
!s.endsWith('ay') &&
|
|
77
78
|
!s.endsWith('ey') &&
|
|
@@ -4,24 +4,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getFieldAttributes = exports.getEnumAttributes = exports.getModelAttributes = exports.parseArgumentToStringOrStringArray = exports.parseAttributesFromDocumentation = void 0;
|
|
7
|
-
const remeda_1 = require("remeda");
|
|
8
|
-
const string_1 = require("../lib/utils/string");
|
|
9
7
|
const zod_1 = __importDefault(require("zod"));
|
|
8
|
+
const string_1 = require("../lib/utils/string");
|
|
10
9
|
/**
|
|
11
10
|
* Parses attributes from a given string using provided prefix.
|
|
12
11
|
*/
|
|
13
12
|
function parseAttributesFromDocumentation({ documentation }) {
|
|
14
13
|
const prefix = '@@';
|
|
15
|
-
if (!documentation)
|
|
14
|
+
if (!documentation) {
|
|
16
15
|
return {};
|
|
16
|
+
}
|
|
17
17
|
return documentation
|
|
18
18
|
.split('\n')
|
|
19
19
|
.filter((d) => d.startsWith(prefix))
|
|
20
20
|
.map((d) => d.replace(prefix, ''))
|
|
21
21
|
.reduce((acc, line) => {
|
|
22
22
|
const pattern = /(\w+)\((.*?)\)$/;
|
|
23
|
-
if (!pattern.test(line))
|
|
23
|
+
if (!pattern.test(line)) {
|
|
24
24
|
return acc;
|
|
25
|
+
}
|
|
25
26
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
26
27
|
const [attribute, arg] = line.match(pattern).slice(1);
|
|
27
28
|
acc[(0, string_1.toCamelCase)(attribute)] = parseArgumentToStringOrStringArray(arg);
|
|
@@ -72,6 +73,7 @@ function getModelAttributes(model) {
|
|
|
72
73
|
description: zod_1.default.string().optional(),
|
|
73
74
|
schema: zod_1.default.string().optional(),
|
|
74
75
|
index: zod_1.default.array(zod_1.default.string()).optional(),
|
|
76
|
+
seed: zod_1.default.string().optional(),
|
|
75
77
|
})
|
|
76
78
|
.transform((obj) => ({
|
|
77
79
|
ignore: obj.ignore,
|
|
@@ -79,6 +81,7 @@ function getModelAttributes(model) {
|
|
|
79
81
|
description: obj.description,
|
|
80
82
|
databaseSchema: obj.schema,
|
|
81
83
|
index: obj.index,
|
|
84
|
+
randomSeed: obj.seed !== undefined ? parseInt(obj.seed, 10) : undefined,
|
|
82
85
|
}));
|
|
83
86
|
const result = decoder.safeParse(attributes);
|
|
84
87
|
if (!result.success) {
|
|
@@ -113,31 +116,47 @@ exports.getEnumAttributes = getEnumAttributes;
|
|
|
113
116
|
*/
|
|
114
117
|
function getFieldAttributes(field) {
|
|
115
118
|
const attributes = parseAttributesFromDocumentation(field);
|
|
116
|
-
if (attributes.examples === undefined && attributes.example !== undefined) {
|
|
117
|
-
attributes.examples = attributes.example;
|
|
118
|
-
}
|
|
119
119
|
// Prisma also has an "@ignore" attribute - see https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#ignore
|
|
120
120
|
// we handle this the same way as our custom "ignore" attribute
|
|
121
121
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
122
122
|
const isPrismaIgnored = field.isIgnored === true;
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
123
|
+
const exampleDecoder = zod_1.default.union([zod_1.default.string(), zod_1.default.number(), zod_1.default.boolean(), zod_1.default.null()]);
|
|
124
|
+
const examplesDecoder = exampleDecoder
|
|
125
|
+
.transform((obj) => [obj])
|
|
126
|
+
.or(zod_1.default.array(exampleDecoder))
|
|
127
|
+
.optional();
|
|
128
|
+
const decoder = zod_1.default
|
|
129
|
+
.object({
|
|
130
|
+
ignore: blankStringBooleanDecoder,
|
|
131
|
+
description: zod_1.default.string().optional(),
|
|
132
|
+
isDefault: blankStringBooleanDecoder,
|
|
133
|
+
label: blankStringBooleanDecoder,
|
|
134
|
+
example: examplesDecoder,
|
|
135
|
+
examples: examplesDecoder,
|
|
136
|
+
maxLength: zod_1.default
|
|
137
|
+
.number()
|
|
138
|
+
.or(zod_1.default.string().transform((s) => parseInt(s, 10)))
|
|
139
|
+
.optional(),
|
|
140
|
+
readonly: blankStringBooleanDecoder,
|
|
141
|
+
})
|
|
142
|
+
.transform((obj) => {
|
|
143
|
+
var _a;
|
|
144
|
+
return ({
|
|
145
|
+
ignore: obj.ignore || isPrismaIgnored,
|
|
146
|
+
description: obj.description,
|
|
147
|
+
isDefaultField: obj.isDefault,
|
|
148
|
+
isLabel: obj.label,
|
|
149
|
+
examples: obj.examples || obj.example,
|
|
150
|
+
maxLength: obj.maxLength,
|
|
151
|
+
isReadonly: obj.readonly || field.isGenerated || field.isUpdatedAt || field.name === 'createdAt' || field.isId,
|
|
152
|
+
isUpdatedAt: (_a = field.isUpdatedAt) !== null && _a !== void 0 ? _a : false,
|
|
153
|
+
isCreatedAt: field.name === 'createdAt',
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
const result = decoder.safeParse(attributes);
|
|
157
|
+
if (!result.success) {
|
|
158
|
+
throw new Error(`Field ${field.name} has invalid field attributes: ${result.error.toString()}`);
|
|
159
|
+
}
|
|
160
|
+
return result.data;
|
|
142
161
|
}
|
|
143
162
|
exports.getFieldAttributes = getFieldAttributes;
|
package/dist/prisma/parse.js
CHANGED
|
@@ -28,19 +28,34 @@ const Types = __importStar(require("../lib/schema/types"));
|
|
|
28
28
|
const error_1 = require("../lib/utils/error");
|
|
29
29
|
const string_1 = require("../lib/utils/string");
|
|
30
30
|
const attributes_1 = require("./attributes");
|
|
31
|
+
/**
|
|
32
|
+
* These models are required for the generators/backend to work.
|
|
33
|
+
*/
|
|
34
|
+
const REQUIRED_MODELS = ['User', 'Config', 'File', 'Action', 'Mutation'];
|
|
31
35
|
/**
|
|
32
36
|
* Converts a Prisma schema (DMMF) document to a Schema that's passed around generators.
|
|
33
37
|
*/
|
|
34
38
|
function parsePrismaSchema({ datamodel: { enums: enumsRaw, models: modelsRaw }, config, }) {
|
|
39
|
+
ensureRequiredModelsExists(modelsRaw);
|
|
35
40
|
// NOTE: We preprocess models and enums so that we can populate relationships.
|
|
36
41
|
const models = modelsRaw.map((dmmfModel) => parseModelCore({ dmmfModel, config }));
|
|
37
42
|
const enums = enumsRaw.map((dmmfEnum) => parseEnum({ dmmfEnum, config }));
|
|
38
43
|
const modelsWithFields = modelsRaw
|
|
39
44
|
.map((dmmfModel) => parseModel({ dmmfModel, models, enums, config }))
|
|
40
|
-
.filter(
|
|
45
|
+
.filter(isModelNotIgnored);
|
|
41
46
|
return { models: modelsWithFields, enums };
|
|
42
47
|
}
|
|
43
48
|
exports.parsePrismaSchema = parsePrismaSchema;
|
|
49
|
+
function ensureRequiredModelsExists(models) {
|
|
50
|
+
for (const requiredModel of REQUIRED_MODELS) {
|
|
51
|
+
if (!models.find((m) => m.name === requiredModel)) {
|
|
52
|
+
(0, error_1.throwError)(`Required model ${requiredModel} not found in schema!`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function isModelNotIgnored(model) {
|
|
57
|
+
return model !== undefined && !model.attributes.ignore;
|
|
58
|
+
}
|
|
44
59
|
/**
|
|
45
60
|
* Parses the core properties of a model without fields.
|
|
46
61
|
*/
|
|
@@ -63,6 +78,10 @@ function parseModelCore({ dmmfModel, config, }) {
|
|
|
63
78
|
*/
|
|
64
79
|
function parseModel({ dmmfModel, enums, models, config, }) {
|
|
65
80
|
const core = parseModelCore({ dmmfModel, config });
|
|
81
|
+
// NOTE: We ignore models which are marked as ignored.
|
|
82
|
+
if (core.attributes.ignore) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
66
85
|
// NOTE: We assume that each relation may only reference one field. Because of this,
|
|
67
86
|
// we can "relate" a given relation to a scalar field used in the relation.
|
|
68
87
|
// Since Prisma doesn't mark those fields as relations, we need to preprocess
|
|
@@ -146,17 +165,21 @@ function parseModel({ dmmfModel, enums, models, config, }) {
|
|
|
146
165
|
(0, error_1.throwError)(`Investigate: Field ${shared.sourceName}.${shared.sourceName} is not scalar, enum nor relation.`);
|
|
147
166
|
})
|
|
148
167
|
.filter((field) => !isFieldIgnored({ field }));
|
|
149
|
-
const { idField, defaultField, nameField } = validateFields({ fields, model: core });
|
|
168
|
+
const { idField, defaultField, nameField, createdAtField, updatedAtField } = validateFields({ fields, model: core });
|
|
150
169
|
return Object.assign(Object.assign({}, core), { idField,
|
|
151
170
|
defaultField,
|
|
152
171
|
nameField,
|
|
153
|
-
fields
|
|
172
|
+
fields,
|
|
173
|
+
createdAtField,
|
|
174
|
+
updatedAtField });
|
|
154
175
|
}
|
|
155
176
|
/**
|
|
156
177
|
* Checks that there is exactly one id field and that there is at most one default field.
|
|
157
178
|
*/
|
|
158
179
|
function validateFields({ fields, model: { name } }) {
|
|
159
180
|
let idField = undefined;
|
|
181
|
+
let createdAtField = undefined;
|
|
182
|
+
let updatedAtField = undefined;
|
|
160
183
|
let nameField = undefined;
|
|
161
184
|
let nameFieldFallback = undefined;
|
|
162
185
|
let defaultField = undefined;
|
|
@@ -166,6 +189,18 @@ function validateFields({ fields, model: { name } }) {
|
|
|
166
189
|
if (field.name === 'name') {
|
|
167
190
|
nameFieldFallback = field;
|
|
168
191
|
}
|
|
192
|
+
if (field.attributes.isCreatedAt) {
|
|
193
|
+
if (createdAtField) {
|
|
194
|
+
throw new Error(`❌❌❌ Model ${name} has multiple createdAt fields`);
|
|
195
|
+
}
|
|
196
|
+
createdAtField = field;
|
|
197
|
+
}
|
|
198
|
+
if (field.attributes.isUpdatedAt) {
|
|
199
|
+
if (updatedAtField) {
|
|
200
|
+
throw new Error(`❌❌❌ Model ${name} has multiple updatedAt fields`);
|
|
201
|
+
}
|
|
202
|
+
updatedAtField = field;
|
|
203
|
+
}
|
|
169
204
|
break;
|
|
170
205
|
case 'id':
|
|
171
206
|
if (idField) {
|
|
@@ -199,7 +234,7 @@ function validateFields({ fields, model: { name } }) {
|
|
|
199
234
|
if (!nameField && nameFieldFallback) {
|
|
200
235
|
nameField = nameFieldFallback;
|
|
201
236
|
}
|
|
202
|
-
return { idField, defaultField, nameField };
|
|
237
|
+
return { idField, defaultField, nameField, createdAtField, updatedAtField };
|
|
203
238
|
}
|
|
204
239
|
function isAutoIncrementField(fieldDmmf) {
|
|
205
240
|
if (fieldDmmf.default === undefined) {
|
|
@@ -232,9 +267,6 @@ function isUniqueField(fieldRaw) {
|
|
|
232
267
|
* Tells whether the parsed schema should skip a given field.
|
|
233
268
|
*/
|
|
234
269
|
function isFieldIgnored({ field }) {
|
|
235
|
-
if (field.name === 'createdAt' || field.name === 'updatedAt' || field.name === 'deletedAt') {
|
|
236
|
-
return true;
|
|
237
|
-
}
|
|
238
270
|
if (Object.hasOwn(field.attributes, 'ignore') && field.attributes.ignore) {
|
|
239
271
|
return true;
|
|
240
272
|
}
|
|
@@ -274,13 +306,14 @@ function getTsTypeForScalar(field) {
|
|
|
274
306
|
case 'Float':
|
|
275
307
|
case 'Int':
|
|
276
308
|
return Types.toTypeName('number');
|
|
277
|
-
case '
|
|
309
|
+
case 'Json':
|
|
278
310
|
case 'Bytes':
|
|
279
311
|
(0, error_1.throwError)('Not implemented yet');
|
|
280
|
-
|
|
312
|
+
// While TypeScript understands that throwError never returns, eslint doesn't and complains.
|
|
313
|
+
// Hence we ignore the fallthrough error.
|
|
314
|
+
// eslint-disable-next-line no-fallthrough
|
|
281
315
|
default:
|
|
282
|
-
|
|
283
|
-
(0, error_1.throwError)(`Investigate: 'default' case in getTypescriptType for field ${field.name} of type ${field.type}`);
|
|
316
|
+
(0, error_1.throwError)(`Investigate: 'default' case in getTsTypeForScalar for field ${field.name} of type ${field.type}`);
|
|
284
317
|
}
|
|
285
318
|
}
|
|
286
319
|
/**
|
package/package.json
CHANGED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateBusinessLogicIndex = void 0;
|
|
4
|
-
const exports_1 = require("../../lib/exports");
|
|
5
|
-
const meta_1 = require("../../lib/meta");
|
|
6
|
-
/**
|
|
7
|
-
* Generates index file for all businessLogic files.
|
|
8
|
-
*/
|
|
9
|
-
function generateBusinessLogicIndex({ models, meta }) {
|
|
10
|
-
const exports = exports_1.ExportsGenerator.from(meta.businessLogic.indexFilePath);
|
|
11
|
-
exports.exportEverythingFromPath(meta.businessLogic.serviceFilePath);
|
|
12
|
-
exports.exportEverythingFromPath(meta.businessLogic.moduleFilePath);
|
|
13
|
-
for (const model of models) {
|
|
14
|
-
const meta = (0, meta_1.getModelMetadata)({ model });
|
|
15
|
-
exports.exportEverythingFromPath(meta.businessLogic.serviceFilePath);
|
|
16
|
-
}
|
|
17
|
-
return exports.generate();
|
|
18
|
-
}
|
|
19
|
-
exports.generateBusinessLogicIndex = generateBusinessLogicIndex;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateSeedIndex = void 0;
|
|
4
|
-
const exports_1 = require("../../lib/exports");
|
|
5
|
-
const meta_1 = require("../../lib/meta");
|
|
6
|
-
/**
|
|
7
|
-
* Generates index file for all seed files.
|
|
8
|
-
*/
|
|
9
|
-
function generateSeedIndex({ models, meta }) {
|
|
10
|
-
const exports = exports_1.ExportsGenerator.from(meta.seed.indexFilePath);
|
|
11
|
-
for (const model of models) {
|
|
12
|
-
const meta = (0, meta_1.getModelMetadata)({ model });
|
|
13
|
-
exports.exportEverythingFromPath(meta.seed.filePath);
|
|
14
|
-
}
|
|
15
|
-
return exports.generate();
|
|
16
|
-
}
|
|
17
|
-
exports.generateSeedIndex = generateSeedIndex;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { SchemaMetaData } from '../../lib/meta';
|
|
2
|
-
import { Model } from '../../lib/schema/schema';
|
|
3
|
-
/**
|
|
4
|
-
* Generates a generic data service object that may be used on the server to access database.
|
|
5
|
-
*/
|
|
6
|
-
export declare function generateTestDataService({ meta, models }: {
|
|
7
|
-
meta: SchemaMetaData;
|
|
8
|
-
models: Model[];
|
|
9
|
-
}): string;
|
|
@@ -1,78 +0,0 @@
|
|
|
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 (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.generateTestDataService = void 0;
|
|
27
|
-
const meta_1 = require("../../lib/meta");
|
|
28
|
-
const Types = __importStar(require("../../lib/schema/types"));
|
|
29
|
-
const imports_1 = require("../../lib/imports");
|
|
30
|
-
/**
|
|
31
|
-
* Generates a generic data service object that may be used on the server to access database.
|
|
32
|
-
*/
|
|
33
|
-
function generateTestDataService({ meta, models }) {
|
|
34
|
-
const imports = imports_1.ImportsGenerator.from(meta.data.testDataServiceFilePath).addImport({
|
|
35
|
-
items: [Types.toVariableName('MockData')],
|
|
36
|
-
from: meta.data.dataMockModuleFilePath,
|
|
37
|
-
});
|
|
38
|
-
const mm = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
|
|
39
|
-
for (const { meta } of mm) {
|
|
40
|
-
imports.addImport({
|
|
41
|
-
items: [meta.data.repositoryClassName],
|
|
42
|
-
from: meta.data.repoFilePath,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
const constructor = mm
|
|
46
|
-
.map(({ meta }) => `private ${meta.data.dataServiceName} :${meta.data.repositoryClassName}`)
|
|
47
|
-
.join(',\n');
|
|
48
|
-
return `
|
|
49
|
-
import { Injectable, Logger } from '@nestjs/common'
|
|
50
|
-
|
|
51
|
-
import { ResetService } from '@pxl/common'
|
|
52
|
-
import { DbService } from '@${meta.config.project}/db'
|
|
53
|
-
|
|
54
|
-
${imports.generate()}
|
|
55
|
-
|
|
56
|
-
@Injectable()
|
|
57
|
-
export class TestDataService {
|
|
58
|
-
private logger = new Logger(TestDataService.name)
|
|
59
|
-
constructor(
|
|
60
|
-
private db: DbService,
|
|
61
|
-
private resetService: ResetService,
|
|
62
|
-
${constructor}
|
|
63
|
-
) {}
|
|
64
|
-
|
|
65
|
-
public async resetTestData(data: MockData) {
|
|
66
|
-
this.logger.log(\`✅ Reset test data\`)
|
|
67
|
-
await this.db.emptyDatabase()
|
|
68
|
-
|
|
69
|
-
${mm
|
|
70
|
-
.map(({ meta }) => `await this.${meta.data.dataServiceName}.reInit(data.${meta.data.mockDataPropertyName} ?? [])`)
|
|
71
|
-
.join('\n')}
|
|
72
|
-
|
|
73
|
-
return this.resetService.reset()
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
`;
|
|
77
|
-
}
|
|
78
|
-
exports.generateTestDataService = generateTestDataService;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ModelMetaData } from '../../lib/meta';
|
|
2
|
-
import { Model } from '../../lib/schema/schema';
|
|
3
|
-
/**
|
|
4
|
-
* Generates business logic for a given model.
|
|
5
|
-
*/
|
|
6
|
-
export declare function generateModelBusinessLogic({ model, meta }: {
|
|
7
|
-
model: Model;
|
|
8
|
-
meta: ModelMetaData;
|
|
9
|
-
}): string;
|