@smartive/graphql-magic 16.3.6 → 16.3.8
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/.github/workflows/testing.yml +1 -1
- package/CHANGELOG.md +2 -2
- package/dist/bin/gqm.cjs +37 -35
- package/dist/cjs/index.cjs +51 -48
- package/dist/esm/api/execute.d.ts +1 -5
- package/dist/esm/api/execute.js.map +1 -1
- package/dist/esm/client/queries.d.ts +4 -4
- package/dist/esm/client/queries.js.map +1 -1
- package/dist/esm/db/generate.js +2 -0
- package/dist/esm/db/generate.js.map +1 -1
- package/dist/esm/migrations/generate.js +1 -1
- package/dist/esm/migrations/generate.js.map +1 -1
- package/dist/esm/models/models.d.ts +1 -1
- package/dist/esm/models/models.js.map +1 -1
- package/dist/esm/models/utils.d.ts +8 -12
- package/dist/esm/models/utils.js +3 -5
- package/dist/esm/models/utils.js.map +1 -1
- package/dist/esm/permissions/check.js +0 -15
- package/dist/esm/permissions/check.js.map +1 -1
- package/dist/esm/permissions/generate.d.ts +5 -19
- package/dist/esm/permissions/generate.js.map +1 -1
- package/dist/esm/resolvers/arguments.js.map +1 -1
- package/dist/esm/resolvers/filters.js +0 -2
- package/dist/esm/resolvers/filters.js.map +1 -1
- package/dist/esm/resolvers/mutations.js +5 -4
- package/dist/esm/resolvers/mutations.js.map +1 -1
- package/dist/esm/resolvers/node.js.map +1 -1
- package/dist/esm/resolvers/resolver.d.ts +2 -2
- package/dist/esm/resolvers/resolver.js +1 -1
- package/dist/esm/resolvers/resolver.js.map +1 -1
- package/dist/esm/resolvers/selects.js.map +1 -1
- package/dist/esm/resolvers/utils.d.ts +2 -6
- package/dist/esm/resolvers/utils.js +4 -2
- package/dist/esm/resolvers/utils.js.map +1 -1
- package/dist/esm/schema/utils.d.ts +4 -4
- package/dist/esm/schema/utils.js +31 -30
- package/dist/esm/schema/utils.js.map +1 -1
- package/dist/esm/utils/dates.d.ts +2 -4
- package/dist/esm/utils/dates.js +1 -3
- package/dist/esm/utils/dates.js.map +1 -1
- package/docs/docs/1-tutorial.md +1 -1
- package/docs/package-lock.json +1675 -893
- package/docs/package.json +4 -4
- package/eslint.config.mjs +42 -0
- package/migrations/20230912185644_setup.ts +3 -3
- package/package.json +8 -13
- package/src/api/execute.ts +1 -0
- package/src/bin/gqm/codegen.ts +1 -1
- package/src/client/gql.ts +1 -1
- package/src/client/mutations.ts +8 -8
- package/src/client/queries.ts +15 -14
- package/src/db/generate.ts +8 -5
- package/src/migrations/generate.ts +26 -22
- package/src/models/models.ts +24 -9
- package/src/models/mutation-hook.ts +1 -1
- package/src/models/utils.ts +8 -7
- package/src/permissions/check.ts +22 -30
- package/src/permissions/generate.ts +8 -25
- package/src/resolvers/arguments.ts +7 -2
- package/src/resolvers/filters.ts +8 -10
- package/src/resolvers/mutations.ts +19 -16
- package/src/resolvers/node.ts +3 -2
- package/src/resolvers/resolver.ts +11 -10
- package/src/resolvers/selects.ts +4 -3
- package/src/resolvers/utils.ts +15 -10
- package/src/schema/generate.ts +11 -11
- package/src/schema/utils.ts +84 -82
- package/src/utils/dates.ts +3 -3
- package/tests/generated/api/index.ts +2 -2
- package/tests/generated/client/index.ts +1 -193
- package/tests/generated/db/index.ts +4 -4
- package/tests/generated/models.json +2 -1
- package/tests/generated/schema.graphql +1 -1
- package/tests/utils/graphql-client.ts +49 -0
- package/tests/utils/models.ts +1 -0
- package/tests/utils/server.ts +4 -5
- package/tsconfig.eslint.json +18 -3
- package/tsconfig.json +11 -2
- package/.eslintrc +0 -13
package/docs/package.json
CHANGED
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
"@mdx-js/react": "^3.0.0",
|
|
21
21
|
"clsx": "^2.0.0",
|
|
22
22
|
"prism-react-renderer": "^2.3.0",
|
|
23
|
-
"react": "^
|
|
24
|
-
"react-dom": "^
|
|
23
|
+
"react": "^19.0.0",
|
|
24
|
+
"react-dom": "^19.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@docusaurus/module-type-aliases": "3.7.0",
|
|
28
28
|
"@docusaurus/tsconfig": "3.7.0",
|
|
29
29
|
"@docusaurus/types": "3.7.0",
|
|
30
|
-
"typescript": "5.
|
|
30
|
+
"typescript": "5.7.3"
|
|
31
31
|
},
|
|
32
32
|
"browserslist": {
|
|
33
33
|
"production": [
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
|
-
"node": ">=
|
|
45
|
+
"node": ">=22.0"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { config } from "@smartive/eslint-config";
|
|
2
|
+
import tsParser from "@typescript-eslint/parser";
|
|
3
|
+
|
|
4
|
+
export default [
|
|
5
|
+
...config('typescript'),
|
|
6
|
+
{
|
|
7
|
+
files: ['src/**/*.ts'],
|
|
8
|
+
languageOptions: {
|
|
9
|
+
parser: tsParser,
|
|
10
|
+
ecmaVersion: 5,
|
|
11
|
+
sourceType: "script",
|
|
12
|
+
|
|
13
|
+
parserOptions: {
|
|
14
|
+
project: "./tsconfig.eslint.json",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
rules: {
|
|
19
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
20
|
+
"@typescript-eslint/no-floating-promises": ["error"],
|
|
21
|
+
"no-constant-binary-expression": "error",
|
|
22
|
+
|
|
23
|
+
"no-console": ["error", {
|
|
24
|
+
allow: ["info", "warn", "error", "trace", "time", "timeEnd"],
|
|
25
|
+
}],
|
|
26
|
+
|
|
27
|
+
// Disable rules causing the most errors
|
|
28
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
29
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
30
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
31
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
32
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
33
|
+
"@typescript-eslint/prefer-nullish-coalescing": "off",
|
|
34
|
+
"@typescript-eslint/restrict-template-expressions": "off",
|
|
35
|
+
"@typescript-eslint/no-base-to-string": "off",
|
|
36
|
+
"@typescript-eslint/no-misused-promises": "off",
|
|
37
|
+
"@typescript-eslint/require-await": "off",
|
|
38
|
+
"@typescript-eslint/no-unsafe-function-type": "off",
|
|
39
|
+
"eqeqeq": "off",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
];
|
|
@@ -10,11 +10,11 @@ export const up = async (knex: Knex) => {
|
|
|
10
10
|
await knex.schema.createTable('User', (table) => {
|
|
11
11
|
table.uuid('id').notNullable().primary();
|
|
12
12
|
table.string('username', undefined).nullable();
|
|
13
|
-
table.enum('role', null
|
|
13
|
+
table.enum('role', null, {
|
|
14
14
|
useNative: true,
|
|
15
15
|
existingType: true,
|
|
16
16
|
enumName: 'role',
|
|
17
|
-
}).
|
|
17
|
+
}).notNullable();
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
await knex.schema.createTable('AnotherObject', (table) => {
|
|
@@ -61,7 +61,7 @@ export const up = async (knex: Knex) => {
|
|
|
61
61
|
|
|
62
62
|
await knex.schema.createTable('Reaction', (table) => {
|
|
63
63
|
table.uuid('id').notNullable().primary();
|
|
64
|
-
table.enum('type', null
|
|
64
|
+
table.enum('type', null, {
|
|
65
65
|
useNative: true,
|
|
66
66
|
existingType: true,
|
|
67
67
|
enumName: 'reactionType',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartive/graphql-magic",
|
|
3
|
-
"version": "16.3.
|
|
3
|
+
"version": "16.3.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"generate:index-files": "cti create ./src --excludes bin --withoutbackup",
|
|
18
18
|
"generate:gqm-stuff": "npx gqm generate",
|
|
19
19
|
"generate:setup-migration": "npm run build:bin && npx gqm generate-migration setup 20230912185644",
|
|
20
|
-
"lint": "eslint src",
|
|
20
|
+
"lint": "eslint src/**/*.ts",
|
|
21
21
|
"lint:fix": "eslint src --fix",
|
|
22
22
|
"deps": "docker compose up",
|
|
23
23
|
"test": "npm run lint && npm run test:all && npm run build",
|
|
@@ -34,10 +34,6 @@
|
|
|
34
34
|
"bin": {
|
|
35
35
|
"gqm": "dist/bin/gqm.cjs"
|
|
36
36
|
},
|
|
37
|
-
"overrides": {
|
|
38
|
-
"graphql": "$graphql",
|
|
39
|
-
"rollup": "3.29.5"
|
|
40
|
-
},
|
|
41
37
|
"browserslist": "> 0.25%, not dead",
|
|
42
38
|
"publishConfig": {
|
|
43
39
|
"access": "public"
|
|
@@ -47,14 +43,14 @@
|
|
|
47
43
|
"@graphql-codegen/add": "^5.0.0",
|
|
48
44
|
"@graphql-codegen/cli": "^5.0.0",
|
|
49
45
|
"@graphql-codegen/typescript": "^4.0.1",
|
|
50
|
-
"@graphql-codegen/typescript-compatibility": "^2.1.5",
|
|
51
46
|
"@graphql-codegen/typescript-operations": "^4.0.1",
|
|
52
47
|
"@graphql-codegen/typescript-resolvers": "^4.0.1",
|
|
48
|
+
"@types/node": "^22.13.5",
|
|
53
49
|
"code-block-writer": "^13.0.0",
|
|
54
50
|
"commander": "^13.0.0",
|
|
55
51
|
"dayjs": "^1.11.10",
|
|
56
52
|
"dotenv": "^16.3.1",
|
|
57
|
-
"graphql": "^
|
|
53
|
+
"graphql": "^16.0.0",
|
|
58
54
|
"inflection": "^3.0.0",
|
|
59
55
|
"knex": "^3.0.1",
|
|
60
56
|
"knex-schema-inspector": "^3.1.0",
|
|
@@ -69,7 +65,7 @@
|
|
|
69
65
|
"knex": "^3.0.1"
|
|
70
66
|
},
|
|
71
67
|
"devDependencies": {
|
|
72
|
-
"@smartive/eslint-config": "
|
|
68
|
+
"@smartive/eslint-config": "6.5.0",
|
|
73
69
|
"@smartive/prettier-config": "3.1.2",
|
|
74
70
|
"@types/jest": "29.5.14",
|
|
75
71
|
"@types/lodash": "4.17.15",
|
|
@@ -79,13 +75,12 @@
|
|
|
79
75
|
"create-ts-index": "1.14.0",
|
|
80
76
|
"del-cli": "6.0.0",
|
|
81
77
|
"esbuild": "0.25.0",
|
|
82
|
-
"eslint": "
|
|
83
|
-
"graphql-request": "6.1.0",
|
|
78
|
+
"eslint": "9.21.0",
|
|
84
79
|
"jest": "29.7.0",
|
|
85
80
|
"mock-knex": "0.4.13",
|
|
86
|
-
"prettier": "
|
|
81
|
+
"prettier": "3.5.2",
|
|
87
82
|
"ts-jest": "29.2.6",
|
|
88
83
|
"ts-node": "10.9.2",
|
|
89
|
-
"typescript": "5.
|
|
84
|
+
"typescript": "5.7.3"
|
|
90
85
|
}
|
|
91
86
|
}
|
package/src/api/execute.ts
CHANGED
package/src/bin/gqm/codegen.ts
CHANGED
|
@@ -30,7 +30,7 @@ export const generateGraphqlClientTypes = async () => {
|
|
|
30
30
|
documents: [graphqlQueriesPath, `${generatedFolderPath}/client/mutations.ts`],
|
|
31
31
|
generates: {
|
|
32
32
|
[`${generatedFolderPath}/client/index.ts`]: {
|
|
33
|
-
plugins: ['typescript', 'typescript-operations'
|
|
33
|
+
plugins: ['typescript', 'typescript-operations'],
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
config: {
|
package/src/client/gql.ts
CHANGED
package/src/client/mutations.ts
CHANGED
|
@@ -10,30 +10,30 @@ export const generateMutations = (models: Models, gqmModule = '@smartive/graphql
|
|
|
10
10
|
if (creatable) {
|
|
11
11
|
parts.push(
|
|
12
12
|
`export const CREATE_${constantCase(
|
|
13
|
-
name
|
|
14
|
-
)} = gql\`\n mutation Create${name}Mutation($data: Create${name}!) {\n create${name}(data: $data) { id }\n }\n
|
|
13
|
+
name,
|
|
14
|
+
)} = gql\`\n mutation Create${name}Mutation($data: Create${name}!) {\n create${name}(data: $data) { id }\n }\n\`;`,
|
|
15
15
|
);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
if (updatable) {
|
|
19
19
|
parts.push(
|
|
20
20
|
`export const UPDATE_${constantCase(
|
|
21
|
-
name
|
|
22
|
-
)} = gql\`\n mutation Update${name}Mutation($id: ID!, $data: Update${name}!) {\n update${name}(where: { id: $id }, data: $data) { id }\n }\n
|
|
21
|
+
name,
|
|
22
|
+
)} = gql\`\n mutation Update${name}Mutation($id: ID!, $data: Update${name}!) {\n update${name}(where: { id: $id }, data: $data) { id }\n }\n\`;`,
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
if (deletable) {
|
|
27
27
|
parts.push(
|
|
28
28
|
`export const DELETE_${constantCase(
|
|
29
|
-
name
|
|
30
|
-
)} = gql\`\n mutation Delete${name}Mutation($id: ID!) {\n delete${name}(where: { id: $id })\n }\n
|
|
29
|
+
name,
|
|
30
|
+
)} = gql\`\n mutation Delete${name}Mutation($id: ID!) {\n delete${name}(where: { id: $id })\n }\n\`;`,
|
|
31
31
|
);
|
|
32
32
|
|
|
33
33
|
parts.push(
|
|
34
34
|
`export const RESTORE_${constantCase(
|
|
35
|
-
name
|
|
36
|
-
)} = gql\`\n mutation Restore${name}Mutation($id: ID!) {\n restore${name}(where: { id: $id })\n }\n
|
|
35
|
+
name,
|
|
36
|
+
)} = gql\`\n mutation Restore${name}Mutation($id: ID!) {\n restore${name}(where: { id: $id })\n }\n\`;`,
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/client/queries.ts
CHANGED
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
export const getUpdateEntityQuery = (
|
|
16
16
|
model: EntityModel,
|
|
17
17
|
role: string,
|
|
18
|
-
fields?: string[]
|
|
19
|
-
additionalFields = ''
|
|
18
|
+
fields?: string[],
|
|
19
|
+
additionalFields = '',
|
|
20
20
|
) => `query Update${model.name}Fields ($id: ID!) {
|
|
21
21
|
data: ${typeToField(model.name)}(where: { id: $id }) {
|
|
22
22
|
id
|
|
@@ -39,6 +39,7 @@ export const fieldIsSearchable = (model: EntityModel, fieldName: string) => {
|
|
|
39
39
|
const relation = model.getRelation(fieldName);
|
|
40
40
|
const targetModel = relation.targetModel;
|
|
41
41
|
const displayField = targetModel.getField(targetModel.displayField || 'id');
|
|
42
|
+
|
|
42
43
|
return displayField.searchable;
|
|
43
44
|
};
|
|
44
45
|
|
|
@@ -52,7 +53,7 @@ export const getSelectEntityRelationsQuery = (model: EntityModel, relationNames:
|
|
|
52
53
|
(relation) =>
|
|
53
54
|
`$${relation.name}Where: ${relation.targetModel.name}Where, $${relation.name}Limit: Int${
|
|
54
55
|
fieldIsSearchable(model, relation.name) ? `, $${relation.name}Search: String` : ''
|
|
55
|
-
}
|
|
56
|
+
}`,
|
|
56
57
|
)
|
|
57
58
|
.join(', ')}) {
|
|
58
59
|
${relations
|
|
@@ -85,7 +86,7 @@ export const getSelectEntityRelationsQuery = (model: EntityModel, relationNames:
|
|
|
85
86
|
export const getManyToManyRelationsQuery = (
|
|
86
87
|
model: Model,
|
|
87
88
|
action: 'create' | 'update',
|
|
88
|
-
manyToManyRelations: ManyToManyRelation[]
|
|
89
|
+
manyToManyRelations: ManyToManyRelation[],
|
|
89
90
|
) =>
|
|
90
91
|
!!manyToManyRelations.length &&
|
|
91
92
|
(action === 'update'
|
|
@@ -138,14 +139,14 @@ export const getMutationQuery = (model: Model, action: 'create' | 'update' | 'de
|
|
|
138
139
|
}
|
|
139
140
|
`
|
|
140
141
|
: action === 'update'
|
|
141
|
-
|
|
142
|
+
? `
|
|
142
143
|
mutation Update${model.name} ($id: ID!, $data: Update${model.name}!) {
|
|
143
144
|
mutated: update${model.name}(where: { id: $id } data: $data) {
|
|
144
145
|
id
|
|
145
146
|
}
|
|
146
147
|
}
|
|
147
148
|
`
|
|
148
|
-
|
|
149
|
+
: `
|
|
149
150
|
mutation Delete${model.name} ($id: ID!) {
|
|
150
151
|
mutated: delete${model.name}(where: { id: $id }) {
|
|
151
152
|
id
|
|
@@ -162,7 +163,7 @@ export const getEntityListQuery = (
|
|
|
162
163
|
role: string,
|
|
163
164
|
relations?: string[],
|
|
164
165
|
fragment = '',
|
|
165
|
-
reverseRelation?: ReverseRelation
|
|
166
|
+
reverseRelation?: ReverseRelation,
|
|
166
167
|
) => `query ${model.plural}List(
|
|
167
168
|
${reverseRelation ? '$id: ID!,' : ''}
|
|
168
169
|
$limit: Int!,
|
|
@@ -171,14 +172,14 @@ export const getEntityListQuery = (
|
|
|
171
172
|
) {
|
|
172
173
|
${reverseRelation ? `root: ${typeToField(reverseRelation.sourceModel.name)}(where: { id: $id }) {` : ''}
|
|
173
174
|
data: ${reverseRelation ? reverseRelation.name : model.pluralField}(limit: $limit, where: $where, ${
|
|
174
|
-
|
|
175
|
-
}) {
|
|
175
|
+
model.fields.some(({ searchable }) => searchable) ? ', search: $search' : ''
|
|
176
|
+
}) {
|
|
176
177
|
${displayField(model)}
|
|
177
178
|
${model.fields.filter(and(isSimpleField, isQueriableBy(role))).map(({ name }) => name)}
|
|
178
179
|
${fragment}
|
|
179
180
|
${queryRelations(
|
|
180
181
|
model.models,
|
|
181
|
-
model.relations.filter((relation) => !relations || relations.includes(relation.name))
|
|
182
|
+
model.relations.filter((relation) => !relations || relations.includes(relation.name)),
|
|
182
183
|
)}
|
|
183
184
|
${fragment}
|
|
184
185
|
}
|
|
@@ -193,14 +194,14 @@ export const getEntityQuery = (model: EntityModel, role: string, relations?: str
|
|
|
193
194
|
${model.fields.filter(and(isSimpleField, isQueriableBy(role))).map(({ name }) => name)}
|
|
194
195
|
${queryRelations(
|
|
195
196
|
model.models,
|
|
196
|
-
model.relations.filter((relation) => !relations || relations.includes(relation.name))
|
|
197
|
+
model.relations.filter((relation) => !relations || relations.includes(relation.name)),
|
|
197
198
|
)}
|
|
198
199
|
${queryRelations(
|
|
199
200
|
model.models,
|
|
200
201
|
model.reverseRelations.filter(
|
|
201
202
|
(reverseRelation) =>
|
|
202
|
-
isToOneRelation(reverseRelation.field) && (!relations || relations.includes(reverseRelation.name))
|
|
203
|
-
)
|
|
203
|
+
isToOneRelation(reverseRelation.field) && (!relations || relations.includes(reverseRelation.name)),
|
|
204
|
+
),
|
|
204
205
|
)}
|
|
205
206
|
${fragment}
|
|
206
207
|
}
|
|
@@ -220,6 +221,6 @@ export const queryRelations = (models: Models, relations: Relation[]) =>
|
|
|
220
221
|
(relation): string => `${relation.name} {
|
|
221
222
|
id
|
|
222
223
|
${displayField(relation.targetModel)}
|
|
223
|
-
}
|
|
224
|
+
}`,
|
|
224
225
|
)
|
|
225
226
|
.join('\n');
|
package/src/db/generate.ts
CHANGED
|
@@ -15,6 +15,7 @@ const PRIMITIVE_TYPES = {
|
|
|
15
15
|
const OPTIONAL_SEED_FIELDS = ['createdAt', 'createdById', 'updatedAt', 'updatedById', 'deletedAt', 'deletedById'];
|
|
16
16
|
|
|
17
17
|
export const generateDBModels = (models: Models, dateLibrary: DateLibrary) => {
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
18
19
|
const writer: CodeBlockWriter = new CodeBlockWriter['default']({
|
|
19
20
|
useSingleQuote: true,
|
|
20
21
|
indentNumberOfSpaces: 2,
|
|
@@ -52,8 +53,8 @@ export const generateDBModels = (models: Models, dateLibrary: DateLibrary) => {
|
|
|
52
53
|
`'${getColumnName(field)}'${field.nonNull && field.defaultValue === undefined ? '' : '?'}: ${getFieldType(
|
|
53
54
|
field,
|
|
54
55
|
dateLibrary,
|
|
55
|
-
true
|
|
56
|
-
)}${field.list ? ' | string' : ''}${field.nonNull ? '' : ' | null'}
|
|
56
|
+
true,
|
|
57
|
+
)}${field.list ? ' | string' : ''}${field.nonNull ? '' : ' | null'};`,
|
|
57
58
|
)
|
|
58
59
|
.newLine();
|
|
59
60
|
}
|
|
@@ -68,7 +69,7 @@ export const generateDBModels = (models: Models, dateLibrary: DateLibrary) => {
|
|
|
68
69
|
.write(
|
|
69
70
|
`'${getColumnName(field)}'?: ${getFieldType(field, dateLibrary, true)}${field.list ? ' | string' : ''}${
|
|
70
71
|
field.nonNull ? '' : ' | null'
|
|
71
|
-
}
|
|
72
|
+
};`,
|
|
72
73
|
)
|
|
73
74
|
.newLine();
|
|
74
75
|
}
|
|
@@ -90,7 +91,7 @@ export const generateDBModels = (models: Models, dateLibrary: DateLibrary) => {
|
|
|
90
91
|
field.nonNull && field.defaultValue === undefined && !OPTIONAL_SEED_FIELDS.includes(fieldName) ? '' : '?'
|
|
91
92
|
}: ${field.kind === 'enum' ? (field.list ? 'string[]' : 'string') : getFieldType(field, dateLibrary, true)}${
|
|
92
93
|
field.list ? ' | string' : ''
|
|
93
|
-
}${field.nonNull ? '' : ' | null'}
|
|
94
|
+
}${field.nonNull ? '' : ' | null'};`,
|
|
94
95
|
)
|
|
95
96
|
.newLine();
|
|
96
97
|
}
|
|
@@ -126,6 +127,7 @@ const getFieldType = (field: EntityField, dateLibrary: DateLibrary, input?: bool
|
|
|
126
127
|
if (field.type === 'DateTime') {
|
|
127
128
|
return (input ? `(${DATE_CLASS[dateLibrary]} | string)` : DATE_CLASS[dateLibrary]) + (field.list ? '[]' : '');
|
|
128
129
|
}
|
|
130
|
+
|
|
129
131
|
return get(PRIMITIVE_TYPES, field.type) + (field.list ? '[]' : '');
|
|
130
132
|
default: {
|
|
131
133
|
const exhaustiveCheck: never = kind;
|
|
@@ -135,6 +137,7 @@ const getFieldType = (field: EntityField, dateLibrary: DateLibrary, input?: bool
|
|
|
135
137
|
};
|
|
136
138
|
|
|
137
139
|
export const generateKnexTables = (models: Models) => {
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
138
141
|
const writer: CodeBlockWriter = new CodeBlockWriter['default']({
|
|
139
142
|
useSingleQuote: true,
|
|
140
143
|
indentNumberOfSpaces: 2,
|
|
@@ -145,7 +148,7 @@ export const generateKnexTables = (models: Models) => {
|
|
|
145
148
|
.write(
|
|
146
149
|
`import { ${models.entities
|
|
147
150
|
.map((model) => `${model.name}, ${model.name}Initializer, ${model.name}Mutator`)
|
|
148
|
-
.join(', ')} } from '.'
|
|
151
|
+
.join(', ')} } from '.';`,
|
|
149
152
|
)
|
|
150
153
|
.blankLine();
|
|
151
154
|
|
|
@@ -22,6 +22,7 @@ import { Value } from '../values';
|
|
|
22
22
|
type Callbacks = (() => void)[];
|
|
23
23
|
|
|
24
24
|
export class MigrationGenerator {
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
25
26
|
private writer: CodeBlockWriter = new CodeBlockWriter['default']({
|
|
26
27
|
useSingleQuote: true,
|
|
27
28
|
indentNumberOfSpaces: 2,
|
|
@@ -31,7 +32,10 @@ export class MigrationGenerator {
|
|
|
31
32
|
private uuidUsed?: boolean;
|
|
32
33
|
private nowUsed?: boolean;
|
|
33
34
|
|
|
34
|
-
constructor(
|
|
35
|
+
constructor(
|
|
36
|
+
knex: Knex,
|
|
37
|
+
private models: Models,
|
|
38
|
+
) {
|
|
35
39
|
this.schema = SchemaInspector(knex);
|
|
36
40
|
}
|
|
37
41
|
|
|
@@ -49,7 +53,7 @@ export class MigrationGenerator {
|
|
|
49
53
|
this.createEnums(
|
|
50
54
|
this.models.enums.filter((enm) => !enums.includes(lowerFirst(enm.name))),
|
|
51
55
|
up,
|
|
52
|
-
down
|
|
56
|
+
down,
|
|
53
57
|
);
|
|
54
58
|
|
|
55
59
|
for (const model of models.entities) {
|
|
@@ -81,10 +85,10 @@ export class MigrationGenerator {
|
|
|
81
85
|
if (model.oldName) {
|
|
82
86
|
// Rename table
|
|
83
87
|
up.push(() => {
|
|
84
|
-
this.renameTable(model.oldName
|
|
88
|
+
this.renameTable(model.oldName!, model.name);
|
|
85
89
|
});
|
|
86
90
|
down.push(() => {
|
|
87
|
-
this.renameTable(model.name, model.oldName);
|
|
91
|
+
this.renameTable(model.name, model.oldName!);
|
|
88
92
|
});
|
|
89
93
|
tables[tables.indexOf(model.oldName)] = model.name;
|
|
90
94
|
this.columns[model.name] = this.columns[model.oldName];
|
|
@@ -137,7 +141,7 @@ export class MigrationGenerator {
|
|
|
137
141
|
model,
|
|
138
142
|
model.fields.filter(not(isInherited)).filter(({ oldName }) => oldName),
|
|
139
143
|
up,
|
|
140
|
-
down
|
|
144
|
+
down,
|
|
141
145
|
);
|
|
142
146
|
|
|
143
147
|
// Add missing fields
|
|
@@ -148,10 +152,10 @@ export class MigrationGenerator {
|
|
|
148
152
|
.filter(
|
|
149
153
|
({ name, ...field }) =>
|
|
150
154
|
field.kind !== 'custom' &&
|
|
151
|
-
!this.getColumn(model.name, field.kind === 'relation' ? field.foreignKey || `${name}Id` : name)
|
|
155
|
+
!this.getColumn(model.name, field.kind === 'relation' ? field.foreignKey || `${name}Id` : name),
|
|
152
156
|
),
|
|
153
157
|
up,
|
|
154
|
-
down
|
|
158
|
+
down,
|
|
155
159
|
);
|
|
156
160
|
|
|
157
161
|
// Update fields
|
|
@@ -160,6 +164,7 @@ export class MigrationGenerator {
|
|
|
160
164
|
if (!col) {
|
|
161
165
|
return false;
|
|
162
166
|
}
|
|
167
|
+
|
|
163
168
|
return !nonNull && !col.is_nullable;
|
|
164
169
|
});
|
|
165
170
|
this.updateFields(model, existingFields, up, down);
|
|
@@ -215,7 +220,7 @@ export class MigrationGenerator {
|
|
|
215
220
|
.filter(
|
|
216
221
|
({ name, ...field }) =>
|
|
217
222
|
field.kind !== 'custom' &&
|
|
218
|
-
!this.getColumn(revisionTable, field.kind === 'relation' ? field.foreignKey || `${name}Id` : name)
|
|
223
|
+
!this.getColumn(revisionTable, field.kind === 'relation' ? field.foreignKey || `${name}Id` : name),
|
|
219
224
|
);
|
|
220
225
|
|
|
221
226
|
this.createRevisionFields(model, missingRevisionFields, up, down);
|
|
@@ -226,7 +231,7 @@ export class MigrationGenerator {
|
|
|
226
231
|
field.kind !== 'custom' &&
|
|
227
232
|
!updatable &&
|
|
228
233
|
!(field.kind === 'relation' && field.foreignKey === 'id') &&
|
|
229
|
-
this.getColumn(revisionTable, field.kind === 'relation' ? field.foreignKey || `${name}Id` : name)
|
|
234
|
+
this.getColumn(revisionTable, field.kind === 'relation' ? field.foreignKey || `${name}Id` : name),
|
|
230
235
|
);
|
|
231
236
|
this.createRevisionFields(model, revisionFieldsToRemove, down, up);
|
|
232
237
|
}
|
|
@@ -267,7 +272,7 @@ export class MigrationGenerator {
|
|
|
267
272
|
model,
|
|
268
273
|
model.fields.filter(isUpdatableField).filter(({ deleted }) => deleted),
|
|
269
274
|
down,
|
|
270
|
-
up
|
|
275
|
+
up,
|
|
271
276
|
);
|
|
272
277
|
}
|
|
273
278
|
}
|
|
@@ -276,7 +281,7 @@ export class MigrationGenerator {
|
|
|
276
281
|
this.createEnums(
|
|
277
282
|
this.models.enums.filter((enm) => enm.deleted),
|
|
278
283
|
down,
|
|
279
|
-
up
|
|
284
|
+
up,
|
|
280
285
|
);
|
|
281
286
|
|
|
282
287
|
writer.writeLine(`import { Knex } from 'knex';`);
|
|
@@ -308,7 +313,7 @@ export class MigrationGenerator {
|
|
|
308
313
|
this.alterTable(model.name, () => {
|
|
309
314
|
this.renameColumn(
|
|
310
315
|
field.kind === 'relation' ? `${field.oldName}Id` : get(field, 'oldName'),
|
|
311
|
-
field.kind === 'relation' ? `${field.name}Id` : field.name
|
|
316
|
+
field.kind === 'relation' ? `${field.name}Id` : field.name,
|
|
312
317
|
);
|
|
313
318
|
});
|
|
314
319
|
}
|
|
@@ -319,15 +324,14 @@ export class MigrationGenerator {
|
|
|
319
324
|
this.alterTable(model.name, () => {
|
|
320
325
|
this.renameColumn(
|
|
321
326
|
field.kind === 'relation' ? `${field.name}Id` : field.name,
|
|
322
|
-
field.kind === 'relation' ? `${field.oldName}Id` : get(field, 'oldName')
|
|
327
|
+
field.kind === 'relation' ? `${field.oldName}Id` : get(field, 'oldName'),
|
|
323
328
|
);
|
|
324
329
|
});
|
|
325
330
|
}
|
|
326
331
|
});
|
|
327
332
|
|
|
328
333
|
for (const field of fields) {
|
|
329
|
-
|
|
330
|
-
summonByName(this.columns[model.name]!, field.kind === 'relation' ? `${field.oldName!}Id` : field.oldName!).name =
|
|
334
|
+
summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.oldName!}Id` : field.oldName!).name =
|
|
331
335
|
field.kind === 'relation' ? `${field.name}Id` : field.name;
|
|
332
336
|
}
|
|
333
337
|
}
|
|
@@ -400,7 +404,7 @@ export class MigrationGenerator {
|
|
|
400
404
|
this.column(
|
|
401
405
|
field,
|
|
402
406
|
{ alter: true },
|
|
403
|
-
summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.name}Id` : field.name)
|
|
407
|
+
summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.name}Id` : field.name),
|
|
404
408
|
);
|
|
405
409
|
}
|
|
406
410
|
});
|
|
@@ -426,7 +430,7 @@ export class MigrationGenerator {
|
|
|
426
430
|
this.column(
|
|
427
431
|
field,
|
|
428
432
|
{ alter: true },
|
|
429
|
-
summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.name}Id` : field.name)
|
|
433
|
+
summonByName(this.columns[model.name], field.kind === 'relation' ? `${field.name}Id` : field.name),
|
|
430
434
|
);
|
|
431
435
|
}
|
|
432
436
|
});
|
|
@@ -476,7 +480,7 @@ export class MigrationGenerator {
|
|
|
476
480
|
.write(
|
|
477
481
|
`${col}: knex.raw('(select "${col}" from "${model.name}" where "${model.name}".id = "${
|
|
478
482
|
model.name
|
|
479
|
-
}Revision"."${typeToField(model.name)}Id")')
|
|
483
|
+
}Revision"."${typeToField(model.name)}Id")'),`,
|
|
480
484
|
)
|
|
481
485
|
.newLine();
|
|
482
486
|
}
|
|
@@ -511,9 +515,9 @@ export class MigrationGenerator {
|
|
|
511
515
|
up.push(() =>
|
|
512
516
|
this.writer
|
|
513
517
|
.writeLine(
|
|
514
|
-
`await knex.raw(\`CREATE TYPE "${name}" AS ENUM (${enm.values.map((value) => `'${value}'`).join(',')})\`)
|
|
518
|
+
`await knex.raw(\`CREATE TYPE "${name}" AS ENUM (${enm.values.map((value) => `'${value}'`).join(',')})\`);`,
|
|
515
519
|
)
|
|
516
|
-
.newLine()
|
|
520
|
+
.newLine(),
|
|
517
521
|
);
|
|
518
522
|
down.push(() => this.writer.writeLine(`await knex.raw('DROP TYPE "${name}"');`));
|
|
519
523
|
}
|
|
@@ -575,7 +579,7 @@ export class MigrationGenerator {
|
|
|
575
579
|
private column(
|
|
576
580
|
{ name, primary, list, ...field }: EntityField,
|
|
577
581
|
{ setUnique = true, setNonNull = true, alter = false, foreign = true, setDefault = true } = {},
|
|
578
|
-
toColumn?: Column
|
|
582
|
+
toColumn?: Column,
|
|
579
583
|
) {
|
|
580
584
|
const col = (what?: string) => {
|
|
581
585
|
if (what) {
|
|
@@ -648,7 +652,7 @@ export class MigrationGenerator {
|
|
|
648
652
|
col(`table.uuid('${field.foreignKey}')`);
|
|
649
653
|
if (foreign && !alter) {
|
|
650
654
|
this.writer.writeLine(
|
|
651
|
-
`table.foreign('${field.foreignKey}').references('id').inTable('${field.type}').onDelete('CASCADE')
|
|
655
|
+
`table.foreign('${field.foreignKey}').references('id').inTable('${field.type}').onDelete('CASCADE');`,
|
|
652
656
|
);
|
|
653
657
|
}
|
|
654
658
|
break;
|