@smartive/graphql-magic 2.1.0 → 3.0.0
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/release.yml +1 -1
- package/.github/workflows/testing.yml +3 -2
- package/.nvmrc +1 -1
- package/CHANGELOG.md +1 -6
- package/dist/cjs/index.cjs +53 -15
- package/dist/esm/db/generate.js +45 -8
- package/dist/esm/db/generate.js.map +1 -1
- package/dist/esm/migrations/generate.js.map +1 -1
- package/dist/esm/permissions/check.js.map +1 -1
- package/dist/esm/permissions/generate.js.map +1 -1
- package/dist/esm/resolvers/filters.js.map +1 -1
- package/dist/esm/resolvers/mutations.js +7 -6
- package/dist/esm/resolvers/mutations.js.map +1 -1
- package/dist/esm/resolvers/node.js.map +1 -1
- package/dist/esm/resolvers/resolver.js.map +1 -1
- package/dist/esm/resolvers/utils.js.map +1 -1
- package/docker-compose.yml +17 -0
- package/package.json +15 -9
- package/src/db/generate.ts +63 -17
- package/src/migrations/generate.ts +9 -9
- package/src/permissions/check.ts +1 -1
- package/src/permissions/generate.ts +7 -7
- package/src/resolvers/filters.ts +3 -3
- package/src/resolvers/mutations.ts +17 -14
- package/src/resolvers/node.ts +1 -1
- package/src/resolvers/resolver.ts +2 -2
- package/src/resolvers/utils.ts +2 -2
- package/tests/api/__snapshots__/query.spec.ts.snap +22 -0
- package/tests/api/query.spec.ts +28 -0
- package/tests/unit/__snapshots__/generate.spec.ts.snap +6 -0
- package/tests/unit/generate.spec.ts +2 -2
- package/tests/unit/resolve.spec.ts +2 -2
- package/tests/utils/database/knex.ts +19 -0
- package/tests/utils/database/schema.ts +51 -0
- package/tests/utils/database/seed.ts +53 -0
- package/tests/utils/generate-migration.ts +35 -0
- package/tests/{unit/utils.ts → utils/models.ts} +16 -5
- package/tests/utils/server.ts +108 -0
- package/tsconfig.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/resolvers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAWpC,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAInC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAM7B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAW,EAAU,EAAE;IACjD,QAAQ,CAAC,CAAC,IAAI,EAAE;QACd,KAAK,UAAU,CAAC;QAChB,KAAK,aAAa;YAChB,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7B;YACE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;KACvB;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAc,EAAW,EAAE;IACpD,QAAQ,IAAI,CAAC,IAAI,EAAE;QACjB,KAAK,UAAU;YACb,OAAO,IAAI,CAAC;QACd,KAAK,aAAa;YAChB,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B;YACE,OAAO,KAAK,CAAC;KAChB;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAU,EAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC;AAEjF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAU,EAA2B,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC;AAE7G,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAU,EAA2B,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC;AAI7G,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAqB,EAAE,IAAY,EAAE,EAAE,CAC7D,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAA6B,EAAE,SAAS,CAAC,CAAC;AAEnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAiD,EAAE,EAAE,CACvF,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AAOhD,MAAM,UAAU,OAAO,CACrB,IAAuB,EACvB,GAAmE;IAEnE,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACnC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5B,MAAM,GAAG,GAAQ,EAAE,CAAC;QACpB,KAAK,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC1D,IAAI,OAAO,GAAG,GAAG,CAAC;YAClB,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/resolvers/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
version: '3.4'
|
|
2
|
+
services:
|
|
3
|
+
postgres:
|
|
4
|
+
image: postgres:13-alpine
|
|
5
|
+
shm_size: 1gb
|
|
6
|
+
environment:
|
|
7
|
+
POSTGRES_DB: postgres
|
|
8
|
+
POSTGRES_USER: postgres
|
|
9
|
+
POSTGRES_PASSWORD: password
|
|
10
|
+
POSTGRES_HOST_AUTH_METHOD: trust
|
|
11
|
+
TZ: 'Europe/Zurich'
|
|
12
|
+
ports:
|
|
13
|
+
- '5432:5432'
|
|
14
|
+
networks:
|
|
15
|
+
default:
|
|
16
|
+
aliases:
|
|
17
|
+
- postgres.local
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartive/graphql-magic",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"main": "dist/cjs/index.cjs",
|
|
9
9
|
"types": "dist/esm/index.d.ts",
|
|
10
10
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
11
|
+
"node": ">=20"
|
|
12
12
|
},
|
|
13
13
|
"sideEffecs": false,
|
|
14
14
|
"scripts": {
|
|
@@ -17,8 +17,11 @@
|
|
|
17
17
|
"generate:index-files": "cti create ./src --excludes types --withoutbackup",
|
|
18
18
|
"lint": "eslint src",
|
|
19
19
|
"lint:fix": "eslint src --fix",
|
|
20
|
-
"
|
|
20
|
+
"deps": "docker-compose up",
|
|
21
|
+
"test": "npm run lint && npm run test:unit && npm run test:api && npm run build",
|
|
21
22
|
"test:unit": "jest tests/unit --no-cache --no-watchman",
|
|
23
|
+
"test:api": "jest tests/api --no-cache --no-watchman",
|
|
24
|
+
"generate-migration": "esbuild tests/utils/generate-migration.ts --bundle --platform=node --outdir=tmp --out-extension:.js=.cjs --format=cjs --packages=external && node tmp/generate-migration.cjs",
|
|
22
25
|
"clean": "del-cli dist/**",
|
|
23
26
|
"prebuild": "npm run clean",
|
|
24
27
|
"build": "npm run build:esm && npm run build:cjs",
|
|
@@ -27,7 +30,7 @@
|
|
|
27
30
|
},
|
|
28
31
|
"overrides": {
|
|
29
32
|
"graphql": "$graphql",
|
|
30
|
-
"rollup": "3.
|
|
33
|
+
"rollup": "3.27.2"
|
|
31
34
|
},
|
|
32
35
|
"browserslist": "> 0.25%, not dead",
|
|
33
36
|
"publishConfig": {
|
|
@@ -48,16 +51,19 @@
|
|
|
48
51
|
"@smartive/eslint-config": "3.2.0",
|
|
49
52
|
"@smartive/prettier-config": "3.1.2",
|
|
50
53
|
"@types/jest": "29.5.3",
|
|
51
|
-
"@types/lodash": "4.14.
|
|
52
|
-
"@types/luxon": "3.3.
|
|
54
|
+
"@types/lodash": "4.14.196",
|
|
55
|
+
"@types/luxon": "3.3.1",
|
|
53
56
|
"@types/uuid": "9.0.2",
|
|
54
57
|
"create-ts-index": "1.14.0",
|
|
55
58
|
"del-cli": "5.0.0",
|
|
56
|
-
"esbuild": "0.
|
|
57
|
-
"eslint": "8.
|
|
58
|
-
"
|
|
59
|
+
"esbuild": "0.19.0",
|
|
60
|
+
"eslint": "8.46.0",
|
|
61
|
+
"graphql-request": "^6.1.0",
|
|
62
|
+
"jest": "29.6.2",
|
|
59
63
|
"mock-knex": "0.4.12",
|
|
64
|
+
"pg": "^8.11.2",
|
|
60
65
|
"prettier": "2.8.8",
|
|
66
|
+
"simple-git": "^3.19.1",
|
|
61
67
|
"ts-jest": "29.1.1",
|
|
62
68
|
"ts-node": "10.9.1",
|
|
63
69
|
"typescript": "5.1.6"
|
package/src/db/generate.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import CodeBlockWriter from 'code-block-writer';
|
|
2
|
-
import { RawModels, getModels, isEnumModel } from '..';
|
|
2
|
+
import { ModelField, RawModels, getModels, isEnumModel } from '..';
|
|
3
3
|
|
|
4
4
|
const PRIMITIVE_TYPES = {
|
|
5
5
|
ID: 'string',
|
|
@@ -8,8 +8,11 @@ const PRIMITIVE_TYPES = {
|
|
|
8
8
|
Int: 'number',
|
|
9
9
|
Float: 'number',
|
|
10
10
|
String: 'string',
|
|
11
|
+
DateTime: 'DateTime | string',
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
const OPTIONAL_SEED_FIELDS = ['createdAt', 'createdById', 'updatedAt', 'updatedById', 'deletedAt', 'deletedById'];
|
|
15
|
+
|
|
13
16
|
export const generateDBModels = (rawModels: RawModels) => {
|
|
14
17
|
const writer: CodeBlockWriter = new CodeBlockWriter['default']({
|
|
15
18
|
useSingleQuote: true,
|
|
@@ -25,17 +28,16 @@ export const generateDBModels = (rawModels: RawModels) => {
|
|
|
25
28
|
const models = getModels(rawModels);
|
|
26
29
|
|
|
27
30
|
for (const model of models) {
|
|
31
|
+
// TODO: deprecate allowing to define foreignKey
|
|
32
|
+
const fields = model.fields.some((field) => field.foreignKey === 'id')
|
|
33
|
+
? model.fields.filter((field) => field.name !== 'id')
|
|
34
|
+
: model.fields;
|
|
35
|
+
|
|
28
36
|
writer
|
|
29
37
|
.write(`export type ${model.name} = `)
|
|
30
38
|
.inlineBlock(() => {
|
|
31
|
-
for (const
|
|
32
|
-
writer
|
|
33
|
-
.write(
|
|
34
|
-
`'${name}${relation ? 'Id' : ''}': ${relation ? 'string' : PRIMITIVE_TYPES[type] || type}${
|
|
35
|
-
nonNull ? '' : ' | null'
|
|
36
|
-
},`
|
|
37
|
-
)
|
|
38
|
-
.newLine();
|
|
39
|
+
for (const field of fields.filter(({ raw }) => !raw)) {
|
|
40
|
+
writer.write(`'${getFieldName(field)}': ${getFieldOutputType(field)}${field.nonNull ? '' : ' | null'},`).newLine();
|
|
39
41
|
}
|
|
40
42
|
})
|
|
41
43
|
.blankLine();
|
|
@@ -43,12 +45,12 @@ export const generateDBModels = (rawModels: RawModels) => {
|
|
|
43
45
|
writer
|
|
44
46
|
.write(`export type ${model.name}Initializer = `)
|
|
45
47
|
.inlineBlock(() => {
|
|
46
|
-
for (const
|
|
48
|
+
for (const field of fields.filter(({ raw }) => !raw)) {
|
|
47
49
|
writer
|
|
48
50
|
.write(
|
|
49
|
-
`'${
|
|
50
|
-
|
|
51
|
-
}${nonNull ? '' : ' | null'},`
|
|
51
|
+
`'${getFieldName(field)}'${field.nonNull && field.default === undefined ? '' : '?'}: ${getFieldInputType(
|
|
52
|
+
field
|
|
53
|
+
)}${field.nonNull ? '' : ' | null'},`
|
|
52
54
|
)
|
|
53
55
|
.newLine();
|
|
54
56
|
}
|
|
@@ -58,12 +60,25 @@ export const generateDBModels = (rawModels: RawModels) => {
|
|
|
58
60
|
writer
|
|
59
61
|
.write(`export type ${model.name}Mutator = `)
|
|
60
62
|
.inlineBlock(() => {
|
|
61
|
-
for (const
|
|
63
|
+
for (const field of fields.filter(({ raw }) => !raw)) {
|
|
64
|
+
writer.write(`'${getFieldName(field)}'?: ${getFieldInputType(field)}${field.nonNull ? '' : ' | null'},`).newLine();
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
.blankLine();
|
|
68
|
+
|
|
69
|
+
writer
|
|
70
|
+
.write(`export type ${model.name}Seed = `)
|
|
71
|
+
.inlineBlock(() => {
|
|
72
|
+
for (const field of fields.filter(({ raw }) => !raw)) {
|
|
73
|
+
const fieldName = getFieldName(field);
|
|
62
74
|
writer
|
|
63
75
|
.write(
|
|
64
|
-
`'${
|
|
65
|
-
nonNull ? '' : '
|
|
66
|
-
}
|
|
76
|
+
`'${getFieldName(field)}'${
|
|
77
|
+
field.nonNull && field.default === undefined && !OPTIONAL_SEED_FIELDS.includes(fieldName) ? '' : '?'
|
|
78
|
+
}: ${getFieldInputType(
|
|
79
|
+
field,
|
|
80
|
+
rawModels.filter(isEnumModel).map(({ name }) => name)
|
|
81
|
+
)}${field.list ? ' | string' : ''}${field.nonNull ? '' : ' | null'},`
|
|
67
82
|
)
|
|
68
83
|
.newLine();
|
|
69
84
|
}
|
|
@@ -71,9 +86,40 @@ export const generateDBModels = (rawModels: RawModels) => {
|
|
|
71
86
|
.blankLine();
|
|
72
87
|
}
|
|
73
88
|
|
|
89
|
+
writer.write(`export type SeedData = `).inlineBlock(() => {
|
|
90
|
+
for (const model of models) {
|
|
91
|
+
writer.write(`${model.name}: ${model.name}Seed[],`).newLine();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
74
95
|
return writer.toString();
|
|
75
96
|
};
|
|
76
97
|
|
|
98
|
+
const getFieldName = ({ relation, name, foreignKey }: ModelField) => {
|
|
99
|
+
return foreignKey || `${name}${relation ? 'Id' : ''}`;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const getFieldOutputType = ({ relation, type, list, json }: ModelField) => {
|
|
103
|
+
if (json || relation) {
|
|
104
|
+
return 'string';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return (PRIMITIVE_TYPES[type] || type) + (list ? '[]' : '');
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const getFieldInputType = (field: ModelField, stringTypes: string[] = []) => {
|
|
111
|
+
let outputType = getFieldOutputType(field);
|
|
112
|
+
|
|
113
|
+
if (field.list || stringTypes.includes(field.type)) {
|
|
114
|
+
outputType += ' | string';
|
|
115
|
+
if (field.list && stringTypes.includes(field.type)) {
|
|
116
|
+
outputType += ' | string[]';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return outputType;
|
|
121
|
+
};
|
|
122
|
+
|
|
77
123
|
export const generateKnexTables = (rawModels: RawModels) => {
|
|
78
124
|
const writer: CodeBlockWriter = new CodeBlockWriter['default']({
|
|
79
125
|
useSingleQuote: true,
|
|
@@ -80,7 +80,7 @@ export class MigrationGenerator {
|
|
|
80
80
|
this.renameTable(model.name, model.oldName!);
|
|
81
81
|
});
|
|
82
82
|
tables[tables.indexOf(model.oldName)] = model.name;
|
|
83
|
-
this.columns[model.name] = this.columns[model.oldName]
|
|
83
|
+
this.columns[model.name] = this.columns[model.oldName];
|
|
84
84
|
delete this.columns[model.oldName];
|
|
85
85
|
|
|
86
86
|
if (model.updatable) {
|
|
@@ -99,7 +99,7 @@ export class MigrationGenerator {
|
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
101
|
tables[tables.indexOf(`${model.oldName}Revision`)] = `${model.name}Revision`;
|
|
102
|
-
this.columns[`${model.name}Revision`] = this.columns[`${model.oldName}Revision`]
|
|
102
|
+
this.columns[`${model.name}Revision`] = this.columns[`${model.oldName}Revision`];
|
|
103
103
|
delete this.columns[`${model.oldName}Revision`];
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -131,7 +131,7 @@ export class MigrationGenerator {
|
|
|
131
131
|
model,
|
|
132
132
|
model.fields.filter(
|
|
133
133
|
({ name, relation, raw, foreignKey }) =>
|
|
134
|
-
!raw && !this.columns[model.name]
|
|
134
|
+
!raw && !this.columns[model.name].some((col) => col.name === (foreignKey || (relation ? `${name}Id` : name)))
|
|
135
135
|
),
|
|
136
136
|
up,
|
|
137
137
|
down
|
|
@@ -139,7 +139,7 @@ export class MigrationGenerator {
|
|
|
139
139
|
|
|
140
140
|
// Update fields
|
|
141
141
|
const existingFields = model.fields.filter(({ name, relation, nonNull }) => {
|
|
142
|
-
const col = this.columns[model.name]
|
|
142
|
+
const col = this.columns[model.name].find((col) => col.name === (relation ? `${name}Id` : name));
|
|
143
143
|
if (!col) {
|
|
144
144
|
return false;
|
|
145
145
|
}
|
|
@@ -197,7 +197,7 @@ export class MigrationGenerator {
|
|
|
197
197
|
({ name, relation, raw, foreignKey, updatable }) =>
|
|
198
198
|
!raw &&
|
|
199
199
|
updatable &&
|
|
200
|
-
!this.columns[revisionTable]
|
|
200
|
+
!this.columns[revisionTable].some((col) => col.name === (foreignKey || (relation ? `${name}Id` : name)))
|
|
201
201
|
);
|
|
202
202
|
|
|
203
203
|
this.createRevisionFields(model, missingRevisionFields, up, down);
|
|
@@ -208,7 +208,7 @@ export class MigrationGenerator {
|
|
|
208
208
|
!raw &&
|
|
209
209
|
!updatable &&
|
|
210
210
|
foreignKey !== 'id' &&
|
|
211
|
-
this.columns[revisionTable]
|
|
211
|
+
this.columns[revisionTable].some((col) => col.name === (foreignKey || (relation ? `${name}Id` : name)))
|
|
212
212
|
);
|
|
213
213
|
this.createRevisionFields(model, revisionFieldsToRemove, down, up);
|
|
214
214
|
}
|
|
@@ -219,7 +219,7 @@ export class MigrationGenerator {
|
|
|
219
219
|
if (tables.includes(model.name)) {
|
|
220
220
|
this.createFields(
|
|
221
221
|
model,
|
|
222
|
-
model.fields.filter(({ name, deleted }) => deleted && this.columns[model.name]
|
|
222
|
+
model.fields.filter(({ name, deleted }) => deleted && this.columns[model.name].some((col) => col.name === name)),
|
|
223
223
|
down,
|
|
224
224
|
up
|
|
225
225
|
);
|
|
@@ -363,7 +363,7 @@ export class MigrationGenerator {
|
|
|
363
363
|
this.column(
|
|
364
364
|
field,
|
|
365
365
|
{ alter: true },
|
|
366
|
-
summonByName(this.columns[model.name]
|
|
366
|
+
summonByName(this.columns[model.name], field.relation ? `${field.name}Id` : field.name)
|
|
367
367
|
);
|
|
368
368
|
}
|
|
369
369
|
});
|
|
@@ -389,7 +389,7 @@ export class MigrationGenerator {
|
|
|
389
389
|
this.column(
|
|
390
390
|
field,
|
|
391
391
|
{ alter: true },
|
|
392
|
-
summonByName(this.columns[model.name]
|
|
392
|
+
summonByName(this.columns[model.name], field.relation ? `${field.name}Id` : field.name)
|
|
393
393
|
);
|
|
394
394
|
}
|
|
395
395
|
});
|
package/src/permissions/check.ts
CHANGED
|
@@ -194,7 +194,7 @@ const permissionLinkQuery = (
|
|
|
194
194
|
) => {
|
|
195
195
|
const aliases = new AliasGenerator();
|
|
196
196
|
let alias = aliases.getShort();
|
|
197
|
-
const { type, me, where } = links[0]
|
|
197
|
+
const { type, me, where } = links[0];
|
|
198
198
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
199
199
|
subQuery.from(`${type} as ${alias}`);
|
|
200
200
|
if (me) {
|
|
@@ -71,7 +71,7 @@ export const generatePermissions = (models: Models, config: PermissionsConfig) =
|
|
|
71
71
|
rolePermissions[type] = {};
|
|
72
72
|
for (const action of ACTIONS) {
|
|
73
73
|
if (action === 'READ' || action in block) {
|
|
74
|
-
rolePermissions[type]
|
|
74
|
+
rolePermissions[type][action] = true;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -95,7 +95,7 @@ export const generatePermissions = (models: Models, config: PermissionsConfig) =
|
|
|
95
95
|
};
|
|
96
96
|
|
|
97
97
|
const addPermissions = (models: Models, permissions: RolePermissions, links: PermissionLink[], block: PermissionsBlock) => {
|
|
98
|
-
const { type } = links[links.length - 1]
|
|
98
|
+
const { type } = links[links.length - 1];
|
|
99
99
|
const model = summonByName(models, type);
|
|
100
100
|
|
|
101
101
|
for (const action of ACTIONS) {
|
|
@@ -103,11 +103,11 @@ const addPermissions = (models: Models, permissions: RolePermissions, links: Per
|
|
|
103
103
|
if (!permissions[type]) {
|
|
104
104
|
permissions[type] = {};
|
|
105
105
|
}
|
|
106
|
-
if (!permissions[type]
|
|
107
|
-
permissions[type]
|
|
106
|
+
if (!permissions[type][action]) {
|
|
107
|
+
permissions[type][action] = [];
|
|
108
108
|
}
|
|
109
|
-
if (permissions[type]
|
|
110
|
-
(permissions[type]
|
|
109
|
+
if (permissions[type][action] !== true) {
|
|
110
|
+
(permissions[type][action] as PermissionStack).push(links);
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -123,7 +123,7 @@ const addPermissions = (models: Models, permissions: RolePermissions, links: Per
|
|
|
123
123
|
reverse: true,
|
|
124
124
|
};
|
|
125
125
|
} else {
|
|
126
|
-
const field = model.reverseRelationsByName[relation]
|
|
126
|
+
const field = model.reverseRelationsByName[relation];
|
|
127
127
|
|
|
128
128
|
if (!field) {
|
|
129
129
|
throw new Error(`Relation ${relation} in model ${model.name} does not exist.`);
|
package/src/resolvers/filters.ts
CHANGED
|
@@ -72,12 +72,12 @@ const applyWhere = (node: WhereNode, where: Where, ops: Ops<Knex.QueryBuilder>,
|
|
|
72
72
|
const specialFilter = key.match(/^(\w+)_(\w+)$/);
|
|
73
73
|
if (specialFilter) {
|
|
74
74
|
const [, actualKey, filter] = specialFilter;
|
|
75
|
-
if (!SPECIAL_FILTERS[filter
|
|
75
|
+
if (!SPECIAL_FILTERS[filter]) {
|
|
76
76
|
// Should not happen
|
|
77
77
|
throw new Error(`Invalid filter ${key}.`);
|
|
78
78
|
}
|
|
79
79
|
ops.push((query) =>
|
|
80
|
-
query.whereRaw(SPECIAL_FILTERS[filter
|
|
80
|
+
query.whereRaw(SPECIAL_FILTERS[filter], [`${node.shortTableAlias}.${actualKey}`, value as string])
|
|
81
81
|
);
|
|
82
82
|
continue;
|
|
83
83
|
}
|
|
@@ -154,7 +154,7 @@ const applyOrderBy = (node: FieldResolverNode, orderBy: OrderBy, query: Knex.Que
|
|
|
154
154
|
throw new UserInputError(`You need to specify exactly 1 value to order by for each orderBy entry.`);
|
|
155
155
|
}
|
|
156
156
|
const key = keys[0];
|
|
157
|
-
const value = vals[key
|
|
157
|
+
const value = vals[key];
|
|
158
158
|
|
|
159
159
|
// Simple field
|
|
160
160
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
@@ -12,7 +12,7 @@ export const mutationResolver = async (_parent: any, args: any, partialCtx: Cont
|
|
|
12
12
|
return await partialCtx.knex.transaction(async (knex) => {
|
|
13
13
|
const [, mutation, modelName] = it(info.fieldName.match(/^(create|update|delete|restore)(.+)$/));
|
|
14
14
|
const ctx = { ...partialCtx, knex, info, aliases: new AliasGenerator() };
|
|
15
|
-
const model = summonByName(ctx.models, modelName
|
|
15
|
+
const model = summonByName(ctx.models, modelName);
|
|
16
16
|
switch (mutation) {
|
|
17
17
|
case 'create':
|
|
18
18
|
return await create(model, args, ctx);
|
|
@@ -110,17 +110,20 @@ const del = async (model: Model, { where, dryRun }: { where: any; dryRun: boolea
|
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
113
|
+
if (!(currentModel.name in toDelete)) {
|
|
114
|
+
toDelete[currentModel.name] = {};
|
|
115
|
+
}
|
|
116
|
+
if (entity.id in toDelete[currentModel.name]) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
entity[currentModel.displayField || 'id'] || entity.id;
|
|
120
|
+
|
|
121
|
+
if (!dryRun) {
|
|
119
122
|
const normalizedInput = { deleted: true, deletedAt: ctx.now, deletedById: ctx.user.id };
|
|
120
123
|
const data = { prev: entity, input: {}, normalizedInput, next: { ...entity, ...normalizedInput } };
|
|
121
124
|
if (ctx.mutationHook) {
|
|
122
125
|
beforeHooks.push(async () => {
|
|
123
|
-
await ctx.mutationHook
|
|
126
|
+
await ctx.mutationHook(currentModel, 'delete', 'before', data, ctx);
|
|
124
127
|
});
|
|
125
128
|
}
|
|
126
129
|
mutations.push(async () => {
|
|
@@ -129,7 +132,7 @@ const del = async (model: Model, { where, dryRun }: { where: any; dryRun: boolea
|
|
|
129
132
|
});
|
|
130
133
|
if (ctx.mutationHook) {
|
|
131
134
|
afterHooks.push(async () => {
|
|
132
|
-
await ctx.mutationHook
|
|
135
|
+
await ctx.mutationHook(currentModel, 'delete', 'after', data, ctx);
|
|
133
136
|
});
|
|
134
137
|
}
|
|
135
138
|
}
|
|
@@ -148,13 +151,13 @@ const del = async (model: Model, { where, dryRun }: { where: any; dryRun: boolea
|
|
|
148
151
|
if (!toUnlink[descendantModel.name]) {
|
|
149
152
|
toUnlink[descendantModel.name] = {};
|
|
150
153
|
}
|
|
151
|
-
if (!toUnlink[descendantModel.name]
|
|
152
|
-
toUnlink[descendantModel.name]
|
|
154
|
+
if (!toUnlink[descendantModel.name][descendant.id]) {
|
|
155
|
+
toUnlink[descendantModel.name][descendant.id] = {
|
|
153
156
|
display: descendant[descendantModel.displayField || 'id'] || entity.id,
|
|
154
157
|
fields: [],
|
|
155
158
|
};
|
|
156
159
|
}
|
|
157
|
-
toUnlink[descendantModel.name]
|
|
160
|
+
toUnlink[descendantModel.name][descendant.id].fields.push(name);
|
|
158
161
|
} else {
|
|
159
162
|
mutations.push(async () => {
|
|
160
163
|
await ctx
|
|
@@ -225,7 +228,7 @@ const restore = async (model: Model, { where }: { where: any }, ctx: FullContext
|
|
|
225
228
|
const data = { prev: relatedEntity, input: {}, normalizedInput, next: { ...relatedEntity, ...normalizedInput } };
|
|
226
229
|
if (ctx.mutationHook) {
|
|
227
230
|
beforeHooks.push(async () => {
|
|
228
|
-
await ctx.mutationHook
|
|
231
|
+
await ctx.mutationHook(model, 'restore', 'before', data, ctx);
|
|
229
232
|
});
|
|
230
233
|
}
|
|
231
234
|
mutations.push(async () => {
|
|
@@ -234,7 +237,7 @@ const restore = async (model: Model, { where }: { where: any }, ctx: FullContext
|
|
|
234
237
|
});
|
|
235
238
|
if (ctx.mutationHook) {
|
|
236
239
|
afterHooks.push(async () => {
|
|
237
|
-
await ctx.mutationHook
|
|
240
|
+
await ctx.mutationHook(model, 'restore', 'after', data, ctx);
|
|
238
241
|
});
|
|
239
242
|
}
|
|
240
243
|
|
package/src/resolvers/node.ts
CHANGED
|
@@ -132,7 +132,7 @@ export const getFragmentSpreads = (node: ResolverNode) =>
|
|
|
132
132
|
node.selectionSet.filter(isFragmentSpreadNode).map((subNode) =>
|
|
133
133
|
getResolverNode({
|
|
134
134
|
ctx: node.ctx,
|
|
135
|
-
node: node.ctx.info.fragments[subNode.name.value]
|
|
135
|
+
node: node.ctx.info.fragments[subNode.name.value],
|
|
136
136
|
tableAlias: node.tableAlias,
|
|
137
137
|
baseTypeDefinition: node.baseTypeDefinition,
|
|
138
138
|
typeName: node.model.name,
|
|
@@ -165,7 +165,7 @@ const applySubQueries = async (
|
|
|
165
165
|
if (!entriesById[entry[ID_ALIAS]]) {
|
|
166
166
|
entriesById[entry[ID_ALIAS]] = [];
|
|
167
167
|
}
|
|
168
|
-
entriesById[entry[ID_ALIAS]
|
|
168
|
+
entriesById[entry[ID_ALIAS]].push(entry);
|
|
169
169
|
}
|
|
170
170
|
const ids = Object.keys(entriesById);
|
|
171
171
|
|
|
@@ -189,7 +189,7 @@ const applySubQueries = async (
|
|
|
189
189
|
const children = hydrate(subNode, rawChildren);
|
|
190
190
|
|
|
191
191
|
for (const child of children) {
|
|
192
|
-
for (const entry of entriesById[child[foreignKey] as string]
|
|
192
|
+
for (const entry of entriesById[child[foreignKey] as string]) {
|
|
193
193
|
if (isList) {
|
|
194
194
|
(entry[fieldName] as Entry[]).push(cloneDeep(child));
|
|
195
195
|
} else {
|
package/src/resolvers/utils.ts
CHANGED
|
@@ -72,13 +72,13 @@ export function hydrate<T extends Entry>(
|
|
|
72
72
|
outer: for (const [column, value] of Object.entries(entry)) {
|
|
73
73
|
let current = res;
|
|
74
74
|
const shortParts = column.split('__');
|
|
75
|
-
const fieldName = shortParts.pop()
|
|
75
|
+
const fieldName = shortParts.pop();
|
|
76
76
|
const columnWithoutField = shortParts.join('__');
|
|
77
77
|
const longColumn = node.ctx.aliases.getLong(columnWithoutField);
|
|
78
78
|
const longColumnWithoutRoot = longColumn.replace(new RegExp(`^${tableAlias}(__)?`), '');
|
|
79
79
|
const allParts = [tableAlias, ...(longColumnWithoutRoot ? longColumnWithoutRoot.split('__') : []), fieldName];
|
|
80
80
|
for (let i = 0; i < allParts.length - 1; i++) {
|
|
81
|
-
const part = allParts[i]
|
|
81
|
+
const part = allParts[i];
|
|
82
82
|
|
|
83
83
|
if (!current[part]) {
|
|
84
84
|
const idField = [node.ctx.aliases.getShort(allParts.slice(0, i + 1).join('__')), ID_ALIAS].join('__');
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`query can be executed 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"manyObjects": [
|
|
6
|
+
{
|
|
7
|
+
"another": {
|
|
8
|
+
"id": "226a20e8-5c18-4423-99ca-eb0df6ff4fdd",
|
|
9
|
+
"manyObjects": [
|
|
10
|
+
{
|
|
11
|
+
"field": null,
|
|
12
|
+
"id": "604ab55d-ec3e-4857-9f27-219158f80e64",
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
"field": null,
|
|
17
|
+
"id": "604ab55d-ec3e-4857-9f27-219158f80e64",
|
|
18
|
+
"xyz": 1,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { gql } from '../../src';
|
|
2
|
+
import { ANOTHER_ID, SOME_ID } from '../utils/database/seed';
|
|
3
|
+
import { withServer } from '../utils/server';
|
|
4
|
+
|
|
5
|
+
describe('query', () => {
|
|
6
|
+
it('can be executed', async () => {
|
|
7
|
+
await withServer(async (request) => {
|
|
8
|
+
expect(
|
|
9
|
+
await request(gql`
|
|
10
|
+
query SomeQuery {
|
|
11
|
+
manyObjects(where: { another: { id: "${ANOTHER_ID}" } }, orderBy: [{ xyz: DESC }]) {
|
|
12
|
+
id
|
|
13
|
+
field
|
|
14
|
+
xyz
|
|
15
|
+
another {
|
|
16
|
+
id
|
|
17
|
+
manyObjects(where: { id: "${SOME_ID}" }) {
|
|
18
|
+
id
|
|
19
|
+
field
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
`)
|
|
25
|
+
).toMatchSnapshot();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -38,6 +38,11 @@ type Query {
|
|
|
38
38
|
manyObjects(where: SomeObjectWhere, search: String, orderBy: [SomeObjectOrderBy!], limit: Int, offset: Int): [SomeObject!]!
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
enum Role {
|
|
42
|
+
ADMIN
|
|
43
|
+
USER
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
enum SomeEnum {
|
|
42
47
|
A
|
|
43
48
|
B
|
|
@@ -89,6 +94,7 @@ scalar Upload
|
|
|
89
94
|
type User {
|
|
90
95
|
id: ID!
|
|
91
96
|
username: String
|
|
97
|
+
role: Role
|
|
92
98
|
createdManyObjects(where: SomeObjectWhere, search: String, orderBy: [SomeObjectOrderBy!], limit: Int, offset: Int): [SomeObject!]!
|
|
93
99
|
updatedManyObjects(where: SomeObjectWhere, search: String, orderBy: [SomeObjectOrderBy!], limit: Int, offset: Int): [SomeObject!]!
|
|
94
100
|
deletedManyObjects(where: SomeObjectWhere, search: String, orderBy: [SomeObjectOrderBy!], limit: Int, offset: Int): [SomeObject!]!
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { makeExecutableSchema } from '@graphql-tools/schema';
|
|
2
2
|
import { execute, parse, Source } from 'graphql';
|
|
3
3
|
import knex from 'knex';
|
|
4
|
+
import { DateTime } from 'luxon';
|
|
4
5
|
import { gql } from '../../src/client/gql';
|
|
5
6
|
import { Context } from '../../src/context';
|
|
6
7
|
import { generate } from '../../src/generate';
|
|
7
8
|
import { getResolvers } from '../../src/resolvers';
|
|
8
|
-
import { models, permissions, rawModels } from '
|
|
9
|
-
import { DateTime } from 'luxon';
|
|
9
|
+
import { models, permissions, rawModels } from '../utils/models';
|
|
10
10
|
|
|
11
11
|
const test = async (operationName: string, query: string, variableValues: object, responses: unknown[]) => {
|
|
12
12
|
const knexInstance = knex({
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import knex from 'knex';
|
|
2
|
+
|
|
3
|
+
export const getKnex = (database = 'postgres') =>
|
|
4
|
+
knex({
|
|
5
|
+
client: 'postgresql',
|
|
6
|
+
connection: {
|
|
7
|
+
host: 'localhost',
|
|
8
|
+
database,
|
|
9
|
+
user: 'postgres',
|
|
10
|
+
password: 'password',
|
|
11
|
+
},
|
|
12
|
+
migrations: {
|
|
13
|
+
tableName: 'knex_migrations',
|
|
14
|
+
},
|
|
15
|
+
pool: {
|
|
16
|
+
min: 0,
|
|
17
|
+
max: 30,
|
|
18
|
+
},
|
|
19
|
+
});
|