@postxl/generator 0.15.1 → 0.15.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.
@@ -23,93 +23,102 @@ function generateSeedModel({ model, itemCount, meta, }) {
23
23
  from: depMeta.types.importPath,
24
24
  });
25
25
  }
26
- const exampleMode = getExampleMode({ model, maxItemCount: itemCount });
27
- const seed = [];
28
- for (let i = 1; i <= exampleMode.itemCount; i++) {
29
- seed.push(generateSeedData({ model, index: i, exampleMode }));
26
+ const mode = getExampleMode({ model, maxItemCount: itemCount });
27
+ const examples = [];
28
+ for (let i = 1; i <= mode.itemCount; i++) {
29
+ examples.push(generateExample({ model, index: i, mode }));
30
30
  }
31
31
  return `
32
32
  ${imports.generate()}
33
33
 
34
34
  export const ${meta.seed.constantName}: ${model.typeName}[] = [
35
- ${seed.join(',\n')}
35
+ ${examples.join(',\n')}
36
36
  ]
37
37
  `;
38
38
  }
39
39
  exports.generateSeedModel = generateSeedModel;
40
40
  /**
41
- * In case of a model with examples, there are two options:
42
- * 1. the number of examples per field is the same for all fields with examples -> we generate them as tuples
43
- * 2. the number of examples per field is different -> we generate them as random permutations
44
- * Here we determine which option to use - and the number of tuples/permutations available
41
+ * Returns the mode of examples and the number of examples per field for a given model.
45
42
  */
