@smartive/graphql-magic 5.1.2 → 7.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 (61) hide show
  1. package/CHANGELOG.md +1 -6
  2. package/dist/cjs/index.cjs +149 -140
  3. package/dist/esm/client/index.d.ts +1 -0
  4. package/dist/esm/client/index.js +1 -0
  5. package/dist/esm/client/index.js.map +1 -1
  6. package/dist/esm/client/models.d.ts +1 -0
  7. package/dist/esm/client/models.js +2 -0
  8. package/dist/esm/client/models.js.map +1 -0
  9. package/dist/esm/client/queries.d.ts +2 -2
  10. package/dist/esm/client/queries.js +3 -3
  11. package/dist/esm/client/queries.js.map +1 -1
  12. package/dist/esm/context.d.ts +5 -1
  13. package/dist/esm/db/generate.js +17 -19
  14. package/dist/esm/db/generate.js.map +1 -1
  15. package/dist/esm/migrations/generate.js +69 -57
  16. package/dist/esm/migrations/generate.js.map +1 -1
  17. package/dist/esm/models/index.d.ts +1 -0
  18. package/dist/esm/models/index.js +1 -0
  19. package/dist/esm/models/index.js.map +1 -1
  20. package/dist/esm/models/models.d.ts +65 -59
  21. package/dist/esm/models/mutation-hook.d.ts +17 -0
  22. package/dist/esm/models/mutation-hook.js +2 -0
  23. package/dist/esm/models/mutation-hook.js.map +1 -0
  24. package/dist/esm/models/utils.d.ts +398 -22
  25. package/dist/esm/models/utils.js +22 -20
  26. package/dist/esm/models/utils.js.map +1 -1
  27. package/dist/esm/permissions/check.js +2 -2
  28. package/dist/esm/permissions/check.js.map +1 -1
  29. package/dist/esm/resolvers/filters.js +1 -1
  30. package/dist/esm/resolvers/mutations.js +4 -4
  31. package/dist/esm/resolvers/mutations.js.map +1 -1
  32. package/dist/esm/resolvers/node.js +2 -2
  33. package/dist/esm/resolvers/node.js.map +1 -1
  34. package/dist/esm/resolvers/resolver.js +1 -1
  35. package/dist/esm/schema/generate.js +27 -37
  36. package/dist/esm/schema/generate.js.map +1 -1
  37. package/dist/esm/schema/utils.d.ts +1 -1
  38. package/dist/esm/schema/utils.js +2 -2
  39. package/dist/esm/schema/utils.js.map +1 -1
  40. package/package.json +5 -5
  41. package/src/client/index.ts +1 -0
  42. package/src/client/models.ts +1 -0
  43. package/src/client/queries.ts +5 -5
  44. package/src/context.ts +4 -1
  45. package/src/db/generate.ts +25 -27
  46. package/src/migrations/generate.ts +69 -57
  47. package/src/models/index.ts +1 -0
  48. package/src/models/models.ts +88 -97
  49. package/src/models/mutation-hook.ts +17 -0
  50. package/src/models/utils.ts +27 -21
  51. package/src/permissions/check.ts +2 -2
  52. package/src/resolvers/filters.ts +1 -1
  53. package/src/resolvers/mutations.ts +9 -8
  54. package/src/resolvers/node.ts +2 -2
  55. package/src/resolvers/resolver.ts +1 -1
  56. package/src/schema/generate.ts +31 -48
  57. package/src/schema/utils.ts +3 -3
  58. package/tests/unit/__snapshots__/generate.spec.ts.snap +2 -2
  59. package/tests/unit/resolve.spec.ts +1 -0
  60. package/tests/utils/models.ts +12 -12
  61. package/tests/utils/server.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1 @@
