@jskit-ai/json-rest-api-core 0.1.104-oldline.0 → 0.1.104

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.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/json-rest-api-core",
3
- "version": "0.1.104-oldline.0",
3
+ "version": "0.1.104",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -9,8 +9,45 @@
9
9
  "./server/jsonRestApiHost": "./src/server/jsonRestApiHost.js"
10
10
  },
11
11
  "dependencies": {
12
+ "@jskit-ai/database-runtime": "0.1.160",
13
+ "@jskit-ai/kernel": "0.1.160",
14
+ "@jskit-ai/resource-crud-core": "0.1.102",
12
15
  "hooked-api": "1.x.x",
13
- "json-rest-api": "^1.0.27",
14
- "@jskit-ai/kernel": "0.1.147"
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
+ "runtime.json-rest-api"
24
+ ],
25
+ "requires": [
26
+ "runtime.database"
27
+ ]
28
+ },
29
+ "runtime": {
30
+ "server": {
31
+ "providers": [
32
+ {
33
+ "entrypoint": "src/server/JsonRestApiProvider.js",
34
+ "export": "JsonRestApiProvider"
35
+ }
36
+ ]
37
+ },
38
+ "client": {
39
+ "providers": []
40
+ }
41
+ },
42
+ "metadata": {
43
+ "apiSummary": {
44
+ "surfaces": [
45
+ {
46
+ "subpath": "./server",
47
+ "summary": "Provides runtime.json-rest-api and exports focused resource/query helpers, including server-only row policies."
48
+ }
49
+ ]
50
+ }
51
+ }
15
52
  }
16
53
  }
@@ -0,0 +1,19 @@
1
+ import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
2
+ import { createJsonRestApiHost } from "./jsonRestApiHost.js";
3
+
4
+ const JsonRestApiProvider = defineProvider({
5
+ id: "runtime.json-rest-api",
6
+ requires: {
7
+ database: "runtime.database"
8
+ },
9
+ provides: {
10
+ jsonRestApi: "runtime.json-rest-api"
11
+ },
12
+ async setup({ database }) {
13
+ return {
14
+ jsonRestApi: await createJsonRestApiHost({ knex: database.knex })
15
+ };
16
+ }
17
+ });
18
+
19
+ export { JsonRestApiProvider };
@@ -11,15 +11,13 @@ import {
11
11
  normalizeRecordId,
12
12
  normalizeUniqueTextList
13
13
  } from "@jskit-ai/kernel/shared/support/normalize";
14
- import { resolveCrudResourceScopeName } from "@jskit-ai/kernel/shared/support/crudLookup";
14
+ import { resolveCrudResourceScopeName } from "@jskit-ai/resource-crud-core/shared/crudLookup";
15
15
  import {
16
16
  normalizeJsonApiFieldList,
17
17
  normalizeJsonApiFieldsets
18
18
  } from "@jskit-ai/kernel/shared/support/jsonApiFieldsets";
19
19
  import { AppError } from "@jskit-ai/kernel/server/runtime/errors";
20
20
 
