@smartive/graphql-magic 3.1.0 → 5.0.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +1 -6
  2. package/README.md +46 -0
  3. package/dist/cjs/index.cjs +260 -196
  4. package/dist/esm/api/execute.d.ts +10 -0
  5. package/dist/esm/api/execute.js +32 -0
  6. package/dist/esm/api/execute.js.map +1 -0
  7. package/dist/esm/api/index.d.ts +1 -0
  8. package/dist/esm/api/index.js +3 -0
  9. package/dist/esm/api/index.js.map +1 -0
  10. package/dist/esm/client/queries.d.ts +4 -1
  11. package/dist/esm/client/queries.js +7 -4
  12. package/dist/esm/client/queries.js.map +1 -1
  13. package/dist/esm/context.d.ts +1 -4
  14. package/dist/esm/db/generate.js +21 -13
  15. package/dist/esm/db/generate.js.map +1 -1
  16. package/dist/esm/generate/generate.d.ts +1 -1
  17. package/dist/esm/generate/generate.js +17 -22
  18. package/dist/esm/generate/generate.js.map +1 -1
  19. package/dist/esm/generate/mutations.d.ts +1 -1
  20. package/dist/esm/generate/utils.d.ts +10 -1
  21. package/dist/esm/generate/utils.js.map +1 -1
  22. package/dist/esm/index.d.ts +2 -2
  23. package/dist/esm/index.js +2 -2
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/migrations/generate.d.ts +1 -1
  26. package/dist/esm/migrations/generate.js +82 -89
  27. package/dist/esm/migrations/generate.js.map +1 -1
  28. package/dist/esm/models/index.d.ts +2 -0
  29. package/dist/esm/models/index.js +4 -0
  30. package/dist/esm/models/index.js.map +1 -0
  31. package/dist/esm/models/models.d.ts +192 -0
  32. package/dist/esm/models/models.js +2 -0
  33. package/dist/esm/models/models.js.map +1 -0
  34. package/dist/esm/models/utils.d.ts +205 -0
  35. package/dist/esm/{utils.js → models/utils.js} +69 -21
  36. package/dist/esm/models/utils.js.map +1 -0
  37. package/dist/esm/permissions/check.d.ts +1 -1
  38. package/dist/esm/permissions/check.js +2 -2
  39. package/dist/esm/permissions/check.js.map +1 -1
  40. package/dist/esm/permissions/generate.d.ts +1 -1
  41. package/dist/esm/permissions/generate.js +2 -2
  42. package/dist/esm/permissions/generate.js.map +1 -1
  43. package/dist/esm/resolvers/arguments.js +1 -1
  44. package/dist/esm/resolvers/arguments.js.map +1 -1
  45. package/dist/esm/resolvers/filters.js +2 -2
  46. package/dist/esm/resolvers/filters.js.map +1 -1
  47. package/dist/esm/resolvers/mutations.js +5 -6
  48. package/dist/esm/resolvers/mutations.js.map +1 -1
  49. package/dist/esm/resolvers/node.d.ts +1 -1
  50. package/dist/esm/resolvers/node.js +4 -5
  51. package/dist/esm/resolvers/node.js.map +1 -1
  52. package/dist/esm/resolvers/resolver.js +3 -3
  53. package/dist/esm/resolvers/resolver.js.map +1 -1
  54. package/dist/esm/resolvers/resolvers.d.ts +1 -1
  55. package/dist/esm/resolvers/resolvers.js +1 -1
  56. package/dist/esm/resolvers/resolvers.js.map +1 -1
  57. package/dist/esm/resolvers/utils.js +1 -1
  58. package/dist/esm/resolvers/utils.js.map +1 -1
  59. package/package.json +5 -5
  60. package/src/api/execute.ts +45 -0
  61. package/src/api/index.ts +3 -0
  62. package/src/client/queries.ts +16 -10
  63. package/src/context.ts +1 -3
  64. package/src/db/generate.ts +22 -15
  65. package/src/generate/generate.ts +26 -34
  66. package/src/generate/mutations.ts +1 -1
  67. package/src/generate/utils.ts +11 -1
  68. package/src/index.ts +2 -2
  69. package/src/migrations/generate.ts +84 -82
  70. package/src/models/index.ts +4 -0
  71. package/src/models/models.ts +184 -0
  72. package/src/models/utils.ts +288 -0
  73. package/src/permissions/check.ts +3 -3
  74. package/src/permissions/generate.ts +3 -3
  75. package/src/resolvers/arguments.ts +1 -1
  76. package/src/resolvers/filters.ts +2 -2
  77. package/src/resolvers/mutations.ts +10 -9
  78. package/src/resolvers/node.ts +6 -6
  79. package/src/resolvers/resolver.ts +3 -3
  80. package/src/resolvers/resolvers.ts +2 -2
  81. package/src/resolvers/utils.ts +1 -1
  82. package/tests/unit/resolve.spec.ts +4 -19
  83. package/tests/utils/models.ts +8 -7
  84. package/tests/utils/server.ts +13 -33
  85. package/dist/esm/models.d.ts +0 -170
  86. package/dist/esm/models.js +0 -27
  87. package/dist/esm/models.js.map +0 -1
  88. package/dist/esm/utils.d.ts +0 -25
  89. package/dist/esm/utils.js.map +0 -1
  90. package/src/models.ts +0 -228
  91. package/src/utils.ts +0 -187
