@smartive/graphql-magic 19.0.0 → 19.1.0-next.2
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/CHANGELOG.md +6 -1
- package/dist/bin/gqm.cjs +127 -64
- package/dist/cjs/index.cjs +65 -0
- package/dist/esm/db/generate.d.ts +8 -0
- package/dist/esm/db/generate.js +1 -1
- package/dist/esm/db/generate.js.map +1 -1
- package/dist/esm/permissions/generate-types.d.ts +2 -0
- package/dist/esm/permissions/generate-types.js +54 -0
- package/dist/esm/permissions/generate-types.js.map +1 -0
- package/dist/esm/permissions/generate.d.ts +1 -0
- package/dist/esm/permissions/generate.js +1 -1
- package/dist/esm/permissions/generate.js.map +1 -1
- package/dist/esm/permissions/index.d.ts +1 -0
- package/dist/esm/permissions/index.js +1 -0
- package/dist/esm/permissions/index.js.map +1 -1
- package/migrations/20230912185644_setup.ts +25 -12
- package/package.json +1 -1
- package/src/bin/gqm/gqm.ts +2 -0
- package/src/db/generate.ts +1 -1
- package/src/permissions/generate-types.ts +66 -0
- package/src/permissions/generate.ts +1 -1
- package/src/permissions/index.ts +1 -0
- package/tests/generated/permissions.ts +171 -0
package/CHANGELOG.md
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
# [19.0.
|
|
1
|
+
# [19.1.0-next.2](https://github.com/smartive/graphql-magic/compare/v19.1.0-next.1...v19.1.0-next.2) (2025-06-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Plural ([e13aecd](https://github.com/smartive/graphql-magic/commit/e13aecd90c2d615c355b65d8704d9ef08bcc8fcb))
|
package/dist/bin/gqm.cjs
CHANGED
|
@@ -1253,6 +1253,68 @@ var import_graphql3 = require("graphql");
|
|
|
1253
1253
|
var import_isEqual = __toESM(require("lodash/isEqual"), 1);
|
|
1254
1254
|
var getColumnName = (field) => field.kind === "relation" ? field.foreignKey || `${field.name}Id` : field.name;
|
|
1255
1255
|
|
|
1256
|
+
// src/permissions/generate-types.ts
|
|
1257
|
+
var import_ts_morph = require("ts-morph");
|
|
1258
|
+
|
|
1259
|
+
// src/permissions/generate.ts
|
|
1260
|
+
var ACTIONS = ["READ", "CREATE", "UPDATE", "DELETE", "RESTORE", "LINK"];
|
|
1261
|
+
|
|
1262
|
+
// src/permissions/generate-types.ts
|
|
1263
|
+
var generatePermissionTypes = (models) => {
|
|
1264
|
+
const project = new import_ts_morph.Project({
|
|
1265
|
+
manipulationSettings: {
|
|
1266
|
+
indentationText: import_ts_morph.IndentationText.TwoSpaces
|
|
1267
|
+
}
|
|
1268
|
+
});
|
|
1269
|
+
const sourceFile = project.createSourceFile("permissions.ts", "", {
|
|
1270
|
+
overwrite: true
|
|
1271
|
+
});
|
|
1272
|
+
sourceFile.addStatements(`export type PermissionsConfig = Record<Role, PermissionsBlock>;`);
|
|
1273
|
+
sourceFile.addStatements(
|
|
1274
|
+
(writer) => writer.write(`export type PermissionsBlock = true | `).inlineBlock(() => {
|
|
1275
|
+
writer.writeLine(`me?: UserPermissionsBlock,`);
|
|
1276
|
+
for (const model of models.entities) {
|
|
1277
|
+
writer.writeLine(`${model.name}?: ${model.name}PermissionsBlock,`);
|
|
1278
|
+
}
|
|
1279
|
+
})
|
|
1280
|
+
);
|
|
1281
|
+
for (const enm2 of models.enums) {
|
|
1282
|
+
sourceFile.addStatements((writer) => writer.write(`type ${enm2.name} = ${enm2.values.map((v) => `'${v}'`).join(" | ")};`));
|
|
1283
|
+
}
|
|
1284
|
+
for (const model of models.entities) {
|
|
1285
|
+
sourceFile.addStatements(
|
|
1286
|
+
(writer) => writer.write(`export type ${model.name}Where = `).inlineBlock(() => {
|
|
1287
|
+
for (const field of model.fields.filter((field2) => field2.filterable)) {
|
|
1288
|
+
if (field.kind === "relation") {
|
|
1289
|
+
writer.writeLine(`${field.name}?: ${field.type}Where,`);
|
|
1290
|
+
} else if (!field.kind || field.kind === "primitive") {
|
|
1291
|
+
writer.writeLine(`${field.name}?: ${PRIMITIVE_TYPES[field.type]} | ${PRIMITIVE_TYPES[field.type]}[],`);
|
|
1292
|
+
} else {
|
|
1293
|
+
writer.writeLine(`${field.name}?: ${field.type} | ${field.type}[],`);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
})
|
|
1297
|
+
);
|
|
1298
|
+
sourceFile.addStatements(
|
|
1299
|
+
(writer) => writer.write(`export type ${model.name}PermissionsBlock = `).inlineBlock(() => {
|
|
1300
|
+
for (const action of ACTIONS) {
|
|
1301
|
+
writer.writeLine(`${action}?: true,`);
|
|
1302
|
+
}
|
|
1303
|
+
writer.writeLine(`WHERE?: ${model.name}Where,`);
|
|
1304
|
+
const relations = [...model.relations, ...model.reverseRelations];
|
|
1305
|
+
if (relations.length > 0) {
|
|
1306
|
+
writer.write(`RELATIONS?: `).inlineBlock(() => {
|
|
1307
|
+
for (const relation of relations) {
|
|
1308
|
+
writer.writeLine(`${relation.name}?: ${relation.targetModel.name}PermissionsBlock,`);
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
})
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
return sourceFile.getFullText();
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1256
1318
|
// src/resolvers/arguments.ts
|
|
1257
1319
|
var import_graphql4 = require("graphql");
|
|
1258
1320
|
|
|
@@ -2000,14 +2062,14 @@ var generateGraphqlClientTypes = async () => {
|
|
|
2000
2062
|
};
|
|
2001
2063
|
|
|
2002
2064
|
// src/bin/gqm/parse-knexfile.ts
|
|
2003
|
-
var
|
|
2065
|
+
var import_ts_morph5 = require("ts-morph");
|
|
2004
2066
|
|
|
2005
2067
|
// src/bin/gqm/static-eval.ts
|
|
2006
2068
|
var import_lodash = require("lodash");
|
|
2007
|
-
var
|
|
2069
|
+
var import_ts_morph3 = require("ts-morph");
|
|
2008
2070
|
|
|
2009
2071
|
// src/bin/gqm/visitor.ts
|
|
2010
|
-
var
|
|
2072
|
+
var import_ts_morph2 = require("ts-morph");
|
|
2011
2073
|
var visit = (node, context, visitor) => {
|
|
2012
2074
|
if (!node) {
|
|
2013
2075
|
if (visitor.undefined) {
|
|
@@ -2027,7 +2089,7 @@ var visit = (node, context, visitor) => {
|
|
|
2027
2089
|
console.error(node.getText());
|
|
2028
2090
|
throw new Error(
|
|
2029
2091
|
`Cannot handle kind ${get(
|
|
2030
|
-
Object.entries(
|
|
2092
|
+
Object.entries(import_ts_morph2.SyntaxKind).find(([, val]) => val === kind),
|
|
2031
2093
|
0
|
|
2032
2094
|
)}`
|
|
2033
2095
|
);
|
|
@@ -2063,11 +2125,11 @@ var KNOWN_IDENTIFIERS = {
|
|
|
2063
2125
|
var staticEval = (node, context) => visit(node, context, VISITOR);
|
|
2064
2126
|
var VISITOR = {
|
|
2065
2127
|
undefined: () => void 0,
|
|
2066
|
-
[
|
|
2067
|
-
[
|
|
2128
|
+
[import_ts_morph3.SyntaxKind.VariableDeclaration]: (node, context) => staticEval(node.getInitializer(), context),
|
|
2129
|
+
[import_ts_morph3.SyntaxKind.ArrayLiteralExpression]: (node, context) => {
|
|
2068
2130
|
const values = [];
|
|
2069
2131
|
for (const value2 of node.getElements()) {
|
|
2070
|
-
if (value2.isKind(
|
|
2132
|
+
if (value2.isKind(import_ts_morph3.SyntaxKind.SpreadElement)) {
|
|
2071
2133
|
values.push(...staticEval(value2, context));
|
|
2072
2134
|
} else {
|
|
2073
2135
|
values.push(staticEval(value2, context));
|
|
@@ -2075,23 +2137,23 @@ var VISITOR = {
|
|
|
2075
2137
|
}
|
|
2076
2138
|
return values;
|
|
2077
2139
|
},
|
|
2078
|
-
[
|
|
2140
|
+
[import_ts_morph3.SyntaxKind.ObjectLiteralExpression]: (node, context) => {
|
|
2079
2141
|
const result = {};
|
|
2080
2142
|
for (const property of node.getProperties()) {
|
|
2081
2143
|
Object.assign(result, staticEval(property, context));
|
|
2082
2144
|
}
|
|
2083
2145
|
return result;
|
|
2084
2146
|
},
|
|
2085
|
-
[
|
|
2086
|
-
[
|
|
2147
|
+
[import_ts_morph3.SyntaxKind.StringLiteral]: (node) => node.getLiteralValue(),
|
|
2148
|
+
[import_ts_morph3.SyntaxKind.PropertyAssignment]: (node, context) => ({
|
|
2087
2149
|
[node.getName()]: staticEval(node.getInitializer(), context)
|
|
2088
2150
|
}),
|
|
2089
|
-
[
|
|
2151
|
+
[import_ts_morph3.SyntaxKind.ShorthandPropertyAssignment]: (node, context) => ({
|
|
2090
2152
|
[node.getName()]: staticEval(node.getNameNode(), context)
|
|
2091
2153
|
}),
|
|
2092
|
-
[
|
|
2093
|
-
[
|
|
2094
|
-
[
|
|
2154
|
+
[import_ts_morph3.SyntaxKind.SpreadElement]: (node, context) => staticEval(node.getExpression(), context),
|
|
2155
|
+
[import_ts_morph3.SyntaxKind.SpreadAssignment]: (node, context) => staticEval(node.getExpression(), context),
|
|
2156
|
+
[import_ts_morph3.SyntaxKind.Identifier]: (node, context) => {
|
|
2095
2157
|
const identifierName = node.getText();
|
|
2096
2158
|
if (identifierName in KNOWN_IDENTIFIERS) {
|
|
2097
2159
|
return KNOWN_IDENTIFIERS[identifierName];
|
|
@@ -2102,19 +2164,19 @@ var VISITOR = {
|
|
|
2102
2164
|
}
|
|
2103
2165
|
return staticEval(definitionNodes[0], context);
|
|
2104
2166
|
},
|
|
2105
|
-
[
|
|
2106
|
-
[
|
|
2107
|
-
[
|
|
2108
|
-
[
|
|
2109
|
-
[
|
|
2110
|
-
[
|
|
2111
|
-
[
|
|
2112
|
-
[
|
|
2167
|
+
[import_ts_morph3.SyntaxKind.ParenthesizedExpression]: (node, context) => staticEval(node.getExpression(), context),
|
|
2168
|
+
[import_ts_morph3.SyntaxKind.AsExpression]: (node, context) => staticEval(node.getExpression(), context),
|
|
2169
|
+
[import_ts_morph3.SyntaxKind.ConditionalExpression]: (node, context) => staticEval(node.getCondition(), context) ? staticEval(node.getWhenTrue(), context) : staticEval(node.getWhenFalse(), context),
|
|
2170
|
+
[import_ts_morph3.SyntaxKind.TrueKeyword]: () => true,
|
|
2171
|
+
[import_ts_morph3.SyntaxKind.FalseKeyword]: () => false,
|
|
2172
|
+
[import_ts_morph3.SyntaxKind.NumericLiteral]: (node) => node.getLiteralValue(),
|
|
2173
|
+
[import_ts_morph3.SyntaxKind.BigIntLiteral]: (node) => node.getLiteralValue(),
|
|
2174
|
+
[import_ts_morph3.SyntaxKind.CallExpression]: (node, context) => {
|
|
2113
2175
|
const method = staticEval(node.getExpression(), context);
|
|
2114
2176
|
const args2 = node.getArguments().map((arg) => staticEval(arg, context));
|
|
2115
2177
|
return method(...args2);
|
|
2116
2178
|
},
|
|
2117
|
-
[
|
|
2179
|
+
[import_ts_morph3.SyntaxKind.PropertyAccessExpression]: (node, context) => {
|
|
2118
2180
|
const target = staticEval(node.getExpression(), context);
|
|
2119
2181
|
const property = target[node.getName()];
|
|
2120
2182
|
if (typeof property === "function") {
|
|
@@ -2153,7 +2215,7 @@ var VISITOR = {
|
|
|
2153
2215
|
}
|
|
2154
2216
|
return property;
|
|
2155
2217
|
},
|
|
2156
|
-
[
|
|
2218
|
+
[import_ts_morph3.SyntaxKind.ArrowFunction]: (node, context) => {
|
|
2157
2219
|
return (...args2) => {
|
|
2158
2220
|
const parameters = {};
|
|
2159
2221
|
let i = 0;
|
|
@@ -2164,12 +2226,12 @@ var VISITOR = {
|
|
|
2164
2226
|
return staticEval(node.getBody(), { ...context, ...parameters });
|
|
2165
2227
|
};
|
|
2166
2228
|
},
|
|
2167
|
-
[
|
|
2229
|
+
[import_ts_morph3.SyntaxKind.Block]: (node, context) => {
|
|
2168
2230
|
for (const statement of node.getStatements()) {
|
|
2169
2231
|
return staticEval(statement, context);
|
|
2170
2232
|
}
|
|
2171
2233
|
},
|
|
2172
|
-
[
|
|
2234
|
+
[import_ts_morph3.SyntaxKind.CaseClause]: (node, context) => {
|
|
2173
2235
|
const statements = node.getStatements();
|
|
2174
2236
|
if (statements.length !== 1) {
|
|
2175
2237
|
console.error(node.getText());
|
|
@@ -2177,7 +2239,7 @@ var VISITOR = {
|
|
|
2177
2239
|
}
|
|
2178
2240
|
return staticEval(statements[0], context);
|
|
2179
2241
|
},
|
|
2180
|
-
[
|
|
2242
|
+
[import_ts_morph3.SyntaxKind.DefaultClause]: (node, context) => {
|
|
2181
2243
|
const statements = node.getStatements();
|
|
2182
2244
|
if (statements.length !== 1) {
|
|
2183
2245
|
console.error(node.getText());
|
|
@@ -2185,18 +2247,18 @@ var VISITOR = {
|
|
|
2185
2247
|
}
|
|
2186
2248
|
return staticEval(statements[0], context);
|
|
2187
2249
|
},
|
|
2188
|
-
[
|
|
2250
|
+
[import_ts_morph3.SyntaxKind.ReturnStatement]: (node, context) => {
|
|
2189
2251
|
return staticEval(node.getExpression(), context);
|
|
2190
2252
|
},
|
|
2191
|
-
[
|
|
2253
|
+
[import_ts_morph3.SyntaxKind.SwitchStatement]: (node, context) => {
|
|
2192
2254
|
const value2 = staticEval(node.getExpression(), context);
|
|
2193
2255
|
let active = false;
|
|
2194
2256
|
for (const clause of node.getCaseBlock().getClauses()) {
|
|
2195
2257
|
switch (clause.getKind()) {
|
|
2196
|
-
case
|
|
2258
|
+
case import_ts_morph3.SyntaxKind.DefaultClause:
|
|
2197
2259
|
return staticEval(clause, context);
|
|
2198
|
-
case
|
|
2199
|
-
const caseClause = clause.asKindOrThrow(
|
|
2260
|
+
case import_ts_morph3.SyntaxKind.CaseClause: {
|
|
2261
|
+
const caseClause = clause.asKindOrThrow(import_ts_morph3.SyntaxKind.CaseClause);
|
|
2200
2262
|
if (caseClause.getStatements().length && active) {
|
|
2201
2263
|
return staticEval(clause, context);
|
|
2202
2264
|
}
|
|
@@ -2211,15 +2273,15 @@ var VISITOR = {
|
|
|
2211
2273
|
}
|
|
2212
2274
|
}
|
|
2213
2275
|
},
|
|
2214
|
-
[
|
|
2215
|
-
[
|
|
2276
|
+
[import_ts_morph3.SyntaxKind.Parameter]: (node, context) => context[node.getName()],
|
|
2277
|
+
[import_ts_morph3.SyntaxKind.BinaryExpression]: (node, context) => {
|
|
2216
2278
|
const mapping = {
|
|
2217
|
-
[
|
|
2218
|
-
[
|
|
2219
|
-
[
|
|
2220
|
-
[
|
|
2221
|
-
[
|
|
2222
|
-
[
|
|
2279
|
+
[import_ts_morph3.SyntaxKind.EqualsEqualsEqualsToken]: (left, right) => left === right(),
|
|
2280
|
+
[import_ts_morph3.SyntaxKind.ExclamationEqualsEqualsToken]: (left, right) => left !== right(),
|
|
2281
|
+
[import_ts_morph3.SyntaxKind.BarBarToken]: (left, right) => left || right(),
|
|
2282
|
+
[import_ts_morph3.SyntaxKind.AmpersandAmpersandToken]: (left, right) => left && right(),
|
|
2283
|
+
[import_ts_morph3.SyntaxKind.EqualsEqualsToken]: (left, right) => left == right(),
|
|
2284
|
+
[import_ts_morph3.SyntaxKind.ExclamationEqualsToken]: (left, right) => left != right()
|
|
2223
2285
|
};
|
|
2224
2286
|
if (node.getOperatorToken().getKind() in mapping) {
|
|
2225
2287
|
return mapping[node.getOperatorToken().getKind()](
|
|
@@ -2229,40 +2291,40 @@ var VISITOR = {
|
|
|
2229
2291
|
}
|
|
2230
2292
|
throw new Error(`Cannot handle operator of kind ${node.getOperatorToken().getKindName()}`);
|
|
2231
2293
|
},
|
|
2232
|
-
[
|
|
2233
|
-
[
|
|
2234
|
-
[
|
|
2235
|
-
[
|
|
2236
|
-
[
|
|
2294
|
+
[import_ts_morph3.SyntaxKind.SatisfiesExpression]: (node, context) => staticEval(node.getExpression(), context),
|
|
2295
|
+
[import_ts_morph3.SyntaxKind.TemplateExpression]: (node, context) => node.getHead().getLiteralText() + node.getTemplateSpans().map((span) => staticEval(span.getExpression(), context) + staticEval(span.getLiteral(), context)).join(""),
|
|
2296
|
+
[import_ts_morph3.SyntaxKind.TemplateTail]: (node) => node.getLiteralText(),
|
|
2297
|
+
[import_ts_morph3.SyntaxKind.TemplateMiddle]: (node) => node.getLiteralText(),
|
|
2298
|
+
[import_ts_morph3.SyntaxKind.PrefixUnaryExpression]: (node, context) => {
|
|
2237
2299
|
switch (node.getOperatorToken()) {
|
|
2238
|
-
case
|
|
2300
|
+
case import_ts_morph3.SyntaxKind.PlusToken:
|
|
2239
2301
|
return +staticEval(node.getOperand(), context);
|
|
2240
|
-
case
|
|
2302
|
+
case import_ts_morph3.SyntaxKind.MinusToken:
|
|
2241
2303
|
return -staticEval(node.getOperand(), context);
|
|
2242
|
-
case
|
|
2304
|
+
case import_ts_morph3.SyntaxKind.TildeToken:
|
|
2243
2305
|
return ~staticEval(node.getOperand(), context);
|
|
2244
|
-
case
|
|
2306
|
+
case import_ts_morph3.SyntaxKind.ExclamationToken:
|
|
2245
2307
|
return !staticEval(node.getOperand(), context);
|
|
2246
|
-
case
|
|
2247
|
-
case
|
|
2308
|
+
case import_ts_morph3.SyntaxKind.PlusPlusToken:
|
|
2309
|
+
case import_ts_morph3.SyntaxKind.MinusMinusToken:
|
|
2248
2310
|
throw new Error(`Cannot handle assignments.`);
|
|
2249
2311
|
}
|
|
2250
2312
|
},
|
|
2251
|
-
[
|
|
2313
|
+
[import_ts_morph3.SyntaxKind.ElementAccessExpression]: (node, context) => {
|
|
2252
2314
|
const target = staticEval(node.getExpression(), context);
|
|
2253
2315
|
const argument = staticEval(node.getArgumentExpression(), context);
|
|
2254
2316
|
return target[argument];
|
|
2255
2317
|
},
|
|
2256
|
-
[
|
|
2257
|
-
[
|
|
2258
|
-
[
|
|
2259
|
-
[
|
|
2318
|
+
[import_ts_morph3.SyntaxKind.NoSubstitutionTemplateLiteral]: (node) => node.getLiteralValue(),
|
|
2319
|
+
[import_ts_morph3.SyntaxKind.NullKeyword]: () => null,
|
|
2320
|
+
[import_ts_morph3.SyntaxKind.NewExpression]: (node, context) => new (staticEval(node.getExpression(), context))(...node.getArguments().map((arg) => staticEval(arg, context))),
|
|
2321
|
+
[import_ts_morph3.SyntaxKind.TypeOfExpression]: (node, context) => typeof staticEval(node.getExpression(), context)
|
|
2260
2322
|
};
|
|
2261
2323
|
|
|
2262
2324
|
// src/bin/gqm/utils.ts
|
|
2263
|
-
var
|
|
2325
|
+
var import_ts_morph4 = require("ts-morph");
|
|
2264
2326
|
var findDeclarationInFile = (sourceFile, name2) => {
|
|
2265
|
-
const syntaxList = sourceFile.getChildrenOfKind(
|
|
2327
|
+
const syntaxList = sourceFile.getChildrenOfKind(import_ts_morph4.SyntaxKind.SyntaxList)[0];
|
|
2266
2328
|
if (!syntaxList) {
|
|
2267
2329
|
throw new Error("No SyntaxList");
|
|
2268
2330
|
}
|
|
@@ -2273,7 +2335,7 @@ var findDeclarationInFile = (sourceFile, name2) => {
|
|
|
2273
2335
|
return declaration;
|
|
2274
2336
|
};
|
|
2275
2337
|
var findDeclaration = (syntaxList, name2) => {
|
|
2276
|
-
for (const variableStatement of syntaxList.getChildrenOfKind(
|
|
2338
|
+
for (const variableStatement of syntaxList.getChildrenOfKind(import_ts_morph4.SyntaxKind.VariableStatement)) {
|
|
2277
2339
|
for (const declaration of variableStatement.getDeclarationList().getDeclarations()) {
|
|
2278
2340
|
if (declaration.getName() === name2) {
|
|
2279
2341
|
return declaration;
|
|
@@ -2284,9 +2346,9 @@ var findDeclaration = (syntaxList, name2) => {
|
|
|
2284
2346
|
|
|
2285
2347
|
// src/bin/gqm/parse-knexfile.ts
|
|
2286
2348
|
var parseKnexfile = async () => {
|
|
2287
|
-
const project = new
|
|
2349
|
+
const project = new import_ts_morph5.Project({
|
|
2288
2350
|
manipulationSettings: {
|
|
2289
|
-
indentationText:
|
|
2351
|
+
indentationText: import_ts_morph5.IndentationText.TwoSpaces
|
|
2290
2352
|
}
|
|
2291
2353
|
});
|
|
2292
2354
|
const knexfilePath = await getSetting("knexfilePath");
|
|
@@ -2298,11 +2360,11 @@ var parseKnexfile = async () => {
|
|
|
2298
2360
|
};
|
|
2299
2361
|
|
|
2300
2362
|
// src/bin/gqm/parse-models.ts
|
|
2301
|
-
var
|
|
2363
|
+
var import_ts_morph6 = require("ts-morph");
|
|
2302
2364
|
var parseModels = async () => {
|
|
2303
|
-
const project = new
|
|
2365
|
+
const project = new import_ts_morph6.Project({
|
|
2304
2366
|
manipulationSettings: {
|
|
2305
|
-
indentationText:
|
|
2367
|
+
indentationText: import_ts_morph6.IndentationText.TwoSpaces
|
|
2306
2368
|
}
|
|
2307
2369
|
});
|
|
2308
2370
|
const modelsPath = await getSetting("modelsPath");
|
|
@@ -2339,6 +2401,7 @@ import_commander.program.command("generate").description("Generate all the thing
|
|
|
2339
2401
|
const dateLibrary = await getSetting("dateLibrary");
|
|
2340
2402
|
writeToFile(`${generatedFolderPath}/db/index.ts`, generateDBModels(models, dateLibrary));
|
|
2341
2403
|
writeToFile(`${generatedFolderPath}/db/knex.ts`, generateKnexTables(models));
|
|
2404
|
+
writeToFile(`${generatedFolderPath}/permissions.ts`, generatePermissionTypes(models));
|
|
2342
2405
|
await generateGraphqlApiTypes(dateLibrary);
|
|
2343
2406
|
await generateGraphqlClientTypes();
|
|
2344
2407
|
});
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.ts
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
+
ACTIONS: () => ACTIONS,
|
|
32
33
|
AliasGenerator: () => AliasGenerator,
|
|
33
34
|
DATE_CLASS: () => DATE_CLASS,
|
|
34
35
|
DATE_CLASS_IMPORT: () => DATE_CLASS_IMPORT,
|
|
@@ -46,6 +47,7 @@ __export(index_exports, {
|
|
|
46
47
|
NormalRelation: () => NormalRelation,
|
|
47
48
|
NotFoundError: () => NotFoundError,
|
|
48
49
|
ObjectModel: () => ObjectModel,
|
|
50
|
+
PRIMITIVE_TYPES: () => PRIMITIVE_TYPES,
|
|
49
51
|
PermissionError: () => PermissionError,
|
|
50
52
|
RawEnumModel: () => RawEnumModel,
|
|
51
53
|
Relation: () => Relation,
|
|
@@ -82,6 +84,7 @@ __export(index_exports, {
|
|
|
82
84
|
generateDefinitions: () => generateDefinitions,
|
|
83
85
|
generateKnexTables: () => generateKnexTables,
|
|
84
86
|
generateMutations: () => generateMutations,
|
|
87
|
+
generatePermissionTypes: () => generatePermissionTypes,
|
|
85
88
|
generatePermissions: () => generatePermissions,
|
|
86
89
|
get: () => get,
|
|
87
90
|
getActionableRelations: () => getActionableRelations,
|
|
@@ -1986,6 +1989,9 @@ var applyWhere = (model, query, alias, where, aliases) => {
|
|
|
1986
1989
|
}
|
|
1987
1990
|
};
|
|
1988
1991
|
|
|
1992
|
+
// src/permissions/generate-types.ts
|
|
1993
|
+
var import_ts_morph = require("ts-morph");
|
|
1994
|
+
|
|
1989
1995
|
// src/permissions/generate.ts
|
|
1990
1996
|
var ACTIONS = ["READ", "CREATE", "UPDATE", "DELETE", "RESTORE", "LINK"];
|
|
1991
1997
|
var generatePermissions = (models, config) => {
|
|
@@ -2067,6 +2073,62 @@ var addPermissions = (models, permissions, links, block) => {
|
|
|
2067
2073
|
}
|
|
2068
2074
|
};
|
|
2069
2075
|
|
|
2076
|
+
// src/permissions/generate-types.ts
|
|
2077
|
+
var generatePermissionTypes = (models) => {
|
|
2078
|
+
const project = new import_ts_morph.Project({
|
|
2079
|
+
manipulationSettings: {
|
|
2080
|
+
indentationText: import_ts_morph.IndentationText.TwoSpaces
|
|
2081
|
+
}
|
|
2082
|
+
});
|
|
2083
|
+
const sourceFile = project.createSourceFile("permissions.ts", "", {
|
|
2084
|
+
overwrite: true
|
|
2085
|
+
});
|
|
2086
|
+
sourceFile.addStatements(`export type PermissionsConfig = Record<Role, PermissionsBlock>;`);
|
|
2087
|
+
sourceFile.addStatements(
|
|
2088
|
+
(writer) => writer.write(`export type PermissionsBlock = true | `).inlineBlock(() => {
|
|
2089
|
+
writer.writeLine(`me?: UserPermissionsBlock,`);
|
|
2090
|
+
for (const model of models.entities) {
|
|
2091
|
+
writer.writeLine(`${model.name}?: ${model.name}PermissionsBlock,`);
|
|
2092
|
+
}
|
|
2093
|
+
})
|
|
2094
|
+
);
|
|
2095
|
+
for (const enm2 of models.enums) {
|
|
2096
|
+
sourceFile.addStatements((writer) => writer.write(`type ${enm2.name} = ${enm2.values.map((v) => `'${v}'`).join(" | ")};`));
|
|
2097
|
+
}
|
|
2098
|
+
for (const model of models.entities) {
|
|
2099
|
+
sourceFile.addStatements(
|
|
2100
|
+
(writer) => writer.write(`export type ${model.name}Where = `).inlineBlock(() => {
|
|
2101
|
+
for (const field of model.fields.filter((field2) => field2.filterable)) {
|
|
2102
|
+
if (field.kind === "relation") {
|
|
2103
|
+
writer.writeLine(`${field.name}?: ${field.type}Where,`);
|
|
2104
|
+
} else if (!field.kind || field.kind === "primitive") {
|
|
2105
|
+
writer.writeLine(`${field.name}?: ${PRIMITIVE_TYPES[field.type]} | ${PRIMITIVE_TYPES[field.type]}[],`);
|
|
2106
|
+
} else {
|
|
2107
|
+
writer.writeLine(`${field.name}?: ${field.type} | ${field.type}[],`);
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
})
|
|
2111
|
+
);
|
|
2112
|
+
sourceFile.addStatements(
|
|
2113
|
+
(writer) => writer.write(`export type ${model.name}PermissionsBlock = `).inlineBlock(() => {
|
|
2114
|
+
for (const action of ACTIONS) {
|
|
2115
|
+
writer.writeLine(`${action}?: true,`);
|
|
2116
|
+
}
|
|
2117
|
+
writer.writeLine(`WHERE?: ${model.name}Where,`);
|
|
2118
|
+
const relations = [...model.relations, ...model.reverseRelations];
|
|
2119
|
+
if (relations.length > 0) {
|
|
2120
|
+
writer.write(`RELATIONS?: `).inlineBlock(() => {
|
|
2121
|
+
for (const relation of relations) {
|
|
2122
|
+
writer.writeLine(`${relation.name}?: ${relation.targetModel.name}PermissionsBlock,`);
|
|
2123
|
+
}
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
})
|
|
2127
|
+
);
|
|
2128
|
+
}
|
|
2129
|
+
return sourceFile.getFullText();
|
|
2130
|
+
};
|
|
2131
|
+
|
|
2070
2132
|
// src/resolvers/arguments.ts
|
|
2071
2133
|
var import_graphql4 = require("graphql");
|
|
2072
2134
|
function getRawValue(value2, values) {
|
|
@@ -3502,6 +3564,7 @@ var printSchemaFromDocument = (document2) => printSchema((0, import_graphql6.bui
|
|
|
3502
3564
|
var printSchemaFromModels = (models) => printSchema((0, import_graphql6.buildASTSchema)(generate(models)));
|
|
3503
3565
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3504
3566
|
0 && (module.exports = {
|
|
3567
|
+
ACTIONS,
|
|
3505
3568
|
AliasGenerator,
|
|
3506
3569
|
DATE_CLASS,
|
|
3507
3570
|
DATE_CLASS_IMPORT,
|
|
@@ -3519,6 +3582,7 @@ var printSchemaFromModels = (models) => printSchema((0, import_graphql6.buildAST
|
|
|
3519
3582
|
NormalRelation,
|
|
3520
3583
|
NotFoundError,
|
|
3521
3584
|
ObjectModel,
|
|
3585
|
+
PRIMITIVE_TYPES,
|
|
3522
3586
|
PermissionError,
|
|
3523
3587
|
RawEnumModel,
|
|
3524
3588
|
Relation,
|
|
@@ -3555,6 +3619,7 @@ var printSchemaFromModels = (models) => printSchema((0, import_graphql6.buildAST
|
|
|
3555
3619
|
generateDefinitions,
|
|
3556
3620
|
generateKnexTables,
|
|
3557
3621
|
generateMutations,
|
|
3622
|
+
generatePermissionTypes,
|
|
3558
3623
|
generatePermissions,
|
|
3559
3624
|
get,
|
|
3560
3625
|
getActionableRelations,
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { Models } from '../models/models';
|
|
2
2
|
import { DateLibrary } from '../utils/dates';
|
|
3
|
+
export declare const PRIMITIVE_TYPES: {
|
|
4
|
+
ID: string;
|
|
5
|
+
Boolean: string;
|
|
6
|
+
Upload: string;
|
|
7
|
+
Int: string;
|
|
8
|
+
Float: string;
|
|
9
|
+
String: string;
|
|
10
|
+
};
|
|
3
11
|
export declare const generateDBModels: (models: Models, dateLibrary: DateLibrary) => string;
|
|
4
12
|
export declare const generateKnexTables: (models: Models) => string;
|
package/dist/esm/db/generate.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import CodeBlockWriter from 'code-block-writer';
|
|
2
2
|
import { get, getColumnName, isCustomField, isInTable, isRootModel, not } from '..';
|
|
3
3
|
import { DATE_CLASS, DATE_CLASS_IMPORT } from '../utils/dates';
|
|
4
|
-
const PRIMITIVE_TYPES = {
|
|
4
|
+
export const PRIMITIVE_TYPES = {
|
|
5
5
|
ID: 'string',
|
|
6
6
|
Boolean: 'boolean',
|
|
7
7
|
Upload: 'string',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/db/generate.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAe,GAAG,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC;AAEjG,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAe,MAAM,gBAAgB,CAAC;AAE5E,MAAM,eAAe,GAAG;
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/db/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { IndentationText, Project } from 'ts-morph';
|
|
2
|
+
import { PRIMITIVE_TYPES } from '../db/generate';
|
|
3
|
+
import { ACTIONS } from './generate';
|
|
4
|
+
export const generatePermissionTypes = (models) => {
|
|
5
|
+
const project = new Project({
|
|
6
|
+
manipulationSettings: {
|
|
7
|
+
indentationText: IndentationText.TwoSpaces,
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
const sourceFile = project.createSourceFile('permissions.ts', '', {
|
|
11
|
+
overwrite: true,
|
|
12
|
+
});
|
|
13
|
+
sourceFile.addStatements(`export type PermissionsConfig = Record<Role, PermissionsBlock>;`);
|
|
14
|
+
sourceFile.addStatements((writer) => writer.write(`export type PermissionsBlock = true | `).inlineBlock(() => {
|
|
15
|
+
writer.writeLine(`me?: UserPermissionsBlock,`);
|
|
16
|
+
for (const model of models.entities) {
|
|
17
|
+
writer.writeLine(`${model.name}?: ${model.name}PermissionsBlock,`);
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
for (const enm of models.enums) {
|
|
21
|
+
sourceFile.addStatements((writer) => writer.write(`type ${enm.name} = ${enm.values.map((v) => `'${v}'`).join(' | ')};`));
|
|
22
|
+
}
|
|
23
|
+
for (const model of models.entities) {
|
|
24
|
+
sourceFile.addStatements((writer) => writer.write(`export type ${model.name}Where = `).inlineBlock(() => {
|
|
25
|
+
for (const field of model.fields.filter((field) => field.filterable)) {
|
|
26
|
+
if (field.kind === 'relation') {
|
|
27
|
+
writer.writeLine(`${field.name}?: ${field.type}Where,`);
|
|
28
|
+
}
|
|
29
|
+
else if (!field.kind || field.kind === 'primitive') {
|
|
30
|
+
writer.writeLine(`${field.name}?: ${PRIMITIVE_TYPES[field.type]} | ${PRIMITIVE_TYPES[field.type]}[],`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
writer.writeLine(`${field.name}?: ${field.type} | ${field.type}[],`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}));
|
|
37
|
+
sourceFile.addStatements((writer) => writer.write(`export type ${model.name}PermissionsBlock = `).inlineBlock(() => {
|
|
38
|
+
for (const action of ACTIONS) {
|
|
39
|
+
writer.writeLine(`${action}?: true,`);
|
|
40
|
+
}
|
|
41
|
+
writer.writeLine(`WHERE?: ${model.name}Where,`);
|
|
42
|
+
const relations = [...model.relations, ...model.reverseRelations];
|
|
43
|
+
if (relations.length > 0) {
|
|
44
|
+
writer.write(`RELATIONS?: `).inlineBlock(() => {
|
|
45
|
+
for (const relation of relations) {
|
|
46
|
+
writer.writeLine(`${relation.name}?: ${relation.targetModel.name}PermissionsBlock,`);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
return sourceFile.getFullText();
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=generate-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-types.js","sourceRoot":"","sources":["../../../src/permissions/generate-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isRelation } from '../models/utils';
|
|
2
|
-
const ACTIONS = ['READ', 'CREATE', 'UPDATE', 'DELETE', 'RESTORE', 'LINK'];
|
|
2
|
+
export const ACTIONS = ['READ', 'CREATE', 'UPDATE', 'DELETE', 'RESTORE', 'LINK'];
|
|
3
3
|
export const generatePermissions = (models, config) => {
|
|
4
4
|
const permissions = {};
|
|
5
5
|
for (const [role, roleConfig] of Object.entries(config)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/permissions/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAI7C,MAAM,OAAO,GAAuB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/permissions/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/permissions/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/permissions/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
|
@@ -3,18 +3,10 @@ import { Knex } from 'knex';
|
|
|
3
3
|
export const up = async (knex: Knex) => {
|
|
4
4
|
await knex.raw(`CREATE TYPE "someEnum" AS ENUM ('A','B','C')`);
|
|
5
5
|
|
|
6
|
-
await knex.raw(`CREATE TYPE "role" AS ENUM ('ADMIN','USER')`);
|
|
7
|
-
|
|
8
6
|
await knex.raw(`CREATE TYPE "reactionType" AS ENUM ('Review','Question','Answer')`);
|
|
9
7
|
|
|
10
|
-
await knex.schema.
|
|
11
|
-
table.
|
|
12
|
-
table.string('username', undefined).nullable();
|
|
13
|
-
table.enum('role', null, {
|
|
14
|
-
useNative: true,
|
|
15
|
-
existingType: true,
|
|
16
|
-
enumName: 'role',
|
|
17
|
-
}).notNullable();
|
|
8
|
+
await knex.schema.alterTable('User', (table) => {
|
|
9
|
+
table.string('username', undefined);
|
|
18
10
|
});
|
|
19
11
|
|
|
20
12
|
await knex.schema.createTable('AnotherObject', (table) => {
|
|
@@ -123,9 +115,29 @@ export const up = async (knex: Knex) => {
|
|
|
123
115
|
table.decimal('rating', undefined, undefined).nullable();
|
|
124
116
|
});
|
|
125
117
|
|
|
118
|
+
await knex.schema.alterTable('User', (table) => {
|
|
119
|
+
table.dropColumn('createdAt');
|
|
120
|
+
table.dropColumn('updatedAt');
|
|
121
|
+
});
|
|
122
|
+
|
|
126
123
|
};
|
|
127
124
|
|
|
128
125
|
export const down = async (knex: Knex) => {
|
|
126
|
+
await knex.schema.alterTable('User', (table) => {
|
|
127
|
+
table.timestamp('createdAt');
|
|
128
|
+
table.timestamp('updatedAt');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
await knex('User').update({
|
|
132
|
+
createdAt: 'TODO',
|
|
133
|
+
updatedAt: 'TODO',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await knex.schema.alterTable('User', (table) => {
|
|
137
|
+
table.timestamp('createdAt').notNullable().alter();
|
|
138
|
+
table.timestamp('updatedAt').notNullable().alter();
|
|
139
|
+
});
|
|
140
|
+
|
|
129
141
|
await knex.schema.dropTable('ReviewRevision');
|
|
130
142
|
|
|
131
143
|
await knex.schema.dropTable('Review');
|
|
@@ -140,10 +152,11 @@ export const down = async (knex: Knex) => {
|
|
|
140
152
|
|
|
141
153
|
await knex.schema.dropTable('AnotherObject');
|
|
142
154
|
|
|
143
|
-
await knex.schema.
|
|
155
|
+
await knex.schema.alterTable('User', (table) => {
|
|
156
|
+
table.dropColumn('username');
|
|
157
|
+
});
|
|
144
158
|
|
|
145
159
|
await knex.raw('DROP TYPE "reactionType"');
|
|
146
|
-
await knex.raw('DROP TYPE "role"');
|
|
147
160
|
await knex.raw('DROP TYPE "someEnum"');
|
|
148
161
|
};
|
|
149
162
|
|
package/package.json
CHANGED
package/src/bin/gqm/gqm.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
getMigrationDate,
|
|
13
13
|
printSchemaFromModels,
|
|
14
14
|
} from '../..';
|
|
15
|
+
import { generatePermissionTypes } from '../../permissions/generate-types';
|
|
15
16
|
import { DateLibrary } from '../../utils/dates';
|
|
16
17
|
import { generateGraphqlApiTypes, generateGraphqlClientTypes } from './codegen';
|
|
17
18
|
import { parseKnexfile } from './parse-knexfile';
|
|
@@ -49,6 +50,7 @@ program
|
|
|
49
50
|
const dateLibrary = (await getSetting('dateLibrary')) as DateLibrary;
|
|
50
51
|
writeToFile(`${generatedFolderPath}/db/index.ts`, generateDBModels(models, dateLibrary));
|
|
51
52
|
writeToFile(`${generatedFolderPath}/db/knex.ts`, generateKnexTables(models));
|
|
53
|
+
writeToFile(`${generatedFolderPath}/permissions.ts`, generatePermissionTypes(models));
|
|
52
54
|
await generateGraphqlApiTypes(dateLibrary);
|
|
53
55
|
await generateGraphqlClientTypes();
|
|
54
56
|
});
|
package/src/db/generate.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { EntityField, get, getColumnName, isCustomField, isInTable, isRootModel,
|
|
|
3
3
|
import { Models } from '../models/models';
|
|
4
4
|
import { DATE_CLASS, DATE_CLASS_IMPORT, DateLibrary } from '../utils/dates';
|
|
5
5
|
|
|
6
|
-
const PRIMITIVE_TYPES = {
|
|
6
|
+
export const PRIMITIVE_TYPES = {
|
|
7
7
|
ID: 'string',
|
|
8
8
|
Boolean: 'boolean',
|
|
9
9
|
Upload: 'string',
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { IndentationText, Project } from 'ts-morph';
|
|
2
|
+
import { PRIMITIVE_TYPES } from '../db/generate';
|
|
3
|
+
import { Models } from '../models';
|
|
4
|
+
import { ACTIONS } from './generate';
|
|
5
|
+
|
|
6
|
+
export const generatePermissionTypes = (models: Models) => {
|
|
7
|
+
const project = new Project({
|
|
8
|
+
manipulationSettings: {
|
|
9
|
+
indentationText: IndentationText.TwoSpaces,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const sourceFile = project.createSourceFile('permissions.ts', '', {
|
|
14
|
+
overwrite: true,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
sourceFile.addStatements(`export type PermissionsConfig = Record<Role, PermissionsBlock>;`);
|
|
18
|
+
|
|
19
|
+
sourceFile.addStatements((writer) =>
|
|
20
|
+
writer.write(`export type PermissionsBlock = true | `).inlineBlock(() => {
|
|
21
|
+
writer.writeLine(`me?: UserPermissionsBlock,`);
|
|
22
|
+
for (const model of models.entities) {
|
|
23
|
+
writer.writeLine(`${model.name}?: ${model.name}PermissionsBlock,`);
|
|
24
|
+
}
|
|
25
|
+
}),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
for (const enm of models.enums) {
|
|
29
|
+
sourceFile.addStatements((writer) => writer.write(`type ${enm.name} = ${enm.values.map((v) => `'${v}'`).join(' | ')};`));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (const model of models.entities) {
|
|
33
|
+
sourceFile.addStatements((writer) =>
|
|
34
|
+
writer.write(`export type ${model.name}Where = `).inlineBlock(() => {
|
|
35
|
+
for (const field of model.fields.filter((field) => field.filterable)) {
|
|
36
|
+
if (field.kind === 'relation') {
|
|
37
|
+
writer.writeLine(`${field.name}?: ${field.type}Where,`);
|
|
38
|
+
} else if (!field.kind || field.kind === 'primitive') {
|
|
39
|
+
writer.writeLine(`${field.name}?: ${PRIMITIVE_TYPES[field.type]} | ${PRIMITIVE_TYPES[field.type]}[],`);
|
|
40
|
+
} else {
|
|
41
|
+
writer.writeLine(`${field.name}?: ${field.type} | ${field.type}[],`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
sourceFile.addStatements((writer) =>
|
|
48
|
+
writer.write(`export type ${model.name}PermissionsBlock = `).inlineBlock(() => {
|
|
49
|
+
for (const action of ACTIONS) {
|
|
50
|
+
writer.writeLine(`${action}?: true,`);
|
|
51
|
+
}
|
|
52
|
+
writer.writeLine(`WHERE?: ${model.name}Where,`);
|
|
53
|
+
const relations = [...model.relations, ...model.reverseRelations];
|
|
54
|
+
if (relations.length > 0) {
|
|
55
|
+
writer.write(`RELATIONS?: `).inlineBlock(() => {
|
|
56
|
+
for (const relation of relations) {
|
|
57
|
+
writer.writeLine(`${relation.name}?: ${relation.targetModel.name}PermissionsBlock,`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return sourceFile.getFullText();
|
|
66
|
+
};
|
|
@@ -3,7 +3,7 @@ import { isRelation } from '../models/utils';
|
|
|
3
3
|
|
|
4
4
|
export type PermissionAction = 'READ' | 'CREATE' | 'UPDATE' | 'DELETE' | 'RESTORE' | 'LINK';
|
|
5
5
|
|
|
6
|
-
const ACTIONS: PermissionAction[] = ['READ', 'CREATE', 'UPDATE', 'DELETE', 'RESTORE', 'LINK'];
|
|
6
|
+
export const ACTIONS: PermissionAction[] = ['READ', 'CREATE', 'UPDATE', 'DELETE', 'RESTORE', 'LINK'];
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Initial representation (tree structure, as defined by user).
|
package/src/permissions/index.ts
CHANGED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
export type PermissionsConfig = Record<Role, PermissionsBlock>;
|
|
2
|
+
export type PermissionsBlock = true | {
|
|
3
|
+
me?: UserPermissionsBlock,
|
|
4
|
+
User?: UserPermissionsBlock,
|
|
5
|
+
AnotherObject?: AnotherObjectPermissionsBlock,
|
|
6
|
+
SomeObject?: SomeObjectPermissionsBlock,
|
|
7
|
+
Reaction?: ReactionPermissionsBlock,
|
|
8
|
+
Review?: ReviewPermissionsBlock,
|
|
9
|
+
Question?: QuestionPermissionsBlock,
|
|
10
|
+
Answer?: AnswerPermissionsBlock,
|
|
11
|
+
}
|
|
12
|
+
type SomeEnum = 'A' | 'B' | 'C';
|
|
13
|
+
type Role = 'ADMIN' | 'USER';
|
|
14
|
+
type ReactionType = 'Review' | 'Question' | 'Answer';
|
|
15
|
+
export type UserWhere = {
|
|
16
|
+
}
|
|
17
|
+
export type UserPermissionsBlock = {
|
|
18
|
+
READ?: true,
|
|
19
|
+
CREATE?: true,
|
|
20
|
+
UPDATE?: true,
|
|
21
|
+
DELETE?: true,
|
|
22
|
+
RESTORE?: true,
|
|
23
|
+
LINK?: true,
|
|
24
|
+
WHERE?: UserWhere,
|
|
25
|
+
RELATIONS?: {
|
|
26
|
+
deletedAnotherObjects?: AnotherObjectPermissionsBlock,
|
|
27
|
+
createdManyObjects?: SomeObjectPermissionsBlock,
|
|
28
|
+
updatedManyObjects?: SomeObjectPermissionsBlock,
|
|
29
|
+
deletedManyObjects?: SomeObjectPermissionsBlock,
|
|
30
|
+
createdReactions?: ReactionPermissionsBlock,
|
|
31
|
+
updatedReactions?: ReactionPermissionsBlock,
|
|
32
|
+
deletedReactions?: ReactionPermissionsBlock,
|
|
33
|
+
createdReviews?: ReviewPermissionsBlock,
|
|
34
|
+
updatedReviews?: ReviewPermissionsBlock,
|
|
35
|
+
deletedReviews?: ReviewPermissionsBlock,
|
|
36
|
+
createdQuestions?: QuestionPermissionsBlock,
|
|
37
|
+
updatedQuestions?: QuestionPermissionsBlock,
|
|
38
|
+
deletedQuestions?: QuestionPermissionsBlock,
|
|
39
|
+
createdAnswers?: AnswerPermissionsBlock,
|
|
40
|
+
updatedAnswers?: AnswerPermissionsBlock,
|
|
41
|
+
deletedAnswers?: AnswerPermissionsBlock,
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export type AnotherObjectWhere = {
|
|
45
|
+
deleted?: boolean | boolean[],
|
|
46
|
+
}
|
|
47
|
+
export type AnotherObjectPermissionsBlock = {
|
|
48
|
+
READ?: true,
|
|
49
|
+
CREATE?: true,
|
|
50
|
+
UPDATE?: true,
|
|
51
|
+
DELETE?: true,
|
|
52
|
+
RESTORE?: true,
|
|
53
|
+
LINK?: true,
|
|
54
|
+
WHERE?: AnotherObjectWhere,
|
|
55
|
+
RELATIONS?: {
|
|
56
|
+
myself?: AnotherObjectPermissionsBlock,
|
|
57
|
+
deletedBy?: UserPermissionsBlock,
|
|
58
|
+
self?: AnotherObjectPermissionsBlock,
|
|
59
|
+
manyObjects?: SomeObjectPermissionsBlock,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export type SomeObjectWhere = {
|
|
63
|
+
field?: string | string[],
|
|
64
|
+
another?: AnotherObjectWhere,
|
|
65
|
+
float?: number | number[],
|
|
66
|
+
xyz?: number | number[],
|
|
67
|
+
deleted?: boolean | boolean[],
|
|
68
|
+
}
|
|
69
|
+
export type SomeObjectPermissionsBlock = {
|
|
70
|
+
READ?: true,
|
|
71
|
+
CREATE?: true,
|
|
72
|
+
UPDATE?: true,
|
|
73
|
+
DELETE?: true,
|
|
74
|
+
RESTORE?: true,
|
|
75
|
+
LINK?: true,
|
|
76
|
+
WHERE?: SomeObjectWhere,
|
|
77
|
+
RELATIONS?: {
|
|
78
|
+
another?: AnotherObjectPermissionsBlock,
|
|
79
|
+
createdBy?: UserPermissionsBlock,
|
|
80
|
+
updatedBy?: UserPermissionsBlock,
|
|
81
|
+
deletedBy?: UserPermissionsBlock,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export type ReactionWhere = {
|
|
85
|
+
deleted?: boolean | boolean[],
|
|
86
|
+
}
|
|
87
|
+
export type ReactionPermissionsBlock = {
|
|
88
|
+
READ?: true,
|
|
89
|
+
CREATE?: true,
|
|
90
|
+
UPDATE?: true,
|
|
91
|
+
DELETE?: true,
|
|
92
|
+
RESTORE?: true,
|
|
93
|
+
LINK?: true,
|
|
94
|
+
WHERE?: ReactionWhere,
|
|
95
|
+
RELATIONS?: {
|
|
96
|
+
parent?: ReactionPermissionsBlock,
|
|
97
|
+
createdBy?: UserPermissionsBlock,
|
|
98
|
+
updatedBy?: UserPermissionsBlock,
|
|
99
|
+
deletedBy?: UserPermissionsBlock,
|
|
100
|
+
childReactions?: ReactionPermissionsBlock,
|
|
101
|
+
childReviews?: ReviewPermissionsBlock,
|
|
102
|
+
childQuestions?: QuestionPermissionsBlock,
|
|
103
|
+
childAnswers?: AnswerPermissionsBlock,
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export type ReviewWhere = {
|
|
107
|
+
deleted?: boolean | boolean[],
|
|
108
|
+
}
|
|
109
|
+
export type ReviewPermissionsBlock = {
|
|
110
|
+
READ?: true,
|
|
111
|
+
CREATE?: true,
|
|
112
|
+
UPDATE?: true,
|
|
113
|
+
DELETE?: true,
|
|
114
|
+
RESTORE?: true,
|
|
115
|
+
LINK?: true,
|
|
116
|
+
WHERE?: ReviewWhere,
|
|
117
|
+
RELATIONS?: {
|
|
118
|
+
parent?: ReactionPermissionsBlock,
|
|
119
|
+
createdBy?: UserPermissionsBlock,
|
|
120
|
+
updatedBy?: UserPermissionsBlock,
|
|
121
|
+
deletedBy?: UserPermissionsBlock,
|
|
122
|
+
childReactions?: ReactionPermissionsBlock,
|
|
123
|
+
childReviews?: ReviewPermissionsBlock,
|
|
124
|
+
childQuestions?: QuestionPermissionsBlock,
|
|
125
|
+
childAnswers?: AnswerPermissionsBlock,
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export type QuestionWhere = {
|
|
129
|
+
deleted?: boolean | boolean[],
|
|
130
|
+
}
|
|
131
|
+
export type QuestionPermissionsBlock = {
|
|
132
|
+
READ?: true,
|
|
133
|
+
CREATE?: true,
|
|
134
|
+
UPDATE?: true,
|
|
135
|
+
DELETE?: true,
|
|
136
|
+
RESTORE?: true,
|
|
137
|
+
LINK?: true,
|
|
138
|
+
WHERE?: QuestionWhere,
|
|
139
|
+
RELATIONS?: {
|
|
140
|
+
parent?: ReactionPermissionsBlock,
|
|
141
|
+
createdBy?: UserPermissionsBlock,
|
|
142
|
+
updatedBy?: UserPermissionsBlock,
|
|
143
|
+
deletedBy?: UserPermissionsBlock,
|
|
144
|
+
childReactions?: ReactionPermissionsBlock,
|
|
145
|
+
childReviews?: ReviewPermissionsBlock,
|
|
146
|
+
childQuestions?: QuestionPermissionsBlock,
|
|
147
|
+
childAnswers?: AnswerPermissionsBlock,
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
export type AnswerWhere = {
|
|
151
|
+
deleted?: boolean | boolean[],
|
|
152
|
+
}
|
|
153
|
+
export type AnswerPermissionsBlock = {
|
|
154
|
+
READ?: true,
|
|
155
|
+
CREATE?: true,
|
|
156
|
+
UPDATE?: true,
|
|
157
|
+
DELETE?: true,
|
|
158
|
+
RESTORE?: true,
|
|
159
|
+
LINK?: true,
|
|
160
|
+
WHERE?: AnswerWhere,
|
|
161
|
+
RELATIONS?: {
|
|
162
|
+
parent?: ReactionPermissionsBlock,
|
|
163
|
+
createdBy?: UserPermissionsBlock,
|
|
164
|
+
updatedBy?: UserPermissionsBlock,
|
|
165
|
+
deletedBy?: UserPermissionsBlock,
|
|
166
|
+
childReactions?: ReactionPermissionsBlock,
|
|
167
|
+
childReviews?: ReviewPermissionsBlock,
|
|
168
|
+
childQuestions?: QuestionPermissionsBlock,
|
|
169
|
+
childAnswers?: AnswerPermissionsBlock,
|
|
170
|
+
}
|
|
171
|
+
}
|