@smartive/graphql-magic 22.2.0-next.1 → 22.2.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.
@@ -160,27 +160,35 @@ export class MigrationGenerator {
160
160
  );
161
161
 
162
162
  // Update fields
163
- const rawExistingFields = model.fields.filter((field) => {
164
- if (!field.generateAs) {
165
- return false;
166
- }
167
-
163
+ const existingFields = model.fields.filter((field) => {
168
164
  const col = this.getColumn(model.name, field.kind === 'relation' ? `${field.name}Id` : field.name);
169
165
  if (!col) {
170
166
  return false;
171
167
  }
172
168
 
173
- if (col.generation_expression !== field.generateAs) {
169
+ if ((!field.nonNull && !col.is_nullable) || (field.nonNull && col.is_nullable)) {
174
170
  return true;
175
171
  }
176
172
 
177
- return this.hasChanged(model, field);
178
- });
179
- if (rawExistingFields.length) {
180
- this.updateFieldsRaw(model, rawExistingFields, up, down);
181
- }
173
+ if (!field.kind || field.kind === 'primitive') {
174
+ if (field.type === 'Int') {
175
+ if (col.data_type !== 'integer') {
176
+ return true;
177
+ }
178
+ }
179
+ if (field.type === 'Float') {
180
+ if (field.double) {
181
+ if (col.data_type !== 'double precision') {
182
+ return true;
183
+ }
184
+ } else if (col.data_type !== 'numeric') {
185
+ return true;
186
+ }
187
+ }
188
+ }
182
189
 
183
- const existingFields = model.fields.filter((field) => !field.generateAs && this.hasChanged(model, field));
190
+ return false;
191
+ });
184
192
  this.updateFields(model, existingFields, up, down);
185
193
  }
186
194
 
