@nhtio/lucid-resourceful 0.1.0-master-1570171e → 0.1.0-master-3ec631a4
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/{definitions-DgI468dW.cjs → data_type_schemas-BqeljaQB.cjs} +21 -177
- package/data_type_schemas-BqeljaQB.cjs.map +1 -0
- package/data_type_schemas-Cpco9Zba.js +225 -0
- package/data_type_schemas-Cpco9Zba.js.map +1 -0
- package/{decorator_utils-U_rZo8tv.cjs → decorator_utils-DSvYjLYD.cjs} +204 -60
- package/decorator_utils-DSvYjLYD.cjs.map +1 -0
- package/{decorator_utils-YSb1EGJ6.js → decorator_utils-gyymixlk.js} +207 -65
- package/decorator_utils-gyymixlk.js.map +1 -0
- package/definitions-DcB6B_4d.js +174 -0
- package/definitions-DcB6B_4d.js.map +1 -0
- package/definitions-DjQRkCeH.cjs +173 -0
- package/definitions-DjQRkCeH.cjs.map +1 -0
- package/definitions.cjs +1 -1
- package/definitions.mjs +11 -11
- package/{errors-B1rr67uM.js → errors-C-x5_jRE.js} +162 -27
- package/errors-C-x5_jRE.js.map +1 -0
- package/{errors-D8jb9VxY.cjs → errors-CNwuNhBV.cjs} +138 -5
- package/errors-CNwuNhBV.cjs.map +1 -0
- package/errors.cjs +5 -1
- package/errors.cjs.map +1 -1
- package/errors.d.ts +24 -2
- package/errors.mjs +19 -15
- package/index.cjs +1471 -771
- package/index.cjs.map +1 -1
- package/index.mjs +1716 -1016
- package/index.mjs.map +1 -1
- package/joi.cjs +1854 -3368
- package/joi.cjs.map +1 -1
- package/joi.mjs +1857 -3371
- package/joi.mjs.map +1 -1
- package/package.json +1 -1
- package/private/decorators.d.ts +8 -8
- package/private/lucene_to_lucid_translator.d.ts +21 -175
- package/private/mixin.d.ts +68 -5
- package/private/services/open_api_schema_service.d.ts +111 -0
- package/private/type_guards.d.ts +62 -0
- package/private/types.d.ts +1 -1
- package/private/utils.d.ts +24 -0
- package/utils.cjs +1 -1
- package/utils.mjs +2 -2
- package/decorator_utils-U_rZo8tv.cjs.map +0 -1
- package/decorator_utils-YSb1EGJ6.js.map +0 -1
- package/definitions-B88XBTUF.js +0 -381
- package/definitions-B88XBTUF.js.map +0 -1
- package/definitions-DgI468dW.cjs.map +0 -1
- package/errors-B1rr67uM.js.map +0 -1
- package/errors-D8jb9VxY.cjs.map +0 -1
package/index.mjs
CHANGED
|
@@ -9,20 +9,17 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
9
9
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
10
10
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
11
11
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
12
|
-
var _a, _hookHandlers, _cleanupHandlers, _state, _handlersToIgnore, _skipAllHooks, _Runner_instances, filter_fn, exec_fn, _b, _hooks, _c, _d;
|
|
13
|
-
import { I as
|
|
14
|
-
import { joi as
|
|
12
|
+
var _attributesToColumns, _allowedColumns, _connection, _dialect, _primaryKey, _tableName, _model, _LuceneLucidQueryBuilder_instances, getSearchableColumns_fn, _OpenApiSchemaService_instances, getFieldKey_fn, extractDataTypeInfo_fn, _a, _hookHandlers, _cleanupHandlers, _state, _handlersToIgnore, _skipAllHooks, _Runner_instances, filter_fn, exec_fn, _b, _hooks, _c, _d;
|
|
13
|
+
import { I as isResourcefulModel, J as isResourcefulArrayType, K as isResourcefulObjectType, L as isObject$2, M as isResourcefulBooleanType, N as isResourcefulNumberType, O as isResourcefulUnsignedIntegerType, P as isResourcefulBigintType, Q as isResourcefulIntegerType, R as isResourcefulStringType, S as isResourcefulBinaryType, T as isResourcefulDateTimeType, U as isResourcefulDateType, V as DateTime, F as consumeString, u as prepareString, y as consumeBinary, m as prepareBinary, D as consumeNumber, s as prepareNumber, C as consumeInteger, r as prepareInteger, x as consumeBigint, l as prepareBigint, G as consumeUnsignedint, v as prepareUnsignedint, z as consumeBoolean, n as prepareBoolean, E as consumeObject, t as prepareObject, w as consumeArray, p as prepareArray } from "./decorator_utils-gyymixlk.js";
|
|
14
|
+
import { joi as zu } from "./joi.mjs";
|
|
15
15
|
import { parse as parse$2, SyntaxError as SyntaxError$1 } from "liqe";
|
|
16
|
-
import { d as
|
|
17
|
-
import {
|
|
18
|
-
import { R as ResourcefulArrayType, a as ResourcefulObjectType, b as ResourcefulBooleanType, c as ResourcefulUnsignedIntegerType, d as ResourcefulBigintType, e as ResourcefulIntegerType, f as ResourcefulNumberType, g as ResourcefulBinaryType, h as ResourcefulDateTimeType, i as ResourcefulDateType, j as ResourcefulStringType } from "./definitions-B88XBTUF.js";
|
|
19
|
-
import { k } from "./definitions-B88XBTUF.js";
|
|
16
|
+
import { d as E_LUCENE_INVALID_TYPE, e as E_LUCENE_REGEX_NOT_SUPPORTED, f as E_LUCENE_SYNTAX_EXCEPTION, g as E_LUCENE_UNEXPECTED_EXCEPTION, i as isString$1, h as isObject$1, s as stripUndefinedValuesFromObject, j as E_INVALID_RESOURCEFUL_MIXIN_OPTIONS, C as CRUDOperationsEnum, o as operationCRUDToACL, A as ACLOperationsEnum, k as E_MISSING_PRIMARY_KEY_EXCEPTION, p as prepareFields, l as E_FORBIDDEN, m as E_INVALID_COLUMN_ACCESS, n as E_INVALID_RESOUREFUL_INDEX_REQUEST_EXCEPTION, q as E_RECORD_NOT_FOUND_EXCEPTION, r as E_INVALID_RELATIONSHIP_EXCEPTION, t as E_INVALID_RESOUREFUL_READ_RELATIONSHIP_REQUEST_EXCEPTION, u as E_INVALID_PAYLOAD_EXCEPTION, v as E_FORBIDDEN_PAYLOAD_EXCEPTION, w as E_BULK_UPDATE_SEARCH_UNKNOWN_EXCEPTION, x as createError, y as Exception, z as getDefaultExportFromCjs, B as commonjsGlobal, D as index_default, F as defineStaticProperty, G as lodash, H as E_INVALID_RESOURCEFUL_DECORATOR_OPTIONS } from "./errors-C-x5_jRE.js";
|
|
17
|
+
import { I } from "./errors-C-x5_jRE.js";
|
|
20
18
|
import require$$0, { debuglog } from "util";
|
|
21
19
|
import "node:path";
|
|
22
20
|
import "node:url";
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
21
|
+
import { R as ResourcefulStringType, a as ResourcefulDateType, b as ResourcefulDateTimeType, c as ResourcefulBinaryType, d as ResourcefulNumberType, e as ResourcefulIntegerType, f as ResourcefulBigintType, g as ResourcefulUnsignedIntegerType, h as ResourcefulBooleanType, i as ResourcefulObjectType, j as ResourcefulArrayType } from "./definitions-DcB6B_4d.js";
|
|
22
|
+
import { k } from "./definitions-DcB6B_4d.js";
|
|
26
23
|
async function pMap(iterable, mapper, {
|
|
27
24
|
concurrency = Number.POSITIVE_INFINITY,
|
|
28
25
|
stopOnError = true,
|
|
@@ -144,384 +141,426 @@ async function pMap(iterable, mapper, {
|
|
|
144
141
|
});
|
|
145
142
|
}
|
|
146
143
|
const pMapSkip = Symbol("skip");
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
144
|
+
const _LuceneLucidQueryBuilder = class _LuceneLucidQueryBuilder {
|
|
145
|
+
constructor(connection, query, attributesToColumns, primaryKey, tableName, allowedColumns, model) {
|
|
146
|
+
__privateAdd(this, _LuceneLucidQueryBuilder_instances);
|
|
147
|
+
__privateAdd(this, _attributesToColumns);
|
|
148
|
+
__privateAdd(this, _allowedColumns);
|
|
149
|
+
__privateAdd(this, _connection);
|
|
150
|
+
__privateAdd(this, _dialect);
|
|
151
|
+
// @ts-ignore - not used yet
|
|
152
|
+
__privateAdd(this, _primaryKey);
|
|
153
|
+
// @ts-ignore - not used yet
|
|
154
|
+
__privateAdd(this, _tableName);
|
|
155
|
+
// @ts-ignore - not used yet
|
|
156
|
+
__privateAdd(this, _model);
|
|
157
|
+
__privateSet(this, _attributesToColumns, attributesToColumns);
|
|
158
|
+
__privateSet(this, _primaryKey, primaryKey);
|
|
159
|
+
__privateSet(this, _tableName, tableName);
|
|
160
|
+
__privateSet(this, _allowedColumns, allowedColumns);
|
|
161
|
+
__privateSet(this, _model, model);
|
|
162
|
+
__privateSet(this, _connection, connection);
|
|
163
|
+
__privateSet(this, _dialect, query.client.dialect.name);
|
|
164
|
+
}
|
|
165
|
+
applyLuceneAst(ast, query, throwOnInvalidType = false) {
|
|
166
|
+
switch (ast.type) {
|
|
167
|
+
case "EmptyExpression":
|
|
168
|
+
this.applyLuceneEmptyExpressionAst(ast, query);
|
|
169
|
+
break;
|
|
170
|
+
case "LogicalExpression":
|
|
171
|
+
this.applyLuceneLogicalExpressionAst(ast, query);
|
|
172
|
+
break;
|
|
173
|
+
case "ParenthesizedExpression":
|
|
174
|
+
this.applyLuceneParenthesizedExpressionAst(ast, query);
|
|
175
|
+
break;
|
|
176
|
+
case "UnaryOperator":
|
|
177
|
+
this.applyLuceneUnaryOperatorAst(ast, query);
|
|
178
|
+
break;
|
|
179
|
+
case "Tag":
|
|
180
|
+
this.applyLuceneTagAst(ast, query);
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
if (throwOnInvalidType) {
|
|
184
|
+
throw new E_LUCENE_INVALID_TYPE(ast.type);
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
applyLuceneEmptyExpressionAst(_ast, _query) {
|
|
190
|
+
}
|
|
191
|
+
applyLuceneLogicalExpressionAst(ast, query) {
|
|
192
|
+
const operatorType = ast.operator.operator;
|
|
193
|
+
query.where((subQuery) => {
|
|
194
|
+
if (operatorType === "AND") {
|
|
195
|
+
this.applyLuceneAst(ast.left, subQuery);
|
|
196
|
+
this.applyLuceneAst(ast.right, subQuery);
|
|
197
|
+
} else {
|
|
198
|
+
subQuery.orWhere((orSubQuery) => {
|
|
199
|
+
this.applyLuceneAst(ast.left, orSubQuery);
|
|
200
|
+
});
|
|
201
|
+
subQuery.orWhere((orSubQuery) => {
|
|
202
|
+
this.applyLuceneAst(ast.right, orSubQuery);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
applyLuceneParenthesizedExpressionAst(ast, query) {
|
|
208
|
+
query.where((subQuery) => {
|
|
209
|
+
this.applyLuceneAst(ast.expression, subQuery);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
applyLuceneUnaryOperatorAst(ast, query) {
|
|
213
|
+
const operator = ast.operator;
|
|
214
|
+
if (operator === "NOT" || operator === "-") {
|
|
215
|
+
query.whereNot((subQuery) => {
|
|
216
|
+
this.applyLuceneAst(ast.operand, subQuery);
|
|
170
217
|
});
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
orSubQuery,
|
|
175
|
-
attributesToColumns,
|
|
176
|
-
primaryKey,
|
|
177
|
-
tableName,
|
|
178
|
-
allowedColumns
|
|
179
|
-
);
|
|
218
|
+
} else {
|
|
219
|
+
query.where((subQuery) => {
|
|
220
|
+
this.applyLuceneAst(ast.operand, subQuery);
|
|
180
221
|
});
|
|
181
222
|
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
223
|
+
}
|
|
224
|
+
applyLuceneTagAst(ast, query) {
|
|
225
|
+
const { expression, field, operator } = ast;
|
|
226
|
+
switch (field.type) {
|
|
227
|
+
case "ImplicitField":
|
|
228
|
+
this.applyLuceneImplicitFieldAst(field, expression, operator, query);
|
|
229
|
+
break;
|
|
230
|
+
case "Field":
|
|
231
|
+
this.applyLuceneFieldAst(field, expression, operator, query);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
applyLuceneImplicitFieldAst(_field, expression, operator, query) {
|
|
236
|
+
const searchableColumns = __privateMethod(this, _LuceneLucidQueryBuilder_instances, getSearchableColumns_fn).call(this);
|
|
237
|
+
const defaultOperator = operator || {
|
|
238
|
+
operator: ":",
|
|
239
|
+
type: "ComparisonOperator",
|
|
240
|
+
location: { start: 0, end: 0 }
|
|
241
|
+
};
|
|
242
|
+
searchableColumns.forEach((columnName) => {
|
|
243
|
+
const fakeField = {
|
|
244
|
+
name: columnName,
|
|
245
|
+
type: "Field",
|
|
246
|
+
location: { start: 0, end: 0 },
|
|
247
|
+
quoted: false
|
|
248
|
+
};
|
|
249
|
+
query.orWhere((s) => {
|
|
250
|
+
this.applyLuceneFieldAst(fakeField, expression, defaultOperator, s);
|
|
205
251
|
});
|
|
206
|
-
|
|
252
|
+
});
|
|
207
253
|
}
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
254
|
+
applyLuceneFieldAst(field, expression, operator, query, forModel) {
|
|
255
|
+
const columnName = !forModel ? __privateGet(this, _attributesToColumns).get(field.name) : forModel.$keys.attributesToColumns.get(field.name);
|
|
256
|
+
if (!columnName || !forModel && __privateGet(this, _allowedColumns) && !__privateGet(this, _allowedColumns).includes(field.name)) {
|
|
257
|
+
if (field.name.includes(".")) {
|
|
258
|
+
const parts = field.name.split(".").filter((p) => "string" === typeof p && p.trim().length > 0).map((p) => p.trim());
|
|
259
|
+
const relationship = parts.shift();
|
|
260
|
+
if (!relationship || parts.length === 0) return;
|
|
261
|
+
this.applyLuceneRelatedFieldAst(
|
|
262
|
+
relationship,
|
|
263
|
+
parts.join("."),
|
|
264
|
+
expression,
|
|
265
|
+
operator,
|
|
266
|
+
query,
|
|
267
|
+
forModel
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
switch (expression.type) {
|
|
273
|
+
case "EmptyExpression":
|
|
274
|
+
this.applyLuceneEmptyExpression(columnName, expression, operator, query);
|
|
275
|
+
break;
|
|
276
|
+
case "LiteralExpression":
|
|
277
|
+
this.applyLuceneLiteralExpression(columnName, expression, operator, query);
|
|
278
|
+
break;
|
|
279
|
+
case "RangeExpression":
|
|
280
|
+
this.applyLuceneRangeExpression(columnName, expression, operator, query);
|
|
281
|
+
break;
|
|
282
|
+
case "RegexExpression":
|
|
283
|
+
this.applyLuceneRegexExpression(columnName, expression, operator, query);
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
applyLuceneRelatedFieldAst(relationship, relatedProperty, expression, operator, query, forModel) {
|
|
288
|
+
if (!forModel && !__privateGet(this, _model)) return;
|
|
289
|
+
const targetModel = forModel || __privateGet(this, _model);
|
|
290
|
+
const lucidRelationshipDefinition = targetModel.$relationsDefinitions.get(relationship);
|
|
291
|
+
if (!lucidRelationshipDefinition) return;
|
|
292
|
+
const sub = lucidRelationshipDefinition.subQuery(__privateGet(this, _connection));
|
|
293
|
+
const relatedField = {
|
|
294
|
+
name: relatedProperty,
|
|
295
|
+
type: "Field",
|
|
296
|
+
location: { start: 0, end: 0 },
|
|
297
|
+
quoted: false
|
|
298
|
+
};
|
|
299
|
+
const relatedModel = lucidRelationshipDefinition.relatedModel();
|
|
300
|
+
this.applyLuceneFieldAst(relatedField, expression, operator, sub, relatedModel);
|
|
301
|
+
query.whereExists(sub.prepare());
|
|
302
|
+
}
|
|
303
|
+
applyLuceneEmptyExpression(column2, _expression, operator, query) {
|
|
212
304
|
switch (operator.operator) {
|
|
213
305
|
case ":":
|
|
214
306
|
case ":=":
|
|
307
|
+
case ":<=":
|
|
308
|
+
case ":>=":
|
|
215
309
|
query.where((sub) => {
|
|
216
310
|
sub.whereNull(column2);
|
|
217
311
|
sub.orWhere(column2, "=", "");
|
|
218
|
-
sub.orWhere(column2, "=", 0);
|
|
219
312
|
});
|
|
220
313
|
break;
|
|
221
|
-
case ":<":
|
|
222
|
-
query.where(column2, "<", 0);
|
|
223
|
-
break;
|
|
224
|
-
case ":<=":
|
|
225
|
-
query.where(column2, "<=", 0);
|
|
226
|
-
break;
|
|
227
|
-
case ":>":
|
|
228
|
-
query.where(column2, ">", 0);
|
|
229
|
-
break;
|
|
230
|
-
case ":>=":
|
|
231
|
-
query.where(column2, ">=", 0);
|
|
232
|
-
break;
|
|
233
314
|
}
|
|
234
|
-
return;
|
|
235
315
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
value = value.replace(/^'/g, "").replace(/'$/g, "");
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
switch (typeof value) {
|
|
244
|
-
case "string":
|
|
316
|
+
applyLuceneLiteralExpression(column2, expression, operator, query) {
|
|
317
|
+
let value = expression.value;
|
|
318
|
+
let isCaseSensitive = false;
|
|
319
|
+
if (value === null) {
|
|
245
320
|
switch (operator.operator) {
|
|
246
321
|
case ":":
|
|
247
322
|
case ":=":
|
|
248
323
|
query.where((sub) => {
|
|
249
|
-
sub.
|
|
250
|
-
sub.orWhere(column2, "
|
|
324
|
+
sub.whereNull(column2);
|
|
325
|
+
sub.orWhere(column2, "=", "");
|
|
326
|
+
sub.orWhere(column2, "=", 0);
|
|
251
327
|
});
|
|
252
328
|
break;
|
|
253
329
|
case ":<":
|
|
254
|
-
query.where(column2, "<",
|
|
330
|
+
query.where(column2, "<", 0);
|
|
255
331
|
break;
|
|
256
332
|
case ":<=":
|
|
257
|
-
query.where(column2, "<=",
|
|
333
|
+
query.where(column2, "<=", 0);
|
|
258
334
|
break;
|
|
259
335
|
case ":>":
|
|
260
|
-
query.where(column2, ">",
|
|
336
|
+
query.where(column2, ">", 0);
|
|
261
337
|
break;
|
|
262
338
|
case ":>=":
|
|
263
|
-
query.where(column2, ">=",
|
|
339
|
+
query.where(column2, ">=", 0);
|
|
264
340
|
break;
|
|
265
341
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
query.where(column2, "<", value);
|
|
275
|
-
break;
|
|
276
|
-
case ":<=":
|
|
277
|
-
query.where(column2, "<=", value);
|
|
278
|
-
break;
|
|
279
|
-
case ":>":
|
|
280
|
-
query.where(column2, ">", value);
|
|
281
|
-
break;
|
|
282
|
-
case ":>=":
|
|
283
|
-
query.where(column2, ">=", value);
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
break;
|
|
287
|
-
case "boolean":
|
|
288
|
-
switch (operator.operator) {
|
|
289
|
-
case ":":
|
|
290
|
-
case ":=":
|
|
291
|
-
query.where(column2, "=", value);
|
|
292
|
-
break;
|
|
293
|
-
case ":<":
|
|
294
|
-
query.where(column2, "<", value);
|
|
295
|
-
break;
|
|
296
|
-
case ":<=":
|
|
297
|
-
query.where(column2, "<=", value);
|
|
298
|
-
break;
|
|
299
|
-
case ":>":
|
|
300
|
-
query.where(column2, ">", value);
|
|
301
|
-
break;
|
|
302
|
-
case ":>=":
|
|
303
|
-
query.where(column2, ">=", value);
|
|
304
|
-
break;
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if ("string" === typeof value && expression.quoted) {
|
|
345
|
+
isCaseSensitive = true;
|
|
346
|
+
if (expression.quotes === "double") {
|
|
347
|
+
value = value.replace(/^"/g, "").replace(/"$/g, "");
|
|
348
|
+
} else if (expression.quotes === "single") {
|
|
349
|
+
value = value.replace(/^'/g, "").replace(/'$/g, "");
|
|
305
350
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
);
|
|
402
|
-
break;
|
|
403
|
-
case "RegexExpression":
|
|
404
|
-
applyLuceneRegexExpression(
|
|
405
|
-
columnName,
|
|
406
|
-
expression,
|
|
407
|
-
operator,
|
|
408
|
-
query
|
|
409
|
-
);
|
|
410
|
-
break;
|
|
351
|
+
}
|
|
352
|
+
switch (typeof value) {
|
|
353
|
+
case "string":
|
|
354
|
+
switch (operator.operator) {
|
|
355
|
+
case ":":
|
|
356
|
+
case ":=":
|
|
357
|
+
if (value.includes("*") || value.includes("?")) {
|
|
358
|
+
let likeValue = value.replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
359
|
+
likeValue = likeValue.replace(/\*/g, "%").replace(/\?/g, "_");
|
|
360
|
+
if (isCaseSensitive) {
|
|
361
|
+
query.whereLike(column2, likeValue);
|
|
362
|
+
} else {
|
|
363
|
+
query.if(
|
|
364
|
+
["postgres", "pg"].includes(__privateGet(this, _dialect)),
|
|
365
|
+
(q) => {
|
|
366
|
+
q.whereILike(column2, likeValue);
|
|
367
|
+
},
|
|
368
|
+
(q) => {
|
|
369
|
+
q.whereLike(column2, likeValue);
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
} else {
|
|
374
|
+
query.where((sub) => {
|
|
375
|
+
if (isCaseSensitive) {
|
|
376
|
+
sub.where(column2, "=", value);
|
|
377
|
+
} else {
|
|
378
|
+
query.if(
|
|
379
|
+
["postgres", "pg"].includes(__privateGet(this, _dialect)),
|
|
380
|
+
() => {
|
|
381
|
+
sub.orWhereILike(column2, value);
|
|
382
|
+
},
|
|
383
|
+
() => {
|
|
384
|
+
sub.whereLike(column2, value);
|
|
385
|
+
}
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
break;
|
|
391
|
+
case ":<":
|
|
392
|
+
query.where(column2, "<", value);
|
|
393
|
+
break;
|
|
394
|
+
case ":<=":
|
|
395
|
+
query.where(column2, "<=", value);
|
|
396
|
+
break;
|
|
397
|
+
case ":>":
|
|
398
|
+
query.where(column2, ">", value);
|
|
399
|
+
break;
|
|
400
|
+
case ":>=":
|
|
401
|
+
query.where(column2, ">=", value);
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
break;
|
|
405
|
+
case "number":
|
|
406
|
+
switch (operator.operator) {
|
|
407
|
+
case ":":
|
|
408
|
+
case ":=":
|
|
409
|
+
query.where(column2, "=", value);
|
|
410
|
+
break;
|
|
411
|
+
case ":<":
|
|
412
|
+
query.where(column2, "<", value);
|
|
413
|
+
break;
|
|
414
|
+
case ":<=":
|
|
415
|
+
query.where(column2, "<=", value);
|
|
416
|
+
break;
|
|
417
|
+
case ":>":
|
|
418
|
+
query.where(column2, ">", value);
|
|
419
|
+
break;
|
|
420
|
+
case ":>=":
|
|
421
|
+
query.where(column2, ">=", value);
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
break;
|
|
425
|
+
case "boolean":
|
|
426
|
+
switch (operator.operator) {
|
|
427
|
+
case ":":
|
|
428
|
+
case ":=":
|
|
429
|
+
query.where(column2, "=", value);
|
|
430
|
+
break;
|
|
431
|
+
case ":<":
|
|
432
|
+
query.where(column2, "<", value);
|
|
433
|
+
break;
|
|
434
|
+
case ":<=":
|
|
435
|
+
query.where(column2, "<=", value);
|
|
436
|
+
break;
|
|
437
|
+
case ":>":
|
|
438
|
+
query.where(column2, ">", value);
|
|
439
|
+
break;
|
|
440
|
+
case ":>=":
|
|
441
|
+
query.where(column2, ">=", value);
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
411
446
|
}
|
|
412
|
-
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
query,
|
|
422
|
-
attributesToColumns,
|
|
423
|
-
primaryKey,
|
|
424
|
-
tableName,
|
|
425
|
-
allowedColumns
|
|
426
|
-
);
|
|
427
|
-
break;
|
|
428
|
-
case "Field":
|
|
429
|
-
applyLuceneFieldAst(
|
|
430
|
-
field,
|
|
431
|
-
expression,
|
|
432
|
-
operator,
|
|
433
|
-
query,
|
|
434
|
-
attributesToColumns,
|
|
435
|
-
primaryKey,
|
|
436
|
-
tableName,
|
|
437
|
-
allowedColumns
|
|
438
|
-
);
|
|
439
|
-
break;
|
|
447
|
+
applyLuceneRangeExpression(column2, expression, operator, query) {
|
|
448
|
+
const comparableMin = expression.range.minInclusive ? expression.range.min : expression.range.min + 1;
|
|
449
|
+
const comparableMax = expression.range.maxInclusive ? expression.range.max : expression.range.max - 1;
|
|
450
|
+
switch (operator.operator) {
|
|
451
|
+
case ":":
|
|
452
|
+
case ":=":
|
|
453
|
+
query.whereBetween(column2, [comparableMin, comparableMax]);
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
440
456
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
457
|
+
applyLuceneRegexExpression(column2, expression, operator, query) {
|
|
458
|
+
let value = expression.value;
|
|
459
|
+
switch (__privateGet(this, _dialect)) {
|
|
460
|
+
case "mysql":
|
|
461
|
+
case "mariadb":
|
|
462
|
+
switch (operator.operator) {
|
|
463
|
+
case ":":
|
|
464
|
+
case ":=":
|
|
465
|
+
query.whereRaw(`?? REGEXP ?`, [column2, value]);
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
break;
|
|
469
|
+
case "pg":
|
|
470
|
+
case "postgres":
|
|
471
|
+
switch (operator.operator) {
|
|
472
|
+
case ":":
|
|
473
|
+
case ":=":
|
|
474
|
+
query.whereRaw(`?? ~ ?`, [column2, value]);
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
break;
|
|
478
|
+
case "oracle":
|
|
479
|
+
case "oracledb":
|
|
480
|
+
case "tedious":
|
|
481
|
+
case "mssql":
|
|
482
|
+
switch (operator.operator) {
|
|
483
|
+
case ":":
|
|
484
|
+
case ":=":
|
|
485
|
+
query.whereRaw(`REGEXP_LIKE(??, ?)`, [column2, value]);
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
break;
|
|
489
|
+
case "sqlite3":
|
|
490
|
+
case "better-sqlite3":
|
|
491
|
+
throw new E_LUCENE_REGEX_NOT_SUPPORTED();
|
|
492
|
+
default:
|
|
493
|
+
value = value.replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
494
|
+
value = value.replace(/\*/g, "%").replace(/\?/g, "_");
|
|
495
|
+
switch (operator.operator) {
|
|
496
|
+
case ":":
|
|
497
|
+
case ":=":
|
|
498
|
+
query.whereLike(column2, value);
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
466
503
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
ast,
|
|
475
|
-
query,
|
|
476
|
-
attributesToColumns,
|
|
477
|
-
primaryKey,
|
|
478
|
-
tableName,
|
|
479
|
-
allowedColumns
|
|
480
|
-
);
|
|
481
|
-
break;
|
|
482
|
-
case "ParenthesizedExpression":
|
|
483
|
-
applyLuceneParenthesizedExpressionAst(
|
|
484
|
-
ast,
|
|
485
|
-
query,
|
|
486
|
-
attributesToColumns,
|
|
487
|
-
primaryKey,
|
|
488
|
-
tableName,
|
|
489
|
-
allowedColumns
|
|
490
|
-
);
|
|
491
|
-
break;
|
|
492
|
-
case "Tag":
|
|
493
|
-
applyLuceneTagAst(ast, query, attributesToColumns, primaryKey, tableName, allowedColumns);
|
|
494
|
-
break;
|
|
495
|
-
case "UnaryOperator":
|
|
496
|
-
applyLuceneUnaryOperatorAst(
|
|
497
|
-
ast,
|
|
498
|
-
query,
|
|
499
|
-
attributesToColumns,
|
|
500
|
-
primaryKey,
|
|
501
|
-
tableName,
|
|
502
|
-
allowedColumns
|
|
503
|
-
);
|
|
504
|
-
break;
|
|
505
|
-
default:
|
|
506
|
-
if (throwOnInvalidType) {
|
|
507
|
-
throw new E_LUCENE_INVALID_TYPE(ast.type);
|
|
504
|
+
static get(luceneQuery, connection, attributesToColumns, primaryKey, tableName, allowedColumns, model) {
|
|
505
|
+
let parsed;
|
|
506
|
+
try {
|
|
507
|
+
parsed = parse$2(luceneQuery);
|
|
508
|
+
} catch (error) {
|
|
509
|
+
if (error instanceof SyntaxError$1) {
|
|
510
|
+
throw new E_LUCENE_SYNTAX_EXCEPTION(luceneQuery, error);
|
|
508
511
|
}
|
|
509
|
-
|
|
512
|
+
throw new E_LUCENE_UNEXPECTED_EXCEPTION(error);
|
|
513
|
+
}
|
|
514
|
+
const query = connection.query().from(tableName);
|
|
515
|
+
const builder = new _LuceneLucidQueryBuilder(
|
|
516
|
+
connection,
|
|
517
|
+
query,
|
|
518
|
+
attributesToColumns,
|
|
519
|
+
primaryKey,
|
|
520
|
+
tableName,
|
|
521
|
+
allowedColumns,
|
|
522
|
+
model
|
|
523
|
+
);
|
|
524
|
+
builder.applyLuceneAst(parsed, query, true);
|
|
525
|
+
return query;
|
|
510
526
|
}
|
|
511
527
|
};
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
528
|
+
_attributesToColumns = new WeakMap();
|
|
529
|
+
_allowedColumns = new WeakMap();
|
|
530
|
+
_connection = new WeakMap();
|
|
531
|
+
_dialect = new WeakMap();
|
|
532
|
+
_primaryKey = new WeakMap();
|
|
533
|
+
_tableName = new WeakMap();
|
|
534
|
+
_model = new WeakMap();
|
|
535
|
+
_LuceneLucidQueryBuilder_instances = new WeakSet();
|
|
536
|
+
getSearchableColumns_fn = function() {
|
|
537
|
+
if (__privateGet(this, _model) && "$resourcefulColumns" in __privateGet(this, _model) && __privateGet(this, _model).$resourcefulColumns instanceof Map) {
|
|
538
|
+
const modelFields = [];
|
|
539
|
+
__privateGet(this, _model).$resourcefulColumns.forEach((_c2, k2) => {
|
|
540
|
+
modelFields.push(k2);
|
|
541
|
+
});
|
|
542
|
+
if ("$resourcefulRelationships" in __privateGet(this, _model) && __privateGet(this, _model).$resourcefulRelationships instanceof Map) {
|
|
543
|
+
__privateGet(this, _model).$resourcefulRelationships.forEach((_r, k2) => {
|
|
544
|
+
modelFields.push(k2);
|
|
545
|
+
});
|
|
519
546
|
}
|
|
520
|
-
|
|
547
|
+
return Array.from(new Set(modelFields)).filter(
|
|
548
|
+
(f) => !__privateGet(this, _allowedColumns) || __privateGet(this, _allowedColumns).includes(f)
|
|
549
|
+
);
|
|
521
550
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
551
|
+
return Object.entries(__privateGet(this, _attributesToColumns).all()).filter(([attr]) => !__privateGet(this, _allowedColumns) || __privateGet(this, _allowedColumns).includes(attr)).map(([, column2]) => column2);
|
|
552
|
+
};
|
|
553
|
+
let LuceneLucidQueryBuilder = _LuceneLucidQueryBuilder;
|
|
554
|
+
const luceneToLucid = (luceneQuery, connection, attributesToColumns, primaryKey, tableName, allowedColumns, model) => {
|
|
555
|
+
return LuceneLucidQueryBuilder.get(
|
|
556
|
+
luceneQuery,
|
|
557
|
+
connection,
|
|
558
|
+
attributesToColumns,
|
|
559
|
+
primaryKey,
|
|
560
|
+
tableName,
|
|
561
|
+
allowedColumns,
|
|
562
|
+
model
|
|
563
|
+
);
|
|
525
564
|
};
|
|
526
565
|
var o = Object.defineProperty;
|
|
527
566
|
var a = (t, s, r) => s in t ? o(t, s, { enumerable: true, configurable: true, writable: true, value: r }) : t[s] = r;
|
|
@@ -588,7 +627,386 @@ class l {
|
|
|
588
627
|
(i) => i.fn !== r && i.fn._ !== r
|
|
589
628
|
) : this.e[s] = []), this;
|
|
590
629
|
}
|
|
591
|
-
}
|
|
630
|
+
}
|
|
631
|
+
class OpenApiSchemaService {
|
|
632
|
+
constructor() {
|
|
633
|
+
__privateAdd(this, _OpenApiSchemaService_instances);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Generates a complete OpenAPI schema object for a resourceful model.
|
|
637
|
+
*
|
|
638
|
+
* This method creates a comprehensive OpenAPI v3 schema representation of the model
|
|
639
|
+
* by processing the provided metadata schema. The metadata should already have
|
|
640
|
+
* field-level access control permissions evaluated for the given request context.
|
|
641
|
+
*
|
|
642
|
+
* @param resourcefulModelMetaSchema - The resourceful model metadata with ACL filtering applied
|
|
643
|
+
* @returns Complete OpenAPI schema object
|
|
644
|
+
*
|
|
645
|
+
* @example
|
|
646
|
+
* ```typescript
|
|
647
|
+
* const service = new OpenApiSchemaService()
|
|
648
|
+
* const schema = service.generateModelSchema(metaSchema)
|
|
649
|
+
* // Returns complete OpenAPI schema with accessible fields only
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
/* istanbul ignore next -- @preserve */
|
|
653
|
+
generateModelSchema(operation = "read", resourcefulModelMetaSchema, model) {
|
|
654
|
+
if (!isObject$1(resourcefulModelMetaSchema) || !resourcefulModelMetaSchema.name || !isResourcefulModel(model)) {
|
|
655
|
+
return {
|
|
656
|
+
type: "object",
|
|
657
|
+
properties: {},
|
|
658
|
+
required: []
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
const schema = {
|
|
662
|
+
type: "object",
|
|
663
|
+
title: resourcefulModelMetaSchema.name,
|
|
664
|
+
description: resourcefulModelMetaSchema.description,
|
|
665
|
+
externalDocs: resourcefulModelMetaSchema.externalDocs,
|
|
666
|
+
example: resourcefulModelMetaSchema.example,
|
|
667
|
+
properties: {}
|
|
668
|
+
};
|
|
669
|
+
/* istanbul ignore next -- @preserve */
|
|
670
|
+
Object.entries(resourcefulModelMetaSchema.properties).forEach(([propertyKey, propertyMeta]) => {
|
|
671
|
+
const resolvedColumnName = __privateMethod(this, _OpenApiSchemaService_instances, getFieldKey_fn).call(this, propertyKey, propertyMeta.lucidDefinitions);
|
|
672
|
+
if (null === resolvedColumnName) {
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
switch (propertyMeta.kind) {
|
|
676
|
+
case "column": {
|
|
677
|
+
schema.properties[propertyKey] = this.generateColumnSchema(
|
|
678
|
+
propertyKey,
|
|
679
|
+
propertyMeta
|
|
680
|
+
);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
case "computedAccessor": {
|
|
684
|
+
schema.properties[propertyKey] = this.generateComputedAccessorSchema(
|
|
685
|
+
propertyKey,
|
|
686
|
+
propertyMeta
|
|
687
|
+
);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
case "relationship": {
|
|
691
|
+
const relatedSchema = this.generateRelationshipSchema(
|
|
692
|
+
propertyKey,
|
|
693
|
+
propertyMeta
|
|
694
|
+
);
|
|
695
|
+
if (relatedSchema) {
|
|
696
|
+
schema.properties[propertyKey] = relatedSchema;
|
|
697
|
+
}
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
const requiredPropSet = /* @__PURE__ */ new Set();
|
|
703
|
+
Object.entries(schema.properties).forEach(([propertyKey, propertySchema]) => {
|
|
704
|
+
if (!isObject$1(propertySchema) || "$ref" in propertySchema) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
const isNullable = propertySchema.nullable === true;
|
|
708
|
+
if (!isNullable && ("read" === operation || !model.$resourcefulComputedAccessors.has(propertyKey) && !model.$resourcefulRelationships.has(propertyKey))) {
|
|
709
|
+
requiredPropSet.add(propertyKey);
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
schema.required = Array.from(requiredPropSet);
|
|
713
|
+
return schema;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Generates OpenAPI schema for a column property.
|
|
717
|
+
*
|
|
718
|
+
* This method converts resourceful column metadata into an OpenAPI schema object,
|
|
719
|
+
* properly extracting data type information and preserving all existing schema
|
|
720
|
+
* properties such as validation constraints, nullability, and access modifiers.
|
|
721
|
+
*
|
|
722
|
+
* @param propertyKey - The name of the column property
|
|
723
|
+
* @param propertyMeta - The resourceful metadata for the column
|
|
724
|
+
* @returns OpenAPI schema object for the column
|
|
725
|
+
*
|
|
726
|
+
* @example
|
|
727
|
+
* ```typescript
|
|
728
|
+
* const service = new OpenApiSchemaService()
|
|
729
|
+
* const schema = service.generateColumnSchema('name', columnMeta)
|
|
730
|
+
* // Returns: { type: 'string', minLength: 1, maxLength: 100, ... }
|
|
731
|
+
* ```
|
|
732
|
+
*/
|
|
733
|
+
generateColumnSchema(propertyKey, propertyMeta) {
|
|
734
|
+
if (!isObject$1(propertyMeta) || !propertyMeta.definition || !propertyMeta.lucidDefinitions) {
|
|
735
|
+
return {};
|
|
736
|
+
}
|
|
737
|
+
const dataTypeInfo = __privateMethod(this, _OpenApiSchemaService_instances, extractDataTypeInfo_fn).call(this, propertyMeta.definition.type);
|
|
738
|
+
const fieldKey = __privateMethod(this, _OpenApiSchemaService_instances, getFieldKey_fn).call(this, propertyKey, propertyMeta.lucidDefinitions);
|
|
739
|
+
const dataType = propertyMeta.definition.type;
|
|
740
|
+
const definition = propertyMeta.definition;
|
|
741
|
+
/* istanbul ignore next -- @preserve */
|
|
742
|
+
const schemaProperties = stripUndefinedValuesFromObject({
|
|
743
|
+
// Core OpenAPI type information (properly extracted)
|
|
744
|
+
type: dataTypeInfo.type,
|
|
745
|
+
format: dataTypeInfo.format,
|
|
746
|
+
// Schema metadata
|
|
747
|
+
items: definition.items || dataType.items,
|
|
748
|
+
title: fieldKey || propertyKey,
|
|
749
|
+
description: definition.description,
|
|
750
|
+
default: "default" in definition ? definition.default : this.getDefaultValueFromPropertyMeta(propertyMeta),
|
|
751
|
+
// Numeric constraints (from data type or definition)
|
|
752
|
+
multipleOf: definition.multipleOf || dataType.multipleOf,
|
|
753
|
+
maximum: definition.maximum || dataType.maximum,
|
|
754
|
+
exclusiveMaximum: definition.exclusiveMaximum || dataType.exclusiveMaximum,
|
|
755
|
+
minimum: definition.minimum || dataType.minimum,
|
|
756
|
+
exclusiveMinimum: definition.exclusiveMinimum || dataType.exclusiveMinimum,
|
|
757
|
+
// String constraints (from data type or definition)
|
|
758
|
+
maxLength: definition.maxLength || dataType.maxLength,
|
|
759
|
+
minLength: definition.minLength || dataType.minLength,
|
|
760
|
+
pattern: definition.pattern || dataType.pattern,
|
|
761
|
+
// Object constraints (from data type or definition)
|
|
762
|
+
additionalProperties: definition.additionalProperties || dataType.additionalProperties,
|
|
763
|
+
maxProperties: definition.maxProperties || dataType.maxProperties,
|
|
764
|
+
minProperties: definition.minProperties || dataType.minProperties,
|
|
765
|
+
properties: definition.properties || dataType.properties,
|
|
766
|
+
// Array constraints (from data type or definition)
|
|
767
|
+
maxItems: definition.maxItems || dataType.maxItems,
|
|
768
|
+
minItems: definition.minItems || dataType.minItems,
|
|
769
|
+
uniqueItems: definition.uniqueItems || dataType.uniqueItems,
|
|
770
|
+
// Schema composition (from data type or definition)
|
|
771
|
+
allOf: definition.allOf || dataType.allOf,
|
|
772
|
+
oneOf: definition.oneOf || dataType.oneOf,
|
|
773
|
+
anyOf: definition.anyOf || dataType.anyOf,
|
|
774
|
+
not: definition.not || dataType.not,
|
|
775
|
+
// Validation and constraints (from data type or definition)
|
|
776
|
+
required: definition.required || dataType.required,
|
|
777
|
+
enum: definition.enum || dataType.enum,
|
|
778
|
+
nullable: definition.nullable !== void 0 ? definition.nullable : dataType.nullable || false,
|
|
779
|
+
// Access control
|
|
780
|
+
readOnly: propertyMeta.canRead && !propertyMeta.canWrite,
|
|
781
|
+
writeOnly: !propertyMeta.canRead && propertyMeta.canWrite,
|
|
782
|
+
// Documentation
|
|
783
|
+
externalDocs: definition.externalDocs,
|
|
784
|
+
example: definition.example
|
|
785
|
+
});
|
|
786
|
+
return schemaProperties;
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Generates OpenAPI schema for a computed accessor property.
|
|
790
|
+
*
|
|
791
|
+
* This method converts resourceful computed accessor metadata into an OpenAPI
|
|
792
|
+
* schema object, applying the same data type extraction improvements as column
|
|
793
|
+
* schema generation while maintaining all existing functionality.
|
|
794
|
+
*
|
|
795
|
+
* @param propertyKey - The name of the computed accessor property
|
|
796
|
+
* @param propertyMeta - The resourceful metadata for the computed accessor
|
|
797
|
+
* @returns OpenAPI schema object for the computed accessor
|
|
798
|
+
*
|
|
799
|
+
* @example
|
|
800
|
+
* ```typescript
|
|
801
|
+
* const service = new OpenApiSchemaService()
|
|
802
|
+
* const schema = service.generateComputedAccessorSchema('fullName', accessorMeta)
|
|
803
|
+
* // Returns: { type: 'string', readOnly: true, ... }
|
|
804
|
+
* ```
|
|
805
|
+
*/
|
|
806
|
+
generateComputedAccessorSchema(propertyKey, propertyMeta) {
|
|
807
|
+
if (!isObject$1(propertyMeta) || !propertyMeta.definition || !propertyMeta.lucidDefinitions) {
|
|
808
|
+
return {};
|
|
809
|
+
}
|
|
810
|
+
const dataTypeInfo = __privateMethod(this, _OpenApiSchemaService_instances, extractDataTypeInfo_fn).call(this, propertyMeta.definition.type);
|
|
811
|
+
const fieldKey = __privateMethod(this, _OpenApiSchemaService_instances, getFieldKey_fn).call(this, propertyKey, propertyMeta.lucidDefinitions);
|
|
812
|
+
const dataType = propertyMeta.definition.type;
|
|
813
|
+
const definition = propertyMeta.definition;
|
|
814
|
+
/* istanbul ignore next -- @preserve */
|
|
815
|
+
const schemaProperties = stripUndefinedValuesFromObject({
|
|
816
|
+
// Core OpenAPI type information (properly extracted)
|
|
817
|
+
type: dataTypeInfo.type,
|
|
818
|
+
format: dataTypeInfo.format,
|
|
819
|
+
// Schema metadata
|
|
820
|
+
items: definition.items || dataType.items,
|
|
821
|
+
title: fieldKey || propertyKey,
|
|
822
|
+
description: definition.description,
|
|
823
|
+
default: "default" in definition ? definition.default : this.getDefaultValueFromPropertyMeta(propertyMeta),
|
|
824
|
+
// Numeric constraints (from data type or definition)
|
|
825
|
+
multipleOf: definition.multipleOf || dataType.multipleOf,
|
|
826
|
+
maximum: definition.maximum || dataType.maximum,
|
|
827
|
+
exclusiveMaximum: definition.exclusiveMaximum || dataType.exclusiveMaximum,
|
|
828
|
+
minimum: definition.minimum || dataType.minimum,
|
|
829
|
+
exclusiveMinimum: definition.exclusiveMinimum || dataType.exclusiveMinimum,
|
|
830
|
+
// String constraints (from data type or definition)
|
|
831
|
+
maxLength: definition.maxLength || dataType.maxLength,
|
|
832
|
+
minLength: definition.minLength || dataType.minLength,
|
|
833
|
+
pattern: definition.pattern || dataType.pattern,
|
|
834
|
+
// Object constraints (from data type or definition)
|
|
835
|
+
additionalProperties: definition.additionalProperties || dataType.additionalProperties,
|
|
836
|
+
maxProperties: definition.maxProperties || dataType.maxProperties,
|
|
837
|
+
minProperties: definition.minProperties || dataType.minProperties,
|
|
838
|
+
properties: definition.properties || dataType.properties,
|
|
839
|
+
// Array constraints (from data type or definition)
|
|
840
|
+
maxItems: definition.maxItems || dataType.maxItems,
|
|
841
|
+
minItems: definition.minItems || dataType.minItems,
|
|
842
|
+
uniqueItems: definition.uniqueItems || dataType.uniqueItems,
|
|
843
|
+
// Schema composition (from data type or definition)
|
|
844
|
+
allOf: definition.allOf || dataType.allOf,
|
|
845
|
+
oneOf: definition.oneOf || dataType.oneOf,
|
|
846
|
+
anyOf: definition.anyOf || dataType.anyOf,
|
|
847
|
+
not: definition.not || dataType.not,
|
|
848
|
+
// Validation and constraints (from data type or definition)
|
|
849
|
+
required: definition.required || dataType.required,
|
|
850
|
+
enum: definition.enum || dataType.enum,
|
|
851
|
+
nullable: definition.nullable !== void 0 ? definition.nullable : dataType.nullable || false,
|
|
852
|
+
// Access control
|
|
853
|
+
readOnly: propertyMeta.canRead && !propertyMeta.canWrite,
|
|
854
|
+
writeOnly: !propertyMeta.canRead && propertyMeta.canWrite,
|
|
855
|
+
// Documentation
|
|
856
|
+
externalDocs: definition.externalDocs,
|
|
857
|
+
example: definition.example
|
|
858
|
+
});
|
|
859
|
+
return schemaProperties;
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Generates OpenAPI schema for a relationship property.
|
|
863
|
+
*
|
|
864
|
+
* This method converts resourceful relationship metadata into an OpenAPI
|
|
865
|
+
* reference object, preserving existing relationship reference generation
|
|
866
|
+
* logic and ensuring proper handling of related model references.
|
|
867
|
+
*
|
|
868
|
+
* @param propertyKey - The name of the relationship property
|
|
869
|
+
* @param propertyMeta - The resourceful metadata for the relationship
|
|
870
|
+
* @returns OpenAPI reference object for the relationship, or undefined if not applicable
|
|
871
|
+
*
|
|
872
|
+
* @example
|
|
873
|
+
* ```typescript
|
|
874
|
+
* const service = new OpenApiSchemaService()
|
|
875
|
+
* const schema = service.generateRelationshipSchema('user', relationshipMeta)
|
|
876
|
+
* // Returns: { $ref: '#/components/schemas/User' }
|
|
877
|
+
* ```
|
|
878
|
+
*/
|
|
879
|
+
generateRelationshipSchema(_propertyKey, propertyMeta) {
|
|
880
|
+
if (!isObject$1(propertyMeta) || !propertyMeta.definition || !propertyMeta.lucidDefinitions || !propertyMeta.relatedModel) {
|
|
881
|
+
return void 0;
|
|
882
|
+
}
|
|
883
|
+
const relatedModel = propertyMeta.relatedModel();
|
|
884
|
+
/* istanbul ignore if -- @preserve */
|
|
885
|
+
if (!relatedModel) {
|
|
886
|
+
return void 0;
|
|
887
|
+
}
|
|
888
|
+
/* istanbul ignore if -- @preserve */
|
|
889
|
+
if (!isResourcefulModel(relatedModel)) {
|
|
890
|
+
return void 0;
|
|
891
|
+
}
|
|
892
|
+
const ref2 = `#/components/schemas/${relatedModel.$resourcefulName}`;
|
|
893
|
+
return {
|
|
894
|
+
$ref: ref2
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Extracts default value from property metadata using Joi description.
|
|
899
|
+
*
|
|
900
|
+
* This protected method provides access to the default value extraction logic
|
|
901
|
+
* that was previously part of the mixin. It examines the Joi validator
|
|
902
|
+
* description to find default values specified in the schema.
|
|
903
|
+
*
|
|
904
|
+
* @param propertyMeta - The resourceful metadata containing the validator
|
|
905
|
+
* @returns The default value if found, undefined otherwise
|
|
906
|
+
*
|
|
907
|
+
* @example
|
|
908
|
+
* ```typescript
|
|
909
|
+
* const service = new OpenApiSchemaService()
|
|
910
|
+
* const defaultValue = service.getDefaultValueFromPropertyMeta(propertyMeta)
|
|
911
|
+
* ```
|
|
912
|
+
*/
|
|
913
|
+
getDefaultValueFromPropertyMeta(propertyMeta) {
|
|
914
|
+
const joiDescription = propertyMeta.validator.describe();
|
|
915
|
+
/* istanbul ignore if -- @preserve */
|
|
916
|
+
if (isObject$1(joiDescription) && "flags" in joiDescription && isObject$1(joiDescription.flags) && "default" in joiDescription.flags) {
|
|
917
|
+
return joiDescription.flags.default;
|
|
918
|
+
}
|
|
919
|
+
/* istanbul ignore next -- @preserve */
|
|
920
|
+
return void 0;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
_OpenApiSchemaService_instances = new WeakSet();
|
|
924
|
+
/**
|
|
925
|
+
* Gets the field key for a property, handling serializeAs transformation.
|
|
926
|
+
*
|
|
927
|
+
* This private method extracts the appropriate field name for a property,
|
|
928
|
+
* taking into account the serializeAs option from Lucid model definitions.
|
|
929
|
+
* Returns null if the field cannot be read (following Lucid's serializeAs behavior).
|
|
930
|
+
*
|
|
931
|
+
* @param key - The original property key
|
|
932
|
+
* @param definition - The Lucid model definition (column, computed, or relation)
|
|
933
|
+
* @returns The field key to use, the original key if no transformation is needed, or null if field cannot be read
|
|
934
|
+
*/
|
|
935
|
+
getFieldKey_fn = function(key, definition) {
|
|
936
|
+
if (definition.serializeAs === null) {
|
|
937
|
+
return null;
|
|
938
|
+
}
|
|
939
|
+
/* istanbul ignore if -- @preserve */
|
|
940
|
+
if (isString$1(definition.serializeAs)) {
|
|
941
|
+
return definition.serializeAs;
|
|
942
|
+
}
|
|
943
|
+
/* istanbul ignore next -- @preserve */
|
|
944
|
+
return key;
|
|
945
|
+
};
|
|
946
|
+
/**
|
|
947
|
+
* Extracts OpenAPI type and format information from resourceful data types.
|
|
948
|
+
*
|
|
949
|
+
* This private method handles the mapping from resourceful data type instances
|
|
950
|
+
* to their corresponding OpenAPI type and format specifications. It properly
|
|
951
|
+
* handles all supported resourceful data types and provides appropriate
|
|
952
|
+
* fallback behavior for unknown types.
|
|
953
|
+
*
|
|
954
|
+
* @param dataType - The resourceful data type instance to extract information from
|
|
955
|
+
* @returns Object containing the OpenAPI type and optional format
|
|
956
|
+
*
|
|
957
|
+
* @example
|
|
958
|
+
* ```typescript
|
|
959
|
+
* const info = this.#extractDataTypeInfo(ResourcefulStringType())
|
|
960
|
+
* // Returns: { type: 'string' }
|
|
961
|
+
*
|
|
962
|
+
* const info = this.#extractDataTypeInfo(ResourcefulDateTimeType())
|
|
963
|
+
* // Returns: { type: 'string', format: 'date-time' }
|
|
964
|
+
* ```
|
|
965
|
+
*/
|
|
966
|
+
extractDataTypeInfo_fn = function(dataType) {
|
|
967
|
+
let baseType;
|
|
968
|
+
try {
|
|
969
|
+
baseType = dataType.type;
|
|
970
|
+
} catch (error) {
|
|
971
|
+
/* istanbul ignore next -- @preserve */
|
|
972
|
+
return { type: "string" };
|
|
973
|
+
}
|
|
974
|
+
const format = "format" in dataType && typeof dataType.format === "string" ? dataType.format : void 0;
|
|
975
|
+
/* istanbul ignore next -- @preserve */
|
|
976
|
+
switch (baseType) {
|
|
977
|
+
case "string": {
|
|
978
|
+
if (format) {
|
|
979
|
+
return { type: "string", format };
|
|
980
|
+
}
|
|
981
|
+
return { type: "string" };
|
|
982
|
+
}
|
|
983
|
+
case "number": {
|
|
984
|
+
if (format === "float" || format === "double") {
|
|
985
|
+
return { type: "number", format };
|
|
986
|
+
}
|
|
987
|
+
return { type: "number" };
|
|
988
|
+
}
|
|
989
|
+
case "integer": {
|
|
990
|
+
if (format === "int32" || format === "int64") {
|
|
991
|
+
return { type: "integer", format };
|
|
992
|
+
}
|
|
993
|
+
return { type: "integer" };
|
|
994
|
+
}
|
|
995
|
+
case "boolean": {
|
|
996
|
+
return { type: "boolean" };
|
|
997
|
+
}
|
|
998
|
+
case "object": {
|
|
999
|
+
return { type: "object" };
|
|
1000
|
+
}
|
|
1001
|
+
case "array": {
|
|
1002
|
+
return { type: "array" };
|
|
1003
|
+
}
|
|
1004
|
+
default: {
|
|
1005
|
+
/* istanbul ignore next -- @preserve */
|
|
1006
|
+
return { type: "string" };
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
592
1010
|
const ResourcefulErrorHandlerMethod = ["bubble", "pass", "fail"];
|
|
593
1011
|
const getFieldKey = (key, definition) => {
|
|
594
1012
|
if (isString$1(definition.serializeAs)) {
|
|
@@ -598,31 +1016,35 @@ const getFieldKey = (key, definition) => {
|
|
|
598
1016
|
};
|
|
599
1017
|
function withResourceful(options = {}) {
|
|
600
1018
|
return (superclass) => {
|
|
601
|
-
const optionsSchema =
|
|
602
|
-
name:
|
|
603
|
-
readRequiredForWrite:
|
|
604
|
-
accessControlFilters:
|
|
605
|
-
list:
|
|
606
|
-
create:
|
|
607
|
-
read:
|
|
608
|
-
update:
|
|
609
|
-
delete:
|
|
1019
|
+
const optionsSchema = zu.object({
|
|
1020
|
+
name: zu.string().default(superclass.name),
|
|
1021
|
+
readRequiredForWrite: zu.boolean().default(false),
|
|
1022
|
+
accessControlFilters: zu.object({
|
|
1023
|
+
list: zu.array().items(zu.function()).default([]),
|
|
1024
|
+
create: zu.array().items(zu.function()).default([]),
|
|
1025
|
+
read: zu.array().items(zu.function()).default([]),
|
|
1026
|
+
update: zu.array().items(zu.function()).default([]),
|
|
1027
|
+
delete: zu.array().items(zu.function()).default([])
|
|
610
1028
|
}).default({}),
|
|
611
|
-
onACLError:
|
|
612
|
-
onValidationScopeError:
|
|
613
|
-
queryScopeCallbacks:
|
|
614
|
-
list:
|
|
615
|
-
access:
|
|
1029
|
+
onACLError: zu.string().valid(...ResourcefulErrorHandlerMethod).default("throw"),
|
|
1030
|
+
onValidationScopeError: zu.string().valid(...ResourcefulErrorHandlerMethod).default("throw"),
|
|
1031
|
+
queryScopeCallbacks: zu.object({
|
|
1032
|
+
list: zu.array().items(zu.function()).default([]),
|
|
1033
|
+
access: zu.array().items(zu.function()).default([])
|
|
616
1034
|
}).default({}),
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
1035
|
+
payloadValidationSchemaBuilders: zu.object({
|
|
1036
|
+
create: zu.array().items(zu.function()).default([]),
|
|
1037
|
+
update: zu.array().items(zu.function()).default([])
|
|
1038
|
+
}).default({ create: [], update: [] }),
|
|
1039
|
+
description: zu.string().optional(),
|
|
1040
|
+
externalDocs: zu.object({
|
|
1041
|
+
description: zu.string().optional(),
|
|
1042
|
+
url: zu.string().uri().required()
|
|
621
1043
|
}).optional(),
|
|
622
|
-
example:
|
|
623
|
-
advanced:
|
|
624
|
-
propertyEvaluationConcurrency:
|
|
625
|
-
aclEvaluationConcurrency:
|
|
1044
|
+
example: zu.string().optional(),
|
|
1045
|
+
advanced: zu.object({
|
|
1046
|
+
propertyEvaluationConcurrency: zu.number().integer().min(1).default(10),
|
|
1047
|
+
aclEvaluationConcurrency: zu.number().integer().min(1).default(2)
|
|
626
1048
|
}).default({
|
|
627
1049
|
propertyEvaluationConcurrency: 10,
|
|
628
1050
|
aclEvaluationConcurrency: 2
|
|
@@ -672,6 +1094,7 @@ function withResourceful(options = {}) {
|
|
|
672
1094
|
Array.from(this.$resourcefulColumns.entries()),
|
|
673
1095
|
async ([propertyKey, columnDefinition]) => {
|
|
674
1096
|
const lucidDefinitions = this.$getColumn(propertyKey);
|
|
1097
|
+
/* istanbul ignore if -- @preserve */
|
|
675
1098
|
if (!lucidDefinitions) return;
|
|
676
1099
|
const resourcefulModelColumnMetaSchema = {
|
|
677
1100
|
propertyKey,
|
|
@@ -709,6 +1132,7 @@ function withResourceful(options = {}) {
|
|
|
709
1132
|
Array.from(this.$resourcefulComputedAccessors.entries()),
|
|
710
1133
|
async ([propertyKey, computedAccessorDefinition]) => {
|
|
711
1134
|
const lucidDefinitions = this.$getComputed(propertyKey);
|
|
1135
|
+
/* istanbul ignore if -- @preserve */
|
|
712
1136
|
if (!lucidDefinitions) return;
|
|
713
1137
|
const resourcefulModelComputedAccessorMetaSchema = {
|
|
714
1138
|
propertyKey,
|
|
@@ -736,6 +1160,7 @@ function withResourceful(options = {}) {
|
|
|
736
1160
|
computedAccessorDefinition.writable
|
|
737
1161
|
)
|
|
738
1162
|
};
|
|
1163
|
+
/* istanbul ignore if -- @preserve */
|
|
739
1164
|
if (!resourcefulModelComputedAccessorMetaSchema.canRead && !resourcefulModelComputedAccessorMetaSchema.canWrite)
|
|
740
1165
|
return;
|
|
741
1166
|
resourcefulModelMetaSchema.properties[propertyKey] = resourcefulModelComputedAccessorMetaSchema;
|
|
@@ -748,6 +1173,7 @@ function withResourceful(options = {}) {
|
|
|
748
1173
|
Array.from(this.$resourcefulRelationships.entries()),
|
|
749
1174
|
async ([propertyKey, relationshipDefinition]) => {
|
|
750
1175
|
const lucidDefinitions = this.$getRelation(propertyKey);
|
|
1176
|
+
/* istanbul ignore if -- @preserve */
|
|
751
1177
|
if (!lucidDefinitions) return;
|
|
752
1178
|
const resourcefulModelRelationshipMetaSchema = {
|
|
753
1179
|
propertyKey,
|
|
@@ -763,9 +1189,10 @@ function withResourceful(options = {}) {
|
|
|
763
1189
|
"relationship"
|
|
764
1190
|
),
|
|
765
1191
|
kind: "relationship",
|
|
766
|
-
validator:
|
|
1192
|
+
validator: zu.forbidden(),
|
|
767
1193
|
relatedModel: relationshipDefinition.relatedModel
|
|
768
1194
|
};
|
|
1195
|
+
/* istanbul ignore if -- @preserve */
|
|
769
1196
|
if (!resourcefulModelRelationshipMetaSchema.canRead && !resourcefulModelRelationshipMetaSchema.canWrite)
|
|
770
1197
|
return;
|
|
771
1198
|
resourcefulModelMetaSchema.properties[propertyKey] = resourcefulModelRelationshipMetaSchema;
|
|
@@ -778,11 +1205,14 @@ function withResourceful(options = {}) {
|
|
|
778
1205
|
}
|
|
779
1206
|
static $getPropertyValidator(ctx, app, key, datatype, nullable, validationScopes, kind, writable = false) {
|
|
780
1207
|
if ("relationship" === kind || "computedAccessor" === kind && !writable) {
|
|
781
|
-
return
|
|
1208
|
+
return zu.any().forbidden();
|
|
782
1209
|
}
|
|
783
1210
|
const baseValidator = this.$getPropertyBaseValidator(datatype, nullable, kind, writable);
|
|
1211
|
+
let retValidator = baseValidator;
|
|
784
1212
|
if (Array.isArray(validationScopes) && validationScopes.length > 0) {
|
|
785
1213
|
validationScopes.forEach((validationScope) => {
|
|
1214
|
+
/* istanbul ignore if -- @preserve */
|
|
1215
|
+
if (retValidator !== baseValidator) return;
|
|
786
1216
|
try {
|
|
787
1217
|
validationScope(baseValidator);
|
|
788
1218
|
} catch (err) {
|
|
@@ -800,145 +1230,192 @@ function withResourceful(options = {}) {
|
|
|
800
1230
|
case "pass":
|
|
801
1231
|
break;
|
|
802
1232
|
case "fail":
|
|
803
|
-
|
|
1233
|
+
retValidator = zu.any().forbidden();
|
|
1234
|
+
break;
|
|
804
1235
|
}
|
|
805
1236
|
}
|
|
806
1237
|
});
|
|
807
1238
|
}
|
|
808
|
-
return
|
|
1239
|
+
return retValidator;
|
|
809
1240
|
}
|
|
810
1241
|
static $getPropertyBaseValidator(datatype, nullable, kind, writable = false) {
|
|
811
1242
|
if ("relationship" === kind || "computedAccessor" === kind && !writable) {
|
|
812
|
-
return
|
|
1243
|
+
return zu.any().forbidden();
|
|
813
1244
|
}
|
|
814
1245
|
nullable = nullable || "boolean" === typeof datatype.nullable && datatype.nullable;
|
|
815
1246
|
switch (true) {
|
|
816
|
-
case datatype
|
|
817
|
-
|
|
818
|
-
const r = Q_.string().min(d.minLength).max(d.maxLength);
|
|
819
|
-
if (d.pattern) {
|
|
820
|
-
r.pattern(new RegExp(d.pattern));
|
|
821
|
-
}
|
|
822
|
-
if (d.enum) {
|
|
823
|
-
r.valid(...d.enum);
|
|
824
|
-
}
|
|
1247
|
+
case isResourcefulDateType(datatype): {
|
|
1248
|
+
let r = zu.date().iso();
|
|
825
1249
|
if (nullable) {
|
|
826
|
-
r.
|
|
1250
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
827
1251
|
}
|
|
828
1252
|
return r;
|
|
829
1253
|
}
|
|
830
|
-
case datatype
|
|
831
|
-
|
|
1254
|
+
case isResourcefulDateTimeType(datatype): {
|
|
1255
|
+
let r = zu.date().iso();
|
|
832
1256
|
if (nullable) {
|
|
833
|
-
r.
|
|
1257
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
834
1258
|
}
|
|
835
1259
|
return r;
|
|
836
1260
|
}
|
|
837
|
-
case datatype
|
|
838
|
-
const
|
|
1261
|
+
case isResourcefulBinaryType(datatype): {
|
|
1262
|
+
const d = datatype;
|
|
1263
|
+
const min2 = "number" === typeof d.minLength ? Math.abs(d.minLength) : 0;
|
|
1264
|
+
const max2 = "number" === typeof d.maxLength ? Math.abs(d.maxLength) : Number.MAX_SAFE_INTEGER;
|
|
1265
|
+
let r = zu.string().min(min2).max(max2);
|
|
839
1266
|
if (nullable) {
|
|
840
|
-
r.
|
|
1267
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
841
1268
|
}
|
|
842
1269
|
return r;
|
|
843
1270
|
}
|
|
844
|
-
case datatype
|
|
1271
|
+
case isResourcefulStringType(datatype): {
|
|
845
1272
|
const d = datatype;
|
|
846
|
-
|
|
847
|
-
if (
|
|
848
|
-
r.
|
|
1273
|
+
let r = zu.string().min(d.minLength).max(d.maxLength);
|
|
1274
|
+
if (d.pattern) {
|
|
1275
|
+
r = r.concat(r.pattern(new RegExp(d.pattern)));
|
|
849
1276
|
}
|
|
850
|
-
if (d.
|
|
851
|
-
r.
|
|
1277
|
+
if (d.enum) {
|
|
1278
|
+
r = r.concat(zu.string().valid(...d.enum));
|
|
852
1279
|
}
|
|
853
|
-
if (
|
|
854
|
-
r.
|
|
1280
|
+
if (nullable) {
|
|
1281
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
855
1282
|
}
|
|
856
1283
|
return r;
|
|
857
1284
|
}
|
|
858
|
-
case datatype
|
|
1285
|
+
case isResourcefulIntegerType(datatype): {
|
|
859
1286
|
const d = datatype;
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
r.allow(null);
|
|
863
|
-
}
|
|
864
|
-
r.multiple(d.multipleOf);
|
|
1287
|
+
let r = zu.number();
|
|
1288
|
+
r = r.concat(zu.number().integer().multiple(d.multipleOf));
|
|
865
1289
|
if (d.exclusiveMaximum) {
|
|
866
|
-
r.less(d.maximum);
|
|
1290
|
+
r = r.concat(zu.number().less(d.maximum));
|
|
867
1291
|
} else {
|
|
868
|
-
r.max(d.maximum);
|
|
1292
|
+
r = r.concat(zu.number().max(d.maximum));
|
|
869
1293
|
}
|
|
870
1294
|
if (d.exclusiveMinimum) {
|
|
871
|
-
r.greater(d.minimum);
|
|
1295
|
+
r = r.concat(zu.number().greater(d.minimum));
|
|
872
1296
|
} else {
|
|
873
|
-
r.min(d.minimum);
|
|
1297
|
+
r = r.concat(zu.number().min(d.minimum));
|
|
1298
|
+
}
|
|
1299
|
+
if (nullable) {
|
|
1300
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
874
1301
|
}
|
|
875
1302
|
return r;
|
|
876
1303
|
}
|
|
877
|
-
case datatype
|
|
1304
|
+
case isResourcefulBigintType(datatype): {
|
|
878
1305
|
const d = datatype;
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
r.allow(null);
|
|
1306
|
+
if ("undefined" === typeof d.minimum) {
|
|
1307
|
+
d.minimum = 0n;
|
|
882
1308
|
}
|
|
883
|
-
|
|
1309
|
+
if ("undefined" === typeof d.maximum) {
|
|
1310
|
+
d.maximum = BigInt(Number.MAX_SAFE_INTEGER);
|
|
1311
|
+
}
|
|
1312
|
+
if ("undefined" === typeof d.multipleOf) {
|
|
1313
|
+
d.multipleOf = 1n;
|
|
1314
|
+
}
|
|
1315
|
+
let b = zu.bigint();
|
|
1316
|
+
let i = zu.number().integer();
|
|
1317
|
+
b = b.concat(
|
|
1318
|
+
zu.bigint().multiple("number" === typeof d.multipleOf ? BigInt(d.multipleOf) : d.multipleOf)
|
|
1319
|
+
);
|
|
1320
|
+
i = i.concat(
|
|
1321
|
+
zu.number().multiple(
|
|
1322
|
+
"bigint" === typeof d.multipleOf ? Number.parseInt(d.multipleOf.toString()) : d.multipleOf
|
|
1323
|
+
)
|
|
1324
|
+
);
|
|
884
1325
|
if (d.exclusiveMaximum) {
|
|
885
|
-
|
|
1326
|
+
if (["number", "bigint"].includes(typeof d.maximum)) {
|
|
1327
|
+
b = b.concat(
|
|
1328
|
+
zu.bigint().less("number" === typeof d.maximum ? BigInt(d.maximum) : d.maximum)
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
i = i.concat(
|
|
1332
|
+
zu.number().less(
|
|
1333
|
+
"bigint" === typeof d.maximum ? Number.parseInt(d.maximum.toString()) : d.maximum
|
|
1334
|
+
)
|
|
1335
|
+
);
|
|
886
1336
|
} else {
|
|
887
|
-
|
|
1337
|
+
if (["number", "bigint"].includes(typeof d.maximum)) {
|
|
1338
|
+
b = b.concat(
|
|
1339
|
+
zu.bigint().max("number" === typeof d.maximum ? BigInt(d.maximum) : d.maximum)
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
i = i.concat(
|
|
1343
|
+
zu.number().max(
|
|
1344
|
+
"bigint" === typeof d.maximum ? Number.parseInt(d.maximum.toString()) : d.maximum
|
|
1345
|
+
)
|
|
1346
|
+
);
|
|
888
1347
|
}
|
|
889
1348
|
if (d.exclusiveMinimum) {
|
|
890
|
-
|
|
1349
|
+
b = b.concat(
|
|
1350
|
+
zu.bigint().greater("number" === typeof d.minimum ? BigInt(d.minimum) : d.minimum)
|
|
1351
|
+
);
|
|
1352
|
+
i = i.concat(
|
|
1353
|
+
zu.number().greater(
|
|
1354
|
+
"bigint" === typeof d.minimum ? Number.parseInt(d.minimum.toString()) : d.minimum
|
|
1355
|
+
)
|
|
1356
|
+
);
|
|
891
1357
|
} else {
|
|
892
|
-
|
|
1358
|
+
b = b.concat(
|
|
1359
|
+
zu.bigint().min("number" === typeof d.minimum ? BigInt(d.minimum) : d.minimum)
|
|
1360
|
+
);
|
|
1361
|
+
i = i.concat(
|
|
1362
|
+
zu.number().min(
|
|
1363
|
+
"bigint" === typeof d.minimum ? Number.parseInt(d.minimum.toString()) : d.minimum
|
|
1364
|
+
)
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
let r = zu.alternatives(b, i);
|
|
1368
|
+
if (nullable) {
|
|
1369
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
893
1370
|
}
|
|
894
1371
|
return r;
|
|
895
1372
|
}
|
|
896
|
-
case datatype
|
|
1373
|
+
case isResourcefulUnsignedIntegerType(datatype): {
|
|
897
1374
|
const d = datatype;
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
r.allow(null);
|
|
901
|
-
}
|
|
902
|
-
r.multiple(d.multipleOf);
|
|
1375
|
+
let r = zu.number().unsafe();
|
|
1376
|
+
r = r.concat(zu.number().integer().multiple(d.multipleOf));
|
|
903
1377
|
if (d.exclusiveMaximum) {
|
|
904
|
-
r.less(d.maximum);
|
|
1378
|
+
r = r.concat(zu.number().less(d.maximum));
|
|
905
1379
|
} else {
|
|
906
|
-
r.max(d.maximum);
|
|
1380
|
+
r = r.concat(zu.number().max(d.maximum));
|
|
907
1381
|
}
|
|
908
1382
|
if (d.exclusiveMinimum) {
|
|
909
|
-
r.greater(d.minimum);
|
|
1383
|
+
r = r.concat(zu.number().greater(d.minimum));
|
|
910
1384
|
} else {
|
|
911
|
-
r.min(d.minimum);
|
|
1385
|
+
r = r.concat(zu.number().min(d.minimum));
|
|
1386
|
+
}
|
|
1387
|
+
if (nullable) {
|
|
1388
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
912
1389
|
}
|
|
913
1390
|
return r;
|
|
914
1391
|
}
|
|
915
|
-
case datatype
|
|
1392
|
+
case isResourcefulNumberType(datatype): {
|
|
916
1393
|
const d = datatype;
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
r.allow(null);
|
|
920
|
-
}
|
|
921
|
-
r.integer().multiple(d.multipleOf);
|
|
1394
|
+
let r = zu.number();
|
|
1395
|
+
r = r.concat(zu.number().multiple(d.multipleOf));
|
|
922
1396
|
if (d.exclusiveMaximum) {
|
|
923
|
-
r.less(d.maximum);
|
|
1397
|
+
r = r.concat(zu.number().less(d.maximum));
|
|
924
1398
|
} else {
|
|
925
|
-
r.max(d.maximum);
|
|
1399
|
+
r = r.concat(zu.number().max(d.maximum));
|
|
926
1400
|
}
|
|
927
1401
|
if (d.exclusiveMinimum) {
|
|
928
|
-
r.greater(d.minimum);
|
|
1402
|
+
r = r.concat(zu.number().greater(d.minimum));
|
|
929
1403
|
} else {
|
|
930
|
-
r.min(d.minimum);
|
|
1404
|
+
r = r.concat(zu.number().min(d.minimum));
|
|
1405
|
+
}
|
|
1406
|
+
if (nullable) {
|
|
1407
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
931
1408
|
}
|
|
932
1409
|
return r;
|
|
933
1410
|
}
|
|
934
|
-
case datatype
|
|
935
|
-
|
|
1411
|
+
case isResourcefulBooleanType(datatype): {
|
|
1412
|
+
let r = zu.boolean();
|
|
936
1413
|
if (nullable) {
|
|
937
|
-
r.
|
|
1414
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
938
1415
|
}
|
|
939
1416
|
return r;
|
|
940
1417
|
}
|
|
941
|
-
case datatype
|
|
1418
|
+
case isResourcefulObjectType(datatype): {
|
|
942
1419
|
const d = datatype;
|
|
943
1420
|
const objectSchema = {};
|
|
944
1421
|
Object.entries(d.properties).forEach(([propKey, propDef]) => {
|
|
@@ -952,7 +1429,7 @@ function withResourceful(options = {}) {
|
|
|
952
1429
|
!(item.readOnly || false)
|
|
953
1430
|
)
|
|
954
1431
|
);
|
|
955
|
-
propValidator =
|
|
1432
|
+
propValidator = zu.alternatives(...alternatives);
|
|
956
1433
|
} else if ("allOf" in propDef) {
|
|
957
1434
|
const schemas = propDef.allOf.map(
|
|
958
1435
|
(item) => this.$getPropertyBaseValidator(
|
|
@@ -962,7 +1439,7 @@ function withResourceful(options = {}) {
|
|
|
962
1439
|
!(item.readOnly || false)
|
|
963
1440
|
)
|
|
964
1441
|
);
|
|
965
|
-
propValidator = schemas.reduce((acc, schema) => acc.concat(schema),
|
|
1442
|
+
propValidator = schemas.reduce((acc, schema) => acc.concat(schema), zu.any());
|
|
966
1443
|
} else if ("anyOf" in propDef) {
|
|
967
1444
|
const alternatives = propDef.anyOf.map(
|
|
968
1445
|
(item) => this.$getPropertyBaseValidator(
|
|
@@ -972,7 +1449,7 @@ function withResourceful(options = {}) {
|
|
|
972
1449
|
!(item.readOnly || false)
|
|
973
1450
|
)
|
|
974
1451
|
);
|
|
975
|
-
propValidator =
|
|
1452
|
+
propValidator = zu.alternatives(...alternatives);
|
|
976
1453
|
} else if ("not" in propDef) {
|
|
977
1454
|
const notSchemas = propDef.not.map(
|
|
978
1455
|
(item) => this.$getPropertyBaseValidator(
|
|
@@ -982,7 +1459,12 @@ function withResourceful(options = {}) {
|
|
|
982
1459
|
!(item.readOnly || false)
|
|
983
1460
|
)
|
|
984
1461
|
);
|
|
985
|
-
propValidator =
|
|
1462
|
+
propValidator = zu.any();
|
|
1463
|
+
notSchemas.forEach((notSchema) => {
|
|
1464
|
+
propValidator = propValidator.concat(
|
|
1465
|
+
zu.when(notSchema, { then: zu.forbidden() })
|
|
1466
|
+
);
|
|
1467
|
+
});
|
|
986
1468
|
} else {
|
|
987
1469
|
propValidator = this.$getPropertyBaseValidator(
|
|
988
1470
|
propDef,
|
|
@@ -990,44 +1472,46 @@ function withResourceful(options = {}) {
|
|
|
990
1472
|
kind,
|
|
991
1473
|
!(propDef.readOnly || false)
|
|
992
1474
|
);
|
|
1475
|
+
if (Array.isArray(d.required) && d.required.includes(propKey)) {
|
|
1476
|
+
propValidator = propValidator.concat(zu.any().required());
|
|
1477
|
+
}
|
|
993
1478
|
}
|
|
994
1479
|
if (d.required && d.required.includes(propKey)) {
|
|
995
1480
|
propValidator.required();
|
|
996
1481
|
}
|
|
997
1482
|
objectSchema[propKey] = propValidator;
|
|
998
1483
|
});
|
|
999
|
-
|
|
1000
|
-
if (nullable) {
|
|
1001
|
-
r.allow(null);
|
|
1002
|
-
}
|
|
1484
|
+
let r = zu.object(objectSchema);
|
|
1003
1485
|
if (d.minProperties !== void 0) {
|
|
1004
|
-
r.min(d.minProperties);
|
|
1486
|
+
r = r.concat(zu.object().min(d.minProperties));
|
|
1005
1487
|
}
|
|
1006
1488
|
if (d.maxProperties !== void 0) {
|
|
1007
|
-
r.max(d.maxProperties);
|
|
1489
|
+
r = r.concat(zu.object().max(d.maxProperties));
|
|
1008
1490
|
}
|
|
1009
|
-
if (isObject$
|
|
1491
|
+
if (isObject$2(d.additionalProperties)) {
|
|
1010
1492
|
const additionalPropertiesType = d.additionalProperties;
|
|
1011
|
-
r.
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1493
|
+
r = r.concat(
|
|
1494
|
+
zu.object().pattern(
|
|
1495
|
+
zu.string(),
|
|
1496
|
+
this.$getPropertyBaseValidator(
|
|
1497
|
+
additionalPropertiesType,
|
|
1498
|
+
additionalPropertiesType.nullable || false,
|
|
1499
|
+
kind,
|
|
1500
|
+
!(additionalPropertiesType.readOnly || false)
|
|
1501
|
+
)
|
|
1018
1502
|
)
|
|
1019
1503
|
);
|
|
1020
1504
|
} else {
|
|
1021
|
-
r.unknown(true === d.additionalProperties);
|
|
1505
|
+
r = r.concat(zu.object().unknown(true === d.additionalProperties));
|
|
1506
|
+
}
|
|
1507
|
+
if (nullable) {
|
|
1508
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
1022
1509
|
}
|
|
1023
1510
|
return r;
|
|
1024
1511
|
}
|
|
1025
|
-
case datatype
|
|
1512
|
+
case isResourcefulArrayType(datatype): {
|
|
1026
1513
|
const d = datatype;
|
|
1027
|
-
|
|
1028
|
-
if (nullable) {
|
|
1029
|
-
r.allow(null);
|
|
1030
|
-
}
|
|
1514
|
+
let r = zu.array();
|
|
1031
1515
|
let itemValidator;
|
|
1032
1516
|
if ("oneOf" in d.items) {
|
|
1033
1517
|
const alternatives = d.items.oneOf.map(
|
|
@@ -1038,7 +1522,7 @@ function withResourceful(options = {}) {
|
|
|
1038
1522
|
!(item.readOnly || false)
|
|
1039
1523
|
)
|
|
1040
1524
|
);
|
|
1041
|
-
itemValidator =
|
|
1525
|
+
itemValidator = zu.alternatives(...alternatives);
|
|
1042
1526
|
} else if ("allOf" in d.items) {
|
|
1043
1527
|
const schemas = d.items.allOf.map(
|
|
1044
1528
|
(item) => this.$getPropertyBaseValidator(
|
|
@@ -1048,7 +1532,7 @@ function withResourceful(options = {}) {
|
|
|
1048
1532
|
!(item.readOnly || false)
|
|
1049
1533
|
)
|
|
1050
1534
|
);
|
|
1051
|
-
itemValidator = schemas.reduce((acc, schema) => acc.concat(schema),
|
|
1535
|
+
itemValidator = schemas.reduce((acc, schema) => acc.concat(schema), zu.any());
|
|
1052
1536
|
} else if ("anyOf" in d.items) {
|
|
1053
1537
|
const alternatives = d.items.anyOf.map(
|
|
1054
1538
|
(item) => this.$getPropertyBaseValidator(
|
|
@@ -1058,7 +1542,7 @@ function withResourceful(options = {}) {
|
|
|
1058
1542
|
!(item.readOnly || false)
|
|
1059
1543
|
)
|
|
1060
1544
|
);
|
|
1061
|
-
itemValidator =
|
|
1545
|
+
itemValidator = zu.alternatives(...alternatives);
|
|
1062
1546
|
} else if ("not" in d.items) {
|
|
1063
1547
|
const notSchemas = d.items.not.map(
|
|
1064
1548
|
(item) => this.$getPropertyBaseValidator(
|
|
@@ -1068,7 +1552,10 @@ function withResourceful(options = {}) {
|
|
|
1068
1552
|
!(item.readOnly || false)
|
|
1069
1553
|
)
|
|
1070
1554
|
);
|
|
1071
|
-
itemValidator =
|
|
1555
|
+
itemValidator = zu.any();
|
|
1556
|
+
notSchemas.forEach((notSchema) => {
|
|
1557
|
+
itemValidator = itemValidator.concat(zu.when(notSchema, { then: zu.forbidden() }));
|
|
1558
|
+
});
|
|
1072
1559
|
} else {
|
|
1073
1560
|
itemValidator = this.$getPropertyBaseValidator(
|
|
1074
1561
|
d.items,
|
|
@@ -1077,20 +1564,23 @@ function withResourceful(options = {}) {
|
|
|
1077
1564
|
!(d.items.readOnly || false)
|
|
1078
1565
|
);
|
|
1079
1566
|
}
|
|
1080
|
-
r.items(itemValidator);
|
|
1567
|
+
r = r.concat(zu.array().items(itemValidator));
|
|
1081
1568
|
if (d.minItems !== void 0) {
|
|
1082
|
-
r.min(d.minItems);
|
|
1569
|
+
r = r.concat(zu.array().min(d.minItems));
|
|
1083
1570
|
}
|
|
1084
1571
|
if (d.maxItems !== void 0) {
|
|
1085
|
-
r.max(d.maxItems);
|
|
1572
|
+
r = r.concat(zu.array().max(d.maxItems));
|
|
1086
1573
|
}
|
|
1087
1574
|
if (d.uniqueItems) {
|
|
1088
|
-
r.unique();
|
|
1575
|
+
r = r.concat(zu.array().unique());
|
|
1576
|
+
}
|
|
1577
|
+
if (nullable) {
|
|
1578
|
+
return zu.alternatives(r, zu.any().valid(null));
|
|
1089
1579
|
}
|
|
1090
1580
|
return r;
|
|
1091
1581
|
}
|
|
1092
1582
|
default:
|
|
1093
|
-
return
|
|
1583
|
+
return zu.any().forbidden();
|
|
1094
1584
|
}
|
|
1095
1585
|
}
|
|
1096
1586
|
static async $getPropertyCanReadWrite(ctx, app, key, lucidDefinition, readAclFilters = [], writeAclFilters = [], kind, writable = false) {
|
|
@@ -1135,158 +1625,14 @@ function withResourceful(options = {}) {
|
|
|
1135
1625
|
);
|
|
1136
1626
|
return results.every((result) => result === true);
|
|
1137
1627
|
}
|
|
1138
|
-
static async $asOpenApiSchemaObject(ctx, app) {
|
|
1628
|
+
static async $asOpenApiSchemaObject(ctx, app, operation = "read") {
|
|
1139
1629
|
const resourcefulModelMetaSchema = await this.$getAsResourcefulForContext(ctx, app);
|
|
1140
|
-
const
|
|
1141
|
-
|
|
1142
|
-
title: resourcefulModelMetaSchema.name,
|
|
1143
|
-
description: resourcefulModelMetaSchema.description,
|
|
1144
|
-
externalDocs: resourcefulModelMetaSchema.externalDocs,
|
|
1145
|
-
example: resourcefulModelMetaSchema.example,
|
|
1146
|
-
properties: {}
|
|
1147
|
-
};
|
|
1148
|
-
Object.entries(resourcefulModelMetaSchema.properties).forEach(
|
|
1149
|
-
([propertyKey, propertyMeta]) => {
|
|
1150
|
-
const resolvedColumnName = getFieldKey(
|
|
1151
|
-
propertyKey,
|
|
1152
|
-
propertyMeta.lucidDefinitions
|
|
1153
|
-
);
|
|
1154
|
-
if (null === resolvedColumnName) {
|
|
1155
|
-
return;
|
|
1156
|
-
}
|
|
1157
|
-
switch (propertyMeta.kind) {
|
|
1158
|
-
case "column": {
|
|
1159
|
-
ret.properties[propertyKey] = this.$resourcefulModelColumnMetaToOpenApiSchema(
|
|
1160
|
-
propertyKey,
|
|
1161
|
-
propertyMeta
|
|
1162
|
-
);
|
|
1163
|
-
return;
|
|
1164
|
-
}
|
|
1165
|
-
case "computedAccessor": {
|
|
1166
|
-
ret.properties[propertyKey] = this.$resourcefulModelComputedAccessorMetaToOpenApiSchema(
|
|
1167
|
-
propertyKey,
|
|
1168
|
-
propertyMeta
|
|
1169
|
-
);
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
case "relationship": {
|
|
1173
|
-
const relatedSchema = this.$resourcefulModelRelationshipMetaToOpenApiSchema(
|
|
1174
|
-
propertyKey,
|
|
1175
|
-
propertyMeta
|
|
1176
|
-
);
|
|
1177
|
-
if (relatedSchema) {
|
|
1178
|
-
ret.properties[propertyKey] = relatedSchema;
|
|
1179
|
-
}
|
|
1180
|
-
return;
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
);
|
|
1185
|
-
const requiredPropSet = /* @__PURE__ */ new Set();
|
|
1186
|
-
Object.entries(ret.properties).forEach(([propertyKey, schema]) => {
|
|
1187
|
-
if (!isObject$1(schema) || "$ref" in schema || !("nullable" in schema) || schema.nullable)
|
|
1188
|
-
return;
|
|
1189
|
-
requiredPropSet.add(propertyKey);
|
|
1190
|
-
});
|
|
1191
|
-
ret.required = Array.from(requiredPropSet);
|
|
1192
|
-
return ret;
|
|
1193
|
-
}
|
|
1194
|
-
static $getDefaultValueFromPropertyMeta(propertyMeta) {
|
|
1195
|
-
const joiDescription = propertyMeta.validator.describe();
|
|
1196
|
-
if (isObject$1(joiDescription) && "flags" in joiDescription && isObject$1(joiDescription.flags) && "default" in joiDescription.flags) {
|
|
1197
|
-
return joiDescription.flags.default;
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
static $resourcefulModelColumnMetaToOpenApiSchema(propertyKey, propertyMeta) {
|
|
1201
|
-
const ret = stripUndefinedValuesFromObject({
|
|
1202
|
-
items: propertyMeta.definition.items,
|
|
1203
|
-
title: getFieldKey(propertyKey, propertyMeta.lucidDefinitions) || propertyKey,
|
|
1204
|
-
description: propertyMeta.definition.description,
|
|
1205
|
-
format: propertyMeta.definition.format,
|
|
1206
|
-
default: this.$getDefaultValueFromPropertyMeta(propertyMeta),
|
|
1207
|
-
multipleOf: propertyMeta.definition.multipleOf,
|
|
1208
|
-
maximum: propertyMeta.definition.maximum,
|
|
1209
|
-
exclusiveMaximum: propertyMeta.definition.exclusiveMaximum,
|
|
1210
|
-
minimum: propertyMeta.definition.minimum,
|
|
1211
|
-
exclusiveMinimum: propertyMeta.definition.exclusiveMinimum,
|
|
1212
|
-
maxLength: propertyMeta.definition.maxLength,
|
|
1213
|
-
minLength: propertyMeta.definition.minLength,
|
|
1214
|
-
pattern: propertyMeta.definition.pattern,
|
|
1215
|
-
additionalProperties: propertyMeta.definition.additionalProperties,
|
|
1216
|
-
maxItems: propertyMeta.definition.maxItems,
|
|
1217
|
-
minItems: propertyMeta.definition.minItems,
|
|
1218
|
-
uniqueItems: propertyMeta.definition.uniqueItems,
|
|
1219
|
-
maxProperties: propertyMeta.definition.maxProperties,
|
|
1220
|
-
minProperties: propertyMeta.definition.minProperties,
|
|
1221
|
-
required: propertyMeta.definition.required,
|
|
1222
|
-
enum: propertyMeta.definition.enum,
|
|
1223
|
-
properties: propertyMeta.definition.properties,
|
|
1224
|
-
allOf: propertyMeta.definition.allOf,
|
|
1225
|
-
oneOf: propertyMeta.definition.oneOf,
|
|
1226
|
-
anyOf: propertyMeta.definition.anyOf,
|
|
1227
|
-
not: propertyMeta.definition.not,
|
|
1228
|
-
nullable: propertyMeta.definition.nullable,
|
|
1229
|
-
readOnly: propertyMeta.canRead && !propertyMeta.canWrite,
|
|
1230
|
-
writeOnly: !propertyMeta.canRead && propertyMeta.canWrite,
|
|
1231
|
-
externalDocs: propertyMeta.definition.externalDocs,
|
|
1232
|
-
example: propertyMeta.definition.example,
|
|
1233
|
-
...propertyMeta.definition.type
|
|
1234
|
-
});
|
|
1235
|
-
return ret;
|
|
1236
|
-
}
|
|
1237
|
-
static $resourcefulModelComputedAccessorMetaToOpenApiSchema(propertyKey, propertyMeta) {
|
|
1238
|
-
const ret = stripUndefinedValuesFromObject({
|
|
1239
|
-
items: propertyMeta.definition.items,
|
|
1240
|
-
title: getFieldKey(propertyKey, propertyMeta.lucidDefinitions) || propertyKey,
|
|
1241
|
-
description: propertyMeta.definition.description,
|
|
1242
|
-
format: propertyMeta.definition.format,
|
|
1243
|
-
default: this.$getDefaultValueFromPropertyMeta(propertyMeta),
|
|
1244
|
-
multipleOf: propertyMeta.definition.multipleOf,
|
|
1245
|
-
maximum: propertyMeta.definition.maximum,
|
|
1246
|
-
exclusiveMaximum: propertyMeta.definition.exclusiveMaximum,
|
|
1247
|
-
minimum: propertyMeta.definition.minimum,
|
|
1248
|
-
exclusiveMinimum: propertyMeta.definition.exclusiveMinimum,
|
|
1249
|
-
maxLength: propertyMeta.definition.maxLength,
|
|
1250
|
-
minLength: propertyMeta.definition.minLength,
|
|
1251
|
-
pattern: propertyMeta.definition.pattern,
|
|
1252
|
-
additionalProperties: propertyMeta.definition.additionalProperties,
|
|
1253
|
-
maxItems: propertyMeta.definition.maxItems,
|
|
1254
|
-
minItems: propertyMeta.definition.minItems,
|
|
1255
|
-
uniqueItems: propertyMeta.definition.uniqueItems,
|
|
1256
|
-
maxProperties: propertyMeta.definition.maxProperties,
|
|
1257
|
-
minProperties: propertyMeta.definition.minProperties,
|
|
1258
|
-
required: propertyMeta.definition.required,
|
|
1259
|
-
enum: propertyMeta.definition.enum,
|
|
1260
|
-
properties: propertyMeta.definition.properties,
|
|
1261
|
-
allOf: propertyMeta.definition.allOf,
|
|
1262
|
-
oneOf: propertyMeta.definition.oneOf,
|
|
1263
|
-
anyOf: propertyMeta.definition.anyOf,
|
|
1264
|
-
not: propertyMeta.definition.not,
|
|
1265
|
-
nullable: propertyMeta.definition.nullable,
|
|
1266
|
-
readOnly: propertyMeta.canRead && !propertyMeta.canWrite,
|
|
1267
|
-
writeOnly: !propertyMeta.canRead && propertyMeta.canWrite,
|
|
1268
|
-
externalDocs: propertyMeta.definition.externalDocs,
|
|
1269
|
-
example: propertyMeta.definition.example,
|
|
1270
|
-
...propertyMeta.definition.type
|
|
1271
|
-
});
|
|
1272
|
-
return ret;
|
|
1273
|
-
}
|
|
1274
|
-
static $resourcefulModelRelationshipMetaToOpenApiSchema(_propertyKey, propertyMeta) {
|
|
1275
|
-
const relatedModel = propertyMeta.relatedModel();
|
|
1276
|
-
if (!relatedModel) {
|
|
1277
|
-
return void 0;
|
|
1278
|
-
}
|
|
1279
|
-
if (!isResourcefulModel(relatedModel)) {
|
|
1280
|
-
return void 0;
|
|
1281
|
-
}
|
|
1282
|
-
const ref2 = `#/components/schemas/${relatedModel.$resourcefulName}`;
|
|
1283
|
-
return {
|
|
1284
|
-
$ref: ref2
|
|
1285
|
-
};
|
|
1630
|
+
const service = new OpenApiSchemaService();
|
|
1631
|
+
return service.generateModelSchema(operation, resourcefulModelMetaSchema, this);
|
|
1286
1632
|
}
|
|
1287
1633
|
static async $resourcefulCheckAccess(config) {
|
|
1288
1634
|
const { ctx, app, operation, instance } = config;
|
|
1289
|
-
const
|
|
1635
|
+
const allowedSerializedMap = /* @__PURE__ */ new Map();
|
|
1290
1636
|
const allowedColumnsMap = /* @__PURE__ */ new Map();
|
|
1291
1637
|
const mixinAccessControlFilters = validatedOptions.accessControlFilters[operation];
|
|
1292
1638
|
if (mixinAccessControlFilters) {
|
|
@@ -1298,37 +1644,72 @@ function withResourceful(options = {}) {
|
|
|
1298
1644
|
return {
|
|
1299
1645
|
isForbidden: true,
|
|
1300
1646
|
message: "Access denied by Mixin ACLs.",
|
|
1301
|
-
|
|
1647
|
+
allowedSerializedMap: void 0
|
|
1302
1648
|
};
|
|
1303
1649
|
}
|
|
1304
1650
|
}
|
|
1305
1651
|
if (operation === CRUDOperationsEnum.DELETE) {
|
|
1306
|
-
return {
|
|
1652
|
+
return {
|
|
1653
|
+
isForbidden: false,
|
|
1654
|
+
allowedSerializedMap,
|
|
1655
|
+
allowedColumnsMap
|
|
1656
|
+
};
|
|
1307
1657
|
}
|
|
1308
1658
|
const columnsOptions = this.$resourcefulColumns.values();
|
|
1309
1659
|
const aclOperation = operationCRUDToACL(operation);
|
|
1310
|
-
const
|
|
1660
|
+
const addColumnOptionToallowedSerializedMap = (propertyKey) => {
|
|
1311
1661
|
const serializedName = this.$keys.attributesToSerialized.resolve(propertyKey);
|
|
1312
1662
|
const columnName = this.$keys.serializedToColumns.resolve(serializedName);
|
|
1313
|
-
if (serializedName) {
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1663
|
+
if (aclOperation === ACLOperationsEnum.WRITE && serializedName === null) {
|
|
1664
|
+
if (columnName) {
|
|
1665
|
+
allowedSerializedMap.set(columnName, true);
|
|
1666
|
+
allowedColumnsMap.set(columnName, true);
|
|
1667
|
+
}
|
|
1668
|
+
} else if ("string" === typeof serializedName) {
|
|
1669
|
+
allowedSerializedMap.set(serializedName, true);
|
|
1670
|
+
if (columnName) {
|
|
1671
|
+
allowedColumnsMap.set(columnName, true);
|
|
1672
|
+
}
|
|
1318
1673
|
}
|
|
1319
1674
|
};
|
|
1320
1675
|
for (const columnOptions of columnsOptions) {
|
|
1321
1676
|
const propertyACLFilters = aclOperation === ACLOperationsEnum.READ ? columnOptions.readAccessControlFilters : columnOptions.writeAccessControlFilters;
|
|
1322
1677
|
if (!propertyACLFilters) {
|
|
1323
|
-
|
|
1678
|
+
addColumnOptionToallowedSerializedMap(columnOptions.propertyKey);
|
|
1324
1679
|
continue;
|
|
1325
1680
|
}
|
|
1326
1681
|
const isAllowed = await this.$evaluatePropertyAccess(ctx, app, propertyACLFilters);
|
|
1327
1682
|
if (isAllowed) {
|
|
1328
|
-
|
|
1683
|
+
addColumnOptionToallowedSerializedMap(columnOptions.propertyKey);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
if (aclOperation === ACLOperationsEnum.READ) {
|
|
1687
|
+
const computedAccessorsOptions = this.$resourcefulComputedAccessors.values();
|
|
1688
|
+
for (const computedAccessorOptions of computedAccessorsOptions) {
|
|
1689
|
+
const propertyACLFilters = computedAccessorOptions.readAccessControlFilters;
|
|
1690
|
+
if (!propertyACLFilters) {
|
|
1691
|
+
allowedSerializedMap.set(computedAccessorOptions.propertyKey, true);
|
|
1692
|
+
continue;
|
|
1693
|
+
}
|
|
1694
|
+
const isAllowed = await this.$evaluatePropertyAccess(ctx, app, propertyACLFilters);
|
|
1695
|
+
if (isAllowed) {
|
|
1696
|
+
allowedSerializedMap.set(computedAccessorOptions.propertyKey, true);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
const relationshipOptions = this.$resourcefulRelationships.values();
|
|
1700
|
+
for (const relationshipOption of relationshipOptions) {
|
|
1701
|
+
const propertyACLFilters = relationshipOption.readAccessControlFilters;
|
|
1702
|
+
if (!propertyACLFilters) {
|
|
1703
|
+
allowedSerializedMap.set(relationshipOption.propertyKey, true);
|
|
1704
|
+
continue;
|
|
1705
|
+
}
|
|
1706
|
+
const isAllowed = await this.$evaluatePropertyAccess(ctx, app, propertyACLFilters);
|
|
1707
|
+
if (isAllowed) {
|
|
1708
|
+
allowedSerializedMap.set(relationshipOption.propertyKey, true);
|
|
1709
|
+
}
|
|
1329
1710
|
}
|
|
1330
1711
|
}
|
|
1331
|
-
const hasNoAllowedFields = !
|
|
1712
|
+
const hasNoAllowedFields = !allowedSerializedMap.size;
|
|
1332
1713
|
if (hasNoAllowedFields) {
|
|
1333
1714
|
return {
|
|
1334
1715
|
isForbidden: true,
|
|
@@ -1337,7 +1718,7 @@ function withResourceful(options = {}) {
|
|
|
1337
1718
|
}
|
|
1338
1719
|
return {
|
|
1339
1720
|
isForbidden: false,
|
|
1340
|
-
|
|
1721
|
+
allowedSerializedMap,
|
|
1341
1722
|
allowedColumnsMap
|
|
1342
1723
|
};
|
|
1343
1724
|
}
|
|
@@ -1350,6 +1731,40 @@ function withResourceful(options = {}) {
|
|
|
1350
1731
|
});
|
|
1351
1732
|
return ret;
|
|
1352
1733
|
}
|
|
1734
|
+
static $loadPossibilitiesForResourcefulRecord() {
|
|
1735
|
+
const allRelationships = Array.from(this.$resourcefulRelationships.entries()).filter(([propertyKey]) => {
|
|
1736
|
+
const relation = this.$getRelation(propertyKey);
|
|
1737
|
+
return !relation ? false : true;
|
|
1738
|
+
}).map(([propertyKey]) => propertyKey);
|
|
1739
|
+
const possibleRelationships = Array.from(this.$resourcefulRelationships.entries()).filter(([propertyKey]) => {
|
|
1740
|
+
const relation = this.$getRelation(propertyKey);
|
|
1741
|
+
if (!relation) return false;
|
|
1742
|
+
if (relation.serializeAs === null) return false;
|
|
1743
|
+
return relation.type === "belongsTo" || relation.type === "hasOne";
|
|
1744
|
+
}).map(([propertyKey]) => propertyKey);
|
|
1745
|
+
const possibleColumns = Array.from(this.$resourcefulColumns.entries()).map(([propertyKey]) => propertyKey).filter((propertyKey) => {
|
|
1746
|
+
const lucidColumnOptions = this.$getColumn(propertyKey);
|
|
1747
|
+
if (!lucidColumnOptions) return false;
|
|
1748
|
+
if (lucidColumnOptions.serializeAs === null) return false;
|
|
1749
|
+
return lucidColumnOptions.serializeAs !== null;
|
|
1750
|
+
});
|
|
1751
|
+
const possibleComputed = Array.from(this.$resourcefulComputedAccessors.entries()).map(([propertyKey]) => propertyKey).filter((propertyKey) => {
|
|
1752
|
+
const lucidComputedOptions = this.$getComputed(propertyKey);
|
|
1753
|
+
if (!lucidComputedOptions) return false;
|
|
1754
|
+
if (lucidComputedOptions.serializeAs === null) return false;
|
|
1755
|
+
return lucidComputedOptions.serializeAs !== null;
|
|
1756
|
+
});
|
|
1757
|
+
const possibleFields = Array.from(
|
|
1758
|
+
/* @__PURE__ */ new Set([...possibleColumns, ...possibleComputed, ...possibleRelationships])
|
|
1759
|
+
).map((prop) => this.$keys.attributesToSerialized.get(prop) || prop).filter((s) => "string" === typeof s);
|
|
1760
|
+
return {
|
|
1761
|
+
allRelationships,
|
|
1762
|
+
possibleRelationships,
|
|
1763
|
+
possibleColumns,
|
|
1764
|
+
possibleComputed,
|
|
1765
|
+
possibleFields
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1353
1768
|
/**
|
|
1354
1769
|
* Performs paginated listing and searching of model records with comprehensive filtering.
|
|
1355
1770
|
*
|
|
@@ -1409,22 +1824,33 @@ function withResourceful(options = {}) {
|
|
|
1409
1824
|
* );
|
|
1410
1825
|
* ```
|
|
1411
1826
|
*/
|
|
1412
|
-
static $formatResourcefulRecord(record) {
|
|
1827
|
+
static $formatResourcefulRecord(record, possibleFields) {
|
|
1828
|
+
if (null === record || void 0 === record) {
|
|
1829
|
+
return record;
|
|
1830
|
+
}
|
|
1413
1831
|
const result = {};
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1832
|
+
const { possibleFields: allPossibleFields } = this.$loadPossibilitiesForResourcefulRecord();
|
|
1833
|
+
possibleFields = possibleFields.filter((field) => allPossibleFields.includes(field));
|
|
1834
|
+
possibleFields.forEach((field) => {
|
|
1835
|
+
const attribute = this.$keys.serializedToAttributes.get(field) || field;
|
|
1836
|
+
if (!attribute) return;
|
|
1837
|
+
const value = record[attribute];
|
|
1838
|
+
if (value !== void 0) {
|
|
1839
|
+
const resourcefulRelationshipOptions = this.$resourcefulRelationships.get(attribute);
|
|
1840
|
+
if (resourcefulRelationshipOptions) {
|
|
1841
|
+
const relatedModel = resourcefulRelationshipOptions.relatedModel();
|
|
1842
|
+
if ("function" === typeof relatedModel.$formatResourcefulRecord && "function" === typeof relatedModel.$loadPossibilitiesForResourcefulRecord) {
|
|
1843
|
+
const { possibleFields: relatedPossibleFields } = relatedModel.$loadPossibilitiesForResourcefulRecord();
|
|
1844
|
+
result[field] = relatedModel.$formatResourcefulRecord(value, relatedPossibleFields);
|
|
1845
|
+
} else if ("function" === typeof value.serialize) {
|
|
1846
|
+
result[field] = value.serialize();
|
|
1847
|
+
}
|
|
1848
|
+
} else {
|
|
1849
|
+
result[field] = value;
|
|
1850
|
+
}
|
|
1423
1851
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
}
|
|
1427
|
-
return result;
|
|
1852
|
+
});
|
|
1853
|
+
return stripUndefinedValuesFromObject(result);
|
|
1428
1854
|
}
|
|
1429
1855
|
static async $validatePayloadWithValidationGetters(ctx, app, payload, validationGetters) {
|
|
1430
1856
|
const schemas = await Promise.all(validationGetters.map((getter) => getter(ctx, app)));
|
|
@@ -1460,7 +1886,7 @@ function withResourceful(options = {}) {
|
|
|
1460
1886
|
filter = "";
|
|
1461
1887
|
}
|
|
1462
1888
|
fields = prepareFields(fields, primaryKey);
|
|
1463
|
-
const { isForbidden,
|
|
1889
|
+
const { isForbidden, allowedSerializedMap, message } = await this.$resourcefulCheckAccess({
|
|
1464
1890
|
ctx,
|
|
1465
1891
|
app,
|
|
1466
1892
|
operation: CRUDOperationsEnum.LIST
|
|
@@ -1468,15 +1894,18 @@ function withResourceful(options = {}) {
|
|
|
1468
1894
|
if (isForbidden) {
|
|
1469
1895
|
throw new E_FORBIDDEN(message);
|
|
1470
1896
|
}
|
|
1471
|
-
const
|
|
1897
|
+
const { allRelationships, possibleRelationships, possibleColumns, possibleComputed } = this.$loadPossibilitiesForResourcefulRecord();
|
|
1898
|
+
const possibleFields = Array.from(allowedSerializedMap.keys()).filter(
|
|
1899
|
+
(f) => possibleColumns.includes(f) || possibleComputed.includes(f) || !allRelationships.includes(f) || possibleRelationships.includes(f)
|
|
1900
|
+
);
|
|
1472
1901
|
if (possibleFields.length === 0) {
|
|
1473
1902
|
throw new E_INVALID_COLUMN_ACCESS("No fields available for access");
|
|
1474
1903
|
}
|
|
1475
|
-
const schema =
|
|
1476
|
-
filter:
|
|
1477
|
-
page:
|
|
1478
|
-
perPage:
|
|
1479
|
-
fields:
|
|
1904
|
+
const schema = zu.object({
|
|
1905
|
+
filter: zu.string().allow("").required(),
|
|
1906
|
+
page: zu.number().integer().min(1).required(),
|
|
1907
|
+
perPage: zu.number().integer().min(1).max(100).required(),
|
|
1908
|
+
fields: zu.array().items(zu.string().valid(...possibleFields)).required()
|
|
1480
1909
|
});
|
|
1481
1910
|
const { error: methodValidationError, value: validatedMethodOptions } = schema.validate(
|
|
1482
1911
|
{
|
|
@@ -1498,7 +1927,8 @@ function withResourceful(options = {}) {
|
|
|
1498
1927
|
this.$keys.serializedToColumns,
|
|
1499
1928
|
primaryKey,
|
|
1500
1929
|
this.table,
|
|
1501
|
-
possibleFields
|
|
1930
|
+
possibleFields,
|
|
1931
|
+
this
|
|
1502
1932
|
);
|
|
1503
1933
|
for (const scopeCallback of [
|
|
1504
1934
|
...this.$resourcefulQueryScopeCallbacks.list || [],
|
|
@@ -1506,28 +1936,47 @@ function withResourceful(options = {}) {
|
|
|
1506
1936
|
]) {
|
|
1507
1937
|
await scopeCallback(ctx, app, query);
|
|
1508
1938
|
}
|
|
1509
|
-
const columnsToSelect = validatedMethodOptions.fields.filter((field) => allowedFieldsMap.has(field)).map((field) => this.$keys.serializedToColumns.get(field)).filter((column2) => !!column2);
|
|
1510
1939
|
const countQuery = query.clone();
|
|
1511
1940
|
const recordsQuery = query.clone();
|
|
1941
|
+
const privateKeyColumn = this.$keys.attributesToColumns.get(primaryKey);
|
|
1512
1942
|
countQuery.count("*", "total");
|
|
1513
|
-
recordsQuery.select(
|
|
1943
|
+
recordsQuery.select(privateKeyColumn).forPage(validatedMethodOptions.page, validatedMethodOptions.perPage);
|
|
1514
1944
|
if (Array.isArray(sort) && sort.length > 0) {
|
|
1515
1945
|
sort.forEach(([field, direction]) => {
|
|
1516
|
-
|
|
1517
|
-
|
|
1946
|
+
const columnName = this.$keys.serializedToColumns.get(field);
|
|
1947
|
+
if (allowedSerializedMap.has(field) && columnName) {
|
|
1948
|
+
recordsQuery.orderBy(columnName, direction);
|
|
1518
1949
|
}
|
|
1519
1950
|
});
|
|
1520
1951
|
}
|
|
1521
1952
|
const countQueryQuery = countQuery.toQuery();
|
|
1522
1953
|
const recordsQueryQuery = recordsQuery.toQuery();
|
|
1523
|
-
const [countResults,
|
|
1954
|
+
const [countResults, rawRecordIds] = await Promise.all([countQuery, recordsQuery]);
|
|
1524
1955
|
const totalRaw = Number((_a2 = countResults == null ? void 0 : countResults[0]) == null ? void 0 : _a2.total);
|
|
1956
|
+
const rawRecordsUnsortedQuery = this.query().whereIn(
|
|
1957
|
+
privateKeyColumn,
|
|
1958
|
+
rawRecordIds.map((r) => r[privateKeyColumn])
|
|
1959
|
+
);
|
|
1960
|
+
const relationsToSelect = validatedMethodOptions.fields.filter(
|
|
1961
|
+
(field) => allowedSerializedMap.has(field) && possibleRelationships.includes(field)
|
|
1962
|
+
);
|
|
1963
|
+
relationsToSelect.forEach((prop) => {
|
|
1964
|
+
rawRecordsUnsortedQuery.preload(prop);
|
|
1965
|
+
});
|
|
1966
|
+
const rawRecordsUnsorted = await rawRecordsUnsortedQuery;
|
|
1967
|
+
const rawRecords = rawRecordsUnsorted.sort((a2, b) => {
|
|
1968
|
+
const aId = a2.$getAttribute(primaryKey);
|
|
1969
|
+
const bId = b.$getAttribute(primaryKey);
|
|
1970
|
+
const rawRecordIdResultsIndexA = rawRecordIds.findIndex((r) => r[primaryKey] === aId);
|
|
1971
|
+
const rawRecordIdResultsIndexB = rawRecordIds.findIndex((r) => r[primaryKey] === bId);
|
|
1972
|
+
return rawRecordIdResultsIndexA - rawRecordIdResultsIndexB;
|
|
1973
|
+
});
|
|
1525
1974
|
return {
|
|
1526
1975
|
total: Number.isNaN(totalRaw) ? 0 : totalRaw,
|
|
1527
1976
|
page: validatedMethodOptions.page,
|
|
1528
1977
|
perPage: validatedMethodOptions.perPage,
|
|
1529
1978
|
records: rawRecords.map(
|
|
1530
|
-
(record) => this.$formatResourcefulRecord(record)
|
|
1979
|
+
(record) => this.$formatResourcefulRecord(record, possibleFields)
|
|
1531
1980
|
),
|
|
1532
1981
|
countQuery: countQueryQuery,
|
|
1533
1982
|
recordsQuery: recordsQueryQuery
|
|
@@ -1570,11 +2019,16 @@ function withResourceful(options = {}) {
|
|
|
1570
2019
|
throw new E_RECORD_NOT_FOUND_EXCEPTION();
|
|
1571
2020
|
}
|
|
1572
2021
|
const rid = recordRaw[this.primaryKey];
|
|
1573
|
-
const
|
|
2022
|
+
const recordQuery = this.query().where(this.primaryKey, rid);
|
|
2023
|
+
const { possibleRelationships, possibleFields } = this.$loadPossibilitiesForResourcefulRecord();
|
|
2024
|
+
possibleRelationships.forEach((prop) => {
|
|
2025
|
+
recordQuery.preload(prop);
|
|
2026
|
+
});
|
|
2027
|
+
const record = await recordQuery.first();
|
|
1574
2028
|
if (!record) {
|
|
1575
2029
|
throw new E_RECORD_NOT_FOUND_EXCEPTION();
|
|
1576
2030
|
}
|
|
1577
|
-
const { isForbidden,
|
|
2031
|
+
const { isForbidden, allowedSerializedMap, message } = await this.$resourcefulCheckAccess({
|
|
1578
2032
|
ctx,
|
|
1579
2033
|
app,
|
|
1580
2034
|
instance: record,
|
|
@@ -1583,14 +2037,193 @@ function withResourceful(options = {}) {
|
|
|
1583
2037
|
if (isForbidden) {
|
|
1584
2038
|
throw new E_FORBIDDEN(message);
|
|
1585
2039
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
2040
|
+
return this.$formatResourcefulRecord(
|
|
2041
|
+
record,
|
|
2042
|
+
possibleFields.filter((f) => allowedSerializedMap.get(f) === true)
|
|
2043
|
+
);
|
|
2044
|
+
}
|
|
2045
|
+
/**
|
|
2046
|
+
* Loads a specific relationship for a model record with pagination, filtering, and access control.
|
|
2047
|
+
*
|
|
2048
|
+
* This method provides paginated relationship loading by leveraging the related model's
|
|
2049
|
+
* $onResourcefulIndex method with automatically generated relationship constraints.
|
|
2050
|
+
* It supports full filtering, sorting, and pagination capabilities while maintaining
|
|
2051
|
+
* proper access control and scoping.
|
|
2052
|
+
*
|
|
2053
|
+
* The method automatically generates query scope hooks to constrain results to only
|
|
2054
|
+
* records related to the specified parent record, preventing unauthorized data access
|
|
2055
|
+
* and ensuring proper relationship boundaries are maintained.
|
|
2056
|
+
*
|
|
2057
|
+
* @param uid - The unique identifier of the parent record
|
|
2058
|
+
* @param relationshipKey - The name of the relationship property to load
|
|
2059
|
+
* @param filter - Lucene-style query string for filtering related records
|
|
2060
|
+
* @param page - The page number for pagination (must be ≥ 1)
|
|
2061
|
+
* @param perPage - Number of records per page (must be ≥ 1 and ≤ 100)
|
|
2062
|
+
* @param fields - Array of field names to include in the response from the related model
|
|
2063
|
+
* @param sort - Array of sort criteria as [field, direction] tuples
|
|
2064
|
+
* @param ctx - HTTP context containing request information and authentication
|
|
2065
|
+
* @param app - Application service instance for accessing app-level services
|
|
2066
|
+
* @param hooks - Optional array of additional query scope callbacks
|
|
2067
|
+
*
|
|
2068
|
+
* @returns Promise resolving to paginated relationship results with the same structure as $onResourcefulIndex
|
|
2069
|
+
*
|
|
2070
|
+
* @throws {E_MISSING_PRIMARY_KEY_EXCEPTION} When the model has no identifiable primary key
|
|
2071
|
+
* @throws {E_INVALID_RELATIONSHIP_EXCEPTION} When the specified relationship doesn't exist or isn't resourceful
|
|
2072
|
+
* @throws {E_FORBIDDEN} When access is denied by model-level or field-level ACL filters
|
|
2073
|
+
* @throws {E_INVALID_RESOUREFUL_INDEX_REQUEST_EXCEPTION} When input validation fails
|
|
2074
|
+
*
|
|
2075
|
+
* @example
|
|
2076
|
+
* ```typescript
|
|
2077
|
+
* // Load user's posts with filtering and pagination
|
|
2078
|
+
* const userPosts = await Post.$onResourcefulReadRelationship(
|
|
2079
|
+
* 123, // user ID
|
|
2080
|
+
* 'posts', // relationship name
|
|
2081
|
+
* 'status:published', // filter
|
|
2082
|
+
* 1, // page
|
|
2083
|
+
* 10, // perPage
|
|
2084
|
+
* ['id', 'title'], // fields
|
|
2085
|
+
* [['createdAt', 'desc']], // sort
|
|
2086
|
+
* ctx,
|
|
2087
|
+
* app
|
|
2088
|
+
* );
|
|
2089
|
+
*
|
|
2090
|
+
* // Load user's skills (many-to-many)
|
|
2091
|
+
* const userSkills = await Skill.$onResourcefulReadRelationship(
|
|
2092
|
+
* 123,
|
|
2093
|
+
* 'skills',
|
|
2094
|
+
* null, // no filter
|
|
2095
|
+
* 1,
|
|
2096
|
+
* 50,
|
|
2097
|
+
* null, // all fields
|
|
2098
|
+
* null, // default sort
|
|
2099
|
+
* ctx,
|
|
2100
|
+
* app
|
|
2101
|
+
* );
|
|
2102
|
+
* ```
|
|
2103
|
+
*/
|
|
2104
|
+
static async $onResourcefulReadRelationship(uid, relationshipKey, filter, page, perPage, fields, sort, ctx, app, hooks = []) {
|
|
2105
|
+
const primaryKey = this.$getPrivateKeyAttribute();
|
|
2106
|
+
if (!primaryKey) {
|
|
2107
|
+
throw new E_MISSING_PRIMARY_KEY_EXCEPTION(this.$resourcefulName);
|
|
2108
|
+
}
|
|
2109
|
+
const relationshipDefinition = this.$resourcefulRelationships.get(relationshipKey);
|
|
2110
|
+
if (!relationshipDefinition) {
|
|
2111
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2112
|
+
`Relationship '${relationshipKey}' not found on model '${this.$resourcefulName}'`
|
|
2113
|
+
);
|
|
2114
|
+
}
|
|
2115
|
+
const lucidRelationshipDefinition = this.$getRelation(relationshipKey);
|
|
2116
|
+
if (!lucidRelationshipDefinition) {
|
|
2117
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2118
|
+
`Lucid relationship '${relationshipKey}' not found on model '${this.$resourcefulName}'`
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
const RelatedModel = relationshipDefinition.relatedModel();
|
|
2122
|
+
if (typeof RelatedModel.$onResourcefulIndex !== "function") {
|
|
2123
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2124
|
+
`Related model for '${relationshipKey}' does not implement resourceful operations`
|
|
2125
|
+
);
|
|
2126
|
+
}
|
|
2127
|
+
const relationshipHook = async (_hookCtx, _hookApp, query) => {
|
|
2128
|
+
const relationshipType = lucidRelationshipDefinition.type;
|
|
2129
|
+
switch (relationshipType) {
|
|
2130
|
+
case "hasMany":
|
|
2131
|
+
{
|
|
2132
|
+
const foreignKey = lucidRelationshipDefinition.foreignKey;
|
|
2133
|
+
if (!foreignKey) {
|
|
2134
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2135
|
+
`HasMany relationship '${relationshipKey}' missing foreignKey`
|
|
2136
|
+
);
|
|
2137
|
+
}
|
|
2138
|
+
const foreignColumn = RelatedModel.$keys.attributesToColumns.get(foreignKey);
|
|
2139
|
+
if (!foreignColumn) {
|
|
2140
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2141
|
+
`Foreign key '${foreignKey}' not found in related model columns`
|
|
2142
|
+
);
|
|
2143
|
+
}
|
|
2144
|
+
query.where(foreignColumn, uid);
|
|
2145
|
+
}
|
|
2146
|
+
break;
|
|
2147
|
+
case "manyToMany":
|
|
2148
|
+
{
|
|
2149
|
+
const pivotTable = lucidRelationshipDefinition.pivotTable;
|
|
2150
|
+
const localKey = lucidRelationshipDefinition.localKey;
|
|
2151
|
+
const relatedKey = lucidRelationshipDefinition.relatedKey;
|
|
2152
|
+
const pivotForeignKey = lucidRelationshipDefinition.pivotForeignKey;
|
|
2153
|
+
const pivotRelatedForeignKey = lucidRelationshipDefinition.pivotRelatedForeignKey;
|
|
2154
|
+
if (!pivotTable || !localKey || !relatedKey || !pivotForeignKey || !pivotRelatedForeignKey) {
|
|
2155
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2156
|
+
`ManyToMany relationship '${relationshipKey}' missing required pivot configuration`
|
|
2157
|
+
);
|
|
2158
|
+
}
|
|
2159
|
+
const relatedColumn = RelatedModel.$keys.attributesToColumns.get(relatedKey);
|
|
2160
|
+
if (!relatedColumn) {
|
|
2161
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2162
|
+
`Related key '${relatedKey}' not found in related model columns`
|
|
2163
|
+
);
|
|
2164
|
+
}
|
|
2165
|
+
query.whereExists((subQuery) => {
|
|
2166
|
+
subQuery.from(pivotTable).select(1).whereColumn(
|
|
2167
|
+
`${pivotTable}.${pivotRelatedForeignKey}`,
|
|
2168
|
+
`${RelatedModel.table}.${relatedColumn}`
|
|
2169
|
+
).where(`${pivotTable}.${pivotForeignKey}`, uid);
|
|
2170
|
+
});
|
|
2171
|
+
}
|
|
2172
|
+
break;
|
|
2173
|
+
case "hasManyThrough":
|
|
2174
|
+
{
|
|
2175
|
+
const throughModel = lucidRelationshipDefinition.options.throughModel ? lucidRelationshipDefinition.options.throughModel() : void 0;
|
|
2176
|
+
const foreignKey = lucidRelationshipDefinition.options.foreignKey || RelatedModel.primaryKey;
|
|
2177
|
+
const localKey = lucidRelationshipDefinition.options.localKey || this.primaryKey;
|
|
2178
|
+
const throughForeignKey = lucidRelationshipDefinition.options.throughForeignKey;
|
|
2179
|
+
const throughLocalKey = lucidRelationshipDefinition.options.throughLocalKey || (throughModel == null ? void 0 : throughModel.primaryKey);
|
|
2180
|
+
if (!throughModel || !foreignKey || !localKey || !throughForeignKey || !throughLocalKey) {
|
|
2181
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2182
|
+
`HasManyThrough relationship '${relationshipKey}' missing required through configuration`
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
const foreignColumn = RelatedModel.$keys.attributesToColumns.get(foreignKey);
|
|
2186
|
+
const localColumn = this.$keys.attributesToColumns.get(localKey);
|
|
2187
|
+
const throughForeignColumn = RelatedModel.$keys.attributesToColumns.get(throughForeignKey);
|
|
2188
|
+
const throughLocalColumn = throughModel.$keys.attributesToColumns.get(throughLocalKey);
|
|
2189
|
+
if (!throughLocalColumn || !throughForeignColumn || !foreignColumn || !localColumn) {
|
|
2190
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2191
|
+
`HasManyThrough relationship '${relationshipKey}' has invalid key mappings`
|
|
2192
|
+
);
|
|
2193
|
+
}
|
|
2194
|
+
query.whereExists((subQuery) => {
|
|
2195
|
+
subQuery.from(throughModel.table).select(1).where(`${throughModel.table}.${throughLocalColumn}`, uid).whereColumn(
|
|
2196
|
+
`${throughModel.table}.${foreignColumn}`,
|
|
2197
|
+
`${RelatedModel.table}.${throughForeignColumn}`
|
|
2198
|
+
).limit(1);
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2201
|
+
break;
|
|
2202
|
+
default:
|
|
2203
|
+
throw new E_INVALID_RELATIONSHIP_EXCEPTION(
|
|
2204
|
+
`Relationship type '${relationshipType}' is not supported for paginated loading`
|
|
2205
|
+
);
|
|
2206
|
+
}
|
|
2207
|
+
};
|
|
2208
|
+
const allHooks = [relationshipHook, ...hooks];
|
|
2209
|
+
try {
|
|
2210
|
+
return RelatedModel.$onResourcefulIndex(
|
|
2211
|
+
filter,
|
|
2212
|
+
page,
|
|
2213
|
+
perPage,
|
|
2214
|
+
fields,
|
|
2215
|
+
sort,
|
|
2216
|
+
ctx,
|
|
2217
|
+
app,
|
|
2218
|
+
allHooks
|
|
2219
|
+
);
|
|
2220
|
+
} catch (err) {
|
|
2221
|
+
if (err instanceof E_INVALID_RESOUREFUL_INDEX_REQUEST_EXCEPTION) {
|
|
2222
|
+
throw new E_INVALID_RESOUREFUL_READ_RELATIONSHIP_REQUEST_EXCEPTION(err);
|
|
2223
|
+
} else {
|
|
2224
|
+
throw err;
|
|
1591
2225
|
}
|
|
1592
2226
|
}
|
|
1593
|
-
return recordObjectWithAllowedFields;
|
|
1594
2227
|
}
|
|
1595
2228
|
/**
|
|
1596
2229
|
* Creates a new model record with payload validation and access control.
|
|
@@ -1631,7 +2264,7 @@ function withResourceful(options = {}) {
|
|
|
1631
2264
|
throw new E_FORBIDDEN_PAYLOAD_EXCEPTION(payloadSchemaGettersError);
|
|
1632
2265
|
}
|
|
1633
2266
|
}
|
|
1634
|
-
const { isForbidden,
|
|
2267
|
+
const { isForbidden, allowedSerializedMap, message } = await this.$resourcefulCheckAccess({
|
|
1635
2268
|
ctx,
|
|
1636
2269
|
app,
|
|
1637
2270
|
operation: CRUDOperationsEnum.CREATE
|
|
@@ -1641,13 +2274,21 @@ function withResourceful(options = {}) {
|
|
|
1641
2274
|
}
|
|
1642
2275
|
const preparedPayload = {};
|
|
1643
2276
|
for (const [key, value] of Object.entries(payload)) {
|
|
1644
|
-
|
|
2277
|
+
let attribute = this.$keys.serializedToAttributes.get(key);
|
|
1645
2278
|
const isValueNull = value === null || value === void 0;
|
|
1646
2279
|
if (!attribute) {
|
|
1647
|
-
|
|
2280
|
+
const columnExists = typeof this.$keys.attributesToColumns.get(key) !== "undefined";
|
|
2281
|
+
if (columnExists) {
|
|
2282
|
+
attribute = key;
|
|
2283
|
+
} else {
|
|
2284
|
+
continue;
|
|
2285
|
+
}
|
|
1648
2286
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
2287
|
+
const isAllowedBySerializedName = allowedSerializedMap.has(key);
|
|
2288
|
+
const isAllowedByColumnName = allowedSerializedMap.has(attribute);
|
|
2289
|
+
const isAllowed = isAllowedBySerializedName || isAllowedByColumnName;
|
|
2290
|
+
if (!isValueNull && !isAllowed) {
|
|
2291
|
+
throw new E_FORBIDDEN(`User does not has write access to field ${key}.`);
|
|
1651
2292
|
}
|
|
1652
2293
|
preparedPayload[attribute] = value;
|
|
1653
2294
|
}
|
|
@@ -1707,7 +2348,7 @@ function withResourceful(options = {}) {
|
|
|
1707
2348
|
if (!record) {
|
|
1708
2349
|
throw new E_RECORD_NOT_FOUND_EXCEPTION();
|
|
1709
2350
|
}
|
|
1710
|
-
const { isForbidden,
|
|
2351
|
+
const { isForbidden, allowedSerializedMap, message } = await this.$resourcefulCheckAccess({
|
|
1711
2352
|
ctx,
|
|
1712
2353
|
app,
|
|
1713
2354
|
instance: record,
|
|
@@ -1717,13 +2358,21 @@ function withResourceful(options = {}) {
|
|
|
1717
2358
|
throw new E_FORBIDDEN(message);
|
|
1718
2359
|
}
|
|
1719
2360
|
const preparedPayload = {};
|
|
1720
|
-
for (const [
|
|
1721
|
-
|
|
2361
|
+
for (const [serializedKey, value] of Object.entries(payload)) {
|
|
2362
|
+
let attribute = this.$keys.serializedToAttributes.get(serializedKey);
|
|
1722
2363
|
const isValueNull = value === null || value === void 0;
|
|
1723
2364
|
if (!attribute) {
|
|
1724
|
-
|
|
2365
|
+
const columnExists = typeof this.$keys.attributesToColumns.get(serializedKey) !== "undefined";
|
|
2366
|
+
if (columnExists) {
|
|
2367
|
+
attribute = serializedKey;
|
|
2368
|
+
} else {
|
|
2369
|
+
continue;
|
|
2370
|
+
}
|
|
1725
2371
|
}
|
|
1726
|
-
|
|
2372
|
+
const isAllowedBySerializedName = allowedSerializedMap.has(serializedKey);
|
|
2373
|
+
const isAllowedByColumnName = allowedSerializedMap.has(attribute);
|
|
2374
|
+
const isAllowed = isAllowedBySerializedName || isAllowedByColumnName;
|
|
2375
|
+
if (!isValueNull && !isAllowed) {
|
|
1727
2376
|
throw new E_FORBIDDEN(`User does not has write access to field ${attribute}.`);
|
|
1728
2377
|
}
|
|
1729
2378
|
preparedPayload[attribute] = value;
|
|
@@ -1769,7 +2418,8 @@ function withResourceful(options = {}) {
|
|
|
1769
2418
|
if (!rawRecord) {
|
|
1770
2419
|
throw new E_RECORD_NOT_FOUND_EXCEPTION();
|
|
1771
2420
|
}
|
|
1772
|
-
const
|
|
2421
|
+
const { possibleFields } = this.$loadPossibilitiesForResourcefulRecord();
|
|
2422
|
+
const record = new this().merge(this.$formatResourcefulRecord(rawRecord, possibleFields));
|
|
1773
2423
|
const { isForbidden, message } = await this.$resourcefulCheckAccess({
|
|
1774
2424
|
ctx,
|
|
1775
2425
|
app,
|
|
@@ -1781,6 +2431,75 @@ function withResourceful(options = {}) {
|
|
|
1781
2431
|
}
|
|
1782
2432
|
await record.delete();
|
|
1783
2433
|
}
|
|
2434
|
+
static async $onResourcefulBulkUpdate(filter, payload, ctx, app, hooks = {}) {
|
|
2435
|
+
const primaryKey = this.$getPrivateKeyAttribute();
|
|
2436
|
+
if (!primaryKey) {
|
|
2437
|
+
throw new E_MISSING_PRIMARY_KEY_EXCEPTION(this.$resourcefulName);
|
|
2438
|
+
}
|
|
2439
|
+
const ctor = this;
|
|
2440
|
+
async function* resourcefulIndexIteratorForUpdate(f) {
|
|
2441
|
+
let page = 1;
|
|
2442
|
+
let pages = 0;
|
|
2443
|
+
const pk = ctor.$getPrivateKeyAttribute();
|
|
2444
|
+
if (!pk) return;
|
|
2445
|
+
const whileAbortController = new AbortController();
|
|
2446
|
+
while ((pages === 0 || page <= pages) && whileAbortController.signal.aborted === false) {
|
|
2447
|
+
try {
|
|
2448
|
+
const result = await ctor.$onResourcefulIndex(
|
|
2449
|
+
f,
|
|
2450
|
+
page,
|
|
2451
|
+
100,
|
|
2452
|
+
[pk],
|
|
2453
|
+
[[pk, "asc"]],
|
|
2454
|
+
ctx,
|
|
2455
|
+
app,
|
|
2456
|
+
hooks.queryScopeCallbacks || []
|
|
2457
|
+
);
|
|
2458
|
+
if (result.total === 0) {
|
|
2459
|
+
whileAbortController.abort();
|
|
2460
|
+
break;
|
|
2461
|
+
}
|
|
2462
|
+
pages = Math.ceil(result.total / result.perPage);
|
|
2463
|
+
page++;
|
|
2464
|
+
yield result.records;
|
|
2465
|
+
} catch (err) {
|
|
2466
|
+
whileAbortController.abort();
|
|
2467
|
+
if (err instanceof Error) {
|
|
2468
|
+
throw err;
|
|
2469
|
+
} else {
|
|
2470
|
+
throw new E_BULK_UPDATE_SEARCH_UNKNOWN_EXCEPTION();
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
const uids = /* @__PURE__ */ new Set();
|
|
2476
|
+
for await (const records of resourcefulIndexIteratorForUpdate(filter)) {
|
|
2477
|
+
for (const record of records) {
|
|
2478
|
+
const uid = record[primaryKey];
|
|
2479
|
+
if (uid !== void 0 && uid !== null) {
|
|
2480
|
+
uids.add(uid);
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
return await this.$onResourcefulBulkUpdateByUid(Array.from(uids), payload, ctx, app, hooks);
|
|
2485
|
+
}
|
|
2486
|
+
static async $onResourcefulBulkUpdateByUid(uids, payload, ctx, app, hooks, concurrency = 5) {
|
|
2487
|
+
const results = {};
|
|
2488
|
+
/* istanbul ignore next -- @preserve */
|
|
2489
|
+
await pMap(
|
|
2490
|
+
uids,
|
|
2491
|
+
async (uid) => {
|
|
2492
|
+
try {
|
|
2493
|
+
results[uid] = await this.$onResourcefulUpdate(uid, payload, ctx, app, hooks);
|
|
2494
|
+
} catch (err) {
|
|
2495
|
+
const e = err instanceof Error ? err : new Error("Unknown error during update");
|
|
2496
|
+
results[uid] = e;
|
|
2497
|
+
}
|
|
2498
|
+
},
|
|
2499
|
+
{ concurrency }
|
|
2500
|
+
);
|
|
2501
|
+
return results;
|
|
2502
|
+
}
|
|
1784
2503
|
}
|
|
1785
2504
|
__publicField(ResourcefulModel, "$resourcefulColumns", resourcefulColumns);
|
|
1786
2505
|
__publicField(ResourcefulModel, "$resourcefulRelationships", resourcefulRelationships);
|
|
@@ -2820,7 +3539,7 @@ var objectInspect = function inspect_(obj, options, depth, seen) {
|
|
|
2820
3539
|
var ys = arrObjKeys(obj, inspect2);
|
|
2821
3540
|
var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
|
|
2822
3541
|
var protoTag = obj instanceof Object ? "" : "null prototype";
|
|
2823
|
-
var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : "";
|
|
3542
|
+
var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr$1(obj), 8, -1) : protoTag ? "Object" : "";
|
|
2824
3543
|
var constructorTag = isPlainObject || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : "";
|
|
2825
3544
|
var tag = constructorTag + (stringTag || protoTag ? "[" + $join.call($concat$1.call([], stringTag || [], protoTag || []), ": ") + "] " : "");
|
|
2826
3545
|
if (ys.length === 0) {
|
|
@@ -2845,25 +3564,25 @@ function canTrustToString(obj) {
|
|
|
2845
3564
|
return !toStringTag || !(typeof obj === "object" && (toStringTag in obj || typeof obj[toStringTag] !== "undefined"));
|
|
2846
3565
|
}
|
|
2847
3566
|
function isArray$3(obj) {
|
|
2848
|
-
return toStr(obj) === "[object Array]" && canTrustToString(obj);
|
|
3567
|
+
return toStr$1(obj) === "[object Array]" && canTrustToString(obj);
|
|
2849
3568
|
}
|
|
2850
3569
|
function isDate(obj) {
|
|
2851
|
-
return toStr(obj) === "[object Date]" && canTrustToString(obj);
|
|
3570
|
+
return toStr$1(obj) === "[object Date]" && canTrustToString(obj);
|
|
2852
3571
|
}
|
|
2853
3572
|
function isRegExp$1(obj) {
|
|
2854
|
-
return toStr(obj) === "[object RegExp]" && canTrustToString(obj);
|
|
3573
|
+
return toStr$1(obj) === "[object RegExp]" && canTrustToString(obj);
|
|
2855
3574
|
}
|
|
2856
3575
|
function isError(obj) {
|
|
2857
|
-
return toStr(obj) === "[object Error]" && canTrustToString(obj);
|
|
3576
|
+
return toStr$1(obj) === "[object Error]" && canTrustToString(obj);
|
|
2858
3577
|
}
|
|
2859
3578
|
function isString(obj) {
|
|
2860
|
-
return toStr(obj) === "[object String]" && canTrustToString(obj);
|
|
3579
|
+
return toStr$1(obj) === "[object String]" && canTrustToString(obj);
|
|
2861
3580
|
}
|
|
2862
3581
|
function isNumber(obj) {
|
|
2863
|
-
return toStr(obj) === "[object Number]" && canTrustToString(obj);
|
|
3582
|
+
return toStr$1(obj) === "[object Number]" && canTrustToString(obj);
|
|
2864
3583
|
}
|
|
2865
3584
|
function isBoolean(obj) {
|
|
2866
|
-
return toStr(obj) === "[object Boolean]" && canTrustToString(obj);
|
|
3585
|
+
return toStr$1(obj) === "[object Boolean]" && canTrustToString(obj);
|
|
2867
3586
|
}
|
|
2868
3587
|
function isSymbol(obj) {
|
|
2869
3588
|
if (hasShammedSymbols) {
|
|
@@ -2899,7 +3618,7 @@ var hasOwn$1 = Object.prototype.hasOwnProperty || function(key) {
|
|
|
2899
3618
|
function has$3(obj, key) {
|
|
2900
3619
|
return hasOwn$1.call(obj, key);
|
|
2901
3620
|
}
|
|
2902
|
-
function toStr(obj) {
|
|
3621
|
+
function toStr$1(obj) {
|
|
2903
3622
|
return objectToString.call(obj);
|
|
2904
3623
|
}
|
|
2905
3624
|
function nameOf(f) {
|
|
@@ -3208,7 +3927,7 @@ var syntax = SyntaxError;
|
|
|
3208
3927
|
var uri = URIError;
|
|
3209
3928
|
var abs$1 = Math.abs;
|
|
3210
3929
|
var floor$1 = Math.floor;
|
|
3211
|
-
var max$
|
|
3930
|
+
var max$2 = Math.max;
|
|
3212
3931
|
var min$1 = Math.min;
|
|
3213
3932
|
var pow$1 = Math.pow;
|
|
3214
3933
|
var round$1 = Math.round;
|
|
@@ -3337,99 +4056,78 @@ function requireObject_getPrototypeOf() {
|
|
|
3337
4056
|
Object_getPrototypeOf = $Object2.getPrototypeOf || null;
|
|
3338
4057
|
return Object_getPrototypeOf;
|
|
3339
4058
|
}
|
|
3340
|
-
var
|
|
3341
|
-
var
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
var
|
|
3346
|
-
var
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
var
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
}
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
var str = "";
|
|
3368
|
-
for (var i = 0; i < arr.length; i += 1) {
|
|
3369
|
-
str += arr[i];
|
|
3370
|
-
if (i + 1 < arr.length) {
|
|
3371
|
-
str += joiner;
|
|
3372
|
-
}
|
|
4059
|
+
var ERROR_MESSAGE = "Function.prototype.bind called on incompatible ";
|
|
4060
|
+
var toStr = Object.prototype.toString;
|
|
4061
|
+
var max$1 = Math.max;
|
|
4062
|
+
var funcType = "[object Function]";
|
|
4063
|
+
var concatty = function concatty2(a2, b) {
|
|
4064
|
+
var arr = [];
|
|
4065
|
+
for (var i = 0; i < a2.length; i += 1) {
|
|
4066
|
+
arr[i] = a2[i];
|
|
4067
|
+
}
|
|
4068
|
+
for (var j = 0; j < b.length; j += 1) {
|
|
4069
|
+
arr[j + a2.length] = b[j];
|
|
4070
|
+
}
|
|
4071
|
+
return arr;
|
|
4072
|
+
};
|
|
4073
|
+
var slicy = function slicy2(arrLike, offset) {
|
|
4074
|
+
var arr = [];
|
|
4075
|
+
for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) {
|
|
4076
|
+
arr[j] = arrLike[i];
|
|
4077
|
+
}
|
|
4078
|
+
return arr;
|
|
4079
|
+
};
|
|
4080
|
+
var joiny = function(arr, joiner) {
|
|
4081
|
+
var str = "";
|
|
4082
|
+
for (var i = 0; i < arr.length; i += 1) {
|
|
4083
|
+
str += arr[i];
|
|
4084
|
+
if (i + 1 < arr.length) {
|
|
4085
|
+
str += joiner;
|
|
3373
4086
|
}
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
);
|
|
3389
|
-
if (Object(result) === result) {
|
|
3390
|
-
return result;
|
|
3391
|
-
}
|
|
3392
|
-
return this;
|
|
3393
|
-
}
|
|
3394
|
-
return target.apply(
|
|
3395
|
-
that,
|
|
4087
|
+
}
|
|
4088
|
+
return str;
|
|
4089
|
+
};
|
|
4090
|
+
var implementation$1 = function bind(that) {
|
|
4091
|
+
var target = this;
|
|
4092
|
+
if (typeof target !== "function" || toStr.apply(target) !== funcType) {
|
|
4093
|
+
throw new TypeError(ERROR_MESSAGE + target);
|
|
4094
|
+
}
|
|
4095
|
+
var args = slicy(arguments, 1);
|
|
4096
|
+
var bound;
|
|
4097
|
+
var binder = function() {
|
|
4098
|
+
if (this instanceof bound) {
|
|
4099
|
+
var result = target.apply(
|
|
4100
|
+
this,
|
|
3396
4101
|
concatty(args, arguments)
|
|
3397
4102
|
);
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
boundArgs[i] = "$" + i;
|
|
3403
|
-
}
|
|
3404
|
-
bound = Function("binder", "return function (" + joiny(boundArgs, ",") + "){ return binder.apply(this,arguments); }")(binder);
|
|
3405
|
-
if (target.prototype) {
|
|
3406
|
-
var Empty = function Empty2() {
|
|
3407
|
-
};
|
|
3408
|
-
Empty.prototype = target.prototype;
|
|
3409
|
-
bound.prototype = new Empty();
|
|
3410
|
-
Empty.prototype = null;
|
|
4103
|
+
if (Object(result) === result) {
|
|
4104
|
+
return result;
|
|
4105
|
+
}
|
|
4106
|
+
return this;
|
|
3411
4107
|
}
|
|
3412
|
-
return
|
|
4108
|
+
return target.apply(
|
|
4109
|
+
that,
|
|
4110
|
+
concatty(args, arguments)
|
|
4111
|
+
);
|
|
3413
4112
|
};
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
var
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
}
|
|
4113
|
+
var boundLength = max$1(0, target.length - args.length);
|
|
4114
|
+
var boundArgs = [];
|
|
4115
|
+
for (var i = 0; i < boundLength; i++) {
|
|
4116
|
+
boundArgs[i] = "$" + i;
|
|
4117
|
+
}
|
|
4118
|
+
bound = Function("binder", "return function (" + joiny(boundArgs, ",") + "){ return binder.apply(this,arguments); }")(binder);
|
|
4119
|
+
if (target.prototype) {
|
|
4120
|
+
var Empty = function Empty2() {
|
|
4121
|
+
};
|
|
4122
|
+
Empty.prototype = target.prototype;
|
|
4123
|
+
bound.prototype = new Empty();
|
|
4124
|
+
Empty.prototype = null;
|
|
4125
|
+
}
|
|
4126
|
+
return bound;
|
|
4127
|
+
};
|
|
4128
|
+
var implementation = implementation$1;
|
|
4129
|
+
var functionBind = Function.prototype.bind || implementation;
|
|
4130
|
+
var functionCall = Function.prototype.call;
|
|
3433
4131
|
var functionApply;
|
|
3434
4132
|
var hasRequiredFunctionApply;
|
|
3435
4133
|
function requireFunctionApply() {
|
|
@@ -3439,14 +4137,14 @@ function requireFunctionApply() {
|
|
|
3439
4137
|
return functionApply;
|
|
3440
4138
|
}
|
|
3441
4139
|
var reflectApply = typeof Reflect !== "undefined" && Reflect && Reflect.apply;
|
|
3442
|
-
var bind$2 =
|
|
4140
|
+
var bind$2 = functionBind;
|
|
3443
4141
|
var $apply$1 = requireFunctionApply();
|
|
3444
|
-
var $call$2 =
|
|
4142
|
+
var $call$2 = functionCall;
|
|
3445
4143
|
var $reflectApply = reflectApply;
|
|
3446
4144
|
var actualApply = $reflectApply || bind$2.call($call$2, $apply$1);
|
|
3447
|
-
var bind$1 =
|
|
4145
|
+
var bind$1 = functionBind;
|
|
3448
4146
|
var $TypeError$4 = type;
|
|
3449
|
-
var $call$1 =
|
|
4147
|
+
var $call$1 = functionCall;
|
|
3450
4148
|
var $actualApply = actualApply;
|
|
3451
4149
|
var callBindApplyHelpers = function callBindBasic(args) {
|
|
3452
4150
|
if (args.length < 1 || typeof args[0] !== "function") {
|
|
@@ -3512,8 +4210,8 @@ function requireHasown() {
|
|
|
3512
4210
|
hasRequiredHasown = 1;
|
|
3513
4211
|
var call = Function.prototype.call;
|
|
3514
4212
|
var $hasOwn = Object.prototype.hasOwnProperty;
|
|
3515
|
-
var
|
|
3516
|
-
hasown =
|
|
4213
|
+
var bind3 = functionBind;
|
|
4214
|
+
hasown = bind3.call(call, $hasOwn);
|
|
3517
4215
|
return hasown;
|
|
3518
4216
|
}
|
|
3519
4217
|
var undefined$1;
|
|
@@ -3527,7 +4225,7 @@ var $TypeError$3 = type;
|
|
|
3527
4225
|
var $URIError = uri;
|
|
3528
4226
|
var abs = abs$1;
|
|
3529
4227
|
var floor = floor$1;
|
|
3530
|
-
var max = max$
|
|
4228
|
+
var max = max$2;
|
|
3531
4229
|
var min = min$1;
|
|
3532
4230
|
var pow = pow$1;
|
|
3533
4231
|
var round = round$1;
|
|
@@ -3561,7 +4259,7 @@ var getProto = requireGetProto();
|
|
|
3561
4259
|
var $ObjectGPO = requireObject_getPrototypeOf();
|
|
3562
4260
|
var $ReflectGPO = requireReflect_getPrototypeOf();
|
|
3563
4261
|
var $apply = requireFunctionApply();
|
|
3564
|
-
var $call =
|
|
4262
|
+
var $call = functionCall;
|
|
3565
4263
|
var needsEval = {};
|
|
3566
4264
|
var TypedArray = typeof Uint8Array === "undefined" || !getProto ? undefined$1 : getProto(Uint8Array);
|
|
3567
4265
|
var INTRINSICS = {
|
|
@@ -3732,13 +4430,13 @@ var LEGACY_ALIASES = {
|
|
|
3732
4430
|
"%WeakMapPrototype%": ["WeakMap", "prototype"],
|
|
3733
4431
|
"%WeakSetPrototype%": ["WeakSet", "prototype"]
|
|
3734
4432
|
};
|
|
3735
|
-
var
|
|
4433
|
+
var bind2 = functionBind;
|
|
3736
4434
|
var hasOwn = requireHasown();
|
|
3737
|
-
var $concat =
|
|
3738
|
-
var $spliceApply =
|
|
3739
|
-
var $replace =
|
|
3740
|
-
var $strSlice =
|
|
3741
|
-
var $exec =
|
|
4435
|
+
var $concat = bind2.call($call, Array.prototype.concat);
|
|
4436
|
+
var $spliceApply = bind2.call($apply, Array.prototype.splice);
|
|
4437
|
+
var $replace = bind2.call($call, String.prototype.replace);
|
|
4438
|
+
var $strSlice = bind2.call($call, String.prototype.slice);
|
|
4439
|
+
var $exec = bind2.call($call, RegExp.prototype.exec);
|
|
3742
4440
|
var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
|
|
3743
4441
|
var reEscapeChar = /\\(\\)?/g;
|
|
3744
4442
|
var stringToPath = function stringToPath2(string) {
|
|
@@ -11814,33 +12512,33 @@ const validateNormalizeAndCastDecoratorOptions = (fieldName, decoratorName, sche
|
|
|
11814
12512
|
}
|
|
11815
12513
|
return value;
|
|
11816
12514
|
};
|
|
11817
|
-
const resourcefulPropertyDefinitionSchema =
|
|
11818
|
-
propertyKey:
|
|
11819
|
-
readAccessControlFilters:
|
|
11820
|
-
writeAccessControlFilters:
|
|
11821
|
-
nullable:
|
|
11822
|
-
description:
|
|
11823
|
-
default:
|
|
11824
|
-
externalDocs:
|
|
11825
|
-
description:
|
|
11826
|
-
url:
|
|
12515
|
+
const resourcefulPropertyDefinitionSchema = zu.object({
|
|
12516
|
+
propertyKey: zu.string().default(""),
|
|
12517
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12518
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12519
|
+
nullable: zu.boolean().default(false),
|
|
12520
|
+
description: zu.string().optional(),
|
|
12521
|
+
default: zu.any().optional(),
|
|
12522
|
+
externalDocs: zu.object({
|
|
12523
|
+
description: zu.string().optional(),
|
|
12524
|
+
url: zu.string().uri().required()
|
|
11827
12525
|
}).optional(),
|
|
11828
|
-
example:
|
|
11829
|
-
deprecated:
|
|
12526
|
+
example: zu.string().optional(),
|
|
12527
|
+
deprecated: zu.boolean().default(false)
|
|
11830
12528
|
});
|
|
11831
12529
|
const joiInstanceCheckerAlternativesFactory = (Ctor, CtorName) => {
|
|
11832
12530
|
return [
|
|
11833
|
-
|
|
11834
|
-
|
|
11835
|
-
|
|
11836
|
-
if (isObject$
|
|
12531
|
+
zu.object().instance(Ctor),
|
|
12532
|
+
zu.function().instance(Ctor),
|
|
12533
|
+
zu.custom((value, helpers) => {
|
|
12534
|
+
if (isObject$2(value) && value.constructor.name === CtorName) {
|
|
11837
12535
|
return value;
|
|
11838
12536
|
}
|
|
11839
12537
|
return helpers.error("any.invalid", { value, type: CtorName });
|
|
11840
12538
|
})
|
|
11841
12539
|
];
|
|
11842
12540
|
};
|
|
11843
|
-
const resourcefulDataTypeSchema =
|
|
12541
|
+
const resourcefulDataTypeSchema = zu.alternatives(
|
|
11844
12542
|
...joiInstanceCheckerAlternativesFactory(ResourcefulStringType, "ResourcefulStringType"),
|
|
11845
12543
|
...joiInstanceCheckerAlternativesFactory(ResourcefulDateType, "ResourcefulDateType"),
|
|
11846
12544
|
...joiInstanceCheckerAlternativesFactory(ResourcefulDateTimeType, "ResourcefulDateTimeType"),
|
|
@@ -11859,95 +12557,97 @@ const resourcefulDataTypeSchema = Q_.alternatives(
|
|
|
11859
12557
|
const localResourcefulPropertyDefinitionSchema = resourcefulPropertyDefinitionSchema.keys({
|
|
11860
12558
|
type: resourcefulDataTypeSchema.required()
|
|
11861
12559
|
});
|
|
11862
|
-
const resourcefulColumnOptionsSchema =
|
|
12560
|
+
const resourcefulColumnOptionsSchema = zu.object({
|
|
11863
12561
|
// Lucid ColumnOptions (partial)
|
|
11864
|
-
columnName:
|
|
11865
|
-
serializeAs:
|
|
11866
|
-
serialize:
|
|
11867
|
-
consume:
|
|
11868
|
-
prepare:
|
|
11869
|
-
meta:
|
|
11870
|
-
isPrimary:
|
|
11871
|
-
hasDefaultValue:
|
|
12562
|
+
columnName: zu.string().optional(),
|
|
12563
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12564
|
+
serialize: zu.function().optional(),
|
|
12565
|
+
consume: zu.function().optional(),
|
|
12566
|
+
prepare: zu.function().optional(),
|
|
12567
|
+
meta: zu.object().optional(),
|
|
12568
|
+
isPrimary: zu.boolean().default(false),
|
|
12569
|
+
hasDefaultValue: zu.boolean().default(false),
|
|
11872
12570
|
// Resourceful options
|
|
11873
|
-
propertyKey:
|
|
11874
|
-
readAccessControlFilters:
|
|
11875
|
-
writeAccessControlFilters:
|
|
11876
|
-
nullable:
|
|
11877
|
-
description:
|
|
11878
|
-
default:
|
|
11879
|
-
externalDocs:
|
|
11880
|
-
description:
|
|
11881
|
-
url:
|
|
12571
|
+
propertyKey: zu.string().default(""),
|
|
12572
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12573
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12574
|
+
nullable: zu.boolean().default(false),
|
|
12575
|
+
description: zu.string().optional(),
|
|
12576
|
+
default: zu.any().optional(),
|
|
12577
|
+
externalDocs: zu.object({
|
|
12578
|
+
description: zu.string().optional(),
|
|
12579
|
+
url: zu.string().uri().required()
|
|
11882
12580
|
}).optional(),
|
|
11883
|
-
example:
|
|
11884
|
-
deprecated:
|
|
12581
|
+
example: zu.string().optional(),
|
|
12582
|
+
deprecated: zu.boolean().default(false),
|
|
11885
12583
|
type: resourcefulDataTypeSchema.required()
|
|
11886
12584
|
});
|
|
11887
|
-
const dataTypeColumnOptionsSchema =
|
|
11888
|
-
// Lucid ColumnOptions (
|
|
11889
|
-
columnName:
|
|
11890
|
-
serializeAs:
|
|
11891
|
-
serialize:
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
|
|
12585
|
+
const dataTypeColumnOptionsSchema = zu.object({
|
|
12586
|
+
// Lucid ColumnOptions (full) - now including 'prepare' and 'consume'
|
|
12587
|
+
columnName: zu.string().optional(),
|
|
12588
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12589
|
+
serialize: zu.function().optional(),
|
|
12590
|
+
consume: zu.function().optional(),
|
|
12591
|
+
prepare: zu.function().optional(),
|
|
12592
|
+
meta: zu.object().optional(),
|
|
12593
|
+
isPrimary: zu.boolean().default(false),
|
|
12594
|
+
hasDefaultValue: zu.boolean().default(false),
|
|
11895
12595
|
// Resourceful options
|
|
11896
|
-
propertyKey:
|
|
11897
|
-
readAccessControlFilters:
|
|
11898
|
-
writeAccessControlFilters:
|
|
11899
|
-
nullable:
|
|
11900
|
-
description:
|
|
11901
|
-
default:
|
|
11902
|
-
externalDocs:
|
|
11903
|
-
description:
|
|
11904
|
-
url:
|
|
12596
|
+
propertyKey: zu.string().default(""),
|
|
12597
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12598
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12599
|
+
nullable: zu.boolean().default(false),
|
|
12600
|
+
description: zu.string().optional(),
|
|
12601
|
+
default: zu.any().optional(),
|
|
12602
|
+
externalDocs: zu.object({
|
|
12603
|
+
description: zu.string().optional(),
|
|
12604
|
+
url: zu.string().uri().required()
|
|
11905
12605
|
}).optional(),
|
|
11906
|
-
example:
|
|
11907
|
-
deprecated:
|
|
12606
|
+
example: zu.string().optional(),
|
|
12607
|
+
deprecated: zu.boolean().default(false),
|
|
11908
12608
|
type: resourcefulDataTypeSchema.optional()
|
|
11909
12609
|
});
|
|
11910
12610
|
const baseDateColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11911
|
-
autoCreate:
|
|
11912
|
-
autoUpdate:
|
|
12611
|
+
autoCreate: zu.boolean().default(false),
|
|
12612
|
+
autoUpdate: zu.boolean().default(false)
|
|
11913
12613
|
});
|
|
11914
12614
|
const stringColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11915
|
-
type:
|
|
12615
|
+
type: zu.alternatives(
|
|
11916
12616
|
...joiInstanceCheckerAlternativesFactory(ResourcefulStringType, "ResourcefulStringType")
|
|
11917
12617
|
).default(() => new ResourcefulStringType())
|
|
11918
12618
|
});
|
|
11919
12619
|
const dateColumnOptionsSchema = baseDateColumnOptionsSchema.keys({
|
|
11920
|
-
type:
|
|
12620
|
+
type: zu.alternatives(
|
|
11921
12621
|
...joiInstanceCheckerAlternativesFactory(ResourcefulDateType, "ResourcefulDateType")
|
|
11922
12622
|
).default(() => new ResourcefulDateType())
|
|
11923
12623
|
});
|
|
11924
12624
|
const dateTimeColumnOptionsSchema = baseDateColumnOptionsSchema.keys({
|
|
11925
|
-
type:
|
|
12625
|
+
type: zu.alternatives(
|
|
11926
12626
|
...joiInstanceCheckerAlternativesFactory(ResourcefulDateTimeType, "ResourcefulDateTimeType")
|
|
11927
12627
|
).default(() => new ResourcefulDateTimeType())
|
|
11928
12628
|
});
|
|
11929
12629
|
const binaryColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11930
|
-
type:
|
|
12630
|
+
type: zu.alternatives(
|
|
11931
12631
|
...joiInstanceCheckerAlternativesFactory(ResourcefulBinaryType, "ResourcefulBinaryType")
|
|
11932
12632
|
).default(() => new ResourcefulBinaryType())
|
|
11933
12633
|
});
|
|
11934
12634
|
const numberColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11935
|
-
type:
|
|
12635
|
+
type: zu.alternatives(
|
|
11936
12636
|
...joiInstanceCheckerAlternativesFactory(ResourcefulNumberType, "ResourcefulNumberType")
|
|
11937
12637
|
).default(() => new ResourcefulNumberType())
|
|
11938
12638
|
});
|
|
11939
12639
|
const integerColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11940
|
-
type:
|
|
12640
|
+
type: zu.alternatives(
|
|
11941
12641
|
...joiInstanceCheckerAlternativesFactory(ResourcefulIntegerType, "ResourcefulIntegerType")
|
|
11942
12642
|
).default(() => new ResourcefulIntegerType())
|
|
11943
12643
|
});
|
|
11944
12644
|
const bigintColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11945
|
-
type:
|
|
12645
|
+
type: zu.alternatives(
|
|
11946
12646
|
...joiInstanceCheckerAlternativesFactory(ResourcefulBigintType, "ResourcefulBigintType")
|
|
11947
12647
|
).default(() => new ResourcefulBigintType())
|
|
11948
12648
|
});
|
|
11949
12649
|
const unsignedIntegerColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11950
|
-
type:
|
|
12650
|
+
type: zu.alternatives(
|
|
11951
12651
|
...joiInstanceCheckerAlternativesFactory(
|
|
11952
12652
|
ResourcefulUnsignedIntegerType,
|
|
11953
12653
|
"ResourcefulUnsignedIntegerType"
|
|
@@ -11955,148 +12655,148 @@ const unsignedIntegerColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
|
11955
12655
|
).default(() => new ResourcefulUnsignedIntegerType())
|
|
11956
12656
|
});
|
|
11957
12657
|
const booleanColumnOptionsSchema = dataTypeColumnOptionsSchema.keys({
|
|
11958
|
-
type:
|
|
12658
|
+
type: zu.alternatives(
|
|
11959
12659
|
...joiInstanceCheckerAlternativesFactory(ResourcefulBooleanType, "ResourcefulBooleanType")
|
|
11960
12660
|
).default(() => new ResourcefulBooleanType())
|
|
11961
12661
|
});
|
|
11962
|
-
const objectColumnOptionsSchema =
|
|
12662
|
+
const objectColumnOptionsSchema = zu.object({
|
|
11963
12663
|
// Lucid ColumnOptions (full)
|
|
11964
|
-
columnName:
|
|
11965
|
-
serializeAs:
|
|
11966
|
-
serialize:
|
|
11967
|
-
consume:
|
|
11968
|
-
prepare:
|
|
11969
|
-
meta:
|
|
11970
|
-
isPrimary:
|
|
11971
|
-
hasDefaultValue:
|
|
12664
|
+
columnName: zu.string().optional(),
|
|
12665
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12666
|
+
serialize: zu.function().optional(),
|
|
12667
|
+
consume: zu.function().optional(),
|
|
12668
|
+
prepare: zu.function().optional(),
|
|
12669
|
+
meta: zu.object().optional(),
|
|
12670
|
+
isPrimary: zu.boolean().default(false),
|
|
12671
|
+
hasDefaultValue: zu.boolean().default(false),
|
|
11972
12672
|
// Resourceful options
|
|
11973
|
-
propertyKey:
|
|
11974
|
-
readAccessControlFilters:
|
|
11975
|
-
writeAccessControlFilters:
|
|
11976
|
-
nullable:
|
|
11977
|
-
description:
|
|
11978
|
-
default:
|
|
11979
|
-
externalDocs:
|
|
11980
|
-
description:
|
|
11981
|
-
url:
|
|
12673
|
+
propertyKey: zu.string().default(""),
|
|
12674
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12675
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12676
|
+
nullable: zu.boolean().default(false),
|
|
12677
|
+
description: zu.string().optional(),
|
|
12678
|
+
default: zu.any().optional(),
|
|
12679
|
+
externalDocs: zu.object({
|
|
12680
|
+
description: zu.string().optional(),
|
|
12681
|
+
url: zu.string().uri().required()
|
|
11982
12682
|
}).optional(),
|
|
11983
|
-
example:
|
|
11984
|
-
deprecated:
|
|
11985
|
-
type:
|
|
12683
|
+
example: zu.string().optional(),
|
|
12684
|
+
deprecated: zu.boolean().default(false),
|
|
12685
|
+
type: zu.alternatives(
|
|
11986
12686
|
...joiInstanceCheckerAlternativesFactory(ResourcefulObjectType, "ResourcefulObjectType")
|
|
11987
12687
|
).default(() => new ResourcefulObjectType())
|
|
11988
12688
|
});
|
|
11989
|
-
const arrayColumnOptionsSchema =
|
|
12689
|
+
const arrayColumnOptionsSchema = zu.object({
|
|
11990
12690
|
// Lucid ColumnOptions (full)
|
|
11991
|
-
columnName:
|
|
11992
|
-
serializeAs:
|
|
11993
|
-
serialize:
|
|
11994
|
-
consume:
|
|
11995
|
-
prepare:
|
|
11996
|
-
meta:
|
|
11997
|
-
isPrimary:
|
|
11998
|
-
hasDefaultValue:
|
|
12691
|
+
columnName: zu.string().optional(),
|
|
12692
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12693
|
+
serialize: zu.function().optional(),
|
|
12694
|
+
consume: zu.function().optional(),
|
|
12695
|
+
prepare: zu.function().optional(),
|
|
12696
|
+
meta: zu.object().optional(),
|
|
12697
|
+
isPrimary: zu.boolean().default(false),
|
|
12698
|
+
hasDefaultValue: zu.boolean().default(false),
|
|
11999
12699
|
// Resourceful options
|
|
12000
|
-
propertyKey:
|
|
12001
|
-
readAccessControlFilters:
|
|
12002
|
-
writeAccessControlFilters:
|
|
12003
|
-
nullable:
|
|
12004
|
-
description:
|
|
12005
|
-
default:
|
|
12006
|
-
externalDocs:
|
|
12007
|
-
description:
|
|
12008
|
-
url:
|
|
12700
|
+
propertyKey: zu.string().default(""),
|
|
12701
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12702
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12703
|
+
nullable: zu.boolean().default(false),
|
|
12704
|
+
description: zu.string().optional(),
|
|
12705
|
+
default: zu.any().optional(),
|
|
12706
|
+
externalDocs: zu.object({
|
|
12707
|
+
description: zu.string().optional(),
|
|
12708
|
+
url: zu.string().uri().required()
|
|
12009
12709
|
}).optional(),
|
|
12010
|
-
example:
|
|
12011
|
-
deprecated:
|
|
12012
|
-
type:
|
|
12710
|
+
example: zu.string().optional(),
|
|
12711
|
+
deprecated: zu.boolean().default(false),
|
|
12712
|
+
type: zu.alternatives(
|
|
12013
12713
|
...joiInstanceCheckerAlternativesFactory(ResourcefulArrayType, "ResourcefulArrayType")
|
|
12014
12714
|
).default(() => new ResourcefulArrayType())
|
|
12015
12715
|
});
|
|
12016
12716
|
localResourcefulPropertyDefinitionSchema.append({
|
|
12017
|
-
writable:
|
|
12717
|
+
writable: zu.boolean().default(false)
|
|
12018
12718
|
});
|
|
12019
|
-
const resourcefulComputedOptionsSchema =
|
|
12719
|
+
const resourcefulComputedOptionsSchema = zu.object({
|
|
12020
12720
|
// Lucid ComputedOptions (partial)
|
|
12021
|
-
serializeAs:
|
|
12022
|
-
serialize:
|
|
12023
|
-
meta:
|
|
12721
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12722
|
+
serialize: zu.function().optional(),
|
|
12723
|
+
meta: zu.object().optional(),
|
|
12024
12724
|
// Resourceful options
|
|
12025
|
-
propertyKey:
|
|
12026
|
-
readAccessControlFilters:
|
|
12027
|
-
writeAccessControlFilters:
|
|
12028
|
-
nullable:
|
|
12029
|
-
description:
|
|
12030
|
-
default:
|
|
12031
|
-
externalDocs:
|
|
12032
|
-
description:
|
|
12033
|
-
url:
|
|
12725
|
+
propertyKey: zu.string().default(""),
|
|
12726
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12727
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12728
|
+
nullable: zu.boolean().default(false),
|
|
12729
|
+
description: zu.string().optional(),
|
|
12730
|
+
default: zu.any().optional(),
|
|
12731
|
+
externalDocs: zu.object({
|
|
12732
|
+
description: zu.string().optional(),
|
|
12733
|
+
url: zu.string().uri().required()
|
|
12034
12734
|
}).optional(),
|
|
12035
|
-
example:
|
|
12036
|
-
deprecated:
|
|
12735
|
+
example: zu.string().optional(),
|
|
12736
|
+
deprecated: zu.boolean().default(false),
|
|
12037
12737
|
type: resourcefulDataTypeSchema.required()
|
|
12038
12738
|
});
|
|
12039
|
-
const dataTypeComputedOptionsSchema =
|
|
12739
|
+
const dataTypeComputedOptionsSchema = zu.object({
|
|
12040
12740
|
// Lucid ComputedOptions (partial) - excluding 'prepare' and 'consume'
|
|
12041
|
-
serializeAs:
|
|
12042
|
-
serialize:
|
|
12043
|
-
meta:
|
|
12741
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12742
|
+
serialize: zu.function().optional(),
|
|
12743
|
+
meta: zu.object().optional(),
|
|
12044
12744
|
// Resourceful options
|
|
12045
|
-
propertyKey:
|
|
12046
|
-
readAccessControlFilters:
|
|
12047
|
-
writeAccessControlFilters:
|
|
12048
|
-
nullable:
|
|
12049
|
-
description:
|
|
12050
|
-
default:
|
|
12051
|
-
externalDocs:
|
|
12052
|
-
description:
|
|
12053
|
-
url:
|
|
12745
|
+
propertyKey: zu.string().default(""),
|
|
12746
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12747
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12748
|
+
nullable: zu.boolean().default(false),
|
|
12749
|
+
description: zu.string().optional(),
|
|
12750
|
+
default: zu.any().optional(),
|
|
12751
|
+
externalDocs: zu.object({
|
|
12752
|
+
description: zu.string().optional(),
|
|
12753
|
+
url: zu.string().uri().required()
|
|
12054
12754
|
}).optional(),
|
|
12055
|
-
example:
|
|
12056
|
-
deprecated:
|
|
12755
|
+
example: zu.string().optional(),
|
|
12756
|
+
deprecated: zu.boolean().default(false),
|
|
12057
12757
|
type: resourcefulDataTypeSchema.optional()
|
|
12058
12758
|
});
|
|
12059
12759
|
const baseDateComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12060
|
-
autoCreate:
|
|
12061
|
-
autoUpdate:
|
|
12760
|
+
autoCreate: zu.boolean().default(false),
|
|
12761
|
+
autoUpdate: zu.boolean().default(false)
|
|
12062
12762
|
});
|
|
12063
12763
|
const stringComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12064
|
-
type:
|
|
12764
|
+
type: zu.alternatives(
|
|
12065
12765
|
...joiInstanceCheckerAlternativesFactory(ResourcefulStringType, "ResourcefulStringType")
|
|
12066
12766
|
).default(() => new ResourcefulStringType())
|
|
12067
12767
|
});
|
|
12068
12768
|
const dateComputedOptionsSchema = baseDateComputedOptionsSchema.keys({
|
|
12069
|
-
type:
|
|
12769
|
+
type: zu.alternatives(
|
|
12070
12770
|
...joiInstanceCheckerAlternativesFactory(ResourcefulDateType, "ResourcefulDateType")
|
|
12071
12771
|
).default(() => new ResourcefulDateType())
|
|
12072
12772
|
});
|
|
12073
12773
|
const dateTimeComputedOptionsSchema = baseDateComputedOptionsSchema.keys({
|
|
12074
|
-
type:
|
|
12774
|
+
type: zu.alternatives(
|
|
12075
12775
|
...joiInstanceCheckerAlternativesFactory(ResourcefulDateTimeType, "ResourcefulDateTimeType")
|
|
12076
12776
|
).default(() => new ResourcefulDateTimeType())
|
|
12077
12777
|
});
|
|
12078
12778
|
const binaryComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12079
|
-
type:
|
|
12779
|
+
type: zu.alternatives(
|
|
12080
12780
|
...joiInstanceCheckerAlternativesFactory(ResourcefulBinaryType, "ResourcefulBinaryType")
|
|
12081
12781
|
).default(() => new ResourcefulBinaryType())
|
|
12082
12782
|
});
|
|
12083
12783
|
const numberComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12084
|
-
type:
|
|
12784
|
+
type: zu.alternatives(
|
|
12085
12785
|
...joiInstanceCheckerAlternativesFactory(ResourcefulNumberType, "ResourcefulNumberType")
|
|
12086
12786
|
).default(() => new ResourcefulNumberType())
|
|
12087
12787
|
});
|
|
12088
12788
|
const integerComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12089
|
-
type:
|
|
12789
|
+
type: zu.alternatives(
|
|
12090
12790
|
...joiInstanceCheckerAlternativesFactory(ResourcefulIntegerType, "ResourcefulIntegerType")
|
|
12091
12791
|
).default(() => new ResourcefulIntegerType())
|
|
12092
12792
|
});
|
|
12093
12793
|
const bigintComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12094
|
-
type:
|
|
12794
|
+
type: zu.alternatives(
|
|
12095
12795
|
...joiInstanceCheckerAlternativesFactory(ResourcefulBigintType, "ResourcefulBigintType")
|
|
12096
12796
|
).default(() => new ResourcefulBigintType())
|
|
12097
12797
|
});
|
|
12098
12798
|
const unsignedIntegerComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12099
|
-
type:
|
|
12799
|
+
type: zu.alternatives(
|
|
12100
12800
|
...joiInstanceCheckerAlternativesFactory(
|
|
12101
12801
|
ResourcefulUnsignedIntegerType,
|
|
12102
12802
|
"ResourcefulUnsignedIntegerType"
|
|
@@ -12104,99 +12804,99 @@ const unsignedIntegerComputedOptionsSchema = dataTypeComputedOptionsSchema.keys(
|
|
|
12104
12804
|
).default(() => new ResourcefulUnsignedIntegerType())
|
|
12105
12805
|
});
|
|
12106
12806
|
const booleanComputedOptionsSchema = dataTypeComputedOptionsSchema.keys({
|
|
12107
|
-
type:
|
|
12807
|
+
type: zu.alternatives(
|
|
12108
12808
|
...joiInstanceCheckerAlternativesFactory(ResourcefulBooleanType, "ResourcefulBooleanType")
|
|
12109
12809
|
).default(() => new ResourcefulBooleanType())
|
|
12110
12810
|
});
|
|
12111
|
-
const objectComputedOptionsSchema =
|
|
12811
|
+
const objectComputedOptionsSchema = zu.object({
|
|
12112
12812
|
// Lucid ComputedOptions (full)
|
|
12113
|
-
serializeAs:
|
|
12114
|
-
serialize:
|
|
12115
|
-
meta:
|
|
12813
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12814
|
+
serialize: zu.function().optional(),
|
|
12815
|
+
meta: zu.object().optional(),
|
|
12116
12816
|
// Resourceful options
|
|
12117
|
-
propertyKey:
|
|
12118
|
-
readAccessControlFilters:
|
|
12119
|
-
writeAccessControlFilters:
|
|
12120
|
-
nullable:
|
|
12121
|
-
description:
|
|
12122
|
-
default:
|
|
12123
|
-
externalDocs:
|
|
12124
|
-
description:
|
|
12125
|
-
url:
|
|
12817
|
+
propertyKey: zu.string().default(""),
|
|
12818
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12819
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12820
|
+
nullable: zu.boolean().default(false),
|
|
12821
|
+
description: zu.string().optional(),
|
|
12822
|
+
default: zu.any().optional(),
|
|
12823
|
+
externalDocs: zu.object({
|
|
12824
|
+
description: zu.string().optional(),
|
|
12825
|
+
url: zu.string().uri().required()
|
|
12126
12826
|
}).optional(),
|
|
12127
|
-
example:
|
|
12128
|
-
deprecated:
|
|
12129
|
-
type:
|
|
12827
|
+
example: zu.string().optional(),
|
|
12828
|
+
deprecated: zu.boolean().default(false),
|
|
12829
|
+
type: zu.alternatives(
|
|
12130
12830
|
...joiInstanceCheckerAlternativesFactory(ResourcefulObjectType, "ResourcefulObjectType")
|
|
12131
12831
|
).default(() => new ResourcefulObjectType())
|
|
12132
12832
|
});
|
|
12133
|
-
const arrayComputedOptionsSchema =
|
|
12833
|
+
const arrayComputedOptionsSchema = zu.object({
|
|
12134
12834
|
// Lucid ComputedOptions (full)
|
|
12135
|
-
serializeAs:
|
|
12136
|
-
serialize:
|
|
12137
|
-
meta:
|
|
12835
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12836
|
+
serialize: zu.function().optional(),
|
|
12837
|
+
meta: zu.object().optional(),
|
|
12138
12838
|
// Resourceful options
|
|
12139
|
-
propertyKey:
|
|
12140
|
-
readAccessControlFilters:
|
|
12141
|
-
writeAccessControlFilters:
|
|
12142
|
-
nullable:
|
|
12143
|
-
description:
|
|
12144
|
-
default:
|
|
12145
|
-
externalDocs:
|
|
12146
|
-
description:
|
|
12147
|
-
url:
|
|
12839
|
+
propertyKey: zu.string().default(""),
|
|
12840
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12841
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12842
|
+
nullable: zu.boolean().default(false),
|
|
12843
|
+
description: zu.string().optional(),
|
|
12844
|
+
default: zu.any().optional(),
|
|
12845
|
+
externalDocs: zu.object({
|
|
12846
|
+
description: zu.string().optional(),
|
|
12847
|
+
url: zu.string().uri().required()
|
|
12148
12848
|
}).optional(),
|
|
12149
|
-
example:
|
|
12150
|
-
deprecated:
|
|
12151
|
-
type:
|
|
12849
|
+
example: zu.string().optional(),
|
|
12850
|
+
deprecated: zu.boolean().default(false),
|
|
12851
|
+
type: zu.alternatives(
|
|
12152
12852
|
...joiInstanceCheckerAlternativesFactory(ResourcefulArrayType, "ResourcefulArrayType")
|
|
12153
12853
|
).default(() => new ResourcefulArrayType())
|
|
12154
12854
|
});
|
|
12155
|
-
const resourcefulRelationshipOptionsSchema =
|
|
12855
|
+
const resourcefulRelationshipOptionsSchema = zu.object({
|
|
12156
12856
|
// Resourceful options
|
|
12157
|
-
propertyKey:
|
|
12158
|
-
readAccessControlFilters:
|
|
12159
|
-
writeAccessControlFilters:
|
|
12160
|
-
nullable:
|
|
12161
|
-
description:
|
|
12162
|
-
default:
|
|
12163
|
-
externalDocs:
|
|
12164
|
-
description:
|
|
12165
|
-
url:
|
|
12857
|
+
propertyKey: zu.string().default(""),
|
|
12858
|
+
readAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12859
|
+
writeAccessControlFilters: zu.array().items(zu.function()).default([]),
|
|
12860
|
+
nullable: zu.boolean().default(false),
|
|
12861
|
+
description: zu.string().optional(),
|
|
12862
|
+
default: zu.any().optional(),
|
|
12863
|
+
externalDocs: zu.object({
|
|
12864
|
+
description: zu.string().optional(),
|
|
12865
|
+
url: zu.string().uri().required()
|
|
12166
12866
|
}).optional(),
|
|
12167
|
-
example:
|
|
12168
|
-
deprecated:
|
|
12867
|
+
example: zu.string().optional(),
|
|
12868
|
+
deprecated: zu.boolean().default(false)
|
|
12169
12869
|
});
|
|
12170
12870
|
const relationOptionsSchema = resourcefulRelationshipOptionsSchema.keys({
|
|
12171
12871
|
// Lucid RelationOptions
|
|
12172
|
-
localKey:
|
|
12173
|
-
foreignKey:
|
|
12174
|
-
serializeAs:
|
|
12175
|
-
onQuery:
|
|
12176
|
-
relatedModel:
|
|
12872
|
+
localKey: zu.string().optional(),
|
|
12873
|
+
foreignKey: zu.string().optional(),
|
|
12874
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12875
|
+
onQuery: zu.function().optional(),
|
|
12876
|
+
relatedModel: zu.function()
|
|
12177
12877
|
});
|
|
12178
12878
|
const manyToManyRelationOptionsSchema = resourcefulRelationshipOptionsSchema.keys({
|
|
12179
12879
|
// Lucid ManyToManyRelationOptions
|
|
12180
|
-
localKey:
|
|
12181
|
-
relatedKey:
|
|
12182
|
-
pivotForeignKey:
|
|
12183
|
-
pivotRelatedForeignKey:
|
|
12184
|
-
pivotTable:
|
|
12185
|
-
pivotTimestamps:
|
|
12186
|
-
pivotColumns:
|
|
12187
|
-
serializeAs:
|
|
12188
|
-
onQuery:
|
|
12189
|
-
relatedModel:
|
|
12880
|
+
localKey: zu.string().optional(),
|
|
12881
|
+
relatedKey: zu.string().optional(),
|
|
12882
|
+
pivotForeignKey: zu.string().optional(),
|
|
12883
|
+
pivotRelatedForeignKey: zu.string().optional(),
|
|
12884
|
+
pivotTable: zu.string().optional(),
|
|
12885
|
+
pivotTimestamps: zu.boolean().optional(),
|
|
12886
|
+
pivotColumns: zu.array().items(zu.string()).optional(),
|
|
12887
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12888
|
+
onQuery: zu.function().optional(),
|
|
12889
|
+
relatedModel: zu.function()
|
|
12190
12890
|
});
|
|
12191
12891
|
const hasManyThroughRelationOptionsSchema = resourcefulRelationshipOptionsSchema.keys({
|
|
12192
12892
|
// Lucid HasManyThroughRelationOptions (ThroughRelationOptions without throughModel)
|
|
12193
|
-
localKey:
|
|
12194
|
-
foreignKey:
|
|
12195
|
-
throughLocalKey:
|
|
12196
|
-
throughForeignKey:
|
|
12197
|
-
serializeAs:
|
|
12198
|
-
onQuery:
|
|
12199
|
-
relatedModel:
|
|
12893
|
+
localKey: zu.string().optional(),
|
|
12894
|
+
foreignKey: zu.string().optional(),
|
|
12895
|
+
throughLocalKey: zu.string().optional(),
|
|
12896
|
+
throughForeignKey: zu.string().optional(),
|
|
12897
|
+
serializeAs: zu.alternatives().try(zu.string(), zu.valid(null)).optional(),
|
|
12898
|
+
onQuery: zu.function().optional(),
|
|
12899
|
+
relatedModel: zu.function()
|
|
12200
12900
|
});
|
|
12201
12901
|
const extractLucidOptionsForLucidDecorator = (options, keys, overrides) => {
|
|
12202
12902
|
const extracted = {};
|
|
@@ -12208,7 +12908,7 @@ const extractLucidOptionsForLucidDecorator = (options, keys, overrides) => {
|
|
|
12208
12908
|
extracted[k2] = v;
|
|
12209
12909
|
}
|
|
12210
12910
|
});
|
|
12211
|
-
if (isObject$
|
|
12911
|
+
if (isObject$2(overrides)) {
|
|
12212
12912
|
Object.assign(extracted, overrides);
|
|
12213
12913
|
}
|
|
12214
12914
|
return extracted;
|
|
@@ -12751,10 +13451,10 @@ function resourcefulHasManyThrough(model, options = {}) {
|
|
|
12751
13451
|
map.set(propertyKey, opts);
|
|
12752
13452
|
};
|
|
12753
13453
|
}
|
|
12754
|
-
const version = "0.1.0-master-
|
|
13454
|
+
const version = "0.1.0-master-3ec631a4";
|
|
12755
13455
|
export {
|
|
12756
13456
|
k as definitions,
|
|
12757
|
-
|
|
13457
|
+
I as errors,
|
|
12758
13458
|
resourcefulBelongsTo,
|
|
12759
13459
|
resourcefulColumn,
|
|
12760
13460
|
resourcefulComputed,
|