@postxl/generator 0.0.1

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.
Files changed (95) hide show
  1. package/README.md +3 -0
  2. package/dist/jest.config.d.ts +3 -0
  3. package/dist/src/generator.d.ts +12 -0
  4. package/dist/src/generator.js +164 -0
  5. package/dist/src/generators/enums/react.generator.d.ts +10 -0
  6. package/dist/src/generators/enums/react.generator.js +81 -0
  7. package/dist/src/generators/enums/types.generator.d.ts +10 -0
  8. package/dist/src/generators/enums/types.generator.js +18 -0
  9. package/dist/src/generators/indices/datamockmodule.generator.d.ts +9 -0
  10. package/dist/src/generators/indices/datamockmodule.generator.js +104 -0
  11. package/dist/src/generators/indices/datamodule.generator.d.ts +9 -0
  12. package/dist/src/generators/indices/datamodule.generator.js +128 -0
  13. package/dist/src/generators/indices/dataservice.generator.d.ts +9 -0
  14. package/dist/src/generators/indices/dataservice.generator.js +47 -0
  15. package/dist/src/generators/indices/repositories.generator.d.ts +9 -0
  16. package/dist/src/generators/indices/repositories.generator.js +17 -0
  17. package/dist/src/generators/indices/seed.generator.d.ts +9 -0
  18. package/dist/src/generators/indices/seed.generator.js +17 -0
  19. package/dist/src/generators/indices/stubs.generator.d.ts +9 -0
  20. package/dist/src/generators/indices/stubs.generator.js +17 -0
  21. package/dist/src/generators/indices/testdataservice.generator.d.ts +7 -0
  22. package/dist/src/generators/indices/testdataservice.generator.js +61 -0
  23. package/dist/src/generators/indices/types.generator.d.ts +10 -0
  24. package/dist/src/generators/indices/types.generator.js +21 -0
  25. package/dist/src/generators/models/react.generator/context.generator.d.ts +9 -0
  26. package/dist/src/generators/models/react.generator/context.generator.js +66 -0
  27. package/dist/src/generators/models/react.generator/index.d.ts +10 -0
  28. package/dist/src/generators/models/react.generator/index.js +32 -0
  29. package/dist/src/generators/models/react.generator/library.generator.d.ts +9 -0
  30. package/dist/src/generators/models/react.generator/library.generator.js +113 -0
  31. package/dist/src/generators/models/react.generator/lookup.generator.d.ts +9 -0
  32. package/dist/src/generators/models/react.generator/lookup.generator.js +97 -0
  33. package/dist/src/generators/models/react.generator/modals.generator.d.ts +23 -0
  34. package/dist/src/generators/models/react.generator/modals.generator.js +521 -0
  35. package/dist/src/generators/models/repository.generator.d.ts +9 -0
  36. package/dist/src/generators/models/repository.generator.js +282 -0
  37. package/dist/src/generators/models/route.generator.d.ts +16 -0
  38. package/dist/src/generators/models/route.generator.js +112 -0
  39. package/dist/src/generators/models/seed.generator.d.ts +20 -0
  40. package/dist/src/generators/models/seed.generator.js +185 -0
  41. package/dist/src/generators/models/stub.generator.d.ts +9 -0
  42. package/dist/src/generators/models/stub.generator.js +74 -0
  43. package/dist/src/generators/models/types.generator.d.ts +9 -0
  44. package/dist/src/generators/models/types.generator.js +116 -0
  45. package/dist/src/lib/attributes.d.ts +43 -0
  46. package/dist/src/lib/attributes.js +2 -0
  47. package/dist/src/lib/exports.d.ts +26 -0
  48. package/dist/src/lib/exports.js +38 -0
  49. package/dist/src/lib/imports.d.ts +35 -0
  50. package/dist/src/lib/imports.js +55 -0
  51. package/dist/src/lib/meta.d.ts +359 -0
  52. package/dist/src/lib/meta.js +195 -0
  53. package/dist/src/lib/schema/fields.d.ts +35 -0
  54. package/dist/src/lib/schema/fields.js +49 -0
  55. package/dist/src/lib/schema/schema.d.ts +275 -0
  56. package/dist/src/lib/schema/schema.js +2 -0
  57. package/dist/src/lib/schema/types.d.ts +72 -0
  58. package/dist/src/lib/schema/types.js +41 -0
  59. package/dist/src/lib/schema/zod.d.ts +8 -0
  60. package/dist/src/lib/schema/zod.js +44 -0
  61. package/dist/src/lib/serializer.d.ts +15 -0
  62. package/dist/src/lib/serializer.js +24 -0
  63. package/dist/src/lib/utils/error.d.ts +5 -0
  64. package/dist/src/lib/utils/error.js +13 -0
  65. package/dist/src/lib/utils/file.d.ts +10 -0
  66. package/dist/src/lib/utils/file.js +54 -0
  67. package/dist/src/lib/utils/logger.d.ts +11 -0
  68. package/dist/src/lib/utils/logger.js +2 -0
  69. package/dist/src/lib/utils/string.d.ts +29 -0
  70. package/dist/src/lib/utils/string.js +75 -0
  71. package/dist/src/lib/utils/types.d.ts +12 -0
  72. package/dist/src/lib/utils/types.js +2 -0
  73. package/dist/src/lib/vfs.d.ts +137 -0
  74. package/dist/src/lib/vfs.js +419 -0
  75. package/dist/src/prisma/attributes.d.ts +17 -0
  76. package/dist/src/prisma/attributes.js +80 -0
  77. package/dist/src/prisma/client-path.d.ts +7 -0
  78. package/dist/src/prisma/client-path.js +29 -0
  79. package/dist/src/prisma/parse.d.ts +12 -0
  80. package/dist/src/prisma/parse.js +276 -0
  81. package/dist/tests/attributes.test.d.ts +1 -0
  82. package/dist/tests/attributes.test.js +76 -0
  83. package/dist/tests/file.test.d.ts +1 -0
  84. package/dist/tests/file.test.js +26 -0
  85. package/dist/tests/utils/random.d.ts +3 -0
  86. package/dist/tests/utils/random.js +15 -0
  87. package/dist/tests/vfs.test.d.ts +1 -0
  88. package/dist/tests/vfs.test.js +74 -0
  89. package/dist/tsconfig.tsbuildinfo +1 -0
  90. package/jest.config.ts +18 -0
  91. package/package.json +42 -0
  92. package/tests/attributes.test.ts +91 -0
  93. package/tests/file.test.ts +32 -0
  94. package/tests/utils/random.ts +11 -0
  95. package/tests/vfs.test.ts +92 -0