@@ -367,10 +375,6 @@ export class MigrationGenerator {
367
375
  for (const field of fields) {
368
376
  alter.push(() => this.column(field, { setNonNull: field.defaultValue !== undefined }));
369
377
 
370
- if (field.generateAs) {
371
- continue;
372
- }
373
-
374
378
  // If the field is not nullable but has no default, write placeholder code
375
379
  if (field.nonNull && field.defaultValue === undefined) {
376
380
  updates.push(() => this.writer.write(`${field.name}: 'TODO',`).newLine());
@@ -401,63 +405,13 @@ export class MigrationGenerator {
401
405
 
402
406
  down.push(() => {
403
407
  this.alterTable(model.name, () => {
404
- for (const { kind, name } of fields.toReversed()) {
408
+ for (const { kind, name } of fields) {
405
409
  this.dropColumn(kind === 'relation' ? `${name}Id` : name);
406
410
  }
407
411
  });
408
412
  });
409
413
  }
410
414
 
411
- private updateFieldsRaw(model: EntityModel, fields: EntityField[], up: Callbacks, down: Callbacks) {
412
- if (!fields.length) {
413
- return;
414
- }
415
-
416
- up.push(() => {
417
- this.alterTableRaw(model.name, () => {
418
- for (const [index, field] of fields.entries()) {
419
- this.columnRaw(field, { alter: true }, index);
420
- }
421
- });
422
- });
423
-
424
- down.push(() => {
425
- this.alterTableRaw(model.name, () => {
426
- for (const [index, field] of fields.entries()) {
427
- this.columnRaw(field, { alter: true }, index);
428
- }
429
- });
430
- });
431
-
432
- if (isUpdatableModel(model)) {
433
- const updatableFields = fields.filter(isUpdatableField);
434
- if (!updatableFields.length) {
435
- return;
436
- }
437
-
438
- up.push(() => {
439
- this.alterTable(`${model.name}Revision`, () => {
440
- for (const [index, field] of updatableFields.entries()) {
441
- this.columnRaw(field, { alter: true }, index);
442
- }
443
- });
444
- });
445
-
446
- down.push(() => {
447
- this.alterTable(`${model.name}Revision`, () => {
448
- for (const [index, field] of updatableFields.entries()) {
449
- this.columnRaw(
450
- field,
451
- { alter: true },
452
- index,
453
- summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.name}Id` : field.name),
454
- );
455
- }
456
- });
457
- });
458
- }
459
- }
460
-
461
415
  private updateFields(model: EntityModel, fields: EntityField[], up: Callbacks, down: Callbacks) {
462
416
  if (!fields.length) {
463
417
  return;
@@ -618,12 +572,6 @@ export class MigrationGenerator {
618
572
  .blankLine();
619
573
  }
620
574
 
621
- private alterTableRaw(table: string, block: () => void) {
622
- this.writer.write(`await knex.raw('ALTER TABLE "${table}"`);
623
- block();
624
- this.writer.write(`');`).newLine().blankLine();
625
- }
626
-
627
575
  private alterTable(table: string, block: () => void) {
628
576
  return this.writer
629
577
  .write(`await knex.schema.alterTable('${table}', (table) => `)
@@ -657,125 +605,29 @@ export class MigrationGenerator {
657
605
  return value;
658
606
  }
659
607
 
660
- private columnRaw(
661
- { name, ...field }: EntityField,
662
- { setNonNull = true, alter = false } = {},
663
- index: number,
664
- toColumn?: Column,
665
- ) {
666
- const nonNull = () => {
667
- if (setNonNull) {
668
- if (toColumn) {
669
- if (toColumn.is_nullable) {
670
- return false;
671
- }
672
-
673
- return true;
674
- }
675
- if (field.nonNull) {
676
- return true;
677
- }
678
-
679
- return false;
680
- }
681
- };
682
- const kind = field.kind;
683
- if (field.generateAs) {
684
- let type = '';
685
- switch (kind) {
686
- case undefined:
687
- case 'primitive':
688
- switch (field.type) {
689
- case 'Float':
690
- type = `decimal(${field.precision ?? 'undefined'}, ${field.scale ?? 'undefined'})`;
691
- break;
692
- default:
693
- throw new Error(`Generated columns of kind ${kind} and type ${field.type} are not supported yet.`);
694
- }
695
- break;
696
- default:
697
- throw new Error(`Generated columns of kind ${kind} are not supported yet.`);
698
- }
699
- if (index) {
700
- this.writer.write(`,`);
701
- }
702
- if (alter) {
703
- this.writer.write(` ALTER COLUMN "${name}" TYPE ${type}`);
704
- if (setNonNull) {
705
- if (nonNull()) {
706
- this.writer.write(`, ALTER COLUMN "${name}" SET NOT NULL`);
707
- } else {
708
- this.writer.write(`, ALTER COLUMN "${name}" DROP NOT NULL`);
709
- }
710
- }
711
- this.writer.write(`, ALTER COLUMN "${name}" SET EXPRESSION AS (${field.generateAs})`);
712
- } else {
713
- this.writer.write(
714
- `${alter ? 'ALTER' : 'ADD'} COLUMN "${name}" ${type}${nonNull() ? ' not null' : ''} GENERATED ALWAYS AS (${field.generateAs}) STORED`,
715
- );
716
- }
717
-
718
- return;
719
- }
720
-
721
- throw new Error(`Only generated columns can be created with columnRaw`);
722
- }
723
-
724
608
  private column(
725
609
  { name, primary, list, ...field }: EntityField,
726
610
  { setUnique = true, setNonNull = true, alter = false, foreign = true, setDefault = true } = {},
727
611
  toColumn?: Column,
728
612
  ) {
729
- const nonNull = () => {
730
- if (setNonNull) {
731
- if (toColumn) {
732
- if (toColumn.is_nullable) {
733
- return false;
734
- }
735
-
736
- return true;
737
- }
738
- if (field.nonNull) {
739
- return true;
740
- }
741
-
742
- return false;
743
- }
744
- };
745
- const kind = field.kind;
746
- if (field.generateAs) {
747
- let type = '';
748
- switch (kind) {
749
- case undefined:
750
- case 'primitive':
751
- switch (field.type) {
752
- case 'Float':
753
- type = `decimal(${field.precision ?? 'undefined'}, ${field.scale ?? 'undefined'})`;
754
- break;
755
- default:
756
- throw new Error(`Generated columns of kind ${kind} and type ${field.type} are not supported yet.`);
757
- }
758
- break;
759
- default:
760
- throw new Error(`Generated columns of kind ${kind} are not supported yet.`);
761
- }
762
- this.writer.write(
763
- `table.specificType('${name}', '${type}${nonNull() ? ' not null' : ''} GENERATED ALWAYS AS (${field.generateAs}) STORED')`,
764
- );
765
- if (alter) {
766
- this.writer.write('.alter()');
767
- }
768
- this.writer.write(';').newLine();
769
-
770
- return;
771
- }
772
-
773
613
  const col = (what?: string) => {
774
614
  if (what) {
775
615
  this.writer.write(what);
776
616
  }
777
617
  if (setNonNull) {
778
- this.writer.write(nonNull() ? '.notNullable()' : '.nullable()');
618
+ if (toColumn) {
619
+ if (toColumn.is_nullable) {
620
+ this.writer.write(`.nullable()`);
621
+ } else {
622
+ this.writer.write('.notNullable()');
623
+ }
624
+ } else {
625
+ if (field.nonNull) {
626
+ this.writer.write(`.notNullable()`);
627
+ } else {
628
+ this.writer.write('.nullable()');
629
+ }
630
+ }
779
631
  }
780
632
  if (setDefault && field.defaultValue !== undefined) {
781
633
  this.writer.write(`.defaultTo(${this.value(field.defaultValue)})`);
@@ -790,6 +642,7 @@ export class MigrationGenerator {
790
642
  }
791
643
  this.writer.write(';').newLine();
792
644
  };
645
+ const kind = field.kind;
793
646
  switch (kind) {
794
647
  case undefined:
795
648
  case 'primitive':
@@ -863,44 +716,6 @@ export class MigrationGenerator {
863
716
  private getColumn(tableName: string, columnName: string) {
864
717
  return this.columns[tableName].find((col) => col.name === columnName);
865
718
  }
866
-
867
- private hasChanged(model: EntityModel, field: EntityField) {
868
- const col = this.getColumn(model.name, field.kind === 'relation' ? `${field.name}Id` : field.name);
869
- if (!col) {
870
- return false;
871
- }
872
-
873
- if (field.generateAs) {
874
- if (col.generation_expression !== field.generateAs) {
875
- throw new Error(
876
- `Column ${col.name} has specific type ${col.generation_expression} but expected ${field.generateAs}`,
877
- );
878
- }
879
- }
880
-
881
- if ((!field.nonNull && !col.is_nullable) || (field.nonNull && col.is_nullable)) {
882
- return true;
883
- }
884
-
885
- if (!field.kind || field.kind === 'primitive') {
886
- if (field.type === 'Int') {
887
- if (col.data_type !== 'integer') {
888
- return true;
889
- }
890
- }
891
- if (field.type === 'Float') {
892
- if (field.double) {
893
- if (col.data_type !== 'double precision') {
894
- return true;
895
- }
896
- } else if (col.data_type !== 'numeric') {
897
- return true;
898
- }
899
- }
900
- }
901
-
902
- return false;
903
- }
904
719
  }
905
720
 
906
721
  export const getMigrationDate = () => {
@@ -90,7 +90,6 @@ export type EntityFieldDefinition = FieldDefinitionBase &
90
90
  indent?: boolean;
91
91
  // If true the field is hidden in the admin interface
92
92
  hidden?: boolean;
93
- generateAs?: string;
94
93
 
95
94
  // Temporary fields for the generation of migrations
96
95
  deleted?: true;