sasat 0.19.13 → 0.19.14

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 (56) hide show
  1. package/lib/cli/cli.js +2 -0
  2. package/lib/cli/commands/migrate.d.ts +6 -3
  3. package/lib/cli/commands/migrate.js +1 -1
  4. package/lib/db/getDbClient.d.ts +1 -1
  5. package/lib/db/sql/createTable/createTableParser.js +2 -2
  6. package/lib/generatorv2/codegen/ts/generateIDEncoder.js +2 -5
  7. package/lib/generatorv2/codegen/ts/generateMiddlewares.d.ts +2 -0
  8. package/lib/generatorv2/codegen/ts/generateMiddlewares.js +45 -0
  9. package/lib/generatorv2/codegen/ts/generateQueryResolver.js +15 -6
  10. package/lib/generatorv2/codegen/ts/generateUserDefinedCondition.js +2 -1
  11. package/lib/generatorv2/codegen/ts/mutation/makeMutationInputDecoder.js +5 -2
  12. package/lib/generatorv2/codegen/ts/tsFileNames.d.ts +1 -0
  13. package/lib/generatorv2/codegen/ts/tsFileNames.js +1 -0
  14. package/lib/generatorv2/codegen/tscodegen_v2.d.ts +1 -0
  15. package/lib/generatorv2/codegen/tscodegen_v2.js +4 -0
  16. package/lib/generatorv2/codegen_v2.d.ts +1 -0
  17. package/lib/generatorv2/codegen_v2.js +10 -0
  18. package/lib/generatorv2/nodes/entityNode.js +11 -5
  19. package/lib/generatorv2/nodes/mutationNode.d.ts +1 -0
  20. package/lib/generatorv2/parser/makeContextNodes.js +2 -2
  21. package/lib/generatorv2/parser/makeMutationNodes.js +27 -23
  22. package/lib/generatorv2/parser/makeSubscriptionNode.js +11 -19
  23. package/lib/index.d.ts +1 -0
  24. package/lib/index.js +1 -0
  25. package/lib/migration/controller.d.ts +2 -1
  26. package/lib/migration/controller.js +6 -2
  27. package/lib/migration/creators/tableCreator.d.ts +5 -11
  28. package/lib/migration/creators/tableCreator.js +6 -16
  29. package/lib/migration/data/GQLOption.d.ts +14 -18
  30. package/lib/migration/data/GQLOption.js +2 -22
  31. package/lib/migration/exec/runMigration.d.ts +2 -1
  32. package/lib/migration/exec/runMigration.js +7 -1
  33. package/lib/migration/front/tableMigrator.d.ts +5 -9
  34. package/lib/migration/front/tableMigrator.js +14 -16
  35. package/lib/migration/makeMutaion.d.ts +16 -0
  36. package/lib/migration/makeMutaion.js +29 -0
  37. package/lib/migration/makeQuery.d.ts +13 -4
  38. package/lib/migration/makeQuery.js +12 -8
  39. package/lib/migration/serializable/table.d.ts +1 -5
  40. package/lib/migration/serializable/table.js +3 -35
  41. package/lib/runtime/resolverMiddleware.d.ts +1 -1
  42. package/package.json +10 -10
  43. package/lib/generatorv2/codegen/gql/generateTypeDefs.d.ts +0 -3
  44. package/lib/generatorv2/codegen/gql/generateTypeDefs.js +0 -114
  45. package/lib/generatorv2/codegen/gql/gqlString.d.ts +0 -16
  46. package/lib/generatorv2/codegen/gql/gqlString.js +0 -43
  47. package/lib/generatorv2/codegen/gql/typeDefinition.d.ts +0 -9
  48. package/lib/generatorv2/codegen/gql/typeDefinition.js +0 -13
  49. package/lib/generatorv2/codegen/ts/relationMap/makeCondition.d.ts +0 -2
  50. package/lib/generatorv2/codegen/ts/relationMap/makeCondition.js +0 -100
  51. package/lib/generatorv2/nodes/ConditionNode.d.ts +0 -56
  52. package/lib/generatorv2/nodes/ConditionNode.js +0 -1
  53. package/lib/generatorv2/parser/makeQueryNodes.d.ts +0 -0
  54. package/lib/generatorv2/parser/makeQueryNodes.js +0 -1
  55. package/lib/runtime/dsl/query/fieldToQuery.d.ts +0 -0
  56. package/lib/runtime/dsl/query/fieldToQuery.js +0 -1
