@jskit-ai/crud-core 0.1.144 → 0.1.145
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/crud-core",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.145",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Shared CRUD helpers used by CRUD modules.",
|
|
7
7
|
dependsOn: [
|
|
@@ -28,7 +28,7 @@ export default Object.freeze({
|
|
|
28
28
|
mutations: {
|
|
29
29
|
dependencies: {
|
|
30
30
|
runtime: {
|
|
31
|
-
"@jskit-ai/crud-core": "0.1.
|
|
31
|
+
"@jskit-ai/crud-core": "0.1.145"
|
|
32
32
|
},
|
|
33
33
|
dev: {}
|
|
34
34
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/crud-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.145",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"./server/routeContracts": "./src/server/routeContracts.js"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
31
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
32
|
-
"@jskit-ai/kernel": "0.1.
|
|
30
|
+
"@jskit-ai/database-runtime": "0.1.135",
|
|
31
|
+
"@jskit-ai/http-runtime": "0.1.134",
|
|
32
|
+
"@jskit-ai/kernel": "0.1.136",
|
|
33
33
|
"json-rest-schema": "1.x.x",
|
|
34
|
-
"@jskit-ai/realtime": "0.1.
|
|
35
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
36
|
-
"@jskit-ai/shell-web": "0.1.
|
|
37
|
-
"@jskit-ai/users-core": "0.1.
|
|
38
|
-
"@jskit-ai/users-web": "0.1.
|
|
34
|
+
"@jskit-ai/realtime": "0.1.133",
|
|
35
|
+
"@jskit-ai/resource-crud-core": "0.1.79",
|
|
36
|
+
"@jskit-ai/shell-web": "0.1.137",
|
|
37
|
+
"@jskit-ai/users-core": "0.1.148",
|
|
38
|
+
"@jskit-ai/users-web": "0.1.153"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@tanstack/vue-query": "^5.90.5",
|
|
@@ -25,6 +25,23 @@ const lookupIncludeQueryValidator = Object.freeze({
|
|
|
25
25
|
mode: "patch"
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
+
const jsonApiFieldsetsQueryValidator = Object.freeze({
|
|
29
|
+
schema: createSchema({
|
|
30
|
+
fields: {
|
|
31
|
+
type: "object",
|
|
32
|
+
required: false,
|
|
33
|
+
values: {
|
|
34
|
+
type: "array",
|
|
35
|
+
items: {
|
|
36
|
+
type: "string",
|
|
37
|
+
minLength: 1
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}),
|
|
42
|
+
mode: "patch"
|
|
43
|
+
});
|
|
44
|
+
|
|
28
45
|
function resolveCrudListUsesOrderedCursor(list = {}) {
|
|
29
46
|
const entries = Array.isArray(list?.orderBy)
|
|
30
47
|
? list.orderBy
|
|
@@ -92,6 +109,7 @@ export {
|
|
|
92
109
|
createCrudCursorPaginationQueryValidator,
|
|
93
110
|
listSearchQueryValidator,
|
|
94
111
|
lookupIncludeQueryValidator,
|
|
112
|
+
jsonApiFieldsetsQueryValidator,
|
|
95
113
|
resolveCrudParentFilterKeys,
|
|
96
114
|
createCrudParentFilterQueryValidator
|
|
97
115
|
};
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
createCrudCursorPaginationQueryValidator,
|
|
12
12
|
listSearchQueryValidator as defaultListSearchQueryValidator,
|
|
13
13
|
lookupIncludeQueryValidator as defaultLookupIncludeQueryValidator,
|
|
14
|
+
jsonApiFieldsetsQueryValidator,
|
|
14
15
|
createCrudParentFilterQueryValidator
|
|
15
16
|
} from "./listQueryValidators.js";
|
|
16
17
|
|
|
@@ -454,7 +455,12 @@ function createCrudJsonApiRouteContracts({
|
|
|
454
455
|
listSearchQueryValidator,
|
|
455
456
|
listParentFilterQueryValidator,
|
|
456
457
|
...(resolvedListFilterQueryValidator ? [resolvedListFilterQueryValidator] : []),
|
|
457
|
-
lookupIncludeQueryValidator
|
|
458
|
+
lookupIncludeQueryValidator,
|
|
459
|
+
jsonApiFieldsetsQueryValidator
|
|
460
|
+
]);
|
|
461
|
+
const viewRouteQueryValidator = composeSchemaDefinitions([
|
|
462
|
+
lookupIncludeQueryValidator,
|
|
463
|
+
jsonApiFieldsetsQueryValidator
|
|
458
464
|
]);
|
|
459
465
|
const recordRouteParamsValidator = routeParamsValidator
|
|
460
466
|
? composeSchemaDefinitions([
|
|
@@ -511,19 +517,23 @@ function createCrudJsonApiRouteContracts({
|
|
|
511
517
|
query: listRouteQueryValidator,
|
|
512
518
|
output: viewOutput,
|
|
513
519
|
outputKind: "collection",
|
|
520
|
+
includeValidation400: true,
|
|
514
521
|
outputAttributeExcludeKeys,
|
|
515
522
|
outputRelationshipEntries: viewOutputRelationships,
|
|
523
|
+
allowSparseFields: true,
|
|
516
524
|
getRecordAttributes: viewRecordAttributes,
|
|
517
525
|
getRecordRelationships: viewRecordRelationships,
|
|
518
526
|
getIncluded: viewIncluded
|
|
519
527
|
}),
|
|
520
528
|
viewRouteContract: createJsonApiResourceRouteContract({
|
|
521
529
|
type: routeType,
|
|
522
|
-
query:
|
|
530
|
+
query: viewRouteQueryValidator,
|
|
523
531
|
output: viewOutput,
|
|
524
532
|
outputKind: "record",
|
|
533
|
+
includeValidation400: true,
|
|
525
534
|
outputAttributeExcludeKeys,
|
|
526
535
|
outputRelationshipEntries: viewOutputRelationships,
|
|
536
|
+
allowSparseFields: true,
|
|
527
537
|
getRecordAttributes: viewRecordAttributes,
|
|
528
538
|
getRecordRelationships: viewRecordRelationships,
|
|
529
539
|
getIncluded: viewIncluded
|
|
@@ -177,7 +177,11 @@ test("createCrudJsonApiRouteContracts builds default CRUD JSON:API contracts", a
|
|
|
177
177
|
include: " ownerId ",
|
|
178
178
|
contactId: " 42 ",
|
|
179
179
|
cursor: " offset:2 ",
|
|
180
|
-
limit: "25"
|
|
180
|
+
limit: "25",
|
|
181
|
+
fields: {
|
|
182
|
+
contacts: ["id", "name"],
|
|
183
|
+
userProfiles: ["id", "name"]
|
|
184
|
+
}
|
|
181
185
|
}, { phase: "input" });
|
|
182
186
|
|
|
183
187
|
assert.deepEqual(normalizedListQuery, {
|
|
@@ -185,9 +189,39 @@ test("createCrudJsonApiRouteContracts builds default CRUD JSON:API contracts", a
|
|
|
185
189
|
include: "ownerId",
|
|
186
190
|
contactId: "42",
|
|
187
191
|
cursor: "offset:2",
|
|
188
|
-
limit: 25
|
|
192
|
+
limit: 25,
|
|
193
|
+
fields: {
|
|
194
|
+
contacts: ["id", "name"],
|
|
195
|
+
userProfiles: ["id", "name"]
|
|
196
|
+
}
|
|
189
197
|
});
|
|
190
198
|
|
|
199
|
+
assert.deepEqual(
|
|
200
|
+
await validateSchemaPayload(contracts.viewRouteContract.query, {
|
|
201
|
+
include: "owner",
|
|
202
|
+
fields: {
|
|
203
|
+
contacts: ["id", "name"],
|
|
204
|
+
userProfiles: ["id", "name"]
|
|
205
|
+
}
|
|
206
|
+
}, { phase: "input" }),
|
|
207
|
+
{
|
|
208
|
+
include: "owner",
|
|
209
|
+
fields: {
|
|
210
|
+
contacts: ["id", "name"],
|
|
211
|
+
userProfiles: ["id", "name"]
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
const sparseResourceSchema =
|
|
217
|
+
contracts.listRouteContract.responses[200].transportSchema.definitions.contactsSuccessResource;
|
|
218
|
+
const sparseAttributesSchemaName = sparseResourceSchema.properties.attributes.allOf[0].$ref
|
|
219
|
+
.replace("#/definitions/", "");
|
|
220
|
+
const sparseAttributesSchema =
|
|
221
|
+
contracts.listRouteContract.responses[200].transportSchema.definitions[sparseAttributesSchemaName];
|
|
222
|
+
assert.deepEqual(sparseResourceSchema.required, ["type", "id"]);
|
|
223
|
+
assert.equal(Object.hasOwn(sparseAttributesSchema, "required"), false);
|
|
224
|
+
|
|
191
225
|
const decodedCreateBody = contracts.createRouteContract.transport.request.body({
|
|
192
226
|
data: {
|
|
193
227
|
type: "contacts",
|