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.
- package/lib/cli/cli.js +2 -0
- package/lib/cli/commands/migrate.d.ts +6 -3
- package/lib/cli/commands/migrate.js +1 -1
- package/lib/db/getDbClient.d.ts +1 -1
- package/lib/db/sql/createTable/createTableParser.js +2 -2
- package/lib/generatorv2/codegen/ts/generateIDEncoder.js +2 -5
- package/lib/generatorv2/codegen/ts/generateMiddlewares.d.ts +2 -0
- package/lib/generatorv2/codegen/ts/generateMiddlewares.js +45 -0
- package/lib/generatorv2/codegen/ts/generateQueryResolver.js +15 -6
- package/lib/generatorv2/codegen/ts/generateUserDefinedCondition.js +2 -1
- package/lib/generatorv2/codegen/ts/mutation/makeMutationInputDecoder.js +5 -2
- package/lib/generatorv2/codegen/ts/tsFileNames.d.ts +1 -0
- package/lib/generatorv2/codegen/ts/tsFileNames.js +1 -0
- package/lib/generatorv2/codegen/tscodegen_v2.d.ts +1 -0
- package/lib/generatorv2/codegen/tscodegen_v2.js +4 -0
- package/lib/generatorv2/codegen_v2.d.ts +1 -0
- package/lib/generatorv2/codegen_v2.js +10 -0
- package/lib/generatorv2/nodes/entityNode.js +11 -5
- package/lib/generatorv2/nodes/mutationNode.d.ts +1 -0
- package/lib/generatorv2/parser/makeContextNodes.js +2 -2
- package/lib/generatorv2/parser/makeMutationNodes.js +27 -23
- package/lib/generatorv2/parser/makeSubscriptionNode.js +11 -19
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/migration/controller.d.ts +2 -1
- package/lib/migration/controller.js +6 -2
- package/lib/migration/creators/tableCreator.d.ts +5 -11
- package/lib/migration/creators/tableCreator.js +6 -16
- package/lib/migration/data/GQLOption.d.ts +14 -18
- package/lib/migration/data/GQLOption.js +2 -22
- package/lib/migration/exec/runMigration.d.ts +2 -1
- package/lib/migration/exec/runMigration.js +7 -1
- package/lib/migration/front/tableMigrator.d.ts +5 -9
- package/lib/migration/front/tableMigrator.js +14 -16
- package/lib/migration/makeMutaion.d.ts +16 -0
- package/lib/migration/makeMutaion.js +29 -0
- package/lib/migration/makeQuery.d.ts +13 -4
- package/lib/migration/makeQuery.js +12 -8
- package/lib/migration/serializable/table.d.ts +1 -5
- package/lib/migration/serializable/table.js +3 -35
- package/lib/runtime/resolverMiddleware.d.ts +1 -1
- package/package.json +10 -10
- package/lib/generatorv2/codegen/gql/generateTypeDefs.d.ts +0 -3
- package/lib/generatorv2/codegen/gql/generateTypeDefs.js +0 -114
- package/lib/generatorv2/codegen/gql/gqlString.d.ts +0 -16
- package/lib/generatorv2/codegen/gql/gqlString.js +0 -43
- package/lib/generatorv2/codegen/gql/typeDefinition.d.ts +0 -9
- package/lib/generatorv2/codegen/gql/typeDefinition.js +0 -13
- package/lib/generatorv2/codegen/ts/relationMap/makeCondition.d.ts +0 -2
- package/lib/generatorv2/codegen/ts/relationMap/makeCondition.js +0 -100
- package/lib/generatorv2/nodes/ConditionNode.d.ts +0 -56
- package/lib/generatorv2/nodes/ConditionNode.js +0 -1
- package/lib/generatorv2/parser/makeQueryNodes.d.ts +0 -0
- package/lib/generatorv2/parser/makeQueryNodes.js +0 -1
- package/lib/runtime/dsl/query/fieldToQuery.d.ts +0 -0
- 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
|
|
2
|
-
|
|
3
|
-
|
|
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);
|
package/lib/db/getDbClient.d.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
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
|
-
|
|
39
|
-
|
|
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,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
|
|
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.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
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(
|
|
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([
|
|
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),
|
|
@@ -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
|
}
|
|
@@ -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:
|
|
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.
|
|
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.
|
|
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 &&
|
|
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 &&
|
|
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
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const makeContextNodes = (store) => {
|
|
2
2
|
return store.tables.flatMap(table => {
|
|
3
|
-
return table.gqlOption.mutation.
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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:
|
|
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: !
|
|
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:
|
|
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:
|
|
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: !
|
|
60
|
+
refetch: !mutation.noReFetch,
|
|
59
61
|
returnType: {
|
|
60
|
-
typeName:
|
|
61
|
-
dbType:
|
|
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: !
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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 = (
|
|
26
|
-
|
|
27
|
-
|
|
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:
|
|
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:
|
|
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 &&
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
52
|
-
|
|
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
|
-
|
|
83
|
-
this.table.
|
|
84
|
-
|
|
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
|
-
|
|
88
|
+
addGQLMutation(...mutation) {
|
|
99
89
|
this.table.setGQLOption({
|
|
100
|
-
|
|
90
|
+
mutations: [...this.table.gqlOption.mutations, ...mutation],
|
|
101
91
|
});
|
|
102
92
|
return this;
|
|
103
93
|
}
|