@jskit-ai/json-rest-api-core 0.1.29 → 0.1.31
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/json-rest-api-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"hooked-api": "1.x.x",
|
|
13
13
|
"json-rest-api": "1.x.x",
|
|
14
|
-
"@jskit-ai/kernel": "0.1.
|
|
14
|
+
"@jskit-ai/kernel": "0.1.86"
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Api } from "hooked-api";
|
|
2
2
|
import { AutoFilterPlugin, RestApiKnexPlugin, RestApiPlugin } from "json-rest-api";
|
|
3
3
|
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
|
+
import { resolveCrudResourceScopeName } from "@jskit-ai/kernel/shared/support/crudLookup";
|
|
4
5
|
|
|
5
6
|
const INTERNAL_JSON_REST_API = "internal.json-rest-api";
|
|
6
7
|
|
|
@@ -79,6 +80,12 @@ function cloneJsonRestResourceValue(value, { writeSerializers = {} } = {}) {
|
|
|
79
80
|
delete next.storage.writeSerializer;
|
|
80
81
|
}
|
|
81
82
|
}
|
|
83
|
+
if (
|
|
84
|
+
isPlainJsonRestObject(next.relation) &&
|
|
85
|
+
normalizeJsonRestText(next.relation.kind).toLowerCase() === "collection"
|
|
86
|
+
) {
|
|
87
|
+
next.virtual = true;
|
|
88
|
+
}
|
|
82
89
|
|
|
83
90
|
return next;
|
|
84
91
|
}
|
|
@@ -144,6 +151,38 @@ function normalizeJsonRestList(value) {
|
|
|
144
151
|
.filter(Boolean);
|
|
145
152
|
}
|
|
146
153
|
|
|
154
|
+
function resolveJsonRestCollectionRelationships(resource = {}) {
|
|
155
|
+
const resourceSchema = normalizeJsonRestObject(resource?.schema);
|
|
156
|
+
const relationships = {};
|
|
157
|
+
|
|
158
|
+
for (const [fieldName, fieldDefinition] of Object.entries(resourceSchema)) {
|
|
159
|
+
const normalizedFieldDefinition = normalizeJsonRestObject(fieldDefinition);
|
|
160
|
+
const relation = normalizeJsonRestObject(normalizedFieldDefinition.relation);
|
|
161
|
+
if (normalizeJsonRestText(relation.kind).toLowerCase() !== "collection") {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const relationshipName = normalizeJsonRestText(relation.as || normalizedFieldDefinition.as, {
|
|
166
|
+
fallback: fieldName
|
|
167
|
+
});
|
|
168
|
+
const target = resolveCrudResourceScopeName(
|
|
169
|
+
relation.target || relation.targetResource || relation.namespace || relation.apiPath
|
|
170
|
+
);
|
|
171
|
+
const foreignKey = normalizeJsonRestText(relation.foreignKey);
|
|
172
|
+
if (!relationshipName || !target || !foreignKey) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
relationships[relationshipName] = {
|
|
177
|
+
type: "hasMany",
|
|
178
|
+
target,
|
|
179
|
+
foreignKey
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return relationships;
|
|
184
|
+
}
|
|
185
|
+
|
|
147
186
|
function buildJsonRestQueryParams(resourceType = "", query = {}, { include = undefined } = {}) {
|
|
148
187
|
const normalizedResourceType = normalizeJsonRestText(resourceType);
|
|
149
188
|
const source = normalizeJsonRestObject(query);
|
|
@@ -292,6 +331,23 @@ function createJsonRestResourceScopeOptions(resource = {}, { writeSerializers =
|
|
|
292
331
|
const scopeOptions = cloneJsonRestResourceValue(resource, {
|
|
293
332
|
writeSerializers: normalizeJsonRestObject(writeSerializers)
|
|
294
333
|
});
|
|
334
|
+
const collectionRelationships = resolveJsonRestCollectionRelationships(scopeOptions);
|
|
335
|
+
if (Object.keys(collectionRelationships).length > 0) {
|
|
336
|
+
if (
|
|
337
|
+
scopeOptions.relationships !== undefined &&
|
|
338
|
+
scopeOptions.relationships !== null &&
|
|
339
|
+
!isPlainJsonRestObject(scopeOptions.relationships)
|
|
340
|
+
) {
|
|
341
|
+
throw new TypeError(
|
|
342
|
+
"json-rest-api resource relationships must be an object when collection relations are derived."
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
scopeOptions.relationships = {
|
|
347
|
+
...collectionRelationships,
|
|
348
|
+
...normalizeJsonRestObject(scopeOptions.relationships)
|
|
349
|
+
};
|
|
350
|
+
}
|
|
295
351
|
|
|
296
352
|
if (typeof normalizeId === "function") {
|
|
297
353
|
scopeOptions.normalizeId = normalizeId;
|
|
@@ -290,6 +290,26 @@ test("createJsonRestResourceScopeOptions clones canonical resource metadata and
|
|
|
290
290
|
required: false
|
|
291
291
|
})
|
|
292
292
|
})
|
|
293
|
+
}),
|
|
294
|
+
pets: Object.freeze({
|
|
295
|
+
type: "array",
|
|
296
|
+
relation: Object.freeze({
|
|
297
|
+
kind: "collection",
|
|
298
|
+
namespace: "pets",
|
|
299
|
+
foreignKey: "contactId"
|
|
300
|
+
}),
|
|
301
|
+
operations: Object.freeze({
|
|
302
|
+
output: Object.freeze({
|
|
303
|
+
required: false
|
|
304
|
+
})
|
|
305
|
+
})
|
|
306
|
+
})
|
|
307
|
+
}),
|
|
308
|
+
relationships: Object.freeze({
|
|
309
|
+
auditEvents: Object.freeze({
|
|
310
|
+
type: "hasMany",
|
|
311
|
+
target: "auditEvents",
|
|
312
|
+
foreignKey: "contactId"
|
|
293
313
|
})
|
|
294
314
|
}),
|
|
295
315
|
operations: Object.freeze({
|
|
@@ -314,10 +334,23 @@ test("createJsonRestResourceScopeOptions clones canonical resource metadata and
|
|
|
314
334
|
assert.equal(result.schema.createdAt.storage.serialize(null), null);
|
|
315
335
|
assert.equal(result.schema.createdAt.storage.writeSerializer, undefined);
|
|
316
336
|
assert.equal(result.schema.bookingSteps.virtual, true);
|
|
337
|
+
assert.equal(result.schema.pets.virtual, true);
|
|
317
338
|
assert.equal(result.normalizeId, normalizeId);
|
|
318
339
|
assert.equal(result.schema.name.maxLength, 190);
|
|
319
340
|
assert.equal(result.schema.name.operations.output.required, true);
|
|
320
341
|
assert.equal(result.operations.view.method, "GET");
|
|
342
|
+
assert.deepEqual(result.relationships, {
|
|
343
|
+
pets: {
|
|
344
|
+
type: "hasMany",
|
|
345
|
+
target: "pets",
|
|
346
|
+
foreignKey: "contactId"
|
|
347
|
+
},
|
|
348
|
+
auditEvents: {
|
|
349
|
+
type: "hasMany",
|
|
350
|
+
target: "auditEvents",
|
|
351
|
+
foreignKey: "contactId"
|
|
352
|
+
}
|
|
353
|
+
});
|
|
321
354
|
|
|
322
355
|
result.schema.createdAt.indexed = true;
|
|
323
356
|
assert.equal(source.schema.createdAt.indexed, undefined);
|