@jskit-ai/json-rest-api-core 0.1.102 → 0.1.104-oldline.0
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.
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export default Object.freeze({
|
|
2
|
+
packageVersion: 1,
|
|
3
|
+
packageId: "@jskit-ai/json-rest-api-core",
|
|
4
|
+
version: "0.1.92",
|
|
5
|
+
kind: "runtime",
|
|
6
|
+
description: "Shared internal json-rest-api host runtime with autofilter, query-projection, and row-policy support.",
|
|
7
|
+
dependsOn: [
|
|
8
|
+
"@jskit-ai/database-runtime",
|
|
9
|
+
"@jskit-ai/kernel"
|
|
10
|
+
],
|
|
11
|
+
capabilities: {
|
|
12
|
+
provides: [
|
|
13
|
+
"json-rest-api.core"
|
|
14
|
+
],
|
|
15
|
+
requires: [
|
|
16
|
+
"runtime.database"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
runtime: {
|
|
20
|
+
server: {
|
|
21
|
+
providers: [
|
|
22
|
+
{
|
|
23
|
+
entrypoint: "src/server/JsonRestApiCoreServiceProvider.js",
|
|
24
|
+
export: "JsonRestApiCoreServiceProvider"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
client: {
|
|
29
|
+
providers: []
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
metadata: {
|
|
33
|
+
apiSummary: {
|
|
34
|
+
surfaces: [
|
|
35
|
+
{
|
|
36
|
+
subpath: "./server",
|
|
37
|
+
summary: "Exports the shared internal json-rest-api host token and resource registration helpers, including server-only row policies."
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
containerTokens: {
|
|
41
|
+
server: [
|
|
42
|
+
"internal.json-rest-api"
|
|
43
|
+
],
|
|
44
|
+
client: []
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
mutations: {
|
|
49
|
+
dependencies: {
|
|
50
|
+
runtime: {},
|
|
51
|
+
dev: {}
|
|
52
|
+
},
|
|
53
|
+
packageJson: {
|
|
54
|
+
scripts: {}
|
|
55
|
+
},
|
|
56
|
+
procfile: {},
|
|
57
|
+
files: [],
|
|
58
|
+
text: []
|
|
59
|
+
}
|
|
60
|
+
});
|
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.104-oldline.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -9,63 +9,8 @@
|
|
|
9
9
|
"./server/jsonRestApiHost": "./src/server/jsonRestApiHost.js"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@jskit-ai/database-runtime": "0.1.158",
|
|
13
|
-
"@jskit-ai/kernel": "0.1.158",
|
|
14
|
-
"@jskit-ai/resource-crud-core": "0.1.100",
|
|
15
12
|
"hooked-api": "1.x.x",
|
|
16
|
-
"json-rest-api": "^1.0.27"
|
|
17
|
-
|
|
18
|
-
"description": "Shared internal json-rest-api host runtime with autofilter, query-projection, and row-policy support.",
|
|
19
|
-
"jskit": {
|
|
20
|
-
"kind": "runtime",
|
|
21
|
-
"capabilities": {
|
|
22
|
-
"provides": [
|
|
23
|
-
"json-rest-api.core"
|
|
24
|
-
],
|
|
25
|
-
"requires": [
|
|
26
|
-
"runtime.database"
|
|
27
|
-
]
|
|
28
|
-
},
|
|
29
|
-
"runtime": {
|
|
30
|
-
"server": {
|
|
31
|
-
"providers": [
|
|
32
|
-
{
|
|
33
|
-
"entrypoint": "src/server/JsonRestApiCoreServiceProvider.js",
|
|
34
|
-
"export": "JsonRestApiCoreServiceProvider"
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
"client": {
|
|
39
|
-
"providers": []
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
"metadata": {
|
|
43
|
-
"apiSummary": {
|
|
44
|
-
"surfaces": [
|
|
45
|
-
{
|
|
46
|
-
"subpath": "./server",
|
|
47
|
-
"summary": "Exports the shared internal json-rest-api host token and resource registration helpers, including server-only row policies."
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
"containerTokens": {
|
|
51
|
-
"server": [
|
|
52
|
-
"internal.json-rest-api"
|
|
53
|
-
],
|
|
54
|
-
"client": []
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
"mutations": {
|
|
59
|
-
"dependencies": {
|
|
60
|
-
"runtime": {},
|
|
61
|
-
"dev": {}
|
|
62
|
-
},
|
|
63
|
-
"packageJson": {
|
|
64
|
-
"scripts": {}
|
|
65
|
-
},
|
|
66
|
-
"procfile": {},
|
|
67
|
-
"files": [],
|
|
68
|
-
"text": []
|
|
69
|
-
}
|
|
13
|
+
"json-rest-api": "^1.0.27",
|
|
14
|
+
"@jskit-ai/kernel": "0.1.147"
|
|
70
15
|
}
|
|
71
16
|
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
normalizeRecordId,
|
|
12
12
|
normalizeUniqueTextList
|
|
13
13
|
} from "@jskit-ai/kernel/shared/support/normalize";
|
|
14
|
-
import { resolveCrudResourceScopeName } from "@jskit-ai/
|
|
14
|
+
import { resolveCrudResourceScopeName } from "@jskit-ai/kernel/shared/support/crudLookup";
|
|
15
15
|
import {
|
|
16
16
|
normalizeJsonApiFieldList,
|
|
17
17
|
normalizeJsonApiFieldsets
|
|
@@ -108,6 +108,38 @@ function cloneJsonRestResourceValue(value, { writeSerializers = {} } = {}) {
|
|
|
108
108
|
return next;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
function applyJsonRestStorageColumns(scopeOptions = {}) {
|
|
112
|
+
const schema = normalizeJsonRestObject(scopeOptions.schema);
|
|
113
|
+
for (const [fieldName, fieldDefinition] of Object.entries(schema)) {
|
|
114
|
+
if (!isPlainJsonRestObject(fieldDefinition)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const actualField = normalizeJsonRestText(fieldDefinition.actualField);
|
|
119
|
+
if (!actualField) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const storage = normalizeJsonRestObject(fieldDefinition.storage);
|
|
124
|
+
const storageColumn = normalizeJsonRestText(storage.column);
|
|
125
|
+
if (storage.virtual === true) {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`json-rest-api schema field "${fieldName}" cannot define actualField when storage.virtual is true.`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
if (storageColumn && storageColumn !== actualField) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`json-rest-api schema field "${fieldName}" actualField and storage.column must match.`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fieldDefinition.storage = {
|
|
137
|
+
...storage,
|
|
138
|
+
column: actualField
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
111
143
|
function resolveCanonicalCalendarDate(value) {
|
|
112
144
|
if (value instanceof Date) {
|
|
113
145
|
return Number.isNaN(value.getTime())
|
|
@@ -677,6 +709,7 @@ function createJsonRestResourceScopeOptions(
|
|
|
677
709
|
const scopeOptions = cloneJsonRestResourceValue(resource, {
|
|
678
710
|
writeSerializers: normalizeJsonRestObject(writeSerializers)
|
|
679
711
|
});
|
|
712
|
+
applyJsonRestStorageColumns(scopeOptions);
|
|
680
713
|
applyJsonRestCalendarDateWriteSerializers(scopeOptions);
|
|
681
714
|
if (isPlainJsonRestObject(searchSchema)) {
|
|
682
715
|
scopeOptions.searchSchema = {
|
|
@@ -32,7 +32,7 @@ test("package exports include explicit server jsonRestApiHost entrypoint only",
|
|
|
32
32
|
assert.equal(packageJson.dependencies?.["json-rest-api"], "^1.0.27");
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
test("server jsonRestApiHost entrypoint
|
|
35
|
+
test("server jsonRestApiHost entrypoint no longer exports host-side JSON:API simplification helpers", async () => {
|
|
36
36
|
const hostModule = await import("../src/server/jsonRestApiHost.js");
|
|
37
37
|
assert.equal(Object.hasOwn(hostModule, "simplifyJsonApiDocument"), false);
|
|
38
38
|
});
|
|
@@ -460,6 +460,48 @@ test("createJsonRestResourceScopeOptions clones canonical resource metadata and
|
|
|
460
460
|
assert.equal(source.schema.createdAt.indexed, undefined);
|
|
461
461
|
});
|
|
462
462
|
|
|
463
|
+
test("createJsonRestResourceScopeOptions maps resource actualField values to storage columns", () => {
|
|
464
|
+
const resource = Object.freeze({
|
|
465
|
+
namespace: "products",
|
|
466
|
+
schema: Object.freeze({
|
|
467
|
+
price1: Object.freeze({ type: "number", actualField: "price_1" }),
|
|
468
|
+
price2: Object.freeze({
|
|
469
|
+
type: "number",
|
|
470
|
+
actualField: "price_2",
|
|
471
|
+
storage: Object.freeze({ writeSerializer: "decimal" })
|
|
472
|
+
})
|
|
473
|
+
}),
|
|
474
|
+
searchSchema: Object.freeze({
|
|
475
|
+
minimumPrice: Object.freeze({ type: "number", actualField: "price_1", filterOperator: ">=" })
|
|
476
|
+
})
|
|
477
|
+
});
|
|
478
|
+
const decimalSerializer = (value) => value;
|
|
479
|
+
|
|
480
|
+
const result = createJsonRestResourceScopeOptions(resource, {
|
|
481
|
+
writeSerializers: { decimal: decimalSerializer }
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
assert.equal(result.schema.price1.storage.column, "price_1");
|
|
485
|
+
assert.equal(result.schema.price2.storage.column, "price_2");
|
|
486
|
+
assert.equal(result.schema.price2.storage.serialize, decimalSerializer);
|
|
487
|
+
assert.equal(result.searchSchema.minimumPrice.actualField, "price_1");
|
|
488
|
+
assert.equal(result.searchSchema.minimumPrice.storage, undefined);
|
|
489
|
+
assert.equal(resource.schema.price1.storage, undefined);
|
|
490
|
+
|
|
491
|
+
assert.throws(
|
|
492
|
+
() => createJsonRestResourceScopeOptions({
|
|
493
|
+
schema: {
|
|
494
|
+
price1: {
|
|
495
|
+
type: "number",
|
|
496
|
+
actualField: "price_1",
|
|
497
|
+
storage: { column: "price1" }
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}),
|
|
501
|
+
/actualField and storage\.column must match/
|
|
502
|
+
);
|
|
503
|
+
});
|
|
504
|
+
|
|
463
505
|
test("createJsonRestResourceScopeOptions maps server query projections into json-rest-api queryFields", () => {
|
|
464
506
|
const select = ({ knex }) => knex.raw("1");
|
|
465
507
|
const resource = {
|