46
43
  function getExampleMode({ model, maxItemCount }) {
47
44
  let numberOfExamplesPerField = undefined;
48
45
  let sameNumberOfExamplesPerField = true;
49
- let examplePermutations = 0;
46
+ let numberOfAllPossiblePermutations = 0;
50
47
  for (const field of model.fields) {
51
- if (field.kind === 'scalar' && field.attributes.examples && field.attributes.examples.length > 0) {
48
+ if ((field.kind === 'scalar' || field.kind === 'relation' || field.kind == 'id') &&
49
+ field.attributes.examples &&
50
+ field.attributes.examples.length > 0) {
52
51
  if (numberOfExamplesPerField === undefined) {
53
52
  numberOfExamplesPerField = field.attributes.examples.length;
54
- examplePermutations = 1;
53
+ numberOfAllPossiblePermutations = 1;
55
54
  }
56
55
  else if (numberOfExamplesPerField !== field.attributes.examples.length) {
57
56
  sameNumberOfExamplesPerField = false;
58
57
  }
59
- examplePermutations *= field.attributes.examples.length;
58
+ numberOfAllPossiblePermutations *= field.attributes.examples.length;
60
59
  }
61
60
  }
62
61
  if (numberOfExamplesPerField === undefined) {
63
- return { mode: 'NoExamples', itemCount: maxItemCount };
62
+ return { kind: 'Random', itemCount: maxItemCount };
64
63
  }
65
- else if (sameNumberOfExamplesPerField) {
66
- return {
67
- mode: 'Tuples',
68
- itemCount: numberOfExamplesPerField,
69
- };
70
- }
71
- else {
72
- return { mode: 'Permutations', itemCount: examplePermutations < maxItemCount ? examplePermutations : maxItemCount };
64
+ if (sameNumberOfExamplesPerField) {
65
+ return { kind: 'Tuples', itemCount: numberOfExamplesPerField };
73
66
  }
67
+ return { kind: 'Permutations', itemCount: Math.min(numberOfAllPossiblePermutations, maxItemCount) };
74
68
  }
75
- function generateSeedData({ model, index, exampleMode, }) {
69
+ function generateExample({ model, index, mode }) {
76
70
  const data = new serializer_1.Serializer();
77
71
  data.append('{');
78
72
  for (const field of model.fields.values()) {
79
- data.append(`${field.name}: ${generateFieldData({ field, model, index, exampleMode })},`);
73
+ data.append(`${field.name}: ${generateFieldData({ field, model, index, mode })},`);
80
74
  }
81
75
  data.append('}');
82
76
  return data.print();
83
77
  }
84
- function generateFieldData({ field, model, index, exampleMode, }) {
78
+ function generateFieldData({ field, model, index, mode, }) {
85
79
  switch (field.kind) {
86
80
  case 'id':
87
- return generateFieldDataId({ field, model, index });
81
+ return generateIdFieldExample({ field, model, index, mode });
88
82
  case 'scalar':
89
- return generateFieldDataScalar({ field, model, index, exampleMode });
83
+ return generateScalarFieldExample({ field, model, index, mode });
90
84
  case 'relation':
91
- return generateFieldDataRelation({ field, model, index, itemCount: exampleMode.itemCount });
85
+ return generateRelationFieldExample({ field, model, index, mode });
92
86
  case 'enum':
93
- return generateFieldDataEnum({ field, exampleMode, index });
87
+ return generateEnumFieldExample({ field, mode, index });
94
88
  default:
95
89
  throw new types_1.ExhaustiveSwitchCheck(field);
96
90
  }
97
91
  }
98
- function generateFieldDataId({ field, index }) {
92
+ function generateIdFieldExample({ field, model, index, mode, }) {
99
93
  const idModelMeta = (0, meta_1.getModelMetadata)({ model: field.model });
100
- return `${idModelMeta.types.toBrandedIdTypeFnName}(${field.unbrandedTypeName === 'string' ? `'${index}'` : index})`;
94
+ const { hasExample, example } = generateFieldExample({ field, model, index, mode });
95
+ if (field.unbrandedTypeName === 'string') {
96
+ if (hasExample && typeof example === 'string' && index <= mode.itemCount) {
97
+ return `${idModelMeta.types.toBrandedIdTypeFnName}('${quoteSingleQuote(example)}')`;
98
+ }
99
+ return `${idModelMeta.types.toBrandedIdTypeFnName}('${index}')`;
100
+ }
101
+ else if (field.unbrandedTypeName === 'number') {
102
+ if (hasExample && typeof example === 'number') {
103
+ return `${idModelMeta.types.toBrandedIdTypeFnName}(${example})`;
104
+ }
105
+ return `${idModelMeta.types.toBrandedIdTypeFnName}(${index})`;
106
+ }
107
+ else {
108
+ throw new Error(`Unsupported id type for ${model.name}.${field.name}: ${field.unbrandedTypeName}`);
109
+ }
101
110
  }
102
111
  function quoteSingleQuote(str) {
103
112
  return str.replace(/'/g, "\\'");
104
113
  }
105
- function generateFieldDataScalar({ field, model, index, exampleMode, }) {
106
- const { hasExample, example } = getFieldExample({ field, model, index, exampleMode });
114
+ function generateScalarFieldExample({ field, model, index, mode, }) {
115
+ const { hasExample, example } = generateFieldExample({ field, model, index, mode });
107
116
  switch (field.typeName) {
108
117
  case 'string': {
109
118
  if (hasExample && typeof example === 'string') {
110
119
  return `'${quoteSingleQuote(example)}'`;
111
120
  }
112
- const result = generateFieldDataString({ field, model, index });
121
+ const result = generateMockString({ field, model, index });
113
122
  if (result === null) {
114
123
  return 'null';
115
124
  }
@@ -122,20 +131,20 @@ function generateFieldDataScalar({ field, model, index, exampleMode, }) {
122
131
  if (hasExample) {
123
132
  return `${example}`;
124
133
  }
125
- return generateFieldDataNumber();
134
+ return generateMockNumber();
126
135
  }
127
136
  case 'boolean': {
128
137
  if (hasExample) {
129
138
  return `${example}`;
130
139
  }
131
- return generateFieldDataBoolean();
140
+ return generateMockBoolean();
132
141
  }
133
142
  case 'Date': {
134
143
  if (hasExample) {
135
144
  // TODO: Maybe we should parse the date example to correct format?
136
145
  return `${example}`;
137
146
  }
138
- return generateFieldDataDate();
147
+ return generateMockDate();
139
148
  }
140
149
  default: {
141
150
  console.warn(`Unknown scalar type: ${field.typeName}`);
@@ -143,14 +152,14 @@ function generateFieldDataScalar({ field, model, index, exampleMode, }) {
143
152
  }
144
153
  }
145
154
  }
146
- function getFieldExample({ field, index, exampleMode, }) {
147
- if (exampleMode.mode === 'NoExamples') {
155
+ function generateFieldExample({ field, index, mode, }) {
156
+ if (mode.kind === 'Random') {
148
157
  return { hasExample: false };
149
158
  }
150
159
  if (!field.attributes.examples || field.attributes.examples.length === 0) {
151
160
  return { hasExample: false };
152
161
  }
153
- switch (exampleMode.mode) {
162
+ switch (mode.kind) {
154
163
  case 'Permutations': {
155
164
  const example = faker_1.faker.helpers.arrayElement(field.attributes.examples);
156
165
  return { hasExample: true, example };
@@ -160,11 +169,11 @@ function getFieldExample({ field, index, exampleMode, }) {
160
169
  return { hasExample: true, example };
161
170
  }
162
171
  default: {
163
- throw new types_1.ExhaustiveSwitchCheck(exampleMode);
172
+ throw new types_1.ExhaustiveSwitchCheck(mode);
164
173
  }
165
174
  }
166
175
  }
167
- function generateFieldDataString({ field, model, index }) {
176
+ function generateMockString({ field, model, index }) {
168
177
  if (field.name === 'name') {
169
178
  return `${(0, string_1.toPascalCase)(model.name)} ${index}`;
170
179
  }
@@ -173,26 +182,39 @@ function generateFieldDataString({ field, model, index }) {
173
182
  }
174
183
  return faker_1.faker.lorem.words(3);
175
184
  }
176
- function generateFieldDataNumber() {
185
+ function generateMockNumber() {
177
186
  return faker_1.faker.datatype.float({ precision: 0.1, min: 0, max: 1 }).toString();
178
187
  }
179
- function generateFieldDataBoolean() {
188
+ function generateMockBoolean() {
180
189
  return faker_1.faker.datatype.boolean().toString();
181
190
  }
182
- function generateFieldDataDate() {
191
+ function generateMockDate() {
183
192
  const d = faker_1.faker.date.past(3, '2023-04-01T00:00:00.000Z');
184
193
  //set time to midnight UTC
185
194
  d.setUTCHours(0, 0, 0, 0);
186
195
  return `new Date('${d.toISOString()}')`;
187
196
  }
188
- function generateFieldDataRelation({ field, itemCount, }) {
189
- const referenceId = faker_1.faker.datatype.number({ min: 1, max: itemCount });
197
+ function generateRelationFieldExample({ field, index, model, mode, }) {
198
+ const referenceId = faker_1.faker.datatype.number({ min: 1, max: mode.itemCount });
190
199
  const refModelMeta = (0, meta_1.getModelMetadata)({ model: field.relationToModel });
191
200
  const brandingFn = refModelMeta.types.toBrandedIdTypeFnName;
192
- return `${brandingFn}(${field.unbrandedTypeName === 'string' ? `'${referenceId}'` : referenceId})`;
201
+ const { hasExample, example } = generateFieldExample({ field, model, index, mode });
202
+ if (field.unbrandedTypeName === 'string') {
203
+ if (hasExample && typeof example === 'string') {
204
+ return `${brandingFn}('${quoteSingleQuote(example)}')`;
205
+ }
206
+ return `${brandingFn}('${referenceId}')`;
207
+ }
208
+ if (field.unbrandedTypeName === 'number') {
209
+ if (hasExample && typeof example === 'number') {
210
+ return `${brandingFn}(${example})`;
211
+ }
212
+ return `${brandingFn}(${referenceId})`;
213
+ }
214
+ throw new Error(`Unsupported relation id type for ${model.name}.${field.name}: ${field.unbrandedTypeName}`);
193
215
  }
194
- function generateFieldDataEnum({ field, exampleMode, index, }) {
195
- if (exampleMode.mode === 'Tuples') {
216
+ function generateEnumFieldExample({ field, mode, index, }) {
217
+ if (mode.kind === 'Tuples') {
196
218
  if (field.attributes.examples) {
197
219
  const example = field.attributes.examples[(index - 1) % field.attributes.examples.length];
198
220
  return `'${example}'`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postxl/generator",
3
- "version": "0.15.1",
3
+ "version": "0.15.2",
4
4
  "main": "./dist/generator.js",
5
5
  "typings": "./dist/generator.d.ts",
6
6
  "bin": {