@postxl/generator 0.47.0 → 0.47.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generator.js +1 -1
- package/dist/generators/indices/seed-migration.generator.js +6 -7
- package/dist/generators/models/react.generator/library.generator.js +4 -1
- package/dist/generators/models/react.generator/lookup.generator.js +11 -9
- package/dist/generators/models/seed.generator.d.ts +2 -1
- package/dist/generators/models/seed.generator.js +25 -11
- package/dist/prisma/parse.js +2 -0
- package/package.json +1 -1
package/dist/generator.js
CHANGED
|
@@ -165,7 +165,7 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
|
|
|
165
165
|
// Types
|
|
166
166
|
generated.write(`/${meta.types.filePath}.ts`, (0, types_generator_3.generateModelTypes)({ model, meta }));
|
|
167
167
|
// Seed
|
|
168
|
-
generated.write(`/${meta.seed.filePath}.ts`, (0, seed_generator_1.generateSeedModel)({ model, itemCount: 5, meta }));
|
|
168
|
+
generated.write(`/${meta.seed.filePath}.ts`, (0, seed_generator_1.generateSeedModel)({ model, itemCount: 5, meta, models }));
|
|
169
169
|
// Data
|
|
170
170
|
generated.write(`/${meta.data.stubFilePath}.ts`, (0, stub_generator_1.generateStub)({ model, meta }));
|
|
171
171
|
generated.write(`/${meta.data.repository.filePath}.ts`, (0, repository_generator_1.generateRepository)({ model, meta }));
|
|
@@ -11,11 +11,11 @@ function generateSeedMigration({ models, meta }) {
|
|
|
11
11
|
const modelTypes = [];
|
|
12
12
|
for (const model of models) {
|
|
13
13
|
const modelMeta = (0, meta_1.getModelMetadata)({ model });
|
|
14
|
-
imports.
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
imports.addImports({
|
|
15
|
+
[modelMeta.seed.filePath]: [modelMeta.seed.constantName],
|
|
16
|
+
[meta.importExport.importPath]: [meta.importExport.converterFunctions.importedDataToBulkMutations],
|
|
17
17
|
});
|
|
18
|
-
modelTypes.push(`${modelMeta.seed.constantName}
|
|
18
|
+
modelTypes.push(`${modelMeta.seed.constantName}`);
|
|
19
19
|
}
|
|
20
20
|
return /* ts */ `
|
|
21
21
|
import { createActionSeedData } from '${meta.seed.importPath}'
|
|
@@ -24,11 +24,10 @@ ${imports.generate()}
|
|
|
24
24
|
export const MIGRATION_001_BASEDATA = createActionSeedData({
|
|
25
25
|
name: 'Base data',
|
|
26
26
|
order: 1,
|
|
27
|
-
data:
|
|
28
|
-
{
|
|
27
|
+
data: ${meta.importExport.converterFunctions.importedDataToBulkMutations}({
|
|
29
28
|
${modelTypes.join(',\n')}
|
|
30
29
|
},
|
|
31
|
-
|
|
30
|
+
),
|
|
32
31
|
})
|
|
33
32
|
`;
|
|
34
33
|
}
|
|
@@ -10,6 +10,9 @@ const imports_1 = require("../../../lib/imports");
|
|
|
10
10
|
function generateModelLibraryComponents({ model, meta }) {
|
|
11
11
|
const { react: { context, components }, } = meta;
|
|
12
12
|
const selectorCollector = id_collector_1.SelectorCollector.from(meta.seed.constantName + '-card');
|
|
13
|
+
const titleProp = model.nameField.isRequired
|
|
14
|
+
? `title={item.${model.nameField.name}}`
|
|
15
|
+
: `title={item.${model.nameField.name} ?? item.${model.idField.name}}`;
|
|
13
16
|
const imports = imports_1.ImportsGenerator.from(meta.react.folderPath)
|
|
14
17
|
.addTypeImport({
|
|
15
18
|
items: [model.typeName],
|
|
@@ -52,7 +55,7 @@ function generateModelLibraryComponents({ model, meta }) {
|
|
|
52
55
|
<>
|
|
53
56
|
<Card
|
|
54
57
|
ref={forwardedRef}
|
|
55
|
-
|
|
58
|
+
${titleProp}
|
|
56
59
|
actions={[
|
|
57
60
|
{
|
|
58
61
|
label: 'Edit',
|
|
@@ -20,7 +20,9 @@ function generateModelLookupComponents({ model, meta }) {
|
|
|
20
20
|
});
|
|
21
21
|
const typeName = model.typeName;
|
|
22
22
|
const tsOmittedFields = `'label' | 'options' | 'loading'`;
|
|
23
|
-
const
|
|
23
|
+
const labelProp = model.nameField.isRequired
|
|
24
|
+
? `label={(l) => l.${model.nameField.name}}`
|
|
25
|
+
: `label={(l) => l.${model.nameField.name} ?? l.${model.idField.name}}`;
|
|
24
26
|
let description = '';
|
|
25
27
|
if (model.description) {
|
|
26
28
|
description = `
|
|
@@ -50,7 +52,7 @@ export const ${components.forms.selectInputName} = ({
|
|
|
50
52
|
const { list, ready } = ${context.hookFnName}()
|
|
51
53
|
return <SelectInput<${typeName}>
|
|
52
54
|
options={list}
|
|
53
|
-
${
|
|
55
|
+
${labelProp}
|
|
54
56
|
loading={!ready}
|
|
55
57
|
__cypress_field_selector__={
|
|
56
58
|
delegated.__cypress_field_selector__
|
|
@@ -67,7 +69,7 @@ export const ${components.forms.selectFieldName} = ({
|
|
|
67
69
|
const { list, ready } = ${context.hookFnName}()
|
|
68
70
|
return <SelectField<${typeName}>
|
|
69
71
|
options={list}
|
|
70
|
-
${
|
|
72
|
+
${labelProp}
|
|
71
73
|
loading={!ready}
|
|
72
74
|
__cypress_field_selector__={
|
|
73
75
|
delegated.__cypress_field_selector__
|
|
@@ -86,7 +88,7 @@ export const ${components.forms.menuSelectInputName} = ({
|
|
|
86
88
|
const { list, ready } = ${context.hookFnName}()
|
|
87
89
|
return <MenuSelectInput<${typeName}>
|
|
88
90
|
options={list}
|
|
89
|
-
${
|
|
91
|
+
${labelProp}
|
|
90
92
|
loading={!ready}
|
|
91
93
|
__cypress_options_selector__={
|
|
92
94
|
delegated.__cypress_options_selector__
|
|
@@ -103,7 +105,7 @@ export const ${components.forms.menuSelectFieldName} = ({
|
|
|
103
105
|
const { list, ready } = ${context.hookFnName}()
|
|
104
106
|
return <MenuSelectField<${typeName}>
|
|
105
107
|
options={list}
|
|
106
|
-
${
|
|
108
|
+
${labelProp}
|
|
107
109
|
loading={!ready}
|
|
108
110
|
__cypress_options_selector__={
|
|
109
111
|
delegated.__cypress_options_selector__
|
|
@@ -122,7 +124,7 @@ export const ${components.forms.searchInputName} = ({
|
|
|
122
124
|
const { list, ready } = ${context.hookFnName}()
|
|
123
125
|
return <SearchInput<${typeName}>
|
|
124
126
|
options={list}
|
|
125
|
-
${
|
|
127
|
+
${labelProp}
|
|
126
128
|
loading={!ready}
|
|
127
129
|
__cypress_combobox_selector__={
|
|
128
130
|
delegated.__cypress_combobox_selector__
|
|
@@ -143,7 +145,7 @@ export const ${components.forms.searchFieldName} = ({
|
|
|
143
145
|
const { list, ready } = ${context.hookFnName}()
|
|
144
146
|
return <SearchField<${typeName}>
|
|
145
147
|
options={list}
|
|
146
|
-
${
|
|
148
|
+
${labelProp}
|
|
147
149
|
loading={!ready}
|
|
148
150
|
__cypress_combobox_selector__={
|
|
149
151
|
delegated.__cypress_combobox_selector__
|
|
@@ -165,7 +167,7 @@ export const ${components.forms.tableSelectInputName} = ({
|
|
|
165
167
|
const { list, ready } = ${context.hookFnName}()
|
|
166
168
|
return <TableSelectInput<${typeName}>
|
|
167
169
|
options={list}
|
|
168
|
-
${
|
|
170
|
+
${labelProp}
|
|
169
171
|
loading={!ready}
|
|
170
172
|
__cypress_input_field_selector__={
|
|
171
173
|
delegated.__cypress_input_field_selector__
|
|
@@ -182,7 +184,7 @@ export const ${components.forms.tableSelectFieldName} = ({
|
|
|
182
184
|
const { list, ready } = ${context.hookFnName}()
|
|
183
185
|
return <TableSelectField<${typeName}>
|
|
184
186
|
options={list}
|
|
185
|
-
${
|
|
187
|
+
${labelProp}
|
|
186
188
|
loading={!ready}
|
|
187
189
|
__cypress_input_field_selector__={
|
|
188
190
|
delegated.__cypress_input_field_selector__
|
|
@@ -3,10 +3,11 @@ import { Model, SchemaConfig } from '../../lib/schema/schema';
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates a seed file for a given model.
|
|
5
5
|
*/
|
|
6
|
-
export declare function generateSeedModel({ model, itemCount, meta, }: {
|
|
6
|
+
export declare function generateSeedModel({ model, itemCount, meta, models, }: {
|
|
7
7
|
model: Model;
|
|
8
8
|
itemCount: number;
|
|
9
9
|
meta: ModelMetaData;
|
|
10
|
+
models: Model[];
|
|
10
11
|
}): string;
|
|
11
12
|
/**
|
|
12
13
|
* Creates the seed file that exposes all seed data as single object.
|
|
@@ -12,11 +12,15 @@ const string_1 = require("../../lib/utils/string");
|
|
|
12
12
|
/**
|
|
13
13
|
* Creates a seed file for a given model.
|
|
14
14
|
*/
|
|
15
|
-
function generateSeedModel({ model, itemCount, meta, }) {
|
|
15
|
+
function generateSeedModel({ model, itemCount, meta, models, }) {
|
|
16
16
|
var _a;
|
|
17
17
|
// NOTE: We seed `faker` independently for each model.
|
|
18
18
|
// This way changes to another model or to the ordering of models in the schema doesn't impact the generated values.
|
|
19
19
|
faker_1.faker.seed((_a = model.attributes.randomSeed) !== null && _a !== void 0 ? _a : 0);
|
|
20
|
+
const modelMap = new Map();
|
|
21
|
+
for (const model of models) {
|
|
22
|
+
modelMap.set(model.name, model);
|
|
23
|
+
}
|
|
20
24
|
const imports = imports_1.ImportsGenerator.from(meta.seed.filePath).addImport({
|
|
21
25
|
items: [(0, types_1.toAnnotatedTypeName)(model.typeName), meta.types.toBrandedIdTypeFnName],
|
|
22
26
|
from: meta.types.importPath,
|
|
@@ -33,7 +37,7 @@ function generateSeedModel({ model, itemCount, meta, }) {
|
|
|
33
37
|
const mode = getExampleMode({ model, maxItemCount: itemCount });
|
|
34
38
|
const examples = [];
|
|
35
39
|
for (let i = 1; i <= mode.itemCount; i++) {
|
|
36
|
-
examples.push(generateExample({ model, index: i, mode }));
|
|
40
|
+
examples.push(generateExample({ model, index: i, mode, models: modelMap }));
|
|
37
41
|
}
|
|
38
42
|
return `
|
|
39
43
|
${imports.generate()}
|
|
@@ -57,7 +61,7 @@ function getExampleMode({ model, maxItemCount }) {
|
|
|
57
61
|
field.attributes.examples.length > 0) {
|
|
58
62
|
if (numberOfExamplesPerField === undefined) {
|
|
59
63
|
numberOfExamplesPerField = field.attributes.examples.length;
|
|
60
|
-
numberOfAllPossiblePermutations =
|
|
64
|
+
numberOfAllPossiblePermutations = field.attributes.examples.length;
|
|
61
65
|
}
|
|
62
66
|
else if (numberOfExamplesPerField !== field.attributes.examples.length) {
|
|
63
67
|
sameNumberOfExamplesPerField = false;
|
|
@@ -73,23 +77,23 @@ function getExampleMode({ model, maxItemCount }) {
|
|
|
73
77
|
}
|
|
74
78
|
return { kind: 'Permutations', itemCount: Math.min(numberOfAllPossiblePermutations, maxItemCount) };
|
|
75
79
|
}
|
|
76
|
-
function generateExample({ model, index, mode }) {
|
|
80
|
+
function generateExample({ model, index, mode, models, }) {
|
|
77
81
|
const data = new serializer_1.Serializer();
|
|
78
82
|
data.append('{');
|
|
79
83
|
for (const field of model.fields.values()) {
|
|
80
|
-
data.append(`${field.name}: ${generateFieldData({ field, model, index, mode })},`);
|
|
84
|
+
data.append(`${field.name}: ${generateFieldData({ field, model, index, mode, models })},`);
|
|
81
85
|
}
|
|
82
86
|
data.append('}');
|
|
83
87
|
return data.print();
|
|
84
88
|
}
|
|
85
|
-
function generateFieldData({ field, model, index, mode, }) {
|
|
89
|
+
function generateFieldData({ field, model, index, mode, models, }) {
|
|
86
90
|
switch (field.kind) {
|
|
87
91
|
case 'id':
|
|
88
92
|
return generateIdFieldExample({ field, model, index, mode });
|
|
89
93
|
case 'scalar':
|
|
90
94
|
return generateScalarFieldExample({ field, model, index, mode });
|
|
91
95
|
case 'relation':
|
|
92
|
-
return generateRelationFieldExample({ field, model, index, mode });
|
|
96
|
+
return generateRelationFieldExample({ field, model, index, mode, models });
|
|
93
97
|
case 'enum':
|
|
94
98
|
return generateEnumFieldExample({ field, mode, index });
|
|
95
99
|
default:
|
|
@@ -215,14 +219,24 @@ function generateMockDate() {
|
|
|
215
219
|
d.setUTCHours(0, 0, 0, 0);
|
|
216
220
|
return `new Date('${d.toISOString()}')`;
|
|
217
221
|
}
|
|
218
|
-
function generateRelationFieldExample({ field, index, model, mode, }) {
|
|
222
|
+
function generateRelationFieldExample({ field, index, model, mode, models, }) {
|
|
219
223
|
if (!field.isRequired) {
|
|
220
224
|
return 'null';
|
|
221
225
|
}
|
|
222
|
-
const
|
|
223
|
-
|
|
226
|
+
const refModel = models.get(field.relationToModel.name);
|
|
227
|
+
if (!refModel) {
|
|
228
|
+
throw new Error(`Could not find model ${field.relationToModel.name}`);
|
|
229
|
+
}
|
|
230
|
+
const refModelMeta = (0, meta_1.getModelMetadata)({ model: refModel });
|
|
231
|
+
const refModelExampleMode = getExampleMode({ model: refModel, maxItemCount: mode.itemCount });
|
|
232
|
+
const referenceId = faker_1.faker.datatype.number({ min: 1, max: refModelExampleMode.itemCount });
|
|
224
233
|
const brandingFn = refModelMeta.types.toBrandedIdTypeFnName;
|
|
225
|
-
const { hasExample, example } = generateFieldExample({
|
|
234
|
+
const { hasExample, example } = generateFieldExample({
|
|
235
|
+
field: refModel.idField,
|
|
236
|
+
model: refModel,
|
|
237
|
+
index,
|
|
238
|
+
mode: refModelExampleMode,
|
|
239
|
+
});
|
|
226
240
|
if (field.unbrandedTypeName === 'string') {
|
|
227
241
|
if (hasExample && typeof example === 'string') {
|
|
228
242
|
return `${brandingFn}('${quoteSingleQuote(example)}')`;
|
package/dist/prisma/parse.js
CHANGED
|
@@ -158,6 +158,8 @@ function parseModel({ dmmfModel, enums, models, config, }) {
|
|
|
158
158
|
if (dmmfField.relationOnDelete && dmmfField.relationOnDelete !== 'NoAction') {
|
|
159
159
|
(0, error_1.throwError)(`Investigate model ${highlight(dmmfModel.name)}: "onDelete" attribute for relationship ${highlight(dmmfField.relationName)} must be "NoAction": any deletes must be handled in the application layer, e.g. to update repository and search caches!`);
|
|
160
160
|
}
|
|
161
|
+
// Note: At this point, we only have the `ModelCore`. After all models are parsed, we need to updated
|
|
162
|
+
// the relations with the full `Model`. This is done in the `linkModels` function.
|
|
161
163
|
relations[dmmfField.relationFromFields[0]] = referencedModel;
|
|
162
164
|
}
|
|
163
165
|
const relationFields = dmmfModel.fields
|