@@ -22,9 +22,19 @@ import {
22
22
  ValueNode,
23
23
  } from 'graphql';
24
24
  import { DateTime } from 'luxon';
25
- import { Field } from '../models';
26
25
  import { Directive, Enum, Value, Values } from '../values';
27
26
 
27
+ export type Field = {
28
+ name: string;
29
+ type: string;
30
+ description?: string;
31
+ list?: boolean;
32
+ nonNull?: boolean;
33
+ default?: Value;
34
+ args?: Field[];
35
+ directives?: Directive[];
36
+ };
37
+
28
38
  export type DirectiveLocation =
29
39
  | 'ARGUMENT_DEFINITION'
30
40
  | 'INPUT_FIELD_DEFINITION'
package/src/index.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  // created from 'create-ts-index'
2
2
 
3
+ export * from './api';
3
4
  export * from './client';
4
5
  export * from './db';
5
6
  export * from './generate';
6
7
  export * from './migrations';
8
+ export * from './models';
7
9
  export * from './permissions';
8
10
  export * from './resolvers';
9
11
  export * from './context';
10
12
  export * from './errors';
11
- export * from './models';
12
- export * from './utils';
13
13
  export * from './values';
@@ -4,8 +4,8 @@ import { SchemaInspector } from 'knex-schema-inspector';
4
4
  import { Column } from 'knex-schema-inspector/dist/types/column';
5
5
  import { SchemaInspector as SchemaInspectorType } from 'knex-schema-inspector/dist/types/schema-inspector';
6
6
  import lowerFirst from 'lodash/lowerFirst';
7
- import { EnumModel, isEnumModel, Model, ModelField, Models, RawModels } from '../models';
8
- import { get, getModels, summonByName, typeToField } from '../utils';
7
+ import { EnumModel, Model, ModelField, Models, RawModels } from '../models/models';
8
+ import { get, getModels, isEnumModel, summonByName, typeToField } from '../models/utils';
9
9
  import { Value } from '../values';
10
10
 
11
11
  type Callbacks = (() => void)[];