1
- ## [5.1.2](https://github.com/smartive/graphql-magic/compare/v5.1.1...v5.1.2) (2023-08-25)
2
-
3
-
4
- ### Bug Fixes
5
-
6
- * Schema generation again ([4e8c6cd](https://github.com/smartive/graphql-magic/commit/4e8c6cd1cf5639430e02077f506c66fdcbc01288))
1
+ # [7.0.0](https://github.com/smartive/graphql-magic/compare/v6.0.0...v7.0.0) (2023-08-31)
@@ -102,6 +102,7 @@ __export(src_exports, {
102
102
  inputValues: () => inputValues,
103
103
  isCreatable: () => isCreatable,
104
104
  isCreatableBy: () => isCreatableBy,
105
+ isEnum: () => isEnum,
105
106
  isEnumList: () => isEnumList,
106
107
  isEnumModel: () => isEnumModel,
107
108
  isFieldNode: () => isFieldNode,
@@ -109,6 +110,7 @@ __export(src_exports, {
109
110
  isInlineFragmentNode: () => isInlineFragmentNode,
110
111
  isListType: () => isListType,
111
112
  isObjectModel: () => isObjectModel,
113
+ isPrimitive: () => isPrimitive,
112
114
  isQueriableBy: () => isQueriableBy,
113
115
  isQueriableField: () => isQueriableField,
114
116
  isRaw: () => isRaw,
@@ -259,18 +261,20 @@ var getModelSlug = (model) => (0, import_kebabCase.default)(getModelPlural(model
259
261
  var getModelLabelPlural = (model) => getLabel(getModelPlural(model));
260
262
  var getModelLabel = (model) => getLabel(model.name);
261
263
  var getLabel = (s) => (0, import_startCase.default)((0, import_camelCase.default)(s));
262
- var isObjectModel = (model) => model.type === "object";
263
- var isEnumModel = (model) => model.type === "enum";
264
- var isRawEnumModel = (model) => model.type === "raw-enum";
265
- var isScalarModel = (model) => model.type === "scalar";
266
- var isRawObjectModel = (model) => model.type === "raw";
267
- var isEnumList = (models, field) => field?.list === true && models.find(({ name: name2 }) => name2 === field.type)?.type === "enum";
264
+ var isObjectModel = (model) => model.kind === "object";
265
+ var isEnumModel = (model) => model.kind === "enum";
266
+ var isRawEnumModel = (model) => model.kind === "raw-enum";
267
+ var isScalarModel = (model) => model.kind === "scalar";
268
+ var isRawObjectModel = (model) => model.kind === "raw";
269
+ var isEnumList = (models, field) => field?.list === true && models.find(({ name: name2 }) => name2 === field.kind)?.kind === "enum";
268
270
  var and = (...predicates) => (field) => predicates.every((predicate) => predicate(field));
269
271
  var not = (predicate) => (field) => !predicate(field);
270
- var isRelation = (field) => field.type === "relation";
272
+ var isPrimitive = (field) => field.kind === void 0 || field.kind === "primitive";
273
+ var isEnum = (field) => field.kind === "enum";
274
+ var isRelation = (field) => field.kind === "relation";
271
275
  var isToOneRelation = (field) => isRelation(field) && !!field.toOne;
272
276
  var isQueriableField = ({ queriable }) => queriable !== false;
273
- var isRaw = (field) => field.type === "raw";
277
+ var isRaw = (field) => field.kind === "raw";
274
278
  var isVisible = ({ hidden }) => hidden !== true;
275
279
  var isSimpleField = and(not(isRelation), not(isRaw));
276
280
  var isUpdatable = ({ updatable }) => !!updatable;
@@ -304,8 +308,8 @@ var getModels = (rawModels) => {
304
308
  },
305
309
  {
306
310
  name: "createdBy",
307
- type: "relation",
308
- typeName: "User",
311
+ kind: "relation",
312
+ type: "User",
309
313
  nonNull: true,
310
314
  reverse: `created${getModelPlural(model)}`,
311
315
  generated: true,
@@ -323,8 +327,8 @@ var getModels = (rawModels) => {
323
327
  },
324
328
  {
325
329
  name: "updatedBy",
326
- type: "relation",
327
- typeName: "User",
330
+ kind: "relation",
331
+ type: "User",
328
332
  nonNull: true,
329
333
  reverse: `updated${getModelPlural(model)}`,
330
334
  generated: true,
@@ -336,7 +340,7 @@ var getModels = (rawModels) => {
336
340
  name: "deleted",
337
341
  type: "Boolean",
338
342
  nonNull: true,
339
- default: false,
343
+ defaultValue: false,
340
344
  filterable: { default: false },
341
345
  generated: true,
342
346
  ...typeof model.deletable === "object" && model.deletable.deleted
@@ -350,8 +354,8 @@ var getModels = (rawModels) => {
350
354
  },
351
355
  {
352
356
  name: "deletedBy",
353
- type: "relation",
354
- typeName: "User",
357
+ kind: "relation",
358
+ type: "User",
355
359
  reverse: `deleted${getModelPlural(model)}`,
356
360
  generated: true,
357
361
  ...typeof model.deletable === "object" && model.deletable.deletedBy
@@ -359,7 +363,7 @@ var getModels = (rawModels) => {
359
363
  ] : []
360
364
  ].map((field) => ({
361
365
  ...field,
362
- ...field.type === "relation" && {
366
+ ...field.kind === "relation" && {
363
367
  foreignKey: field.foreignKey || `${field.name}Id`
364
368
  }
365
369
  }))
@@ -371,15 +375,15 @@ var getModels = (rawModels) => {
371
375
  });
372
376
  for (const model of models) {
373
377
  for (const field of model.fields) {
374
- if (field.type !== "relation") {
378
+ if (field.kind !== "relation") {
375
379
  continue;
376
380
  }
377
- const fieldModel = summonByName(models, field.typeName);
381
+ const fieldModel = summonByName(models, field.type);
378
382
  const reverseRelation = {
379
- type: "relation",
383
+ kind: "relation",
380
384
  name: field.reverse || (field.toOne ? typeToField(model.name) : getModelPluralField(model)),
381
385
  foreignKey: get(field, "foreignKey"),
382
- typeName: model.name,
386
+ type: model.name,
383
387
  toOne: !!field.toOne,
384
388
  fieldModel,
385
389
  field,
@@ -457,8 +461,8 @@ var getEditEntityRelationsQuery = (models, model, action, fields2, ignoreFields,
457
461
  ({ name: name2 }) => (!fields2 || fields2.includes(name2)) && (!ignoreFields || !ignoreFields.includes(name2))
458
462
  );
459
463
  return !!relations.length && `query ${(0, import_upperFirst.default)(action)}${model.name}Relations {
460
- ${relations.map(({ name: name2, typeName }) => {
461
- const model2 = summonByName(models, typeName);
464
+ ${relations.map(({ name: name2, type }) => {
465
+ const model2 = summonByName(models, type);
462
466
  let filters = "";
463
467
  if (model2.displayField) {
464
468
  const displayField2 = model2.fieldsByName[model2.displayField];
@@ -568,7 +572,7 @@ var getEntityQuery = (models, model, role, visibleRelationsByRole, typesWithSubR
568
572
  ${model.fields.filter(and(isSimpleField, isQueriableBy(role))).map(({ name: name2 }) => name2)}
569
573
  ${queryRelations(
570
574
  models,
571
- model.fields.filter(and(isRelation, isVisibleRelation(visibleRelationsByRole, model.name, role))),
575
+ model.fields.filter(isRelation).filter(isVisibleRelation(visibleRelationsByRole, model.name, role)),
572
576
  role,
573
577
  typesWithSubRelations
574
578
  )}
@@ -618,34 +622,33 @@ var generateDBModels = (rawModels) => {
618
622
  }
619
623
  const models = getModels(rawModels);
620
624
  for (const model of models) {
621
- const fields2 = model.fields.some((field) => field.type === "relation" && field.foreignKey === "id") ? model.fields.filter((field) => field.name !== "id") : model.fields;
625
+ const fields2 = model.fields.some((field) => field.kind === "relation" && field.foreignKey === "id") ? model.fields.filter((field) => field.name !== "id") : model.fields;
622
626
  writer.write(`export type ${model.name} = `).inlineBlock(() => {
623
627
  for (const field of fields2.filter(not(isRaw))) {
624
- writer.write(`'${getFieldName(field)}': ${getFieldOutputType(field)}${field.nonNull ? "" : " | null"},`).newLine();
628
+ writer.write(`'${getFieldName(field)}': ${getFieldType(field)}${field.nonNull ? "" : " | null"},`).newLine();
625
629
  }
626
630
  }).blankLine();
627
631
  writer.write(`export type ${model.name}Initializer = `).inlineBlock(() => {
628
632
  for (const field of fields2.filter(not(isRaw))) {
629
633
  writer.write(
630
- `'${getFieldName(field)}'${field.nonNull && field.default === void 0 ? "" : "?"}: ${getFieldInputType(
634
+ `'${getFieldName(field)}'${field.nonNull && field.defaultValue === void 0 ? "" : "?"}: ${getFieldType(
631
635
  field
632
- )}${field.nonNull ? "" : " | null"},`
636
+ )}${field.list ? " | string" : ""}${field.nonNull ? "" : " | null"},`
633
637
  ).newLine();
634
638
  }
635
639
  }).blankLine();
636
640
  writer.write(`export type ${model.name}Mutator = `).inlineBlock(() => {
637
641
  for (const field of fields2.filter(not(isRaw))) {
638
- writer.write(`'${getFieldName(field)}'?: ${getFieldInputType(field)}${field.nonNull ? "" : " | null"},`).newLine();
642
+ writer.write(
643
+ `'${getFieldName(field)}'?: ${getFieldType(field)}${field.list ? " | string" : ""}${field.nonNull ? "" : " | null"},`
644
+ ).newLine();
639
645
  }
640
646
  }).blankLine();
641
647
  writer.write(`export type ${model.name}Seed = `).inlineBlock(() => {
642
648
  for (const field of fields2.filter(not(isRaw))) {
643
649
  const fieldName = getFieldName(field);
644
650
  writer.write(
645
- `'${getFieldName(field)}'${field.nonNull && field.default === void 0 && !OPTIONAL_SEED_FIELDS.includes(fieldName) ? "" : "?"}: ${getFieldInputType(
646
- field,
647
- rawModels.filter(isEnumModel).map(({ name: name2 }) => name2)
648
- )}${field.list ? " | string" : ""}${field.nonNull ? "" : " | null"},`
651
+ `'${getFieldName(field)}'${field.nonNull && field.defaultValue === void 0 && !OPTIONAL_SEED_FIELDS.includes(fieldName) ? "" : "?"}: ${field.kind === "enum" ? field.list ? "string[]" : "string" : getFieldType(field)}${field.list ? " | string" : ""}${field.nonNull ? "" : " | null"},`
649
652
  ).newLine();
650
653
  }
651
654
  }).blankLine();
@@ -657,30 +660,26 @@ var generateDBModels = (rawModels) => {
657
660
  });
658
661
  return writer.toString();
659
662
  };
660
- var getFieldName = (field) => field.type === "relation" ? field.foreignKey || `${field.name}Id` : field.name;
661
- var getFieldOutputType = (field) => {
662
- switch (field.type) {
663
+ var getFieldName = (field) => field.kind === "relation" ? field.foreignKey || `${field.name}Id` : field.name;
664
+ var getFieldType = (field) => {
665
+ const kind = field.kind;
666
+ switch (kind) {
663
667
  case "json":
664
668
  return "string";
665
669
  case "relation":
666
670
  return "string";
667
671
  case "enum":
668
- return field.typeName + (field.list ? "[]" : "");
672
+ return field.type + (field.list ? "[]" : "");
669
673
  case "raw":
670
674
  throw new Error(`Raw fields are not in the db.`);
671
- default:
675
+ case "primitive":
676
+ case void 0:
672
677
  return get(PRIMITIVE_TYPES, field.type) + (field.list ? "[]" : "");
673
- }
674
- };
675
- var getFieldInputType = (field, stringTypes = []) => {
676
- let outputType = getFieldOutputType(field);
677
- if (field.list || stringTypes.includes(field.type)) {
678
- outputType += " | string";
679
- if (field.list && stringTypes.includes(field.type)) {
680
- outputType += " | string[]";
678
+ default: {
679
+ const exhaustiveCheck = kind;
680
+ throw new Error(exhaustiveCheck);
681
681
  }
682
682
  }
683
- return outputType;
684
683
  };
685
684
  var generateKnexTables = (rawModels) => {
686
685
  const writer = new import_code_block_writer.default["default"]({
@@ -805,15 +804,15 @@ var MigrationGenerator = class {
805
804
  this.createFields(
806
805
  model,
807
806
  model.fields.filter(
808
- ({ name: name2, ...field }) => field.type !== "raw" && !this.columns[model.name].some(
809
- (col) => col.name === (field.type === "relation" ? field.foreignKey || `${name2}Id` : name2)
807
+ ({ name: name2, ...field }) => field.kind !== "raw" && !this.columns[model.name].some(
808
+ (col) => col.name === (field.kind === "relation" ? field.foreignKey || `${name2}Id` : name2)
810
809
  )
811
810
  ),
812
811
  up,
813
812
  down
814
813
  );
815
- const existingFields = model.fields.filter(({ name: name2, type, nonNull: nonNull2 }) => {
816
- const col = this.columns[model.name].find((col2) => col2.name === (type === "relation" ? `${name2}Id` : name2));
814
+ const existingFields = model.fields.filter(({ name: name2, kind, nonNull: nonNull2 }) => {
815
+ const col = this.columns[model.name].find((col2) => col2.name === (kind === "relation" ? `${name2}Id` : name2));
817
816
  if (!col) {
818
817
  return false;
819
818
  }
@@ -840,8 +839,8 @@ var MigrationGenerator = class {
840
839
  if (model.deletable) {
841
840
  writer.writeLine(`deleted: row.deleted,`);
842
841
  }
843
- for (const { name: name2, type } of model.fields.filter(({ updatable }) => updatable)) {
844
- const col = type === "relation" ? `${name2}Id` : name2;
842
+ for (const { name: name2, kind } of model.fields.filter(({ updatable }) => updatable)) {
843
+ const col = kind === "relation" ? `${name2}Id` : name2;
845
844
  writer.writeLine(`${col}: row.${col},`);
846
845
  }
847
846
  }).write(")));").newLine();
@@ -855,14 +854,14 @@ var MigrationGenerator = class {
855
854
  } else {
856
855
  const revisionTable = `${model.name}Revision`;
857
856
  const missingRevisionFields = model.fields.filter(
858
- ({ name: name2, updatable, ...field }) => field.type !== "raw" && updatable && !this.columns[revisionTable].some(
859
- (col) => col.name === (field.type === "relation" ? field.foreignKey || `${name2}Id` : name2)
857
+ ({ name: name2, updatable, ...field }) => field.kind !== "raw" && updatable && !this.columns[revisionTable].some(
858
+ (col) => col.name === (field.kind === "relation" ? field.foreignKey || `${name2}Id` : name2)
860
859
  )
861
860
  );
862
861
  this.createRevisionFields(model, missingRevisionFields, up, down);
863
862
  const revisionFieldsToRemove = model.fields.filter(
864
- ({ name: name2, updatable, generated, ...field }) => !generated && field.type !== "raw" && !updatable && !(field.type === "relation" && field.foreignKey === "id") && this.columns[revisionTable].some(
865
- (col) => col.name === (field.type === "relation" ? field.foreignKey || `${name2}Id` : name2)
863
+ ({ name: name2, updatable, generated, ...field }) => !generated && field.kind !== "raw" && !updatable && !(field.kind === "relation" && field.foreignKey === "id") && this.columns[revisionTable].some(
864
+ (col) => col.name === (field.kind === "relation" ? field.foreignKey || `${name2}Id` : name2)
866
865
  )
867
866
  );
868
867
  this.createRevisionFields(model, revisionFieldsToRemove, down, up);
@@ -915,8 +914,8 @@ var MigrationGenerator = class {
915
914
  for (const field of fields2) {
916
915
  this.alterTable(model.name, () => {
917
916
  this.renameColumn(
918
- field.type === "relation" ? `${field.oldName}Id` : get(field, "oldName"),
919
- field.type === "relation" ? `${field.name}Id` : field.name
917
+ field.kind === "relation" ? `${field.oldName}Id` : get(field, "oldName"),
918
+ field.kind === "relation" ? `${field.name}Id` : field.name
920
919
  );
921
920
  });
922
921
  }
@@ -925,14 +924,14 @@ var MigrationGenerator = class {
925
924
  for (const field of fields2) {
926
925
  this.alterTable(model.name, () => {
927
926
  this.renameColumn(
928
- field.type === "relation" ? `${field.name}Id` : field.name,
929
- field.type === "relation" ? `${field.oldName}Id` : get(field, "oldName")
927
+ field.kind === "relation" ? `${field.name}Id` : field.name,
928
+ field.kind === "relation" ? `${field.oldName}Id` : get(field, "oldName")
930
929
  );
931
930
  });
932
931
  }
933
932
  });
934
933
  for (const field of fields2) {
935
- summonByName(this.columns[model.name], field.type === "relation" ? `${field.oldName}Id` : field.oldName).name = field.type === "relation" ? `${field.name}Id` : field.name;
934
+ summonByName(this.columns[model.name], field.kind === "relation" ? `${field.oldName}Id` : field.oldName).name = field.kind === "relation" ? `${field.name}Id` : field.name;
936
935
  }
937
936
  }
938
937
  createFields(model, fields2, up, down) {
@@ -944,8 +943,8 @@ var MigrationGenerator = class {
944
943
  const updates = [];
945
944
  const postAlter = [];
946
945
  for (const field of fields2) {
947
- alter.push(() => this.column(field, { setNonNull: field.default !== void 0 }));
948
- if (field.nonNull && field.default === void 0) {
946
+ alter.push(() => this.column(field, { setNonNull: field.defaultValue !== void 0 }));
947
+ if (field.nonNull && field.defaultValue === void 0) {
949
948
  updates.push(() => this.writer.write(`${field.name}: 'TODO',`).newLine());
950
949
  postAlter.push(() => this.column(field, { alter: true, foreign: false }));
951
950
  }
@@ -968,8 +967,8 @@ var MigrationGenerator = class {
968
967
  });
969
968
  down.push(() => {
970
969
  this.alterTable(model.name, () => {
971
- for (const { type, name: name2 } of fields2) {
972
- this.dropColumn(type === "relation" ? `${name2}Id` : name2);
970
+ for (const { kind, name: name2 } of fields2) {
971
+ this.dropColumn(kind === "relation" ? `${name2}Id` : name2);
973
972
  }
974
973
  });
975
974
  });
@@ -991,7 +990,7 @@ var MigrationGenerator = class {
991
990
  this.column(
992
991
  field,
993
992
  { alter: true },
994
- summonByName(this.columns[model.name], field.type === "relation" ? `${field.name}Id` : field.name)
993
+ summonByName(this.columns[model.name], field.kind === "relation" ? `${field.name}Id` : field.name)
995
994
  );
996
995
  }
997
996
  });
@@ -1014,7 +1013,7 @@ var MigrationGenerator = class {
1014
1013
  this.column(
1015
1014
  field,
1016
1015
  { alter: true },
1017
- summonByName(this.columns[model.name], field.type === "relation" ? `${field.name}Id` : field.name)
1016
+ summonByName(this.columns[model.name], field.kind === "relation" ? `${field.name}Id` : field.name)
1018
1017
  );
1019
1018
  }
1020
1019
  });
@@ -1048,7 +1047,7 @@ var MigrationGenerator = class {
1048
1047
  }
1049
1048
  });
1050
1049
  this.writer.write(`await knex('${model.name}Revision').update(`).inlineBlock(() => {
1051
- for (const { name: name2, type } of missingRevisionFields) {
1050
+ for (const { name: name2, kind: type } of missingRevisionFields) {
1052
1051
  const col = type === "relation" ? `${name2}Id` : name2;
1053
1052
  this.writer.write(
1054
1053
  `${col}: knex.raw('(select "${col}" from "${model.name}" where "${model.name}".id = "${model.name}Revision"."${typeToField(model.name)}Id")'),`
@@ -1067,7 +1066,7 @@ var MigrationGenerator = class {
1067
1066
  down.push(() => {
1068
1067
  this.alterTable(revisionTable, () => {
1069
1068
  for (const field of missingRevisionFields) {
1070
- this.dropColumn(field.type === "relation" ? `${field.name}Id` : field.name);
1069
+ this.dropColumn(field.kind === "relation" ? `${field.name}Id` : field.name);
1071
1070
  }
1072
1071
  });
1073
1072
  });
@@ -1133,8 +1132,8 @@ var MigrationGenerator = class {
1133
1132
  }
1134
1133
  }
1135
1134
  }
1136
- if (setDefault && field.default !== void 0) {
1137
- this.writer.write(`.defaultTo(${this.value(field.default)})`);
1135
+ if (setDefault && field.defaultValue !== void 0) {
1136
+ this.writer.write(`.defaultTo(${this.value(field.defaultValue)})`);
1138
1137
  }
1139
1138
  if (primary) {
1140
1139
  this.writer.write(".primary()");
@@ -1146,39 +1145,44 @@ var MigrationGenerator = class {
1146
1145
  }
1147
1146
  this.writer.write(";").newLine();
1148
1147
  };
1149
- switch (field.type) {
1150
- case "Boolean":
1151
- col(`table.boolean('${name2}')`);
1152
- break;
1153
- case "Int":
1154
- col(`table.integer('${name2}')`);
1155
- break;
1156
- case "Float":
1157
- if (field.double) {
1158
- col(`table.double('${name2}')`);
1159
- } else {
1160
- col(`table.decimal('${name2}', ${get(field, "precision")}, ${get(field, "scale")})`);
1161
- }
1162
- break;
1163
- case "String":
1164
- if (field.large) {
1165
- col(`table.text('${name2}')`);
1166
- } else {
1167
- col(`table.string('${name2}', ${field.maxLength})`);
1148
+ const kind = field.kind;
1149
+ switch (kind) {
1150
+ case "primitive":
1151
+ switch (field.type) {
1152
+ case "Boolean":
1153
+ col(`table.boolean('${name2}')`);
1154
+ break;
1155
+ case "Int":
1156
+ col(`table.integer('${name2}')`);
1157
+ break;
1158
+ case "Float":
1159
+ if (field.double) {
1160
+ col(`table.double('${name2}')`);
1161
+ } else {
1162
+ col(`table.decimal('${name2}', ${get(field, "precision")}, ${get(field, "scale")})`);
1163
+ }
1164
+ break;
1165
+ case "String":
1166
+ if (field.large) {
1167
+ col(`table.text('${name2}')`);
1168
+ } else {
1169
+ col(`table.string('${name2}', ${field.maxLength})`);
1170
+ }
1171
+ break;
1172
+ case "DateTime":
1173
+ col(`table.timestamp('${name2}')`);
1174
+ break;
1175
+ case "ID":
1176
+ col(`table.uuid('${name2}')`);
1177
+ break;
1178
+ case "Upload":
1179
+ break;
1168
1180
  }
1169
1181
  break;
1170
- case "DateTime":
1171
- col(`table.timestamp('${name2}')`);
1172
- break;
1173
- case "ID":
1174
- col(`table.uuid('${name2}')`);
1175
- break;
1176
- case "Upload":
1177
- break;
1178
1182
  case "relation":
1179
1183
  col(`table.uuid('${name2}Id')`);
1180
1184
  if (foreign && !alter) {
1181
- this.writer.writeLine(`table.foreign('${name2}Id').references('id').inTable('${field.typeName}');`);
1185
+ this.writer.writeLine(`table.foreign('${name2}Id').references('id').inTable('${field.type}');`);
1182
1186
  }
1183
1187
  break;
1184
1188
  case "enum":
@@ -1193,8 +1197,15 @@ var MigrationGenerator = class {
1193
1197
  }
1194
1198
  col();
1195
1199
  break;
1196
- default:
1197
- throw new Error(`Unknown field type ${field.type}`);
1200
+ case "json":
1201
+ this.writer.write(`table.json('${typeToField(field.type)}')`);
1202
+ break;
1203
+ case "raw":
1204
+ throw new Error("Raw fields aren't stored in the database");
1205
+ default: {
1206
+ const exhaustiveCheck = kind;
1207
+ throw new Error(exhaustiveCheck);
1208
+ }
1198
1209
  }
1199
1210
  }
1200
1211
  };
@@ -1418,8 +1429,8 @@ var checkCanWrite = async (ctx, model, data, action) => {
1418
1429
  if (!foreignId) {
1419
1430
  continue;
1420
1431
  }
1421
- const fieldPermissions = field[action === "CREATE" ? "creatableBy" : "updatableBy"];
1422
- if (fieldPermissions && !fieldPermissions.includes(ctx.user.role)) {
1432
+ const fieldPermissions = field[action === "CREATE" ? "creatable" : "updatable"];
1433
+ if (fieldPermissions && typeof fieldPermissions === "object" && !fieldPermissions.roles?.includes(ctx.user.role)) {
1423
1434
  throw new PermissionError(action, `this ${model.name}'s ${field.name}`, "field permission not available");
1424
1435
  }
1425
1436
  linked = true;
@@ -1733,7 +1744,7 @@ var applyWhere2 = (node, where, ops, joins) => {
1733
1744
  }
1734
1745
  const field = summonByName(node.model.fields, key);
1735
1746
  const fullKey = `${node.shortTableAlias}.${key}`;
1736
- if (field.type === "relation") {
1747
+ if (field.kind === "relation") {
1737
1748
  const relation = get(node.model.relationsByName, field.name);
1738
1749
  const tableAlias = `${node.model.name}__W__${key}`;
1739
1750
  const subNode = {
@@ -1847,7 +1858,7 @@ var getSimpleFields = (node) => {
1847
1858
  if (!selection.selectionSet) {
1848
1859
  return true;
1849
1860
  }
1850
- return node.model.fields.some(({ type, name: name2 }) => type === "json" && name2 === selection.name.value);
1861
+ return node.model.fields.some(({ kind: type, name: name2 }) => type === "json" && name2 === selection.name.value);
1851
1862
  });
1852
1863
  };
1853
1864
  var getInlineFragments = (node) => node.selectionSet.filter(isInlineFragmentNode).map(
@@ -1890,7 +1901,7 @@ var getJoins = (node, toMany) => {
1890
1901
  foreignKey = reverseRelation.foreignKey;
1891
1902
  } else {
1892
1903
  const modelField = baseModel.fieldsByName[fieldName];
1893
- if (modelField?.type !== "relation") {
1904
+ if (modelField?.kind !== "relation") {
1894
1905
  continue;
1895
1906
  }
1896
1907
  foreignKey = modelField.foreignKey;
@@ -1983,7 +1994,7 @@ var applySelects = (node, query, joins) => {
1983
1994
  { field: "id", alias: ID_ALIAS },
1984
1995
  ...getSimpleFields(node).filter((n) => {
1985
1996
  const field = node.model.fields.find(({ name: name2 }) => name2 === n.name.value);
1986
- if (!field || field.type === "relation" || field.type === "raw") {
1997
+ if (!field || field.kind === "relation" || field.kind === "raw") {
1987
1998
  return false;
1988
1999
  }
1989
2000
  if (typeof field.queriable === "object" && !field.queriable.roles?.includes(node.ctx.user.role)) {
@@ -2285,10 +2296,10 @@ var createRevision = async (model, data, ctx) => {
2285
2296
  if (model.deletable) {
2286
2297
  revisionData.deleted = data.deleted || false;
2287
2298
  }
2288
- for (const { type, name: name2, nonNull: nonNull2, ...field } of model.fields.filter(({ updatable }) => updatable)) {
2299
+ for (const { kind: type, name: name2, nonNull: nonNull2, ...field } of model.fields.filter(({ updatable }) => updatable)) {
2289
2300
  const col = type === "relation" ? `${name2}Id` : name2;
2290
2301
  if (nonNull2 && (!(col in data) || col === void 0 || col === null)) {
2291
- revisionData[col] = get(field, "default");
2302
+ revisionData[col] = get(field, "defaultValue");
2292
2303
  } else {
2293
2304
  revisionData[col] = data[col];
2294
2305
  }
@@ -2316,7 +2327,7 @@ var sanitize = (ctx, model, data) => {
2316
2327
  }
2317
2328
  }
2318
2329
  };
2319
- var isEndOfDay = (field) => field.type === "DateTime" && field?.endOfDay === true && field?.dateTimeType === "date" && field?.type === "DateTime";
2330
+ var isEndOfDay = (field) => isPrimitive(field) && field.type === "DateTime" && field?.endOfDay === true && field?.dateTimeType === "date";
2320
2331
 
2321
2332
  // src/resolvers/resolvers.ts
2322
2333
  var getResolvers = (models) => ({
@@ -2399,7 +2410,7 @@ var inputValues = (fields2) => fields2.map(
2399
2410
  kind: "InputValueDefinition",
2400
2411
  name: name(field.name),
2401
2412
  type: fieldType(field),
2402
- defaultValue: field.default === void 0 ? void 0 : value(field.default),
2413
+ defaultValue: field.defaultValue === void 0 ? void 0 : value(field.defaultValue),
2403
2414
  directives: directives(field.directives)
2404
2415
  })
2405
2416
  );
@@ -2412,7 +2423,7 @@ var fields = (fields2) => fields2.map(
2412
2423
  kind: "InputValueDefinition",
2413
2424
  name: name(arg.name),
2414
2425
  type: fieldType(arg),
2415
- defaultValue: arg.default === void 0 ? void 0 : value(arg.default)
2426
+ defaultValue: arg.defaultValue === void 0 ? void 0 : value(arg.defaultValue)
2416
2427
  })),
2417
2428
  directives: directives(field.directives)
2418
2429
  })
@@ -2519,14 +2530,10 @@ var generateDefinitions = (rawModels) => {
2519
2530
  ...rawModels.filter(isScalarModel).map((model) => scalar(model.name)),
2520
2531
  ...rawModels.filter(isRawObjectModel).map((model) => object(model.name, model.fields)),
2521
2532
  ...rawModels.filter(isRawObjectModel).filter(
2522
- (model) => models.some(
2523
- (m) => m.creatable && m.fields.some((f) => f.creatable && f.type === "json" && f.typeName === model.name)
2524
- )
2533
+ (model) => models.some((m) => m.creatable && m.fields.some((f) => f.creatable && f.kind === "json" && f.type === model.name))
2525
2534
  ).map((model) => input(`Create${model.name}`, model.fields)),
2526
2535
  ...rawModels.filter(isRawObjectModel).filter(
2527
- (model) => models.some(
2528
- (m) => m.creatable && m.fields.some((f) => f.creatable && f.type === "json" && f.typeName === model.name)
2529
- )
2536
+ (model) => models.some((m) => m.creatable && m.fields.some((f) => f.creatable && f.kind === "json" && f.type === model.name))
2530
2537
  ).map((model) => input(`Update${model.name}`, model.fields)),
2531
2538
  ...(0, import_flatMap2.default)(
2532
2539
  models.map((model) => {
@@ -2536,7 +2543,7 @@ var generateDefinitions = (rawModels) => {
2536
2543
  [
2537
2544
  ...model.fields.filter(isQueriableField).map((field) => ({
2538
2545
  ...field,
2539
- type: field.type === "relation" || field.type === "enum" || field.type === "raw" || field.type === "json" ? field.typeName : field.type,
2546
+ type: field.type,
2540
2547
  args: [...field.args || []],
2541
2548
  directives: field.directives
2542
2549
  })),
@@ -2557,29 +2564,29 @@ var generateDefinitions = (rawModels) => {
2557
2564
  model.interfaces
2558
2565
  ),
2559
2566
  input(`${model.name}Where`, [
2560
- ...model.fields.filter(({ type, unique, filterable }) => (unique || filterable) && type !== "relation").map(({ type, name: name2, filterable }) => ({
2561
- name: name2,
2562
- type,
2567
+ ...model.fields.filter(({ kind, unique, filterable }) => (unique || filterable) && kind !== "relation").map((field) => ({
2568
+ name: field.name,
2569
+ type: field.type,
2563
2570
  list: true,
2564
- default: typeof filterable === "object" ? filterable.default : void 0
2571
+ default: typeof field.filterable === "object" ? field.filterable.default : void 0
2565
2572
  })),
2566
2573
  ...(0, import_flatMap2.default)(
2567
2574
  model.fields.filter(({ comparable }) => comparable),
2568
- ({ name: name2, type }) => [
2569
- { name: `${name2}_GT`, type },
2570
- { name: `${name2}_GTE`, type },
2571
- { name: `${name2}_LT`, type },
2572
- { name: `${name2}_LTE`, type }
2575
+ (field) => [
2576
+ { name: `${field.name}_GT`, type: field.type },
2577
+ { name: `${field.name}_GTE`, type: field.type },
2578
+ { name: `${field.name}_LT`, type: field.type },
2579
+ { name: `${field.name}_LTE`, type: field.type }
2573
2580
  ]
2574
2581
  ),
2575
- ...model.fields.filter(isRelation).filter(({ filterable }) => filterable).map(({ name: name2, typeName }) => ({
2582
+ ...model.fields.filter(isRelation).filter(({ filterable }) => filterable).map(({ name: name2, type }) => ({
2576
2583
  name: name2,
2577
- type: `${typeName}Where`
2584
+ type: `${type}Where`
2578
2585
  }))
2579
2586
  ]),
2580
2587
  input(
2581
2588
  `${model.name}WhereUnique`,
2582
- model.fields.filter(({ unique }) => unique).map(({ name: name2, type }) => ({ name: name2, type }))
2589
+ model.fields.filter(({ unique }) => unique).map((field) => ({ name: field.name, type: field.type }))
2583
2590
  ),
2584
2591
  ...model.fields.some(({ orderable }) => orderable) ? [
2585
2592
  input(
@@ -2593,11 +2600,11 @@ var generateDefinitions = (rawModels) => {
2593
2600
  input(
2594
2601
  `Create${model.name}`,
2595
2602
  model.fields.filter(({ creatable }) => creatable).map(
2596
- ({ name: name2, nonNull: nonNull2, list: list2, default: defaultValue, ...field }) => field.type === "relation" ? { name: `${name2}Id`, type: "ID", nonNull: nonNull2 } : {
2597
- name: name2,
2598
- type: field.type === "enum" ? field.typeName : field.type === "json" ? `Create${field.typeName}` : field.type,
2599
- list: list2,
2600
- nonNull: nonNull2 && defaultValue === void 0
2603
+ (field) => field.kind === "relation" ? { name: `${field.name}Id`, type: "ID", nonNull: field.nonNull } : {
2604
+ name: field.name,
2605
+ type: field.kind === "json" ? `Create${field.type}` : field.type,
2606
+ list: field.list,
2607
+ nonNull: field.nonNull && field.defaultValue === void 0
2601
2608
  }
2602
2609
  )
2603
2610
  )
@@ -2608,10 +2615,10 @@ var generateDefinitions = (rawModels) => {
2608
2615
  input(
2609
2616
  `Update${model.name}`,
2610
2617
  model.fields.filter(({ updatable }) => updatable).map(
2611
- ({ name: name2, list: list2, ...field }) => field.type === "relation" ? { name: `${name2}Id`, type: "ID" } : {
2612
- name: name2,
2613
- type: field.type === "enum" ? field.typeName : field.type === "json" ? `Update${field.typeName}` : field.type,
2614
- list: list2
2618
+ (field) => field.kind === "relation" ? { name: `${field.name}Id`, type: "ID" } : {
2619
+ name: field.name,
2620
+ type: field.kind === "json" ? `Update${field.type}` : field.type,
2621
+ list: field.list
2615
2622
  }
2616
2623
  )
2617
2624
  )
@@ -2807,6 +2814,7 @@ var printSchemaFromModels = (models) => printSchema((0, import_graphql5.buildAST
2807
2814
  inputValues,
2808
2815
  isCreatable,
2809
2816
  isCreatableBy,
2817
+ isEnum,
2810
2818
  isEnumList,
2811
2819
  isEnumModel,
2812
2820
  isFieldNode,
@@ -2814,6 +2822,7 @@ var printSchemaFromModels = (models) => printSchema((0, import_graphql5.buildAST
2814
2822
  isInlineFragmentNode,
2815
2823
  isListType,
2816
2824
  isObjectModel,
2825
+ isPrimitive,
2817
2826
  isQueriableBy,
2818
2827
  isQueriableField,
2819
2828
  isRaw,