sasat 0.14.13 → 0.15.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.
- package/lib/cli/cli.js +3 -1
- package/lib/cli/commands/dumpDb.js +3 -1
- package/lib/db/connectors/mariadb/client.js +1 -1
- package/lib/db/connectors/mysql/client.js +1 -1
- package/lib/db/formatQuery.js +3 -1
- package/lib/db/sql/columnToSql.js +5 -2
- package/lib/db/sql/condition.js +17 -6
- package/lib/db/sql/createTable/createTableParser.js +29 -24
- package/lib/db/sql/createTable/createTableSerializer.js +40 -12
- package/lib/db/sql/createTable/lexer/lexer2.js +3 -1
- package/lib/db/sql/createTable/lexer/rules.js +3 -1
- package/lib/db/sql/expression/comparison.js +6 -2
- package/lib/db/sql/expression/compositeCondition.js +2 -2
- package/lib/db/sql/expression/conditionExpression.js +1 -1
- package/lib/db/sql/sqlCreater.js +6 -2
- package/lib/generator/gql/Directive.d.ts +13 -0
- package/lib/generator/gql/Directive.js +3 -0
- package/lib/generator/ts/code/importDeclaration.js +2 -1
- package/lib/generator/ts/code/node/class.js +2 -1
- package/lib/generator/ts/code/node/enumDeclaration.js +3 -1
- package/lib/generator/ts/code/node/expressions.js +5 -2
- package/lib/generator/ts/code/node/interface.d.ts +3 -0
- package/lib/generator/ts/code/node/interface.js +9 -1
- package/lib/generator/ts/code/node/propertyDeclaration.js +3 -1
- package/lib/generator/ts/code/node/type/typeReference.js +7 -2
- package/lib/generator/ts/code/node/variableDeclaration.js +4 -1
- package/lib/generator/ts/db/generatedRepositoryGenerator.js +25 -9
- package/lib/generator/ts/entityGenerator.js +4 -1
- package/lib/generator/ts/file.js +4 -1
- package/lib/generator/ts/generator.d.ts +1 -1
- package/lib/generator/ts/generator.js +4 -1
- package/lib/generator/ts/gql/mutationGenerator.d.ts +1 -0
- package/lib/generator/ts/gql/mutationGenerator.js +89 -30
- package/lib/generator/ts/gql/queryGenerator.d.ts +3 -0
- package/lib/generator/ts/gql/queryGenerator.js +56 -17
- package/lib/generator/ts/gql/resolverGenerator.js +17 -4
- package/lib/generator/ts/gql/subscriptionGenerator.js +10 -3
- package/lib/generator/ts/gql/typeDefGenerator.d.ts +2 -0
- package/lib/generator/ts/gql/typeDefGenerator.js +26 -3
- package/lib/generator/ts/relationMapGenerator.js +16 -4
- package/lib/generator/ts/staticFiles.js +8 -5
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -0
- package/lib/migration/controller.js +8 -3
- package/lib/migration/creators/columnCreator.d.ts +8 -8
- package/lib/migration/creators/tableCreator.d.ts +10 -5
- package/lib/migration/creators/tableCreator.js +19 -3
- package/lib/migration/data/gqlOption.d.ts +19 -11
- package/lib/migration/data/gqlOption.js +13 -18
- package/lib/migration/front/tableMigrator.d.ts +9 -4
- package/lib/migration/front/tableMigrator.js +23 -5
- package/lib/migration/functions/assembleColumn.js +1 -1
- package/lib/migration/migrationReader.js +6 -3
- package/lib/migration/migrationTargetResolver.js +3 -1
- package/lib/migration/serializable/column.js +3 -1
- package/lib/migration/serializable/table.d.ts +5 -3
- package/lib/migration/serializable/table.js +44 -9
- package/lib/parser/node/entityName.d.ts +2 -0
- package/lib/parser/node/entityName.js +12 -0
- package/lib/parser/node/entityNode.js +4 -1
- package/lib/parser/node/fieldNode.js +4 -4
- package/lib/parser/node/gql/mutationNode.d.ts +4 -3
- package/lib/parser/node/gql/mutationNode.js +14 -8
- package/lib/parser/node/gql/queryNode.d.ts +2 -1
- package/lib/parser/node/gql/queryNode.js +2 -1
- package/lib/parser/node/parameterNode.js +3 -1
- package/lib/parser/node/relationNode.js +4 -4
- package/lib/parser/node/repositoryNode.js +11 -7
- package/lib/parser/node/typeNode.d.ts +10 -2
- package/lib/parser/node/typeNode.js +28 -10
- package/lib/parser/nodeFactory/contextNodeFactory.js +2 -2
- package/lib/parser/nodeFactory/mutationNodeFactory.js +13 -10
- package/lib/parser/nodeFactory/queryNodeFactory.js +5 -3
- package/lib/runtime/createTypeDef.d.ts +1 -1
- package/lib/runtime/createTypeDef.js +8 -5
- package/lib/runtime/dsl/factory.d.ts +4 -4
- package/lib/runtime/dsl/factory.js +2 -2
- package/lib/runtime/dsl/query/fieldToQuery.d.ts +1 -0
- package/lib/runtime/dsl/query/fieldToQuery.js +11 -2
- package/lib/runtime/dsl/query/query.d.ts +5 -3
- package/lib/runtime/dsl/query/query.js +1 -0
- package/lib/runtime/dsl/query/sql/hydrate.d.ts +2 -1
- package/lib/runtime/dsl/query/sql/hydrate.js +19 -6
- package/lib/runtime/dsl/query/sql/nodeToSql.js +23 -9
- package/lib/runtime/dsl/query/sql/queryToSql.js +9 -2
- package/lib/runtime/dsl/replaceAliases.js +40 -11
- package/lib/runtime/sasatRepository.d.ts +21 -2
- package/lib/runtime/sasatRepository.js +34 -10
- package/lib/runtime/util.d.ts +3 -0
- package/lib/runtime/util.js +1 -0
- package/lib/util/assignDeep.js +14 -11
- package/lib/util/stringUtil.js +1 -1
- package/package.json +25 -25
package/lib/cli/cli.js
CHANGED
|
@@ -17,7 +17,9 @@ try {
|
|
|
17
17
|
});
|
|
18
18
|
});
|
|
19
19
|
cli.command('generate', 'generate files').action(generate);
|
|
20
|
-
cli
|
|
20
|
+
cli
|
|
21
|
+
.command('migration:create [name]', 'generate new migration file')
|
|
22
|
+
.action(createMigration);
|
|
21
23
|
cli.command('dump-db', 'dump database schema').action(dumpDB);
|
|
22
24
|
cli.command('init').action(init);
|
|
23
25
|
cli.parse();
|
|
@@ -8,7 +8,9 @@ import { getDbClient } from '../../db/getDbClient.js';
|
|
|
8
8
|
export const dumpDB = async () => {
|
|
9
9
|
const con = getDbClient();
|
|
10
10
|
try {
|
|
11
|
-
const tables = await con
|
|
11
|
+
const tables = await con
|
|
12
|
+
.rawQuery('show tables')
|
|
13
|
+
.then(it => it.flatMap(it => Object.values(it)));
|
|
12
14
|
const serialized = await Promise.all(tables.map(table => {
|
|
13
15
|
return con
|
|
14
16
|
.rawQuery('show create table ' + SqlString.escapeId(table))
|
package/lib/db/formatQuery.js
CHANGED
|
@@ -5,7 +5,9 @@ export const formatQuery = (str, ...params) => {
|
|
|
5
5
|
if (typeof params[i] === 'function')
|
|
6
6
|
ret += params[i]();
|
|
7
7
|
else if (Array.isArray(params[i]))
|
|
8
|
-
ret += params[i]
|
|
8
|
+
ret += params[i]
|
|
9
|
+
.map((it) => SqlString.escape(it))
|
|
10
|
+
.join(', ');
|
|
9
11
|
else
|
|
10
12
|
ret += SqlString.escape(params[i]);
|
|
11
13
|
ret += str[i + 1];
|
|
@@ -3,7 +3,9 @@ import { SqlString } from '../../runtime/sql/sqlString.js';
|
|
|
3
3
|
export const columnToSql = (column) => {
|
|
4
4
|
const words = [SqlString.escapeId(column.columnName), column.type];
|
|
5
5
|
if (column.length)
|
|
6
|
-
words.push(`(${[column.length, column.scale]
|
|
6
|
+
words.push(`(${[column.length, column.scale]
|
|
7
|
+
.filter(it => it !== undefined)
|
|
8
|
+
.join(',')})`);
|
|
7
9
|
if (column.signed === true)
|
|
8
10
|
words.push('SIGNED');
|
|
9
11
|
else if (column.signed === false)
|
|
@@ -16,7 +18,8 @@ export const columnToSql = (column) => {
|
|
|
16
18
|
words.push('NOT NULL');
|
|
17
19
|
else if (!column.notNull)
|
|
18
20
|
words.push('NULL');
|
|
19
|
-
if ((column.type === DBColumnTypes.timestamp ||
|
|
21
|
+
if ((column.type === DBColumnTypes.timestamp ||
|
|
22
|
+
column.type === DBColumnTypes.dateTime) &&
|
|
20
23
|
column.default === 'CURRENT_TIMESTAMP')
|
|
21
24
|
words.push('DEFAULT CURRENT_TIMESTAMP');
|
|
22
25
|
else if (column.default !== undefined)
|
package/lib/db/sql/condition.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as SqlString from 'sqlstring';
|
|
2
|
-
import { conditionExpressionToSql } from './expression/conditionExpression.js';
|
|
2
|
+
import { conditionExpressionToSql, } from './expression/conditionExpression.js';
|
|
3
3
|
const formatTable = (table) => {
|
|
4
|
-
return typeof table === 'string'
|
|
4
|
+
return typeof table === 'string'
|
|
5
|
+
? SqlString.escapeId(table)
|
|
6
|
+
: table.map(it => SqlString.escapeId(it)).join('as');
|
|
5
7
|
};
|
|
6
8
|
const joinClause = (sql) => {
|
|
7
9
|
if (!sql.join)
|
|
@@ -21,7 +23,9 @@ const joinClause = (sql) => {
|
|
|
21
23
|
})
|
|
22
24
|
.join(' ');
|
|
23
25
|
};
|
|
24
|
-
export const orderToSQL = (order) => order
|
|
26
|
+
export const orderToSQL = (order) => order
|
|
27
|
+
.map(it => `${SqlString.escapeId(it[0])} ${it[1] === 'DESC' ? 'DESC' : 'ASK'}`)
|
|
28
|
+
.join(', ');
|
|
25
29
|
const mergeWhereClause = (whereClauses) => {
|
|
26
30
|
const result = [];
|
|
27
31
|
whereClauses.forEach(it => {
|
|
@@ -33,15 +37,22 @@ const mergeWhereClause = (whereClauses) => {
|
|
|
33
37
|
return result;
|
|
34
38
|
};
|
|
35
39
|
export const createSQLString = (sql) => {
|
|
36
|
-
const select = [
|
|
37
|
-
.
|
|
40
|
+
const select = [
|
|
41
|
+
...sql.select,
|
|
42
|
+
...(sql.join ? sql.join.flatMap(it => it.select) : []),
|
|
43
|
+
]
|
|
44
|
+
.map(it => Array.isArray(it)
|
|
45
|
+
? it.map(it => SqlString.escapeId(it)).join(' as ')
|
|
46
|
+
: SqlString.escapeId(it))
|
|
38
47
|
.join(', ');
|
|
39
48
|
const join = joinClause(sql);
|
|
40
49
|
const whereClauses = [
|
|
41
50
|
sql.where,
|
|
42
51
|
...(sql.join ? sql.join.map(it => it.where) : []),
|
|
43
52
|
].filter(it => it !== undefined && Object.keys(it).length);
|
|
44
|
-
const where = whereClauses.length === 0
|
|
53
|
+
const where = whereClauses.length === 0
|
|
54
|
+
? ''
|
|
55
|
+
: ' WHERE ' + conditionExpressionToSql(mergeWhereClause(whereClauses));
|
|
45
56
|
const order = sql.order ? ' ORDER BY ' + orderToSQL(sql.order) : '';
|
|
46
57
|
const limit = sql.limit ? ' LIMIT ' + sql.limit : '';
|
|
47
58
|
const offset = sql.offset ? ' OFFSET ' : '';
|
|
@@ -2,6 +2,7 @@ import { TokenKind } from './lexer/lexer.js';
|
|
|
2
2
|
import { camelize } from '../../../util/stringUtil.js';
|
|
3
3
|
import { columnTypeToGqlPrimitive } from '../../../generator/gql/columnToGqlType.js';
|
|
4
4
|
import { GqlPrimitive } from '../../../generator/gql/types.js';
|
|
5
|
+
import { getDefaultGqlOption } from '../../../migration/data/gqlOption.js';
|
|
5
6
|
const splitArray = (array, callback) => {
|
|
6
7
|
const indexes = [];
|
|
7
8
|
array.forEach((it, i) => {
|
|
@@ -49,27 +50,13 @@ export class CreateTableParser {
|
|
|
49
50
|
this.normalizeFieldName = (fieldName) => {
|
|
50
51
|
return /^[0-9].*/.test(fieldName) ? '_' + fieldName : fieldName;
|
|
51
52
|
};
|
|
52
|
-
const defaultGqlOption = {
|
|
53
|
-
mutation: {
|
|
54
|
-
create: true,
|
|
55
|
-
update: true,
|
|
56
|
-
delete: true,
|
|
57
|
-
fromContextColumns: [],
|
|
58
|
-
},
|
|
59
|
-
subscription: {
|
|
60
|
-
onCreate: false,
|
|
61
|
-
onUpdate: false,
|
|
62
|
-
onDelete: false,
|
|
63
|
-
filter: [],
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
53
|
this.result = {
|
|
67
54
|
tableName: '',
|
|
68
55
|
columns: [],
|
|
69
56
|
primaryKey: [],
|
|
70
57
|
uniqueKeys: [],
|
|
71
58
|
indexes: [],
|
|
72
|
-
gqlOption:
|
|
59
|
+
gqlOption: getDefaultGqlOption(),
|
|
73
60
|
};
|
|
74
61
|
}
|
|
75
62
|
resolveParen() {
|
|
@@ -104,7 +91,9 @@ export class CreateTableParser {
|
|
|
104
91
|
const next = tokens[defaultTokenIndex + 1];
|
|
105
92
|
if (next.kind === 'NULL')
|
|
106
93
|
return undefined;
|
|
107
|
-
if (next.kind === TokenKind.Number ||
|
|
94
|
+
if (next.kind === TokenKind.Number ||
|
|
95
|
+
gqlType === GqlPrimitive.Float ||
|
|
96
|
+
gqlType === GqlPrimitive.Int)
|
|
108
97
|
return +next.value;
|
|
109
98
|
if (next.kind === TokenKind.String)
|
|
110
99
|
return next.value;
|
|
@@ -127,8 +116,12 @@ export class CreateTableParser {
|
|
|
127
116
|
});
|
|
128
117
|
};
|
|
129
118
|
const identifiers = tokens.filter(it => it.kind === TokenKind.Identifier);
|
|
130
|
-
const length = tokens[2] && isParenToken(tokens[2])
|
|
131
|
-
|
|
119
|
+
const length = tokens[2] && isParenToken(tokens[2])
|
|
120
|
+
? tokens[2].tokens[0]?.value
|
|
121
|
+
: undefined;
|
|
122
|
+
const scale = tokens[2] && isParenToken(tokens[2])
|
|
123
|
+
? tokens[2].tokens[1]?.value
|
|
124
|
+
: undefined;
|
|
132
125
|
const column = {
|
|
133
126
|
hasReference: false,
|
|
134
127
|
columnName,
|
|
@@ -162,17 +155,23 @@ export class CreateTableParser {
|
|
|
162
155
|
parsePrimary(tokens) {
|
|
163
156
|
const keyIndex = tokens.findIndex(it => it.kind === 'KEY');
|
|
164
157
|
const paren = tokens[keyIndex + 1];
|
|
165
|
-
this.result.primaryKey = paren.tokens
|
|
158
|
+
this.result.primaryKey = paren.tokens
|
|
159
|
+
.filter(it => it.kind !== TokenKind.Separator)
|
|
160
|
+
.map(it => it.value);
|
|
166
161
|
}
|
|
167
162
|
parseUnique(tokens) {
|
|
168
163
|
const paren = tokens.find(it => it.kind === 'Paren');
|
|
169
|
-
this.result.uniqueKeys.push(paren.tokens
|
|
164
|
+
this.result.uniqueKeys.push(paren.tokens
|
|
165
|
+
.filter(it => it.kind !== TokenKind.Separator)
|
|
166
|
+
.map(it => it.value));
|
|
170
167
|
}
|
|
171
168
|
parseIndex(tokens) {
|
|
172
169
|
const paren = tokens.find(it => it.kind === 'Paren');
|
|
173
170
|
this.result.indexes.push({
|
|
174
171
|
constraintName: tokens[1].value,
|
|
175
|
-
columns: paren.tokens
|
|
172
|
+
columns: paren.tokens
|
|
173
|
+
.filter(it => it.kind !== TokenKind.Separator && it.kind !== 'Paren')
|
|
174
|
+
.map(it => it.value),
|
|
176
175
|
});
|
|
177
176
|
}
|
|
178
177
|
parseFkey(tokens) {
|
|
@@ -183,7 +182,9 @@ export class CreateTableParser {
|
|
|
183
182
|
const targetColumn = tokens[refIndex + 2].tokens[0].value;
|
|
184
183
|
let onDelete = undefined;
|
|
185
184
|
let onUpdate = undefined;
|
|
186
|
-
const on = tokens
|
|
185
|
+
const on = tokens
|
|
186
|
+
.map((it, i) => (it.kind === 'ON' ? i : 0))
|
|
187
|
+
.filter(it => it !== 0);
|
|
187
188
|
on.forEach(it => {
|
|
188
189
|
const action = () => {
|
|
189
190
|
let name = tokens[it + 2].value.toUpperCase();
|
|
@@ -199,14 +200,18 @@ export class CreateTableParser {
|
|
|
199
200
|
onUpdate = action();
|
|
200
201
|
}
|
|
201
202
|
});
|
|
202
|
-
const isColumnUnique = this.result.uniqueKeys
|
|
203
|
+
const isColumnUnique = this.result.uniqueKeys
|
|
204
|
+
.filter(it => it.length === 1)
|
|
205
|
+
.find(it => it[0] === columnName);
|
|
203
206
|
const sameTableRefs = this.result.columns.filter(it => it.hasReference && it.reference.targetTable === targetTable);
|
|
204
207
|
const reference = {
|
|
205
208
|
targetTable,
|
|
206
209
|
targetColumn,
|
|
207
210
|
columnName,
|
|
208
211
|
relation: isColumnUnique ? 'OneOrZero' : 'Many',
|
|
209
|
-
relationName: sameTableRefs.length !== 0
|
|
212
|
+
relationName: sameTableRefs.length !== 0
|
|
213
|
+
? targetTable + sameTableRefs.length
|
|
214
|
+
: undefined,
|
|
210
215
|
onUpdate,
|
|
211
216
|
onDelete,
|
|
212
217
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { columnTypeToTsType } from '../../../migration/column/columnTypes.js';
|
|
1
|
+
import { columnTypeToTsType, } from '../../../migration/column/columnTypes.js';
|
|
2
2
|
import { lexColumn } from './lexer/columnLexer.js';
|
|
3
3
|
import { TokenKind } from './lexer/lexer.js';
|
|
4
4
|
import { camelize } from '../../../util/stringUtil.js';
|
|
@@ -17,7 +17,12 @@ const startStrMap = [
|
|
|
17
17
|
word: 'PRIMARY KEY',
|
|
18
18
|
fn: (str, table) => {
|
|
19
19
|
const tokens = getInParenValues(lexColumn(str));
|
|
20
|
-
return {
|
|
20
|
+
return {
|
|
21
|
+
...table,
|
|
22
|
+
primaryKey: tokens
|
|
23
|
+
.filter(it => it.kind === TokenKind.String)
|
|
24
|
+
.map(it => it.value),
|
|
25
|
+
};
|
|
21
26
|
},
|
|
22
27
|
},
|
|
23
28
|
{
|
|
@@ -27,7 +32,12 @@ const startStrMap = [
|
|
|
27
32
|
const inParen = getInParenValues(tokens);
|
|
28
33
|
return {
|
|
29
34
|
...table,
|
|
30
|
-
uniqueKeys: [
|
|
35
|
+
uniqueKeys: [
|
|
36
|
+
...table.uniqueKeys,
|
|
37
|
+
inParen
|
|
38
|
+
.filter(it => it.kind === TokenKind.String)
|
|
39
|
+
.map(it => it.value),
|
|
40
|
+
],
|
|
31
41
|
};
|
|
32
42
|
},
|
|
33
43
|
},
|
|
@@ -57,7 +67,9 @@ const startStrMap = [
|
|
|
57
67
|
const refIndex = tokens.findIndex(it => it.kind === TokenKind.Keyword && it.value === 'REFERENCES');
|
|
58
68
|
const targetTable = tokens[refIndex + 1].value;
|
|
59
69
|
const targetColumn = getInParenValues(tokens, refIndex)[0].value;
|
|
60
|
-
const isColumnUnique = table.uniqueKeys
|
|
70
|
+
const isColumnUnique = table.uniqueKeys
|
|
71
|
+
.filter(it => it.length === 1)
|
|
72
|
+
.find(it => it[0] === columnName);
|
|
61
73
|
const sameTableRefs = table.columns.filter(it => it.hasReference && it.reference.targetTable === targetTable);
|
|
62
74
|
const onUpdate = tokens.findIndex(it => it.kind === TokenKind.Keyword && it.value === 'ON UPDATE');
|
|
63
75
|
const onDelete = tokens.findIndex(it => it.kind === TokenKind.Keyword && it.value === 'ON DELETE');
|
|
@@ -66,13 +78,21 @@ const startStrMap = [
|
|
|
66
78
|
targetColumn,
|
|
67
79
|
columnName,
|
|
68
80
|
relation: isColumnUnique ? 'OneOrZero' : 'Many',
|
|
69
|
-
relationName: sameTableRefs.length !== 0
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
relationName: sameTableRefs.length !== 0
|
|
82
|
+
? targetTable + sameTableRefs.length
|
|
83
|
+
: undefined,
|
|
84
|
+
onUpdate: onUpdate !== -1
|
|
85
|
+
? tokens[onUpdate + 1].value
|
|
86
|
+
: undefined,
|
|
87
|
+
onDelete: onDelete !== -1
|
|
88
|
+
? tokens[onDelete + 1].value
|
|
89
|
+
: undefined,
|
|
72
90
|
};
|
|
73
91
|
return {
|
|
74
92
|
...table,
|
|
75
|
-
columns: table.columns.map(it => it.columnName === columnName
|
|
93
|
+
columns: table.columns.map(it => it.columnName === columnName
|
|
94
|
+
? { ...it, hasReference: true, reference }
|
|
95
|
+
: it),
|
|
76
96
|
};
|
|
77
97
|
},
|
|
78
98
|
},
|
|
@@ -80,7 +100,9 @@ const startStrMap = [
|
|
|
80
100
|
word: '`',
|
|
81
101
|
fn: (str, table) => {
|
|
82
102
|
const tokens = lexColumn(str);
|
|
83
|
-
const keywords = tokens
|
|
103
|
+
const keywords = tokens
|
|
104
|
+
.filter(it => it.kind === TokenKind.Keyword)
|
|
105
|
+
.map(it => it.value);
|
|
84
106
|
const getDefault = () => {
|
|
85
107
|
const index = tokens.findIndex(it => it.kind === TokenKind.Keyword && it.value === 'DEFAULT');
|
|
86
108
|
if (index === -1)
|
|
@@ -88,7 +110,8 @@ const startStrMap = [
|
|
|
88
110
|
const next = tokens[index + 1];
|
|
89
111
|
if (next.kind === TokenKind.String || next.kind === TokenKind.Number)
|
|
90
112
|
return next;
|
|
91
|
-
if (next.kind === TokenKind.Identifier &&
|
|
113
|
+
if (next.kind === TokenKind.Identifier &&
|
|
114
|
+
next.value === 'CURRENT_TIMESTAMP')
|
|
92
115
|
return next;
|
|
93
116
|
return undefined;
|
|
94
117
|
};
|
|
@@ -97,7 +120,8 @@ const startStrMap = [
|
|
|
97
120
|
const getDefaultValue = (defaultToken) => {
|
|
98
121
|
if (!defaultToken || defaultToken.kind === TokenKind.Identifier)
|
|
99
122
|
return undefined;
|
|
100
|
-
if (defaultToken.kind === TokenKind.Keyword &&
|
|
123
|
+
if (defaultToken.kind === TokenKind.Keyword &&
|
|
124
|
+
defaultToken.value === 'NULL')
|
|
101
125
|
return null;
|
|
102
126
|
if (columnTypeToTsType(type) === 'number')
|
|
103
127
|
return +defaultToken.value;
|
|
@@ -112,7 +136,11 @@ const startStrMap = [
|
|
|
112
136
|
notNull: keywords.includes('NOT NULL'),
|
|
113
137
|
default: getDefaultValue(defaultToken),
|
|
114
138
|
zerofill: keywords.includes('zerofill'),
|
|
115
|
-
signed: keywords.includes('unsigned')
|
|
139
|
+
signed: keywords.includes('unsigned')
|
|
140
|
+
? false
|
|
141
|
+
: keywords.includes('signed')
|
|
142
|
+
? true
|
|
143
|
+
: undefined,
|
|
116
144
|
autoIncrement: keywords.includes('AUTO_INCREMENT'),
|
|
117
145
|
length: inPrenValues.length > 0 ? +inPrenValues[0].value : undefined,
|
|
118
146
|
scale: inPrenValues.length > 1 ? +inPrenValues[1].value : undefined,
|
|
@@ -34,7 +34,9 @@ export class Lexer2 {
|
|
|
34
34
|
findOperator(current) {
|
|
35
35
|
const operator = (value) => ({ kind: TokenKind.Operator, value });
|
|
36
36
|
if (!current.hasNext) {
|
|
37
|
-
return this.operators.includes(current.value)
|
|
37
|
+
return this.operators.includes(current.value)
|
|
38
|
+
? operator(current.value)
|
|
39
|
+
: undefined;
|
|
38
40
|
}
|
|
39
41
|
let operators = this.operators.filter(it => it.startsWith(current.value));
|
|
40
42
|
let state = current.value;
|
|
@@ -46,7 +46,9 @@ const createKeywordRule = (keywords, ignoreCase = false) => {
|
|
|
46
46
|
terminator: ['whitespace', 'separator'],
|
|
47
47
|
fn: (start, next) => {
|
|
48
48
|
let str = ignoreCase ? start.toUpperCase() : start;
|
|
49
|
-
let words = keywords.map(it => typeof it === 'string'
|
|
49
|
+
let words = keywords.map(it => typeof it === 'string'
|
|
50
|
+
? { kind: TokenKind.Keyword, value: it }
|
|
51
|
+
: { ...it, value: it.value });
|
|
50
52
|
if (ignoreCase)
|
|
51
53
|
words = words.map(it => ({ ...it, value: it.value.toUpperCase() }));
|
|
52
54
|
let v;
|
|
@@ -12,7 +12,9 @@ export var Comparison;
|
|
|
12
12
|
Comparison["notLike"] = "NOT LIKE";
|
|
13
13
|
})(Comparison || (Comparison = {}));
|
|
14
14
|
export const comparisonExpressionToSql = (exp) => {
|
|
15
|
-
const type = Object.prototype.hasOwnProperty.call(exp, '__type')
|
|
15
|
+
const type = Object.prototype.hasOwnProperty.call(exp, '__type')
|
|
16
|
+
? exp.__type || 'AND'
|
|
17
|
+
: 'AND';
|
|
16
18
|
return Object.entries(exp)
|
|
17
19
|
.map(([key, value]) => {
|
|
18
20
|
const column = SqlString.escapeId(key);
|
|
@@ -24,7 +26,9 @@ export const comparisonExpressionToSql = (exp) => {
|
|
|
24
26
|
return `${column} IS NOT NULL`;
|
|
25
27
|
if (value[0] === 'IN') {
|
|
26
28
|
const [, ...columns] = value;
|
|
27
|
-
return `${column} IN (${[
|
|
29
|
+
return `${column} IN (${[
|
|
30
|
+
columns.map(column => SqlString.escape(column)).join(', '),
|
|
31
|
+
]})`;
|
|
28
32
|
}
|
|
29
33
|
if (value[0] === 'BETWEEN')
|
|
30
34
|
return `${column} BETWEEN ${SqlString.escape(value[1])} AND ${SqlString.escape(value[2])}`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { conditionExpressionToSql } from './conditionExpression.js';
|
|
1
|
+
import { conditionExpressionToSql, } from './conditionExpression.js';
|
|
2
2
|
export class CompositeCondition {
|
|
3
3
|
constructor(type, conditions) {
|
|
4
4
|
this.type = type;
|
|
@@ -11,6 +11,6 @@ export class CompositeCondition {
|
|
|
11
11
|
return new CompositeCondition('AND', conditions);
|
|
12
12
|
}
|
|
13
13
|
toSQL() {
|
|
14
|
-
return '(' + this.conditions.map(conditionExpressionToSql).join(this.type) + ')';
|
|
14
|
+
return ('(' + this.conditions.map(conditionExpressionToSql).join(this.type) + ')');
|
|
15
15
|
}
|
|
16
16
|
}
|
package/lib/db/sql/sqlCreater.js
CHANGED
|
@@ -5,8 +5,12 @@ export const SqlCreator = {
|
|
|
5
5
|
addUniqueKey: (tableName, columns) => `ALTER TABLE ${tableName} ADD UNIQUE ${columns.join('__')}(${columns.join(',')})`,
|
|
6
6
|
addPrimaryKey: (tableName, columns) => `ALTER TABLE ${tableName} ADD PRIMARY KEY ${columns.join('__')}(${columns.join(',')})`,
|
|
7
7
|
addForeignKey: (tableName, constraintName, reference) => {
|
|
8
|
-
const onUpdate = reference.onUpdate
|
|
9
|
-
|
|
8
|
+
const onUpdate = reference.onUpdate
|
|
9
|
+
? ' ON UPDATE ' + reference.onUpdate
|
|
10
|
+
: '';
|
|
11
|
+
const onDelete = reference.onDelete
|
|
12
|
+
? ' ON DELETE ' + reference.onDelete
|
|
13
|
+
: '';
|
|
10
14
|
return `ALTER TABLE ${tableName} ADD CONSTRAINT '${constraintName}' FOREIGN KEY (${reference.columnName}) REFERENCES ${reference.targetTable}(${reference.targetColumn})${onUpdate}${onDelete}`;
|
|
11
15
|
},
|
|
12
16
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DirectiveLocation } from "graphql";
|
|
2
|
+
declare type DirectiveArgs = {
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
default: any;
|
|
6
|
+
};
|
|
7
|
+
declare type Directive = {
|
|
8
|
+
types: DirectiveLocation[];
|
|
9
|
+
args: DirectiveArgs[];
|
|
10
|
+
name: string;
|
|
11
|
+
};
|
|
12
|
+
export declare const directiveToTypeDefs: (directive: Directive) => string;
|
|
13
|
+
export {};
|
|
@@ -5,7 +5,8 @@ export class ImportDeclaration {
|
|
|
5
5
|
this.module = module;
|
|
6
6
|
}
|
|
7
7
|
toString() {
|
|
8
|
-
const addJsExt = config().generator.addJsExtToImportStatement &&
|
|
8
|
+
const addJsExt = config().generator.addJsExtToImportStatement &&
|
|
9
|
+
this.module.startsWith('.');
|
|
9
10
|
return `import {${this.types.join(',')}} from "${addJsExt ? this.module + '.js' : this.module}";`;
|
|
10
11
|
}
|
|
11
12
|
}
|
|
@@ -37,6 +37,7 @@ export class Class extends ExportableDeclaration {
|
|
|
37
37
|
const implement = this._implements ? this._implements.toString() + ' ' : '';
|
|
38
38
|
const extend = this._extends ? this._extends.toString() + '' : '';
|
|
39
39
|
const modifier = this.isAbstract ? 'abstract ' : '';
|
|
40
|
-
return modifier +
|
|
40
|
+
return (modifier +
|
|
41
|
+
`class ${this.name} ${implement}${extend}{${properties}${methods}}`);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -12,6 +12,8 @@ export class EnumDeclaration extends ExportableDeclaration {
|
|
|
12
12
|
return this;
|
|
13
13
|
}
|
|
14
14
|
toTsString() {
|
|
15
|
-
return `enum ${this.identifier}{${this.members
|
|
15
|
+
return `enum ${this.identifier}{${this.members
|
|
16
|
+
.map(it => it.toString() + ',')
|
|
17
|
+
.join('')}}`;
|
|
16
18
|
}
|
|
17
19
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TsCode } from '../abstruct/tsCode.js';
|
|
2
2
|
import { ExpressionStatement } from './expressionStatement.js';
|
|
3
3
|
import { Parameter } from './parameter.js';
|
|
4
|
+
import { tsValueString } from "../../tsValueString.js";
|
|
4
5
|
export class TsExpression extends TsCode {
|
|
5
6
|
constructor() {
|
|
6
7
|
super(...arguments);
|
|
@@ -30,7 +31,8 @@ export class CallExpression extends TsExpression {
|
|
|
30
31
|
this.args = args;
|
|
31
32
|
}
|
|
32
33
|
toTsString() {
|
|
33
|
-
return this.identifier.toString() +
|
|
34
|
+
return (this.identifier.toString() +
|
|
35
|
+
`(${this.args.map(it => it.toString()).join(',')})`);
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
export class Literal extends TsExpression {
|
|
@@ -41,8 +43,9 @@ export class StringLiteral extends Literal {
|
|
|
41
43
|
this.value = value;
|
|
42
44
|
}
|
|
43
45
|
toTsString() {
|
|
44
|
-
return
|
|
46
|
+
return tsValueString(this.value);
|
|
45
47
|
}
|
|
48
|
+
;
|
|
46
49
|
}
|
|
47
50
|
export class NumericLiteral extends Literal {
|
|
48
51
|
constructor(value) {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { PropertySignature } from './propertySignature.js';
|
|
2
2
|
import { ExportableDeclaration } from '../abstruct/exportableDeclaration.js';
|
|
3
3
|
import { TsType } from './type/type.js';
|
|
4
|
+
import { ExtendsClause } from "./extendsClause";
|
|
4
5
|
export declare class TsInterface extends ExportableDeclaration {
|
|
5
6
|
private readonly name;
|
|
6
7
|
private properties;
|
|
8
|
+
private _extends?;
|
|
7
9
|
constructor(name: string);
|
|
8
10
|
addProperty(propertyName: string, type: TsType, isOptional?: boolean, isReadOnly?: boolean): this;
|
|
9
11
|
addProperties(properties: PropertySignature[]): this;
|
|
12
|
+
extends(value: ExtendsClause): this;
|
|
10
13
|
protected toTsString(): string;
|
|
11
14
|
}
|
|
@@ -15,7 +15,15 @@ export class TsInterface extends ExportableDeclaration {
|
|
|
15
15
|
this.mergeImport(...properties);
|
|
16
16
|
return this;
|
|
17
17
|
}
|
|
18
|
+
extends(value) {
|
|
19
|
+
this._extends = value;
|
|
20
|
+
this.mergeImport(value);
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
18
23
|
toTsString() {
|
|
19
|
-
|
|
24
|
+
const extend = this._extends ? this._extends.toString() + ' ' : '';
|
|
25
|
+
return `interface ${this.name} ${extend}{${this.properties
|
|
26
|
+
.map(it => it.toString())
|
|
27
|
+
.join(';')}}`;
|
|
20
28
|
}
|
|
21
29
|
}
|
|
@@ -23,7 +23,9 @@ export class PropertyDeclaration extends TsCode {
|
|
|
23
23
|
return this;
|
|
24
24
|
}
|
|
25
25
|
toTsString() {
|
|
26
|
-
const initializer = this._initializer
|
|
26
|
+
const initializer = this._initializer
|
|
27
|
+
? ` = ${this._initializer.toString()}`
|
|
28
|
+
: '';
|
|
27
29
|
return (this._modifiers.toString() +
|
|
28
30
|
`${this.propertyName}${TsUtil.questionToken(this.optional)}: ${this.type}` +
|
|
29
31
|
initializer +
|
|
@@ -16,10 +16,15 @@ export class TypeReference extends TsCode {
|
|
|
16
16
|
return new TypeReference('Partial', [this]);
|
|
17
17
|
}
|
|
18
18
|
pick(...properties) {
|
|
19
|
-
return new TypeReference('Pick', [
|
|
19
|
+
return new TypeReference('Pick', [
|
|
20
|
+
this,
|
|
21
|
+
new Identifier(properties.map(it => `'${it}'`).join('|')),
|
|
22
|
+
]);
|
|
20
23
|
}
|
|
21
24
|
toTsString() {
|
|
22
|
-
const typeArgs = this.typeArguments.length === 0
|
|
25
|
+
const typeArgs = this.typeArguments.length === 0
|
|
26
|
+
? ''
|
|
27
|
+
: `<${this.typeArguments.join(',')}>`;
|
|
23
28
|
return `${this.typeName}${typeArgs}`;
|
|
24
29
|
}
|
|
25
30
|
}
|
|
@@ -6,7 +6,10 @@ export class VariableDeclaration extends ExportableDeclaration {
|
|
|
6
6
|
this.flag = flag;
|
|
7
7
|
this.expression = expression;
|
|
8
8
|
this.type = type;
|
|
9
|
-
this.variableName =
|
|
9
|
+
this.variableName =
|
|
10
|
+
typeof variableName === 'string'
|
|
11
|
+
? new Identifier(variableName)
|
|
12
|
+
: variableName;
|
|
10
13
|
this.mergeImport(expression, this.variableName, type);
|
|
11
14
|
}
|
|
12
15
|
toTsString() {
|