package/lib/cli/cli.js CHANGED
@@ -11,6 +11,8 @@ try {
11
11
  .usage('yarn sasat <command> [options]\n')
12
12
  .command('migrate', 'execute migration')
13
13
  .option('-g, --generateFiles', 'migrate with generate files')
14
+ .option('-d, --dry', 'dry run')
15
+ .option('-s, --silent', 'do not print logs')
14
16
  .action(async (options) => {
15
17
  await migrate(options).catch(() => {
16
18
  process.exit(1);
@@ -1,3 +1,6 @@
1
- export declare const migrate: (options: {
2
- [key: string]: boolean;
3
- }) => Promise<void>;
1
+ export type MigrateCommandOption = {
2
+ generateFiles: boolean;
3
+ silent: boolean;
4
+ dry: boolean;
5
+ };
6
+ export declare const migrate: (options: MigrateCommandOption) => Promise<void>;
@@ -8,7 +8,7 @@ export const migrate = async (options) => {
8
8
  let current;
9
9
  try {
10
10
  const migration = new MigrationController();
11
- const result = await migration.migrate();
11
+ const result = await migration.migrate(options);
12
12
  current = result.currentMigration;
13
13
  if (options.generateFiles) {
14
14
  const storeHandler = new DataStoreHandler(result.store);
@@ -1,2 +1,2 @@
1
1
  import { DBClient } from './connectors/dbClient.js';
2
- export declare const getDbClient: (connectionOption?: Partial<import("mysql2").ConnectionOptions> | undefined, poolOption?: Partial<import("mysql2").PoolOptions> | undefined) => DBClient;
2
+ export declare const getDbClient: (connectionOption?: Partial<import("mysql2/typings/mysql/lib/Connection.js").ConnectionOptions> | undefined, poolOption?: Partial<import("mysql2/typings/mysql/lib/Pool.js").PoolOptions> | undefined) => DBClient;
@@ -1,7 +1,7 @@
1
1
  import { TokenKind } from './lexer/lexer.js';
2
2
  import { camelize } from '../../../util/stringUtil.js';
3
3
  import { defaultColumnOption, } from '../../../migration/serialized/serializedColumn.js';
4
- import { getDefaultGqlOption } from '../../../migration/data/GQLOption.js';
4
+ import { defaultGQLOption } from '../../../migration/data/GQLOption.js';
5
5
  import { columnTypeToGqlPrimitive } from '../../../generatorv2/scripts/columnToGqlType.js';
6
6
  const splitArray = (array, callback) => {
7
7
  const indexes = [];
@@ -56,7 +56,7 @@ export class CreateTableParser {
56
56
  primaryKey: [],
57
57
  uniqueKeys: [],
58
58
  indexes: [],
59
- gqlOption: getDefaultGqlOption(),
59
+ gqlOption: defaultGQLOption(),
60
60
  virtualRelations: [],
61
61
  };
62
62
  }
@@ -35,9 +35,6 @@ export const generateIDEncoder = (root, content) => {
35
35
  const makeEncoder = isImported(sourceFile, 'makeNumberIdEncoder', ['sasat'])
36
36
  ? ''
37
37
  : new ImportDeclaration(['makeNumberIdEncoder'], 'sasat').toString();
38
- return (imports +
39
- makeEncoder +
40
- content +
41
- '\n' +
42
- new TsFile(...statements).toString());
38
+ const addition = statements.length === 0 ? '' : '\n' + new TsFile(...statements).toString();
39
+ return imports + makeEncoder + content + addition;
43
40
  };
@@ -0,0 +1,2 @@
1
+ import { RootNode } from '../../nodes/rootNode.js';
2
+ export declare const generateMiddlewares: (root: RootNode, content: string) => string | null;
@@ -0,0 +1,45 @@
1
+ import typescript from 'typescript';
2
+ import { TsFile, tsg } from '../../../tsg/index.js';
3
+ import { isImported } from './scripts/ast/isImported.js';
4
+ import { getExportedVariables } from './scripts/ast/getExportedVariables.js';
5
+ import { tsFileNames } from './tsFileNames.js';
6
+ import { ImportDeclaration as TsgImport } from '../../../tsg/importDeclaration.js';
7
+ import { unique } from '../../../runtime/util.js';
8
+ const { createSourceFile, ScriptTarget } = typescript;
9
+ export const generateMiddlewares = (root, content) => {
10
+ const middlewares = unique(root.entities.flatMap(it => [
11
+ ...it.queries.flatMap(it => it.middlewares),
12
+ ...it.mutations.flatMap(it => it.middlewares),
13
+ ]));
14
+ if (middlewares.length === 0)
15
+ return null;
16
+ const sourceFile = createSourceFile(tsFileNames.middleware + '.ts', content, ScriptTarget.ESNext);
17
+ const exportedVariables = getExportedVariables(sourceFile);
18
+ const statements = [];
19
+ middlewares.forEach(middleware => {
20
+ const exists = exportedVariables.some(it => {
21
+ return (it.declarationList.declarations[0].name.getText(sourceFile) ===
22
+ middleware);
23
+ });
24
+ if (exists)
25
+ return;
26
+ statements.push(tsg
27
+ .variable('const', middleware, tsg.arrowFunc([tsg.parameter('args')], undefined, tsg.block(tsg.throw(tsg.new(tsg.identifier('Error'), tsg.string('TODO: Not implemented'))), tsg.return(tsg.identifier('args')))), tsg.typeRef('ResolverMiddleware', [tsg.typeRef('GQLContext')]))
28
+ .export());
29
+ });
30
+ const contextImported = isImported(sourceFile, 'GQLContext', [
31
+ './context',
32
+ './context.js',
33
+ ]);
34
+ const resolverMiddlewareImported = isImported(sourceFile, 'ResolverMiddleware', ['sasat']);
35
+ const imports = [
36
+ contextImported
37
+ ? ''
38
+ : new TsgImport(['GQLContext'], './context').toString() + '\n',
39
+ resolverMiddlewareImported
40
+ ? ''
41
+ : new TsgImport(['ResolverMiddleware'], 'sasat').toString() + '\n',
42
+ ].join('');
43
+ const addition = statements.length === 0 ? '' : '\n' + new TsFile(...statements).toString();
44
+ return imports + content + addition;
45
+ };
@@ -78,15 +78,24 @@ const getHashIdArgs = (entity, query) => {
78
78
  })
79
79
  .filter(nonNullable);
80
80
  };
81
- const makeMiddlewares = (entity, query) => {
81
+ const makeHashIdMiddleware = (entity, query) => {
82
82
  const args = getHashIdArgs(entity, query);
83
83
  if (!args || args?.length === 0)
84
84
  return null;
85
- return tsg.array([
86
- tsg.arrowFunc([tsg.parameter('args')], undefined, tsg.block(new RawCodeStatement(`args[1] = {...args[1], ${args
87
- .map(it => `${it.name}: ${it.encoder}.decode(args[1].${it.name} as string),`)
88
- .join('')}};`).addImport(args.map(it => it.encoder), Directory.resolve(DIR, 'BASE', tsFileNames.encoder)), tsg.return(tsg.identifier('args')))),
89
- ]);
85
+ return tsg.arrowFunc([tsg.parameter('args')], undefined, tsg.block(new RawCodeStatement(`args[1] = {...args[1], ${args
86
+ .map(it => `${it.name}: ${it.encoder}.decode(args[1].${it.name} as string),`)
87
+ .join('')}};`).addImport(args.map(it => it.encoder), Directory.resolve(DIR, 'BASE', tsFileNames.encoder)), tsg.return(tsg.identifier('args'))));
88
+ };
89
+ const makeMiddlewares = (entity, query) => {
90
+ const hashId = makeHashIdMiddleware(entity, query);
91
+ if (!hashId && query.middlewares.length === 0)
92
+ return null;
93
+ if (query.middlewares.length === 0)
94
+ return tsg.array([hashId]);
95
+ const middlewares = query.middlewares.map(it => tsg.identifier(it).importFrom('../' + tsFileNames.middleware));
96
+ if (!hashId)
97
+ return tsg.array(middlewares);
98
+ return tsg.array([hashId, ...middlewares]);
90
99
  };
91
100
  const makeTypeArgs = (args) => {
92
101
  let hashIds = false;
@@ -44,5 +44,6 @@ export const generateUserDefinedCondition = (root, content) => {
44
44
  const condition = customConditionImported
45
45
  ? ''
46
46
  : new TsgImport(['CustomCondition'], 'sasat').toString() + '\n';
47
- return (context + condition + content + '\n' + new TsFile(...statements).toString());
47
+ const addition = statements.length === 0 ? '' : '\n' + new TsFile(...statements).toString();
48
+ return context + condition + content + addition;
48
49
  };
@@ -40,7 +40,7 @@ const makeResolverMiddleware = (typeName, entity, fields, node) => {
40
40
  if (!node.requireIdDecodeMiddleware)
41
41
  return [
42
42
  requiredType,
43
- tsg.variable('const', middlewareName, tsg.array([]), tsg.arrayType(tsg
43
+ tsg.variable('const', middlewareName, tsg.array(node.middlewares.map(it => tsg.identifier(it).importFrom('../' + tsFileNames.middleware))), tsg.arrayType(tsg
44
44
  .typeRef('ResolverMiddleware', [
45
45
  makeContextTypeRef(DIR),
46
46
  tsg.identifier(typeName),
@@ -50,7 +50,10 @@ const makeResolverMiddleware = (typeName, entity, fields, node) => {
50
50
  const incomingType = tsg.typeAlias('GQL' + typeName, tsg.typeLiteral([
51
51
  tsg.propertySignature(entity.name.lowerCase(), tsg.typeLiteral(sig)),
52
52
  ]));
53
- const middleware = tsg.variable('const', node.mutationName + 'Middleware', tsg.array([makeIdDecodeMiddleware(fields, node)]), tsg.arrayType(tsg
53
+ const middleware = tsg.variable('const', node.mutationName + 'Middleware', tsg.array([
54
+ makeIdDecodeMiddleware(fields, node),
55
+ ...node.middlewares.map(it => tsg.identifier(it).importFrom('../' + tsFileNames.middleware)),
56
+ ]), tsg.arrayType(tsg
54
57
  .typeRef('ResolverMiddleware', [
55
58
  makeContextTypeRef(DIR),
56
59
  tsg.identifier(typeName),
@@ -1,4 +1,5 @@
1
1
  export declare const tsFileNames: {
2
2
  encoder: string;
3
3
  conditions: string;
4
+ middleware: string;
4
5
  };
@@ -1,4 +1,5 @@
1
1
  export const tsFileNames = {
2
2
  encoder: 'idEncoder',
3
3
  conditions: 'conditions',
4
+ middleware: 'middlewares',
4
5
  };
@@ -19,4 +19,5 @@ export declare class TsCodegen_v2 {
19
19
  generateOnceFiles: () => FileData[];
20
20
  generateConditions: (root: RootNode, currentFile: string) => string | null;
21
21
  generateIDEncoders: (root: RootNode, currentFile: string) => string | null;
22
+ generateMiddlewares: (root: RootNode, currentFile: string) => string | null;
22
23
  }
@@ -12,6 +12,7 @@ import { generateContext } from './ts/generateContext.js';
12
12
  import { generateSubscription } from './ts/generateSubscription.js';
13
13
  import { generateUserDefinedCondition } from './ts/generateUserDefinedCondition.js';
14
14
  import { generateIDEncoder } from './ts/generateIDEncoder.js';
15
+ import { generateMiddlewares } from './ts/generateMiddlewares.js';
15
16
  export class TsCodegen_v2 {
16
17
  constructor() {
17
18
  this.fileExtension = 'ts';
@@ -42,5 +43,8 @@ export class TsCodegen_v2 {
42
43
  this.generateIDEncoders = (root, currentFile) => {
43
44
  return generateIDEncoder(root, currentFile);
44
45
  };
46
+ this.generateMiddlewares = (root, currentFile) => {
47
+ return generateMiddlewares(root, currentFile);
48
+ };
45
49
  }
46
50
  }
@@ -19,4 +19,5 @@ export declare class CodeGen_v2 {
19
19
  private generateOnceFiles;
20
20
  private generateCondition;
21
21
  private generateIDEncoders;
22
+ private generateMiddleware;
22
23
  }
@@ -28,6 +28,7 @@ export class CodeGen_v2 {
28
28
  ...this.generateOnceFiles(),
29
29
  this.generateCondition(this.root),
30
30
  this.generateIDEncoders(this.root),
31
+ this.generateMiddleware(this.root),
31
32
  ]);
32
33
  }
33
34
  async prepareDirs() {
@@ -87,4 +88,13 @@ export class CodeGen_v2 {
87
88
  if (nextContent)
88
89
  fs.writeFileSync(filePath, nextContent);
89
90
  }
91
+ async generateMiddleware(rootNode) {
92
+ const filePath = this.getFullPath(this.outDir, tsFileNames.middleware);
93
+ const content = fs.existsSync(filePath)
94
+ ? fs.readFileSync(filePath).toString()
95
+ : '';
96
+ const nextContent = this.codeGen.generateMiddlewares(rootNode, content);
97
+ if (nextContent)
98
+ fs.writeFileSync(filePath, nextContent);
99
+ }
90
100
  }
@@ -32,7 +32,7 @@ const makeFieldNode = (store, entity, column) => {
32
32
  isNullable: column.isNullable(),
33
33
  isUpdatable: !(column.data.onUpdateCurrentTimeStamp || column.isPrimary()) &&
34
34
  column.data.option.updatable,
35
- isGQLOpen: !column.table.gqlOption.mutation.fromContextColumns.some(it => it.column === column.columnName()),
35
+ isGQLOpen: true,
36
36
  column: column.data,
37
37
  option: column.data.option,
38
38
  hashId,
@@ -53,7 +53,8 @@ const makeCreatableFieldNode = (store, entity, column) => {
53
53
  isPrimary: column.isPrimary(),
54
54
  isNullable: column.isNullableOnCreate(),
55
55
  isUpdatable: column.isUpdatable(),
56
- isGQLOpen: !column.table.gqlOption.mutation.fromContextColumns.some(it => it.column === column.columnName()),
56
+ isGQLOpen: !(column.table.gqlOption.mutations.find(it => it.type === 'create')
57
+ ?.contextFields || []).some(it => it.column === column.columnName()),
57
58
  column: column.data,
58
59
  option: column.data.option,
59
60
  hashId: getHashId(store, entity.name, column),
@@ -74,7 +75,8 @@ const makeUpdatableFieldNode = (store, entity, column) => {
74
75
  isNullable: true,
75
76
  isPrimary: false,
76
77
  isUpdatable: true,
77
- isGQLOpen: !column.table.gqlOption.mutation.fromContextColumns.some(it => it.column === column.columnName()),
78
+ isGQLOpen: !(column.table.gqlOption.mutations.find(it => it.type === 'update')
79
+ ?.contextFields || []).some(it => it.column === column.columnName()),
78
80
  column: column.data,
79
81
  option: column.data.option,
80
82
  hashId: getHashId(store, entity.name, column),
@@ -89,13 +91,17 @@ export class EntityNode {
89
91
  this.identifyKeys = table.primaryKey;
90
92
  this.queries = table.gqlOption.queries;
91
93
  this.creatable = {
92
- gqlEnabled: table.gqlOption.enabled && table.gqlOption.mutation.create.enabled,
94
+ gqlEnabled: table.gqlOption.enabled &&
95
+ table.gqlOption.mutations.find(it => it.type === 'create') !==
96
+ undefined,
93
97
  fields: table.columns
94
98
  .map(it => makeCreatableFieldNode(store, this, it))
95
99
  .filter(nonNullable),
96
100
  };
97
101
  this.updateInput = {
98
- gqlEnabled: table.gqlOption.enabled && table.gqlOption.mutation.update.enabled,
102
+ gqlEnabled: table.gqlOption.enabled &&
103
+ table.gqlOption.mutations.find(it => it.type === 'update') !==
104
+ undefined,
99
105
  fields: [
100
106
  ...this.fields.filter(it => it.isPrimary),
101
107
  ...table.columns
@@ -19,4 +19,5 @@ export type MutationNode = {
19
19
  refetch: boolean;
20
20
  contextFields: ContextField[];
21
21
  requireIdDecodeMiddleware: boolean;
22
+ middlewares: string[];
22
23
  };
@@ -1,8 +1,8 @@
1
1
  export const makeContextNodes = (store) => {
2
2
  return store.tables.flatMap(table => {
3
- return table.gqlOption.mutation.fromContextColumns.map(it => ({
3
+ return table.gqlOption.mutations.flatMap(mutation => mutation.contextFields.map(it => ({
4
4
  name: it.contextName || it.column,
5
5
  dbtype: table.column(it.column).dataType(),
6
- }));
6
+ })));
7
7
  });
8
8
  };
@@ -1,29 +1,31 @@
1
1
  import { DBColumnTypes } from '../../migration/column/columnTypes.js';
2
2
  export const makeEntityMutationNodes = (table, entity) => {
3
- const result = [];
4
3
  if (!table.gqlOption.enabled)
5
4
  return [];
6
- if (table.gqlOption.mutation.create.enabled)
7
- result.push(makeCreateMutationNode(table, entity));
8
- if (table.gqlOption.mutation.update.enabled)
9
- result.push(makeUpdateMutationNode(table, entity));
10
- if (table.gqlOption.mutation.delete.enabled)
11
- result.push(makeDeleteMutationNode(table, entity));
12
- return result;
5
+ return table.gqlOption.mutations.map(mutation => {
6
+ switch (mutation.type) {
7
+ case 'create':
8
+ return makeCreateMutationNode(table, entity, mutation);
9
+ case 'update':
10
+ return makeUpdateMutationNode(table, entity, mutation);
11
+ case 'delete':
12
+ return makeDeleteMutationNode(table, entity, mutation);
13
+ }
14
+ });
13
15
  };
14
16
  const makeContextField = (params) => ({
15
17
  fieldName: params.column,
16
18
  contextName: params.contextName || params.column,
17
19
  });
18
- const makeCreateMutationNode = (table, entity) => {
20
+ const makeCreateMutationNode = (table, entity, mutation) => {
19
21
  return {
20
22
  entity,
21
- contextFields: table.gqlOption.mutation.fromContextColumns.map(makeContextField),
23
+ contextFields: mutation.contextFields.map(makeContextField),
22
24
  entityName: table.getEntityName(),
23
25
  identifyFields: table.getPrimaryKeyColumns().map(it => it.fieldName()),
24
26
  mutationName: `create${table.getEntityName().name}`,
25
27
  inputName: entity.name.createInputName(),
26
- refetch: !table.gqlOption.mutation.create.noReFetch,
28
+ refetch: !mutation.noReFetch,
27
29
  returnType: {
28
30
  typeName: table.getEntityName().name,
29
31
  nullable: false,
@@ -42,28 +44,28 @@ const makeCreateMutationNode = (table, entity) => {
42
44
  },
43
45
  ],
44
46
  mutationType: 'create',
45
- subscription: table.gqlOption.mutation.create.subscription,
47
+ subscription: mutation.subscription.enabled,
46
48
  requireIdDecodeMiddleware: entity.creatable.fields.some(it => it.hashId),
49
+ middlewares: mutation.middlewares,
47
50
  };
48
51
  };
49
- const makeUpdateMutationNode = (table, entity) => {
50
- const noRefetch = table.gqlOption.mutation.update.noReFetch;
52
+ const makeUpdateMutationNode = (table, entity, mutation) => {
51
53
  return {
52
54
  entity,
53
- contextFields: table.gqlOption.mutation.fromContextColumns.map(makeContextField),
55
+ contextFields: mutation.contextFields.map(makeContextField),
54
56
  entityName: table.getEntityName(),
55
57
  identifyFields: table.getPrimaryKeyColumns().map(it => it.fieldName()),
56
58
  mutationName: `update${table.getEntityName().name}`,
57
59
  inputName: entity.name.updateInputName(),
58
- refetch: !table.gqlOption.mutation.update.noReFetch,
60
+ refetch: !mutation.noReFetch,
59
61
  returnType: {
60
- typeName: noRefetch ? 'Boolean' : table.getEntityName().name,
61
- dbType: noRefetch
62
+ typeName: mutation.noReFetch ? 'Boolean' : table.getEntityName().name,
63
+ dbType: mutation.noReFetch
62
64
  ? DBColumnTypes.boolean
63
65
  : undefined,
64
66
  nullable: false,
65
67
  array: false,
66
- entity: !noRefetch,
68
+ entity: !mutation.noReFetch,
67
69
  },
68
70
  args: [
69
71
  {
@@ -77,16 +79,17 @@ const makeUpdateMutationNode = (table, entity) => {
77
79
  },
78
80
  ],
79
81
  mutationType: 'update',
80
- subscription: table.gqlOption.mutation.update.subscription,
82
+ subscription: mutation.subscription.enabled,
81
83
  requireIdDecodeMiddleware: entity.updateInput.fields.some(it => it.hashId),
84
+ middlewares: mutation.middlewares,
82
85
  };
83
86
  };
84
- const makeDeleteMutationNode = (table, entity) => {
87
+ const makeDeleteMutationNode = (table, entity, mutation) => {
85
88
  return {
86
89
  entity,
87
90
  mutationName: `delete${table.getEntityName().name}`,
88
91
  inputName: entity.name.identifyInputName(),
89
- contextFields: table.gqlOption.mutation.fromContextColumns.map(makeContextField),
92
+ contextFields: mutation.contextFields.map(makeContextField),
90
93
  entityName: table.getEntityName(),
91
94
  identifyFields: table.getPrimaryKeyColumns().map(it => it.fieldName()),
92
95
  refetch: false,
@@ -109,7 +112,8 @@ const makeDeleteMutationNode = (table, entity) => {
109
112
  },
110
113
  ],
111
114
  mutationType: 'delete',
112
- subscription: table.gqlOption.mutation.update.subscription,
115
+ subscription: mutation.subscription.enabled,
113
116
  requireIdDecodeMiddleware: entity.identifyFields().some(it => it.hashId),
117
+ middlewares: mutation.middlewares,
114
118
  };
115
119
  };
@@ -2,18 +2,9 @@ import { nonNullable } from '../../runtime/util.js';
2
2
  export const makeSubscriptionNodes = (store) => {
3
3
  return store.tables
4
4
  .flatMap(table => {
5
- const mutation = table.gqlOption.mutation;
6
- return [
7
- mutation.create.subscription
8
- ? makeSubscriptionNode('create', table)
9
- : undefined,
10
- mutation.update.subscription
11
- ? makeSubscriptionNode('update', table)
12
- : undefined,
13
- mutation.delete.subscription
14
- ? makeSubscriptionNode('delete', table)
15
- : undefined,
16
- ];
5
+ return table.gqlOption.mutations.map(it => {
6
+ return makeSubscriptionNode(table, it);
7
+ });
17
8
  })
18
9
  .filter(nonNullable);
19
10
  };
@@ -22,9 +13,10 @@ const subscriptionNamePostfix = {
22
13
  update: 'Updated',
23
14
  delete: 'Deleted',
24
15
  };
25
- const makeSubscriptionNode = (mutationType, table) => {
26
- const subscriptionName = table.getEntityName().name + subscriptionNamePostfix[mutationType];
27
- const option = table.gqlOption.mutation[mutationType];
16
+ const makeSubscriptionNode = (table, mutation) => {
17
+ if (!mutation.subscription.enabled)
18
+ return null;
19
+ const subscriptionName = table.getEntityName().name + subscriptionNamePostfix[mutation.type];
28
20
  return {
29
21
  subscriptionName,
30
22
  entity: table.getEntityName(),
@@ -35,7 +27,7 @@ const makeSubscriptionNode = (mutationType, table) => {
35
27
  array: false,
36
28
  entity: true,
37
29
  },
38
- args: table.gqlOption.mutation[mutationType].subscriptionFilter.map(it => {
30
+ args: mutation.subscription.subscriptionFilter.map(it => {
39
31
  const column = table.column(it);
40
32
  return {
41
33
  name: it,
@@ -48,14 +40,14 @@ const makeSubscriptionNode = (mutationType, table) => {
48
40
  },
49
41
  };
50
42
  }),
51
- filters: option.subscriptionFilter.map(it => {
43
+ filters: (mutation.subscription?.subscriptionFilter || []).map(it => {
52
44
  const column = table.column(it);
53
45
  return {
54
46
  field: column.fieldName(),
55
47
  gqlType: column.gqlType(),
56
48
  };
57
49
  }),
58
- mutationType,
59
- gqlEnabled: table.gqlOption.enabled && option.enabled,
50
+ mutationType: mutation.type,
51
+ gqlEnabled: table.gqlOption.enabled && mutation.subscription.enabled,
60
52
  };
61
53
  };
package/lib/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { ResolverMiddleware } from './runtime/resolverMiddleware.js';
3
3
  export { makeNumberIdEncoder } from './runtime/id.js';
4
4
  export type { CustomCondition } from './runtime/types.js';
5
5
  export { Queries } from './migration/makeQuery.js';
6
+ export { Mutations } from './migration/makeMutaion.js';
6
7
  export { Conditions } from './migration/makeCondition.js';
7
8
  export type { BooleanValueExpression, Query, LockMode, } from './runtime/dsl/query/query.js';
8
9
  export type { Relation } from './migration/data/relation.js';
package/lib/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { makeNumberIdEncoder } from './runtime/id.js';
2
2
  export { Queries } from './migration/makeQuery.js';
3
+ export { Mutations } from './migration/makeMutaion.js';
3
4
  export { Conditions } from './migration/makeCondition.js';
4
5
  export { QExpr } from './runtime/dsl/factory.js';
5
6
  export { gqlResolveInfoToField } from './runtime/gqlResolveInfoToField.js';
@@ -1,6 +1,7 @@
1
1
  import { SerializedStore } from './serialized/serializedStore.js';
2
+ import { MigrateCommandOption } from '../cli/commands/migrate.js';
2
3
  export declare class MigrationController {
3
- migrate(): Promise<{
4
+ migrate(options: MigrateCommandOption): Promise<{
4
5
  store: SerializedStore;
5
6
  currentMigration: string;
6
7
  }>;
@@ -5,15 +5,19 @@ import { readMigration } from './exec/readMigrationFile.js';
5
5
  import { runMigration } from './exec/runMigration.js';
6
6
  import { getMigrationTargets } from './exec/getMigrationTarget.js';
7
7
  import { createCurrentMigrationDataStore } from './exec/createCurrentMigrationDataStore.js';
8
+ import { Console } from '../cli/console.js';
8
9
  export class MigrationController {
9
- async migrate() {
10
+ async migrate(options) {
10
11
  const fileNames = await compileMigrationFiles();
11
12
  const currentMigration = await getCurrentMigration();
12
13
  let store = await createCurrentMigrationDataStore(currentMigration);
13
14
  const target = getMigrationTargets(fileNames, currentMigration);
14
15
  for (const tsFileName of target.files) {
16
+ if (!options.silent) {
17
+ Console.log('---------\n' + tsFileName);
18
+ }
15
19
  store = await readMigration(store, tsFileName, target.direction);
16
- await runMigration(store, tsFileName, target.direction);
20
+ await runMigration(store, tsFileName, target.direction, options);
17
21
  store.resetQueue();
18
22
  }
19
23
  return {
@@ -2,7 +2,7 @@ import { ColumnCreator } from './columnCreator.js';
2
2
  import { ColumnBuilderBase, ReferenceColumnBuilder } from './columnBuilder.js';
3
3
  import { Reference } from '../serialized/serializedColumn.js';
4
4
  import { TableHandler } from '../serializable/table.js';
5
- import { GqlFromContextParam, GQLOption, GQLQuery, MutationOption } from '../data/GQLOption.js';
5
+ import { GQLMutation, GQLOption, GQLQuery } from '../data/GQLOption.js';
6
6
  import { DataStore } from '../dataStore.js';
7
7
  import { VirtualRelation } from '../data/virtualRelation.js';
8
8
  export interface TableBuilder {
@@ -18,13 +18,10 @@ export interface TableBuilder {
18
18
  createdAt(): TableBuilder;
19
19
  updatedAt(): TableBuilder;
20
20
  addIndex(...columns: string[]): TableBuilder;
21
- setGQLCreate(enabled: boolean, options?: Partial<MutationOption>): TableBuilder;
22
- setGQLUpdate(enabled: boolean, options?: Partial<MutationOption>): TableBuilder;
23
- setGQLDelete(enabled: boolean, options?: Partial<Omit<MutationOption, 'noReFetch'>>): TableBuilder;
24
- setGQLContextColumn(columns: GqlFromContextParam[]): TableBuilder;
25
21
  enableGQL(): TableBuilder;
26
22
  setGQLOption(option: Partial<GQLOption>): TableBuilder;
27
- addQuery(query: GQLQuery): TableBuilder;
23
+ addGQLQuery(...query: GQLQuery[]): TableBuilder;
24
+ addGQLMutation(...mutation: GQLMutation[]): TableBuilder;
28
25
  }
29
26
  export declare class TableCreator implements TableBuilder {
30
27
  tableName: string;
@@ -48,9 +45,6 @@ export declare class TableCreator implements TableBuilder {
48
45
  addIndex(...columns: string[]): TableBuilder;
49
46
  enableGQL(): TableBuilder;
50
47
  setGQLOption(option: Partial<GQLOption>): TableBuilder;
51
- setGQLCreate(enabled: boolean, options?: Partial<MutationOption>): TableBuilder;
52
- setGQLUpdate(enabled: boolean, options?: Partial<MutationOption>): TableBuilder;
53
- setGQLDelete(enabled: boolean, options?: Partial<Omit<MutationOption, 'noReFetch'>>): TableBuilder;
54
- setGQLContextColumn(columns: GqlFromContextParam[]): TableBuilder;
55
- addQuery(query: GQLQuery): TableBuilder;
48
+ addGQLQuery(...query: GQLQuery[]): TableBuilder;
49
+ addGQLMutation(...mutation: GQLMutation[]): TableBuilder;
56
50
  }
@@ -79,25 +79,15 @@ export class TableCreator {
79
79
  this.table.setGQLOption(option);
80
80
  return this;
81
81
  }
82
- setGQLCreate(enabled, options) {
83
- this.table.setGQLCreate(enabled, options);
84
- return this;
85
- }
86
- setGQLUpdate(enabled, options) {
87
- this.table.setGQLUpdate(enabled, options);
88
- return this;
89
- }
90
- setGQLDelete(enabled, options) {
91
- this.table.setGQLDelete(enabled, options);
92
- return this;
93
- }
94
- setGQLContextColumn(columns) {
95
- this.table.setGQLContextColumn(columns);
82
+ addGQLQuery(...query) {
83
+ this.table.setGQLOption({
84
+ queries: [...this.table.gqlOption.queries, ...query],
85
+ });
96
86
  return this;
97
87
  }
98
- addQuery(query) {
88
+ addGQLMutation(...mutation) {
99
89
  this.table.setGQLOption({
100
- queries: [...this.table.gqlOption.queries, query],
90
+ mutations: [...this.table.gqlOption.mutations, ...mutation],
101
91
  });
102
92
  return this;
103
93
  }