@jskit-ai/crud-core 0.1.63 → 0.1.65
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/package.descriptor.mjs +4 -2
- package/package.json +18 -10
- package/src/server/crudModuleConfig.js +25 -5
- package/src/server/fieldAccess.js +9 -39
- package/src/server/listFilters.js +384 -389
- package/src/server/listQueryValidators.js +39 -77
- package/src/server/lookupHydration.js +4 -1
- package/src/server/repositorySupport.js +71 -121
- package/src/server/resourceRuntime/index.js +49 -74
- package/src/server/resourceRuntime/lookupHydration.js +4 -1
- package/src/server/routeContracts.js +74 -0
- package/src/server/serviceEvents.js +75 -4
- package/src/shared/crudFieldSupport.js +54 -0
- package/src/shared/crudNamespaceSupport.js +1 -27
- package/src/shared/crudResource.js +1 -0
- package/test/createCrudServiceFromResource.test.js +30 -28
- package/test/{crudFieldMetaSupport.test.js → crudFieldSupport.test.js} +1 -1
- package/test/crudModuleConfig.test.js +33 -0
- package/test/crudResource.test.js +97 -0
- package/test/listFilters.test.js +221 -59
- package/test/listQueryValidators.test.js +131 -97
- package/test/repositorySupport.test.js +241 -241
- package/test/resourceRuntime.test.js +204 -248
- package/test/routeContracts.test.js +146 -0
- package/test/serviceEvents.test.js +41 -1
- package/test/serviceMethods.test.js +12 -10
- package/src/shared/crudFieldMetaSupport.js +0 -153
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { createSchema, validateSchemaPayload } from "@jskit-ai/kernel/shared/validators";
|
|
4
|
+
import { defineCrudResource } from "../src/shared/crudResource.js";
|
|
5
|
+
|
|
6
|
+
function createContactsResource(overrides = {}) {
|
|
7
|
+
return defineCrudResource({
|
|
8
|
+
namespace: "contacts",
|
|
9
|
+
schema: {
|
|
10
|
+
name: {
|
|
11
|
+
type: "string",
|
|
12
|
+
maxLength: 190,
|
|
13
|
+
operations: {
|
|
14
|
+
output: { required: true },
|
|
15
|
+
create: { required: true },
|
|
16
|
+
patch: { required: false }
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
createdAt: {
|
|
20
|
+
type: "dateTime",
|
|
21
|
+
operations: {
|
|
22
|
+
output: { required: true }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
contract: {
|
|
27
|
+
lookup: {
|
|
28
|
+
containerKey: "lookups"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
...overrides
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
test("defineCrudResource derives full CRUD operations by default", async () => {
|
|
36
|
+
const resource = createContactsResource();
|
|
37
|
+
|
|
38
|
+
assert.deepEqual(
|
|
39
|
+
Object.keys(resource.operations),
|
|
40
|
+
["list", "view", "create", "patch", "delete"]
|
|
41
|
+
);
|
|
42
|
+
assert.deepEqual(resource.operations.list.realtime?.events, ["contacts.record.changed"]);
|
|
43
|
+
|
|
44
|
+
const normalizedCreateBody = await validateSchemaPayload(resource.operations.create.body, {
|
|
45
|
+
name: " Example "
|
|
46
|
+
}, { phase: "input" });
|
|
47
|
+
assert.equal(normalizedCreateBody.name, "Example");
|
|
48
|
+
|
|
49
|
+
const normalizedViewOutput = await validateSchemaPayload(resource.operations.view.output, {
|
|
50
|
+
id: 7,
|
|
51
|
+
name: " Example ",
|
|
52
|
+
createdAt: "2026-05-01 12:30:00.000",
|
|
53
|
+
lookups: {}
|
|
54
|
+
}, { phase: "output" });
|
|
55
|
+
assert.equal(normalizedViewOutput.id, "7");
|
|
56
|
+
assert.equal(normalizedViewOutput.name, "Example");
|
|
57
|
+
assert.ok(normalizedViewOutput.createdAt instanceof Date);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("defineCrudResource supports an explicit standard CRUD operation subset", () => {
|
|
61
|
+
const resource = createContactsResource({
|
|
62
|
+
crudOperations: ["list", "view", "create"]
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
assert.deepEqual(
|
|
66
|
+
Object.keys(resource.operations),
|
|
67
|
+
["list", "view", "create"]
|
|
68
|
+
);
|
|
69
|
+
assert.equal(Object.hasOwn(resource, "crudOperations"), false);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("defineCrudResource merges authored operation overrides into derived defaults", () => {
|
|
73
|
+
const resource = createContactsResource({
|
|
74
|
+
operations: {
|
|
75
|
+
list: {
|
|
76
|
+
realtime: {
|
|
77
|
+
events: ["contacts.custom.changed"]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
archive: {
|
|
81
|
+
method: "POST",
|
|
82
|
+
output: Object.freeze({
|
|
83
|
+
mode: "replace",
|
|
84
|
+
schema: createSchema({
|
|
85
|
+
archived: {
|
|
86
|
+
type: "boolean",
|
|
87
|
+
required: true
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
assert.deepEqual(resource.operations.list.realtime?.events, ["contacts.custom.changed"]);
|
|
96
|
+
assert.equal(resource.operations.archive.method, "POST");
|
|
97
|
+
});
|
package/test/listFilters.test.js
CHANGED
|
@@ -1,22 +1,51 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
3
|
+
import { createSchema } from "json-rest-schema";
|
|
4
4
|
import { compileRouteValidator } from "@jskit-ai/kernel/_testable";
|
|
5
|
-
import {
|
|
5
|
+
import { defineCrudListFilters } from "@jskit-ai/kernel/shared/support/crudListFilters";
|
|
6
|
+
import {
|
|
7
|
+
composeSchemaDefinitions,
|
|
8
|
+
cursorPaginationQueryValidator
|
|
9
|
+
} from "@jskit-ai/kernel/shared/validators";
|
|
6
10
|
import { listSearchQueryValidator } from "../src/server/listQueryValidators.js";
|
|
7
11
|
import {
|
|
8
12
|
CRUD_LIST_FILTER_INVALID_VALUES_REJECT,
|
|
9
13
|
CRUD_LIST_FILTER_INVALID_VALUES_DISCARD,
|
|
14
|
+
createCrudListFilterQueryField,
|
|
15
|
+
createCrudListFilterQuerySchema,
|
|
10
16
|
createCrudListFilters
|
|
11
17
|
} from "../src/server/listFilters.js";
|
|
12
18
|
|
|
19
|
+
function composeSchemaDefinition(...definitions) {
|
|
20
|
+
return composeSchemaDefinitions(definitions, {
|
|
21
|
+
mode: "patch",
|
|
22
|
+
context: "crudCore.listFilters.compose"
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
13
26
|
test("crud-core exposes createCrudListFilters through the public package export", async () => {
|
|
14
27
|
const module = await import("@jskit-ai/crud-core/server/listFilters");
|
|
15
28
|
assert.equal(typeof module.createCrudListFilters, "function");
|
|
29
|
+
assert.equal(typeof module.createCrudListFilterQueryField, "function");
|
|
30
|
+
assert.equal(typeof module.createCrudListFilterQuerySchema, "function");
|
|
16
31
|
assert.equal(module.CRUD_LIST_FILTER_INVALID_VALUES_REJECT, CRUD_LIST_FILTER_INVALID_VALUES_REJECT);
|
|
17
32
|
assert.equal(module.CRUD_LIST_FILTER_INVALID_VALUES_DISCARD, CRUD_LIST_FILTER_INVALID_VALUES_DISCARD);
|
|
18
33
|
});
|
|
19
34
|
|
|
35
|
+
test("importing crud-core list filters does not register a global json-rest-schema type", () => {
|
|
36
|
+
const schema = createSchema({
|
|
37
|
+
status: {
|
|
38
|
+
type: "crudListFilterQuery"
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
assert.throws(() => {
|
|
43
|
+
schema.patch({
|
|
44
|
+
status: "active"
|
|
45
|
+
});
|
|
46
|
+
}, /No casting function for type: crudListFilterQuery/);
|
|
47
|
+
});
|
|
48
|
+
|
|
20
49
|
function createQueryDouble() {
|
|
21
50
|
const calls = [];
|
|
22
51
|
const nestedQuery = {
|
|
@@ -69,7 +98,7 @@ function createQueryDouble() {
|
|
|
69
98
|
};
|
|
70
99
|
}
|
|
71
100
|
|
|
72
|
-
test("createCrudListFilters
|
|
101
|
+
test("createCrudListFilters parses filters into semantic values", () => {
|
|
73
102
|
const runtime = createCrudListFilters({
|
|
74
103
|
onlyStaff: {
|
|
75
104
|
type: "flag",
|
|
@@ -97,28 +126,33 @@ test("createCrudListFilters normalizes filters into semantic values", () => {
|
|
|
97
126
|
}
|
|
98
127
|
});
|
|
99
128
|
|
|
100
|
-
const
|
|
129
|
+
const validator = runtime.createQueryValidator({
|
|
130
|
+
invalidValues: CRUD_LIST_FILTER_INVALID_VALUES_DISCARD
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const result = validator.schema.patch({
|
|
101
134
|
onlyStaff: "",
|
|
102
135
|
status: ["active", "ignored", "archived"],
|
|
103
|
-
|
|
104
|
-
arrivalDateTo: "2026-04-30",
|
|
136
|
+
arrivalDate: "2026-04-01..2026-04-30",
|
|
105
137
|
supplierContactId: ["7", "bad", "4"],
|
|
106
|
-
|
|
107
|
-
weightMax: 18
|
|
138
|
+
weight: "12.5..18"
|
|
108
139
|
});
|
|
109
140
|
|
|
110
|
-
assert.deepEqual(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
141
|
+
assert.deepEqual(result, {
|
|
142
|
+
validatedObject: {
|
|
143
|
+
onlyStaff: true,
|
|
144
|
+
status: ["active", "archived"],
|
|
145
|
+
arrivalDate: {
|
|
146
|
+
from: "2026-04-01",
|
|
147
|
+
to: "2026-04-30"
|
|
148
|
+
},
|
|
149
|
+
supplierContactId: ["7", "4"],
|
|
150
|
+
weight: {
|
|
151
|
+
min: 12.5,
|
|
152
|
+
max: 18
|
|
153
|
+
}
|
|
116
154
|
},
|
|
117
|
-
|
|
118
|
-
weight: {
|
|
119
|
-
min: 12.5,
|
|
120
|
-
max: 18
|
|
121
|
-
}
|
|
155
|
+
errors: {}
|
|
122
156
|
});
|
|
123
157
|
});
|
|
124
158
|
|
|
@@ -171,10 +205,8 @@ test("createCrudListFilters applies default column filters by type", () => {
|
|
|
171
205
|
onlyStaff: "",
|
|
172
206
|
status: ["active", "archived"],
|
|
173
207
|
supplierContactId: "7",
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
weightMin: "12.5",
|
|
177
|
-
weightMax: "18",
|
|
208
|
+
arrivalDate: "2026-04-01..2026-04-30",
|
|
209
|
+
weight: "12.5..18",
|
|
178
210
|
locationAssignment: "missing"
|
|
179
211
|
});
|
|
180
212
|
|
|
@@ -248,16 +280,87 @@ test("createCrudListFilters query validator stays mergeable with search and curs
|
|
|
248
280
|
});
|
|
249
281
|
|
|
250
282
|
const compiled = compileRouteValidator({
|
|
251
|
-
|
|
283
|
+
query: composeSchemaDefinition(
|
|
252
284
|
cursorPaginationQueryValidator,
|
|
253
285
|
listSearchQueryValidator,
|
|
254
286
|
runtime.createQueryValidator({
|
|
255
287
|
invalidValues: CRUD_LIST_FILTER_INVALID_VALUES_REJECT
|
|
256
288
|
})
|
|
257
|
-
|
|
289
|
+
)
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
assert.deepEqual(compiled.schema.querystring.required || [], []);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test("createCrudListFilterQueryField keeps route query params explicit while reusing filter semantics", () => {
|
|
296
|
+
const filters = defineCrudListFilters({
|
|
297
|
+
status: {
|
|
298
|
+
type: "enum",
|
|
299
|
+
label: "Status",
|
|
300
|
+
options: [
|
|
301
|
+
{ value: "active", label: "Active" },
|
|
302
|
+
{ value: "archived", label: "Archived" }
|
|
303
|
+
]
|
|
304
|
+
},
|
|
305
|
+
arrivalDate: {
|
|
306
|
+
type: "dateRange",
|
|
307
|
+
label: "Arrival Date"
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const explicitFilterQueryValidator = Object.freeze({
|
|
312
|
+
schema: createCrudListFilterQuerySchema({
|
|
313
|
+
status: createCrudListFilterQueryField(filters.status, {
|
|
314
|
+
invalidValues: CRUD_LIST_FILTER_INVALID_VALUES_REJECT
|
|
315
|
+
}),
|
|
316
|
+
arrivalDate: createCrudListFilterQueryField(filters.arrivalDate, {
|
|
317
|
+
invalidValues: CRUD_LIST_FILTER_INVALID_VALUES_REJECT
|
|
318
|
+
})
|
|
319
|
+
}),
|
|
320
|
+
mode: "patch"
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const compiled = compileRouteValidator({
|
|
324
|
+
query: composeSchemaDefinition(
|
|
325
|
+
cursorPaginationQueryValidator,
|
|
326
|
+
listSearchQueryValidator,
|
|
327
|
+
explicitFilterQueryValidator
|
|
328
|
+
)
|
|
329
|
+
});
|
|
330
|
+
const transportSchema = explicitFilterQueryValidator.schema.toJsonSchema({
|
|
331
|
+
mode: explicitFilterQueryValidator.mode
|
|
258
332
|
});
|
|
259
333
|
|
|
260
334
|
assert.deepEqual(compiled.schema.querystring.required || [], []);
|
|
335
|
+
assert.equal(transportSchema.type, "object");
|
|
336
|
+
assert.equal(transportSchema.properties.status.enum[0], "active");
|
|
337
|
+
assert.equal(
|
|
338
|
+
transportSchema.properties.arrivalDate.pattern,
|
|
339
|
+
"^(?:\\d{4}-\\d{2}-\\d{2}(?:\\.\\.(?:\\d{4}-\\d{2}-\\d{2})?)?|\\.\\.\\d{4}-\\d{2}-\\d{2})$"
|
|
340
|
+
);
|
|
341
|
+
assert.deepEqual(explicitFilterQueryValidator.schema.patch({
|
|
342
|
+
status: "active",
|
|
343
|
+
arrivalDate: "2026-04-01..2026-04-30"
|
|
344
|
+
}), {
|
|
345
|
+
validatedObject: {
|
|
346
|
+
status: "active",
|
|
347
|
+
arrivalDate: {
|
|
348
|
+
from: "2026-04-01",
|
|
349
|
+
to: "2026-04-30"
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
errors: {}
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test("createCrudListFilterQueryField requires normalized filter definitions", () => {
|
|
357
|
+
assert.throws(
|
|
358
|
+
() => createCrudListFilterQueryField({
|
|
359
|
+
type: "enum",
|
|
360
|
+
label: "Status"
|
|
361
|
+
}),
|
|
362
|
+
/normalized filter definition/
|
|
363
|
+
);
|
|
261
364
|
});
|
|
262
365
|
|
|
263
366
|
test("createCrudListFilters requires explicit invalid-value mode for new query validators", () => {
|
|
@@ -296,28 +399,45 @@ test("createCrudListFilters reject validator keeps strict filter schemas", () =>
|
|
|
296
399
|
const validator = runtime.createQueryValidator({
|
|
297
400
|
invalidValues: CRUD_LIST_FILTER_INVALID_VALUES_REJECT
|
|
298
401
|
});
|
|
402
|
+
const transportSchema = validator.schema.toJsonSchema({
|
|
403
|
+
mode: validator.mode
|
|
404
|
+
});
|
|
299
405
|
|
|
300
|
-
assert.equal(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
assert.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
assert.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}),
|
|
406
|
+
assert.equal(transportSchema.type, "object");
|
|
407
|
+
assert.equal(transportSchema.additionalProperties, false);
|
|
408
|
+
assert.equal(
|
|
409
|
+
transportSchema.properties.arrivalDate.pattern,
|
|
410
|
+
"^(?:\\d{4}-\\d{2}-\\d{2}(?:\\.\\.(?:\\d{4}-\\d{2}-\\d{2})?)?|\\.\\.\\d{4}-\\d{2}-\\d{2})$"
|
|
411
|
+
);
|
|
412
|
+
assert.deepEqual(transportSchema.properties.status.anyOf[1].items.enum, ["active", "archived"]);
|
|
413
|
+
assert.equal(transportSchema.properties.supplierContactId.anyOf[1].items.anyOf[0].pattern, "^[1-9][0-9]*$");
|
|
414
|
+
assert.equal(
|
|
415
|
+
transportSchema.properties.weight.anyOf[0].pattern,
|
|
416
|
+
"^(?:[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?(?:\\.\\.(?:[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?)?)?|\\.\\.[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?)$"
|
|
417
|
+
);
|
|
418
|
+
assert.deepEqual(validator.schema.patch({
|
|
419
|
+
arrivalDate: "2026-04-01..2026-04-30",
|
|
420
|
+
status: ["active", "archived"],
|
|
421
|
+
supplierContactId: ["7", "4"],
|
|
422
|
+
weight: "12.5..18"
|
|
423
|
+
}), {
|
|
424
|
+
validatedObject: {
|
|
425
|
+
arrivalDate: {
|
|
426
|
+
from: "2026-04-01",
|
|
427
|
+
to: "2026-04-30"
|
|
428
|
+
},
|
|
429
|
+
status: ["active", "archived"],
|
|
430
|
+
supplierContactId: ["7", "4"],
|
|
431
|
+
weight: {
|
|
432
|
+
min: 12.5,
|
|
433
|
+
max: 18
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
errors: {}
|
|
437
|
+
});
|
|
318
438
|
});
|
|
319
439
|
|
|
320
|
-
test("createCrudListFilters discard validator
|
|
440
|
+
test("createCrudListFilters discard validator returns canonical partial values directly", () => {
|
|
321
441
|
const runtime = createCrudListFilters({
|
|
322
442
|
arrivalDate: {
|
|
323
443
|
type: "dateRange",
|
|
@@ -344,25 +464,65 @@ test("createCrudListFilters discard validator accepts malformed values and lets
|
|
|
344
464
|
const validator = runtime.createQueryValidator({
|
|
345
465
|
invalidValues: CRUD_LIST_FILTER_INVALID_VALUES_DISCARD
|
|
346
466
|
});
|
|
467
|
+
const transportSchema = validator.schema.toJsonSchema({
|
|
468
|
+
mode: validator.mode
|
|
469
|
+
});
|
|
347
470
|
|
|
348
|
-
assert.equal(
|
|
349
|
-
|
|
471
|
+
assert.equal(transportSchema.type, "object");
|
|
472
|
+
assert.equal(transportSchema.properties.arrivalDate.minLength, 0);
|
|
473
|
+
assert.equal(transportSchema.properties.status.anyOf[0].minLength, 0);
|
|
474
|
+
assert.equal(transportSchema.properties.supplierContactId.anyOf[0].anyOf[0].minLength, 0);
|
|
475
|
+
assert.deepEqual(validator.schema.patch({
|
|
476
|
+
arrivalDate: "bad-date..2026-04-30",
|
|
350
477
|
status: ["active", "unexpected"],
|
|
351
478
|
supplierContactId: ["7", "bad"],
|
|
352
|
-
|
|
353
|
-
}), true);
|
|
354
|
-
assert.deepEqual(validator.normalize({
|
|
355
|
-
arrivalDateFrom: "bad-date",
|
|
356
|
-
arrivalDateTo: "2026-04-30",
|
|
357
|
-
status: ["active", "unexpected"],
|
|
358
|
-
supplierContactId: ["7", "bad"],
|
|
359
|
-
weightMin: "bad"
|
|
479
|
+
weight: "bad..18"
|
|
360
480
|
}), {
|
|
481
|
+
validatedObject: {
|
|
482
|
+
arrivalDate: {
|
|
483
|
+
to: "2026-04-30"
|
|
484
|
+
},
|
|
485
|
+
status: ["active"],
|
|
486
|
+
supplierContactId: ["7"],
|
|
487
|
+
weight: {
|
|
488
|
+
max: 18
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
errors: {}
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
test("createCrudListFilters treats exact range filter values as exact bounds", () => {
|
|
496
|
+
const runtime = createCrudListFilters({
|
|
361
497
|
arrivalDate: {
|
|
362
|
-
|
|
498
|
+
type: "dateRange",
|
|
499
|
+
label: "Arrival Date"
|
|
500
|
+
},
|
|
501
|
+
weight: {
|
|
502
|
+
type: "numberRange",
|
|
503
|
+
label: "Weight"
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
const validator = runtime.createQueryValidator({
|
|
508
|
+
invalidValues: CRUD_LIST_FILTER_INVALID_VALUES_DISCARD
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
assert.deepEqual(validator.schema.patch({
|
|
512
|
+
arrivalDate: "2026-04-18",
|
|
513
|
+
weight: 12.5
|
|
514
|
+
}), {
|
|
515
|
+
validatedObject: {
|
|
516
|
+
arrivalDate: {
|
|
517
|
+
from: "2026-04-18",
|
|
518
|
+
to: "2026-04-18"
|
|
519
|
+
},
|
|
520
|
+
weight: {
|
|
521
|
+
min: 12.5,
|
|
522
|
+
max: 12.5
|
|
523
|
+
}
|
|
363
524
|
},
|
|
364
|
-
|
|
365
|
-
supplierContactId: ["7"]
|
|
525
|
+
errors: {}
|
|
366
526
|
});
|
|
367
527
|
});
|
|
368
528
|
|
|
@@ -374,6 +534,8 @@ test("createCrudListFilters exposes no default query validator alias", () => {
|
|
|
374
534
|
}
|
|
375
535
|
});
|
|
376
536
|
|
|
377
|
-
assert.equal(Object.hasOwn(runtime, "
|
|
378
|
-
assert.equal(runtime.
|
|
537
|
+
assert.equal(Object.hasOwn(runtime, "query"), false);
|
|
538
|
+
assert.equal(runtime.query, undefined);
|
|
539
|
+
assert.equal(Object.hasOwn(runtime, "normalize"), false);
|
|
540
|
+
assert.equal(runtime.normalize, undefined);
|
|
379
541
|
});
|