21
- const INTERNAL_JSON_REST_API = "internal.json-rest-api";
22
-
23
21
  const JSON_REST_AUTOFILTER_PRESETS = Object.freeze({
24
22
  public: Object.freeze([]),
25
23
  workspace: Object.freeze([
@@ -108,38 +106,6 @@ function cloneJsonRestResourceValue(value, { writeSerializers = {} } = {}) {
108
106
  return next;
109
107
  }
110
108
 
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
-
143
109
  function resolveCanonicalCalendarDate(value) {
144
110
  if (value instanceof Date) {
145
111
  return Number.isNaN(value.getTime())
@@ -709,7 +675,6 @@ function createJsonRestResourceScopeOptions(
709
675
  const scopeOptions = cloneJsonRestResourceValue(resource, {
710
676
  writeSerializers: normalizeJsonRestObject(writeSerializers)
711
677
  });
712
- applyJsonRestStorageColumns(scopeOptions);
713
678
  applyJsonRestCalendarDateWriteSerializers(scopeOptions);
714
679
  if (isPlainJsonRestObject(searchSchema)) {
715
680
  scopeOptions.searchSchema = {
@@ -870,23 +835,7 @@ async function createJsonRestApiHost({ knex }) {
870
835
  return api;
871
836
  }
872
837
 
873
- async function registerJsonRestApiHost(app) {
874
- if (!app || typeof app.instance !== "function" || typeof app.make !== "function" || typeof app.has !== "function") {
875
- throw new Error("registerJsonRestApiHost requires application instance()/make()/has().");
876
- }
877
-
878
- if (app.has(INTERNAL_JSON_REST_API)) {
879
- return app.make(INTERNAL_JSON_REST_API);
880
- }
881
-
882
- const knex = app.make("jskit.database.knex");
883
- const api = await createJsonRestApiHost({ knex });
884
- app.instance(INTERNAL_JSON_REST_API, api);
885
- return api;
886
- }
887
-
888
838
  export {
889
- INTERNAL_JSON_REST_API,
890
839
  JSON_REST_AUTOFILTER_PRESETS,
891
840
  addResourceIfMissing,
892
841
  buildJsonRestQueryParams,
@@ -900,6 +849,5 @@ export {
900
849
  returnBadRequestWhenJsonRestFieldsetInvalid,
901
850
  resolveWorkspaceScopeValue,
902
851
  resolveUserScopeValue,
903
- createJsonRestApiHost,
904
- registerJsonRestApiHost
852
+ createJsonRestApiHost
905
853
  };
@@ -6,7 +6,6 @@ import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
6
6
  import { RestApiFieldsetError } from "json-rest-api";
7
7
 
8
8
  import {
9
- INTERNAL_JSON_REST_API,
10
9
  addResourceIfMissing,
11
10
  buildJsonRestQueryParams,
12
11
  createJsonApiInputRecord,
@@ -16,13 +15,12 @@ import {
16
15
  createJsonRestApiHost,
17
16
  extractJsonRestCollectionRows,
18
17
  isJsonRestResourceMissingError,
19
- registerJsonRestApiHost,
20
18
  returnNullWhenJsonRestResourceMissing,
21
19
  returnBadRequestWhenJsonRestFieldsetInvalid,
22
20
  resolveWorkspaceScopeValue,
23
21
  resolveUserScopeValue
24
22
  } from "../src/server/jsonRestApiHost.js";
25
- import { JsonRestApiCoreServiceProvider } from "../src/server/JsonRestApiCoreServiceProvider.js";
23
+ import { JsonRestApiProvider } from "../src/server/JsonRestApiProvider.js";
26
24
 
27
25
  test("package exports include explicit server jsonRestApiHost entrypoint only", async () => {
28
26
  const packageJson = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
@@ -32,13 +30,12 @@ test("package exports include explicit server jsonRestApiHost entrypoint only",
32
30
  assert.equal(packageJson.dependencies?.["json-rest-api"], "^1.0.27");
33
31
  });
34
32
 
35
- test("server jsonRestApiHost entrypoint no longer exports host-side JSON:API simplification helpers", async () => {
33
+ test("server jsonRestApiHost entrypoint exposes only the focused host API", async () => {
36
34
  const hostModule = await import("../src/server/jsonRestApiHost.js");
37
35
  assert.equal(Object.hasOwn(hostModule, "simplifyJsonApiDocument"), false);
38
36
  });
39
37
 
40
38
  test("server entrypoint exports shared host helpers", () => {
41
- assert.equal(INTERNAL_JSON_REST_API, "internal.json-rest-api");
42
39
  assert.equal(typeof addResourceIfMissing, "function");
43
40
  assert.equal(typeof buildJsonRestQueryParams, "function");
44
41
  assert.equal(typeof createJsonApiInputRecord, "function");
@@ -48,12 +45,13 @@ test("server entrypoint exports shared host helpers", () => {
48
45
  assert.equal(typeof createJsonRestApiHost, "function");
49
46
  assert.equal(typeof extractJsonRestCollectionRows, "function");
50
47
  assert.equal(typeof isJsonRestResourceMissingError, "function");
51
- assert.equal(typeof registerJsonRestApiHost, "function");
52
48
  assert.equal(typeof returnNullWhenJsonRestResourceMissing, "function");
53
49
  assert.equal(typeof returnBadRequestWhenJsonRestFieldsetInvalid, "function");
54
50
  assert.equal(typeof resolveWorkspaceScopeValue, "function");
55
51
  assert.equal(typeof resolveUserScopeValue, "function");
56
- assert.equal(typeof JsonRestApiCoreServiceProvider, "function");
52
+ assert.equal(JsonRestApiProvider.id, "runtime.json-rest-api");
53
+ assert.deepEqual(JsonRestApiProvider.requires, { database: "runtime.database" });
54
+ assert.deepEqual(JsonRestApiProvider.provides, { jsonRestApi: "runtime.json-rest-api" });
57
55
  });
58
56
 
59
57
  test("createJsonRestContext returns a mutable clone for frozen JSKIT execution context", () => {
@@ -460,48 +458,6 @@ test("createJsonRestResourceScopeOptions clones canonical resource metadata and
460
458
  assert.equal(source.schema.createdAt.indexed, undefined);
461
459
  });
462
460
 
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
-
505
461
  test("createJsonRestResourceScopeOptions maps server query projections into json-rest-api queryFields", () => {
506
462
  const select = ({ knex }) => knex.raw("1");
507
463
  const resource = {
@@ -1,60 +0,0 @@
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
- });
@@ -1,13 +0,0 @@
1
- import { registerJsonRestApiHost } from "./jsonRestApiHost.js";
2
-
3
- class JsonRestApiCoreServiceProvider {
4
- static id = "json-rest-api.core";
5
-
6
- static dependsOn = ["runtime.database"];
7
-
8
- async boot(app) {
9
- await registerJsonRestApiHost(app);
10
- }
11
- }
12
-
13
- export { JsonRestApiCoreServiceProvider };