@@ -130,20 +130,23 @@ export class MigrationGenerator {
130
130
  this.createFields(
131
131
  model,
132
132
  model.fields.filter(
133
- ({ name, relation, raw, foreignKey }) =>
134
- !raw && !this.columns[model.name].some((col) => col.name === (foreignKey || (relation ? `${name}Id` : name)))
133
+ ({ name, ...field }) =>
134
+ field.type !== 'raw' &&
135
+ !this.columns[model.name].some(
136
+ (col) => col.name === (field.type === 'relation' ? field.foreignKey || `${name}Id` : name)
137
+ )
135
138
  ),
136
139
  up,
137
140
  down
138
141
  );
139
142
 
140
143
  // Update fields
141
- const existingFields = model.fields.filter(({ name, relation, nonNull }) => {
142
- const col = this.columns[model.name].find((col) => col.name === (relation ? `${name}Id` : name));
144
+ const existingFields = model.fields.filter(({ name, type, nonNull }) => {
145
+ const col = this.columns[model.name].find((col) => col.name === (type === 'relation' ? `${name}Id` : name));
143
146
  if (!col) {
144
147
  return false;
145
148
  }
146
- return !model.nonStrict && !nonNull && !col.is_nullable;
149
+ return !nonNull && !col.is_nullable;
147
150
  });
148
151
  this.updateFields(model, existingFields, up, down);
149
152
  }
@@ -174,8 +177,8 @@ export class MigrationGenerator {
174
177
  writer.writeLine(`deleted: row.deleted,`);
175
178
  }
176
179
 
177
- for (const { name, relation } of model.fields.filter(({ updatable }) => updatable)) {
178
- const col = relation ? `${name}Id` : name;
180
+ for (const { name, type } of model.fields.filter(({ updatable }) => updatable)) {
181
+ const col = type === 'relation' ? `${name}Id` : name;
179
182
 
180
183
  writer.writeLine(`${col}: row.${col},`);
181
184
  }
@@ -194,21 +197,25 @@ export class MigrationGenerator {
194
197
  } else {
195
198
  const revisionTable = `${model.name}Revision`;
196
199
  const missingRevisionFields = model.fields.filter(
197
- ({ name, relation, raw, foreignKey, updatable }) =>
198
- !raw &&
200
+ ({ name, updatable, ...field }) =>
201
+ field.type !== 'raw' &&
199
202
  updatable &&
200
- !this.columns[revisionTable].some((col) => col.name === (foreignKey || (relation ? `${name}Id` : name)))
203
+ !this.columns[revisionTable].some(
204
+ (col) => col.name === (field.type === 'relation' ? field.foreignKey || `${name}Id` : name)
205
+ )
201
206
  );
202
207
 
203
208
  this.createRevisionFields(model, missingRevisionFields, up, down);
204
209
 
205
210
  const revisionFieldsToRemove = model.fields.filter(
206
- ({ name, updatable, foreignKey, relation, raw, generated }) =>
211
+ ({ name, updatable, generated, ...field }) =>
207
212
  !generated &&
208
- !raw &&
213
+ field.type !== 'raw' &&
209
214
  !updatable &&
210
- foreignKey !== 'id' &&
211
- this.columns[revisionTable].some((col) => col.name === (foreignKey || (relation ? `${name}Id` : name)))
215
+ !(field.type === 'relation' && field.foreignKey === 'id') &&
216
+ this.columns[revisionTable].some(
217
+ (col) => col.name === (field.type === 'relation' ? field.foreignKey || `${name}Id` : name)
218
+ )
212
219
  );
213
220
  this.createRevisionFields(model, revisionFieldsToRemove, down, up);
214
221
  }
@@ -269,8 +276,8 @@ export class MigrationGenerator {
269
276
  for (const field of fields) {
270
277
  this.alterTable(model.name, () => {
271
278
  this.renameColumn(
272
- field.relation ? `${field.oldName}Id` : get(field, 'oldName'),
273
- field.relation ? `${field.name}Id` : field.name
279
+ field.type === 'relation' ? `${field.oldName}Id` : get(field, 'oldName'),
280
+ field.type === 'relation' ? `${field.name}Id` : field.name
274
281
  );
275
282
  });
276
283
  }
@@ -280,8 +287,8 @@ export class MigrationGenerator {
280
287
  for (const field of fields) {
281
288
  this.alterTable(model.name, () => {
282
289
  this.renameColumn(
283
- field.relation ? `${field.name}Id` : field.name,
284
- field.relation ? `${field.oldName}Id` : get(field, 'oldName')
290
+ field.type === 'relation' ? `${field.name}Id` : field.name,
291
+ field.type === 'relation' ? `${field.oldName}Id` : get(field, 'oldName')
285
292
  );
286
293
  });
287
294
  }
@@ -289,9 +296,8 @@ export class MigrationGenerator {
289
296
 
290
297
  for (const field of fields) {
291
298
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
292
- summonByName(this.columns[model.name]!, field.relation ? `${field.oldName!}Id` : field.oldName!).name = field.relation
293
- ? `${field.name}Id`
294
- : field.name;
299
+ summonByName(this.columns[model.name]!, field.type === 'relation' ? `${field.oldName!}Id` : field.oldName!).name =
300
+ field.type === 'relation' ? `${field.name}Id` : field.name;
295
301
  }
296
302
  }
297
303
 
@@ -337,8 +343,8 @@ export class MigrationGenerator {
337
343
 
338
344
  down.push(() => {
339
345
  this.alterTable(model.name, () => {
340
- for (const { relation, name } of fields) {
341
- this.dropColumn(relation ? `${name}Id` : name);
346
+ for (const { type, name } of fields) {
347
+ this.dropColumn(type === 'relation' ? `${name}Id` : name);
342
348
  }
343
349
  });
344
350
  });
@@ -363,7 +369,7 @@ export class MigrationGenerator {
363
369
  this.column(
364
370
  field,
365
371
  { alter: true },
366
- summonByName(this.columns[model.name], field.relation ? `${field.name}Id` : field.name)
372
+ summonByName(this.columns[model.name], field.type === 'relation' ? `${field.name}Id` : field.name)
367
373
  );
368
374
  }
369
375
  });
@@ -389,7 +395,7 @@ export class MigrationGenerator {
389
395
  this.column(
390
396
  field,
391
397
  { alter: true },
392
- summonByName(this.columns[model.name], field.relation ? `${field.name}Id` : field.name)
398
+ summonByName(this.columns[model.name], field.type === 'relation' ? `${field.name}Id` : field.name)
393
399
  );
394
400
  }
395
401
  });
@@ -405,9 +411,7 @@ export class MigrationGenerator {
405
411
  writer.writeLine(`table.uuid('id').notNullable().primary();`);
406
412
  writer.writeLine(`table.uuid('${typeToField(model.name)}Id').notNullable();`);
407
413
  writer.write(`table.uuid('createdById')`);
408
- if (!model.nonStrict) {
409
- writer.write('.notNullable()');
410
- }
414
+ writer.write('.notNullable()');
411
415
  writer.write(';').newLine();
412
416
  writer.writeLine(`table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now(0));`);
413
417
  if (model.deletable) {
@@ -435,8 +439,8 @@ export class MigrationGenerator {
435
439
  this.writer
436
440
  .write(`await knex('${model.name}Revision').update(`)
437
441
  .inlineBlock(() => {
438
- for (const { name, relation } of missingRevisionFields) {
439
- const col = relation ? `${name}Id` : name;
442
+ for (const { name, type } of missingRevisionFields) {
443
+ const col = type === 'relation' ? `${name}Id` : name;
440
444
  this.writer
441
445
  .write(
442
446
  `${col}: knex.raw('(select "${col}" from "${model.name}" where "${model.name}".id = "${
@@ -463,7 +467,7 @@ export class MigrationGenerator {
463
467
  down.push(() => {
464
468
  this.alterTable(revisionTable, () => {
465
469
  for (const field of missingRevisionFields) {
466
- this.dropColumn(field.relation ? `${field.name}Id` : field.name);
470
+ this.dropColumn(field.type === 'relation' ? `${field.name}Id` : field.name);
467
471
  }
468
472
  });
469
473
  });
@@ -538,7 +542,7 @@ export class MigrationGenerator {
538
542
  }
539
543
 
540
544
  private column(
541
- { name, relation, type, primary, list, ...field }: ModelField,
545
+ { name, primary, list, ...field }: ModelField,
542
546
  { setUnique = true, setNonNull = true, alter = false, foreign = true, setDefault = true } = {},
543
547
  toColumn?: Column
544
548
  ) {
@@ -574,60 +578,58 @@ export class MigrationGenerator {
574
578
  }
575
579
  this.writer.write(';').newLine();
576
580
  };
577
- if (relation) {
578
- col(`table.uuid('${name}Id')`);
579
- if (foreign && !alter) {
580
- this.writer.writeLine(`table.foreign('${name}Id').references('id').inTable('${type}');`);
581
- }
582
- } else if (this.rawModels.some((m) => m.name === type && m.type === 'enum')) {
583
- list
584
- ? this.writer.write(`table.specificType('${name}', '"${typeToField(type)}"[]');`)
585
- : this.writer
581
+ switch (field.type) {
582
+ case 'Boolean':
583
+ col(`table.boolean('${name}')`);
584
+ break;
585
+ case 'Int':
586
+ col(`table.integer('${name}')`);
587
+ break;
588
+ case 'Float':
589
+ if (field.double) {
590
+ col(`table.double('${name}')`);
591
+ } else {
592
+ col(`table.decimal('${name}', ${get(field, 'precision')}, ${get(field, 'scale')})`);
593
+ }
594
+ break;
595
+ case 'String':
596
+ if (field.large) {
597
+ col(`table.text('${name}')`);
598
+ } else {
599
+ col(`table.string('${name}', ${field.maxLength})`);
600
+ }
601
+ break;
602
+ case 'DateTime':
603
+ col(`table.timestamp('${name}')`);
604
+ break;
605
+ case 'ID':
606
+ col(`table.uuid('${name}')`);
607
+ break;
608
+ case 'Upload':
609
+ break;
610
+ case 'relation':
611
+ col(`table.uuid('${name}Id')`);
612
+ if (foreign && !alter) {
613
+ this.writer.writeLine(`table.foreign('${name}Id').references('id').inTable('${field.typeName}');`);
614
+ }
615
+ break;
616
+ case 'enum':
617
+ if (list) {
618
+ this.writer.write(`table.specificType('${name}', '"${typeToField(field.type)}"[]');`);
619
+ } else {
620
+ this.writer
586
621
  .write(`table.enum('${name}', null as any, `)
587
622
  .inlineBlock(() => {
588
623
  this.writer.writeLine(`useNative: true,`);
589
624
  this.writer.writeLine(`existingType: true,`);
590
- this.writer.writeLine(`enumName: '${typeToField(type)}',`);
625
+ this.writer.writeLine(`enumName: '${typeToField(field.type)}',`);
591
626
  })
592
627
  .write(')');
593
- col();
594
- } else {
595
- switch (type) {
596
- case 'Boolean':
597
- col(`table.boolean('${name}')`);
598
- break;
599
- case 'Int':
600
- col(`table.integer('${name}')`);
601
- break;
602
- case 'Float':
603
- if (field.double) {
604
- col(`table.double('${name}')`);
605
- } else {
606
- col(`table.decimal('${name}', ${get(field, 'precision')}, ${get(field, 'scale')})`);
607
- }
608
- break;
609
- case 'String':
610
- if (field.large) {
611
- col(`table.text('${name}')`);
612
- } else {
613
- col(`table.string('${name}', ${field.maxLength})`);
614
- }
615
- break;
616
- case 'DateTime':
617
- col(`table.timestamp('${name}')`);
618
- break;
619
- case 'ID':
620
- if (field.maxLength) {
621
- col(`table.string('${name}', ${get(field, 'maxLength')})`);
622
- } else {
623
- col(`table.uuid('${name}')`);
624
- }
625
- break;
626
- case 'Upload':
627
- break;
628
- default:
629
- throw new Error(`Unknown field type ${type}`);
630
- }
628
+ }
629
+ col();
630
+ break;
631
+ default:
632
+ throw new Error(`Unknown field type ${field.type}`);
631
633
  }
632
634
  }
633
635
  }
@@ -0,0 +1,4 @@
1
+ // created from 'create-ts-index'
2
+
3
+ export * from './models';
4
+ export * from './utils';
@@ -0,0 +1,184 @@
1
+ import { DateTime } from 'luxon';
2
+ import { Field } from '..';
3
+ import type { Context } from '../context';
4
+ import type { OrderBy } from '../resolvers/arguments';
5
+ import type { Value } from '../values';
6
+
7
+ export type RawModels = RawModel[];
8
+
9
+ export type RawModel = ScalarModel | EnumModel | RawEnumModel | InterfaceModel | ObjectModel | RawObjectModel;
10
+
11
+ type BaseModel = {
12
+ name: string;
13
+ plural?: string;
14
+ description?: string;
15
+ };
16
+
17
+ export type ScalarModel = BaseModel & { type: 'scalar' };
18
+
19
+ export type EnumModel = BaseModel & { type: 'enum'; values: string[]; deleted?: true };
20
+
21
+ export type RawEnumModel = BaseModel & { type: 'raw-enum'; values: string[] };
22
+
23
+ export type InterfaceModel = BaseModel & { type: 'interface'; fields: ModelField[] };
24
+
25
+ export type RawObjectModel = BaseModel & {
26
+ type: 'raw';
27
+ fields: RawObjectField[];
28
+ };
29
+
30
+ export type Entity = Record<string, unknown> & { createdAt?: DateTime; deletedAt?: DateTime };
31
+
32
+ export type Action = 'create' | 'update' | 'delete' | 'restore';
33
+
34
+ export type MutationHook = (
35
+ model: Model,
36
+ action: Action,
37
+ when: 'before' | 'after',
38
+ data: { prev: Entity; input: Entity; normalizedInput: Entity; next: Entity },
39
+ ctx: Context
40
+ ) => Promise<void>;
41
+
42
+ export type ObjectModel = BaseModel & {
43
+ type: 'object';
44
+ interfaces?: string[];
45
+ queriable?: boolean;
46
+ listQueriable?: boolean;
47
+ creatable?: boolean | { createdBy?: Partial<RelationField>; createdAt?: Partial<DateTimeField> };
48
+ updatable?: boolean | { updatedBy?: Partial<RelationField>; updatedAt?: Partial<DateTimeField> };
49
+ deletable?:
50
+ | boolean
51
+ | { deleted?: Partial<BooleanField>; deletedBy?: Partial<RelationField>; deletedAt?: Partial<DateTimeField> };
52
+ displayField?: string;
53
+ defaultOrderBy?: OrderBy;
54
+ fields: ModelField[];
55
+
56
+ // temporary fields for the generation of migrations
57
+ deleted?: true;
58
+ oldName?: string;
59
+ };
60
+
61
+ type BaseNumberType = {
62
+ unit?: 'million';
63
+ min?: number;
64
+ max?: number;
65
+ };
66
+
67
+ type BaseField = Omit<Field, 'type'>;
68
+
69
+ type PrimitiveField =
70
+ | { type: 'ID' }
71
+ | { type: 'Boolean' }
72
+ | {
73
+ type: 'String';
74
+ stringType?: 'email' | 'url' | 'phone';
75
+ large?: true;
76
+ maxLength?: number;
77
+ }
78
+ | {
79
+ type: 'DateTime';
80
+ dateTimeType?: 'year' | 'date' | 'datetime' | 'year_and_month';
81
+ endOfDay?: boolean;
82
+ }
83
+ | ({
84
+ type: 'Int';
85
+ intType?: 'currency';
86
+ } & BaseNumberType)
87
+ | ({
88
+ type: 'Float';
89
+ floatType?: 'currency' | 'percentage';
90
+ double?: boolean;
91
+ precision?: number;
92
+ scale?: number;
93
+ } & BaseNumberType)
94
+ | { type: 'Upload' };
95
+
96
+ type RawObjectField = BaseField & PrimitiveField;
97
+
98
+ export type ModelField = BaseField &
99
+ (
100
+ | PrimitiveField
101
+ | { type: 'json'; typeName: string }
102
+ | { type: 'enum'; typeName: string; possibleValues?: Value[] }
103
+ | { type: 'raw'; typeName: string }
104
+ | {
105
+ type: 'relation';
106
+ typeName: string;
107
+ toOne?: boolean;
108
+ reverse?: string;
109
+ foreignKey?: string;
110
+ onDelete?: 'cascade' | 'set-null';
111
+ }
112
+ ) & {
113
+ primary?: boolean;
114
+ unique?: boolean;
115
+ filterable?:
116
+ | boolean
117
+ | {
118
+ default?: Value;
119
+ };
120
+ searchable?: boolean;
121
+ orderable?: boolean;
122
+ comparable?: boolean;
123
+ queriable?:
124
+ | boolean
125
+ | {
126
+ roles?: string[];
127
+ };
128
+ creatable?:
129
+ | boolean
130
+ | {
131
+ roles?: string[];
132
+ };
133
+ updatable?:
134
+ | boolean
135
+ | {
136
+ roles?: string[];
137
+ };
138
+ generated?: boolean;
139
+ // The tooltip is "hidden" behind an icon in the admin forms
140
+ tooltip?: string;
141
+ defaultValue?: string | number | ReadonlyArray<string> | undefined;
142
+ // If true the field must be filled within forms but can be null in the database
143
+ required?: boolean;
144
+ indent?: boolean;
145
+ // If true the field is hidden in the admin interface
146
+ hidden?: boolean;
147
+
148
+ // temporary fields for the generation of migrations
149
+ deleted?: true;
150
+ oldName?: string;
151
+ };
152
+
153
+ export type IDField = Extract<ModelField, { type: 'ID' }>;
154
+ export type BooleanField = Extract<ModelField, { type: 'Boolean' }>;
155
+ export type StringField = Extract<ModelField, { type: 'String' }>;
156
+ export type DateTimeField = Extract<ModelField, { type: 'DateTime' }>;
157
+ export type IntField = Extract<ModelField, { type: 'Int' }>;
158
+ export type FloatField = Extract<ModelField, { type: 'Float' }>;
159
+ export type JsonField = Extract<ModelField, { type: 'json' }>;
160
+ export type EnumField = Extract<ModelField, { type: 'enum' }>;
161
+ export type RawField = Extract<ModelField, { type: 'raw' }>;
162
+ export type RelationField = Extract<ModelField, { type: 'relation' }>;
163
+
164
+ export type Models = Model[];
165
+
166
+ export type Model = ObjectModel & {
167
+ fieldsByName: Record<string, ModelField>;
168
+ relations: Relation[];
169
+ relationsByName: Record<string, Relation>;
170
+ reverseRelations: ReverseRelation[];
171
+ reverseRelationsByName: Record<string, ReverseRelation>;
172
+ };
173
+
174
+ export type Relation = {
175
+ field: RelationField;
176
+ model: Model;
177
+ reverseRelation: ReverseRelation;
178
+ };
179
+
180
+ export type ReverseRelation = RelationField & {
181
+ model: Model;
182
+ field: RelationField;
183
+ fieldModel: Model;
184
+ };