@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.102",
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
  }
@@ -3,6 +3,8 @@ import { registerJsonRestApiHost } from "./jsonRestApiHost.js";
3
3
  class JsonRestApiCoreServiceProvider {
4
4
  static id = "json-rest-api.core";
5
5
 
6
+ static dependsOn = ["runtime.database"];
7
+
6
8
  async boot(app) {
7
9
  await registerJsonRestApiHost(app);
8
10
  }
@@ -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/resource-crud-core/shared/crudLookup";
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 exposes only the focused host API", async () => {
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 = {