@@ -0,0 +1,521 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.generateDeleteModalModelComponent = exports.generateEditModalModelComponent = exports.generateModelCreateModalComponent = void 0;
30
+ const assert_never_1 = __importDefault(require("assert-never"));
31
+ const serializer_1 = require("../../../lib/serializer");
32
+ const StringUtils = __importStar(require("../../../lib/utils/string"));
33
+ const meta_1 = require("../../../lib/meta");
34
+ const fields_1 = require("../../../lib/schema/fields");
35
+ const imports_1 = require("../../../lib/imports");
36
+ /**
37
+ * Utility generator that creates a create modal component for a given model.
38
+ */
39
+ function generateModelCreateModalComponent({ model, meta }) {
40
+ const { fields } = model;
41
+ const { react: { components: { modals }, }, trpc, } = meta;
42
+ return `
43
+ ${getFormImports({ model, meta })}
44
+
45
+ type CreateInputData = {
46
+ ${getFormInputFields({ model, nullable: true })}
47
+ }
48
+
49
+ /**
50
+ * A modal component that lets the user create a new ${meta.userFriendlyName} instance.
51
+ */
52
+ export const ${modals.createComponentName} = ({ show, onHide }: { show: boolean; onHide: () => void }) => {
53
+ const cache = trpc.useContext()
54
+ const mutation = trpc.${trpc.create.reactQueryMethod}.useMutation()
55
+
56
+ return (
57
+ <ModalWithNavigationContainer label="Create new ${meta.userFriendlyName}" show={show} onHide={onHide} fixed wide>
58
+ <Formik<CreateInputData>
59
+ initialValues={{
60
+ ${fields
61
+ .filter((f) => f.kind !== 'id')
62
+ .map((field) => `${getFormikFieldName(field.name)}: null,`)
63
+ .join('\n')}
64
+ }}
65
+ validate={(values) => {
66
+ const errors: FormikErrors<CreateInputData> = {}
67
+
68
+ ${getFormikValidationCases({ model, includeId: false })}
69
+
70
+ return errors
71
+ }}
72
+ onSubmit={async (values) => {
73
+
74
+ try {
75
+ const res = await toast.promise(
76
+ mutation.mutateAsync(
77
+ {
78
+ ${getFormikMutationData({ model, includeId: false })}
79
+ },
80
+ {
81
+ async onSuccess() {
82
+ await cache.${trpc.getMap.reactQueryMethod}.invalidate()
83
+ },
84
+ },
85
+ ),
86
+ {
87
+ loading: "Creating new ${meta.userFriendlyName}...",
88
+ success: "New ${meta.userFriendlyName} created!",
89
+ error: "Something went wrong...",
90
+ },
91
+ )
92
+
93
+ if (res.id) {
94
+ onHide()
95
+ }
96
+ } catch (err) {
97
+ console.error(err)
98
+ }
99
+ }}
100
+ >
101
+ {({ isSubmitting, handleSubmit, isValid }) => (
102
+ <ModalWithActions actions={
103
+ <ConfirmButton
104
+ color="primary"
105
+ label="Create"
106
+ fill="fill"
107
+ onClick={handleSubmit}
108
+ loading={isSubmitting}
109
+ disabled={!isValid}
110
+ />
111
+ }>
112
+ ${getFormFieldComponents({ model })}
113
+ </ModalWithActions>
114
+ )}
115
+ </Formik>
116
+ </ModalWithNavigationContainer>
117
+ )
118
+ }
119
+
120
+ `;
121
+ }
122
+ exports.generateModelCreateModalComponent = generateModelCreateModalComponent;
123
+ /**
124
+ * Returns a React component that lets you edit a model instance.
125
+ */
126
+ function generateEditModalModelComponent({ model, meta }) {
127
+ const { fields } = model;
128
+ const { react: { components }, trpc, } = meta;
129
+ return `
130
+ ${getFormImports({ model, meta })}
131
+
132
+
133
+ type EditInputData = {
134
+ ${getFormikFieldName(model.idField.name)}: ${model.brandedIdType}
135
+ ${getFormInputFields({ model, nullable: false })}
136
+ }
137
+
138
+ /**
139
+ * Modal component that may be used to edit a ${model.name} instance.
140
+ */
141
+ export const ${components.modals.editComponentName} = ({
142
+ data,
143
+ show,
144
+ onHide
145
+ }: { data: ${model.typeName}; show: boolean; onHide: () => void }) => {
146
+ const cache = trpc.useContext()
147
+ const mutation = trpc.${trpc.update.reactQueryMethod}.useMutation()
148
+
149
+ return (
150
+ <ModalWithNavigationContainer label="Edit ${meta.userFriendlyName}" show={show} onHide={onHide} fixed wide>
151
+ <Formik<EditInputData>
152
+ initialValues={{
153
+ ${fields
154
+ .map((field) => {
155
+ switch (field.kind) {
156
+ case 'enum':
157
+ case 'relation':
158
+ if (field.isRequired) {
159
+ return `${getFormikFieldName(field.name)}: { id: data.${field.name} },`;
160
+ }
161
+ return `${getFormikFieldName(field.name)}: data.${field.name} ? { id: data.${field.name} } : null,`;
162
+ case 'id':
163
+ case 'scalar':
164
+ return `${getFormikFieldName(field.name)}: data.${field.name},`;
165
+ default:
166
+ (0, assert_never_1.default)(field);
167
+ }
168
+ })
169
+ .join('\n')}
170
+ }}
171
+ validate={(values) => {
172
+ const errors: { [K in keyof EditInputData]?: string } = {}
173
+
174
+ ${getFormikValidationCases({ model, includeId: true })}
175
+
176
+ return errors
177
+ }}
178
+ onSubmit={async (values) => {
179
+ try {
180
+ await toast.promise(
181
+ mutation.mutateAsync(
182
+ {
183
+ ${getFormikMutationData({ model, includeId: true })}
184
+ },
185
+ {
186
+ async onSuccess() {
187
+ await cache.${trpc.getMap.reactQueryMethod}.invalidate()
188
+ },
189
+ },
190
+ ),
191
+ {
192
+ loading: "Updating ${meta.userFriendlyName}...",
193
+ success: "${meta.userFriendlyName} updated!",
194
+ error: "Something went wrong...",
195
+ },
196
+ )
197
+
198
+ onHide()
199
+ } catch (err) {
200
+ console.error(err)
201
+ }
202
+ }}
203
+ >
204
+ {({ isSubmitting, isValid, handleSubmit }) => (
205
+ <ModalWithActions
206
+ actions={
207
+ <ConfirmButton
208
+ label="Save"
209
+ color="primary"
210
+ onClick={handleSubmit}
211
+ loading={isSubmitting}
212
+ disabled={!isValid}
213
+ />
214
+ }
215
+ >
216
+ ${getFormFieldComponents({ model })}
217
+ </ModalWithActions>
218
+ )}
219
+ </Formik>
220
+ </ModalWithNavigationContainer>
221
+ )
222
+ }
223
+ `;
224
+ }
225
+ exports.generateEditModalModelComponent = generateEditModalModelComponent;
226
+ /**
227
+ * Generates a modal component that lets you delete a model instance.
228
+ */
229
+ function generateDeleteModalModelComponent({ model, meta }) {
230
+ const { react: { components }, trpc, } = meta;
231
+ const imports = imports_1.ImportsGenerator.from(meta.react.folderPath).addImport({
232
+ items: [model.brandedIdType],
233
+ from: meta.types.importPath,
234
+ });
235
+ return `
236
+ import { Formik, FormikErrors } from 'formik'
237
+ import React, { useCallback } from 'react'
238
+ import { toast } from 'react-hot-toast'
239
+
240
+ import { ConfirmationModal } from '@components/atoms/Modal'
241
+ import { trpc } from '@lib/trpc'
242
+
243
+ ${imports.generate()}
244
+
245
+ /**
246
+ * Modal components that shows a confirmation modal before deleting a ${meta.userFriendlyName}.
247
+ */
248
+ export const ${components.modals.deleteComponentName} = ({
249
+ id,
250
+ show,
251
+ onHide
252
+ }: {
253
+ id: ${model.brandedIdType};
254
+ show: boolean;
255
+ onHide: () => void
256
+ }) => {
257
+ const cache = trpc.useContext()
258
+ const mutation = trpc.${trpc.delete.reactQueryMethod}.useMutation()
259
+
260
+ const handleDelete = useCallback(async () => {
261
+ try {
262
+ await toast.promise(
263
+ mutation.mutateAsync(id, {
264
+ async onSuccess() {
265
+ await cache.${trpc.getMap.reactQueryMethod}.invalidate()
266
+ },
267
+ }),
268
+ {
269
+ loading: "Deleting ${meta.userFriendlyName}...",
270
+ success: "${meta.userFriendlyName} deleted!",
271
+ error: "Something went wrong...",
272
+ },
273
+ )
274
+ } catch (err) {
275
+ console.error(err)
276
+ }
277
+ }, [mutation, id, cache])
278
+
279
+ return (
280
+ <ConfirmationModal
281
+ show={show}
282
+ onHide={onHide}
283
+ onConfirm={handleDelete}
284
+ label="Delete ${meta.userFriendlyName}"
285
+ description="Please confirm that you want to delete this ${meta.userFriendlyName}."
286
+ variant="danger"
287
+ loading={mutation.isLoading}
288
+ />
289
+ )
290
+ }
291
+ `;
292
+ }
293
+ exports.generateDeleteModalModelComponent = generateDeleteModalModelComponent;
294
+ /**
295
+ * Returns the import statements to the models that are used in this modal.
296
+ */
297
+ function getFormImports({ model, meta }) {
298
+ const imports = imports_1.ImportsGenerator.from(meta.react.folderPath).addImport({
299
+ items: [model.brandedIdType, model.typeName],
300
+ from: meta.types.importPath,
301
+ });
302
+ for (const ref of (0, fields_1.getRelationFields)(model)) {
303
+ const refModel = ref.relationToModel;
304
+ const refMeta = (0, meta_1.getModelMetadata)({ model: refModel });
305
+ imports.addImport({
306
+ items: [refMeta.react.components.forms.searchFieldName],
307
+ from: refMeta.react.folderPath,
308
+ });
309
+ imports.addImport({
310
+ items: [refModel.brandedIdType],
311
+ from: refMeta.types.importPath,
312
+ });
313
+ }
314
+ for (const f of (0, fields_1.getEnumFields)(model)) {
315
+ const enumMeta = (0, meta_1.getEnumMetadata)(f);
316
+ imports.addImport({
317
+ items: [f.enumerator.typeName],
318
+ from: enumMeta.types.importPath,
319
+ });
320
+ imports.addImport({
321
+ items: [enumMeta.react.selectFieldName],
322
+ from: enumMeta.react.folderPath,
323
+ });
324
+ }
325
+ return `
326
+ import React from 'react'
327
+ import { toast } from 'react-hot-toast'
328
+ import { Formik, FormikErrors } from 'formik'
329
+
330
+ import { CheckBoxField } from '@components/atoms/CheckBoxInput'
331
+ import { ConfirmButton, ModalWithNavigationContainer, Label, ModalWithActions } from '@components/atoms/Modal'
332
+ import { TextAreaField } from '@components/atoms/TextAreaInput'
333
+ import { TextField } from '@components/atoms/TextInput'
334
+ import { NumberField } from '@components/atoms/NumberInput'
335
+
336
+ import { trpc } from '@lib/trpc'
337
+
338
+ ${imports.generate()}
339
+ `;
340
+ }
341
+ /**
342
+ * Returns a string containing the fields of the input data without the ID field.
343
+ */
344
+ function getFormInputFields({ model, nullable }) {
345
+ const form = new serializer_1.Serializer();
346
+ for (const field of model.fields.values()) {
347
+ switch (field.kind) {
348
+ case 'id':
349
+ continue;
350
+ case 'relation':
351
+ if (field.isRequired && nullable !== true) {
352
+ form.append(`${getFormikFieldName(field.name)}: { id: ${field.relationToModel.brandedIdType} }`);
353
+ }
354
+ else {
355
+ form.append(`${getFormikFieldName(field.name)}: { id: ${field.relationToModel.brandedIdType} } | null`);
356
+ }
357
+ break;
358
+ case 'scalar':
359
+ if (field.isRequired && nullable !== true) {
360
+ form.append(`${getFormikFieldName(field.name)}: ${field.typeName}`);
361
+ }
362
+ else {
363
+ form.append(`${getFormikFieldName(field.name)}: ${field.typeName} | null`);
364
+ }
365
+ break;
366
+ case 'enum':
367
+ if (field.isRequired && nullable !== true) {
368
+ form.append(`${getFormikFieldName(field.name)}: { id: ${field.typeName} }`);
369
+ }
370
+ else {
371
+ form.append(`${getFormikFieldName(field.name)}: { id: ${field.typeName} } | null`);
372
+ }
373
+ break;
374
+ default:
375
+ (0, assert_never_1.default)(field);
376
+ }
377
+ }
378
+ return form.print();
379
+ }
380
+ /**
381
+ * Returns a string containing all the components that should appear in the Formik form for this model.
382
+ */
383
+ function getFormFieldComponents({ model }) {
384
+ var _a;
385
+ const form = new serializer_1.Serializer();
386
+ for (const field of model.fields.values()) {
387
+ const formikFieldName = getFormikFieldName(field.name);
388
+ const label = StringUtils.toPascalCase(field.name);
389
+ switch (field.kind) {
390
+ case 'id': {
391
+ // NOTE: We never show the ID field in the form even if it's in the type signiture of the form input.
392
+ break;
393
+ }
394
+ case 'scalar': {
395
+ // Each scalar field has a different generic component based on the provided type.
396
+ scalar: switch (field.typeName) {
397
+ case 'string':
398
+ form.append(`
399
+ <div>
400
+ <Label>${label}</Label>
401
+ <TextField placeholder="Type..." name="${formikFieldName}" />
402
+ </div>
403
+ `);
404
+ break scalar;
405
+ case 'number':
406
+ let decimals = 0;
407
+ if (((_a = field.validation) === null || _a === void 0 ? void 0 : _a.type) === 'float') {
408
+ decimals = 2;
409
+ }
410
+ form.append(`
411
+ <div>
412
+ <Label>${label}</Label>
413
+ <NumberField placeholder="2511" name="${formikFieldName}" decimals={${decimals}}/>
414
+ </div>
415
+ `);
416
+ break scalar;
417
+ case 'boolean':
418
+ form.append(`
419
+ <div>
420
+ <Label>Is ${label}</Label>
421
+ <CheckBoxField label="${label}" name="${formikFieldName}" />
422
+ </div>
423
+ `);
424
+ break scalar;
425
+ case 'Date':
426
+ form.append(`{/* Skipped date field ${field.name}. */}`);
427
+ break scalar;
428
+ default:
429
+ console.warn(`Unknown scalar type ${field.typeName} for field ${model.name}.${field.name}.`);
430
+ break scalar;
431
+ }
432
+ break;
433
+ }
434
+ case 'relation': {
435
+ const refMeta = (0, meta_1.getModelMetadata)({ model: field.relationToModel });
436
+ form.append(`
437
+ <div>
438
+ <Label>${refMeta.userFriendlyName}</Label>
439
+ <${refMeta.react.components.forms.searchFieldName} name="${formikFieldName}" placeholder="Search..." />
440
+ </div>
441
+ `);
442
+ break;
443
+ }
444
+ case 'enum': {
445
+ const enumMeta = (0, meta_1.getEnumMetadata)({ enumerator: field.enumerator });
446
+ form.append(`
447
+ <div>
448
+ <Label>${label}</Label>
449
+ <${enumMeta.react.selectFieldName} name="${formikFieldName}" placeholder="Search..." />
450
+ </div>
451
+ `);
452
+ break;
453
+ }
454
+ default:
455
+ (0, assert_never_1.default)(field);
456
+ }
457
+ }
458
+ return form.print();
459
+ }
460
+ /**
461
+ * Returns a string containing a list of checks for Formik validation function.
462
+ */
463
+ function getFormikValidationCases({ model, includeId }) {
464
+ const form = new serializer_1.Serializer();
465
+ for (const field of model.fields.values()) {
466
+ if (!includeId && field.kind === 'id')
467
+ continue;
468
+ const formikFieldName = getFormikFieldName(field.name);
469
+ if (field.isRequired) {
470
+ form.append(`
471
+ if (!values.${formikFieldName}) {
472
+ errors.${formikFieldName} = "Required..."
473
+ }
474
+ `);
475
+ }
476
+ }
477
+ return form.print();
478
+ }
479
+ function getFormikMutationData({ model: { fields }, includeId }) {
480
+ return fields
481
+ .map((field) => {
482
+ const formikFieldName = getFormikFieldName(field.name);
483
+ switch (field.kind) {
484
+ case 'id':
485
+ case 'scalar':
486
+ if (field.kind === 'id' && !includeId) {
487
+ return '';
488
+ }
489
+ if (field.isRequired) {
490
+ return `
491
+ // NOTE: We force unwrap values, because we validate values using Formik.
492
+ ${field.name}: values.${formikFieldName}!,
493
+ `;
494
+ }
495
+ return `${field.name}: values.${formikFieldName},`;
496
+ case 'relation':
497
+ if (field.isRequired) {
498
+ return `
499
+ // NOTE: We force unwrap values, because we validate values using Formik.
500
+ ${field.name}: values.${formikFieldName}!.id,
501
+ `;
502
+ }
503
+ return `${field.name}: values.${formikFieldName}?.id ? values.${formikFieldName}!.id : null,`;
504
+ case 'enum':
505
+ if (field.isRequired) {
506
+ return `
507
+ // NOTE: We force unwrap values, because we validate values using Formik.
508
+ ${field.name}: values.${formikFieldName}!.id,
509
+ `;
510
+ }
511
+ return `${field.name}: values.${formikFieldName}?.id ? values.${formikFieldName}!.id : null,`;
512
+ default:
513
+ (0, assert_never_1.default)(field);
514
+ }
515
+ })
516
+ .join('\n');
517
+ }
518
+ // NOTE: This function is separated because many parts rely on the name of the field.
519
+ function getFormikFieldName(name) {
520
+ return `formik${StringUtils.toPascalCase(name)}`;
521
+ }
@@ -0,0 +1,9 @@
1
+ import { Model } from '../../lib/schema/schema';
2
+ import { ModelMetaData } from '../../lib/meta';
3
+ /**
4
+ * Generates repository data structure for a given model.
5
+ */
6
+ export declare function generateRepository({ model, meta }: {
7
+ model: Model;
8
+ meta: ModelMetaData;
9
+ }): string;