@jskit-ai/json-rest-api-core 0.1.63 → 0.1.65

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.
@@ -1,9 +1,9 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/json-rest-api-core",
4
- version: "0.1.63",
4
+ version: "0.1.65",
5
5
  kind: "runtime",
6
- description: "Shared internal json-rest-api host runtime for JSKIT server packages.",
6
+ description: "Shared internal json-rest-api host runtime with autofilter, query-projection, and row-policy support.",
7
7
  dependsOn: [
8
8
  "@jskit-ai/database-runtime",
9
9
  "@jskit-ai/kernel"
@@ -34,7 +34,7 @@ export default Object.freeze({
34
34
  surfaces: [
35
35
  {
36
36
  subpath: "./server",
37
- summary: "Exports the shared internal json-rest-api host token and host registration helpers."
37
+ summary: "Exports the shared internal json-rest-api host token and resource registration helpers, including server-only row policies."
38
38
  }
39
39
  ],
40
40
  containerTokens: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/json-rest-api-core",
3
- "version": "0.1.63",
3
+ "version": "0.1.65",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "hooked-api": "1.x.x",
13
- "json-rest-api": "1.x.x",
14
- "@jskit-ai/kernel": "0.1.120"
13
+ "json-rest-api": "^1.0.25",
14
+ "@jskit-ai/kernel": "0.1.121"
15
15
  }
16
16
  }
@@ -1,5 +1,11 @@
1
1
  import { Api } from "hooked-api";
2
- import { AutoFilterPlugin, QueryProjectionsPlugin, RestApiKnexPlugin, RestApiPlugin } from "json-rest-api";
2
+ import {
3
+ AutoFilterPlugin,
4
+ QueryProjectionsPlugin,
5
+ RestApiKnexPlugin,
6
+ RestApiPlugin,
7
+ RowPolicyPlugin
8
+ } from "json-rest-api";
3
9
  import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
4
10
  import { resolveCrudResourceScopeName } from "@jskit-ai/kernel/shared/support/crudLookup";
5
11
 
@@ -464,6 +470,7 @@ function createJsonRestResourceScopeOptions(
464
470
  {
465
471
  writeSerializers = {},
466
472
  normalizeId = null,
473
+ rowPolicy = undefined,
467
474
  searchSchema = null,
468
475
  queryFields = null
469
476
  } = {}
@@ -499,6 +506,9 @@ function createJsonRestResourceScopeOptions(
499
506
  if (typeof normalizeId === "function") {
500
507
  scopeOptions.normalizeId = normalizeId;
501
508
  }
509
+ if (rowPolicy !== undefined) {
510
+ scopeOptions.rowPolicy = rowPolicy;
511
+ }
502
512
 
503
513
  return scopeOptions;
504
514
  }
@@ -591,6 +601,7 @@ async function createJsonRestApiHost({ knex }) {
591
601
 
592
602
  await api.use(QueryProjectionsPlugin);
593
603
  await api.use(RestApiKnexPlugin, { knex });
604
+ await api.use(RowPolicyPlugin);
594
605
  await api.use(AutoFilterPlugin, {
595
606
  resolvers: {
596
607
  workspace: ({ context }) => resolveWorkspaceScopeValue(context),
@@ -26,6 +26,7 @@ test("package exports include explicit server jsonRestApiHost entrypoint only",
26
26
  const exportsMap = packageJson && typeof packageJson === "object" ? packageJson.exports : {};
27
27
  assert.equal(exportsMap["./server/jsonRestApiHost"], "./src/server/jsonRestApiHost.js");
28
28
  assert.equal(exportsMap["./server"], undefined);
29
+ assert.equal(packageJson.dependencies?.["json-rest-api"], "^1.0.25");
29
30
  });
30
31
 
31
32
  test("server jsonRestApiHost entrypoint no longer exports host-side JSON:API simplification helpers", async () => {
@@ -157,6 +158,46 @@ test("createJsonRestApiHost configures the internal json-rest logger at error le
157
158
  assert.equal(api.options.logging.level, "error");
158
159
  });
159
160
 
161
+ test("createJsonRestApiHost installs row policies before resources are added", async () => {
162
+ const fakeKnex = Object.assign(() => {}, {
163
+ client: {
164
+ config: {
165
+ client: "sqlite3"
166
+ }
167
+ },
168
+ async raw() {
169
+ return [
170
+ {
171
+ version: "3.35.5"
172
+ }
173
+ ];
174
+ },
175
+ transaction() {}
176
+ });
177
+
178
+ const api = await createJsonRestApiHost({ knex: fakeKnex });
179
+ const rowPolicy = () => false;
180
+ const scopeOptions = createJsonRestResourceScopeOptions({
181
+ tableName: "private_contacts",
182
+ schema: {
183
+ id: { type: "id", primary: true }
184
+ }
185
+ }, {
186
+ rowPolicy
187
+ });
188
+
189
+ await api.addResource("privateContacts", scopeOptions);
190
+
191
+ assert.deepEqual(api.rowPolicies.getConfig(), {
192
+ policies: []
193
+ });
194
+ assert.deepEqual(api.rowPolicies.getScopeConfig("privateContacts"), {
195
+ policy: "<inline>",
196
+ source: "inline"
197
+ });
198
+ assert.equal(scopeOptions.rowPolicy, rowPolicy);
199
+ });
200
+
160
201
  test("shared query/document helpers build json-rest-api request shapes", () => {
161
202
  assert.deepEqual(
162
203
  buildJsonRestQueryParams("contacts", {
@@ -284,6 +325,7 @@ test("buildJsonRestQueryParams preserves structured filter values", () => {
284
325
  test("createJsonRestResourceScopeOptions clones canonical resource metadata and resolves symbolic write serializers", () => {
285
326
  const serializer = (value) => value;
286
327
  const normalizeId = (value) => String(value || "").trim() || null;
328
+ const rowPolicy = () => false;
287
329
  const source = Object.freeze({
288
330
  namespace: "contacts",
289
331
  tableName: "contacts",
@@ -353,6 +395,7 @@ test("createJsonRestResourceScopeOptions clones canonical resource metadata and
353
395
 
354
396
  const result = createJsonRestResourceScopeOptions(source, {
355
397
  normalizeId,
398
+ rowPolicy,
356
399
  writeSerializers: {
357
400
  "datetime-utc": serializer
358
401
  }
@@ -368,6 +411,7 @@ test("createJsonRestResourceScopeOptions clones canonical resource metadata and
368
411
  assert.equal(result.schema.bookingSteps.virtual, true);
369
412
  assert.equal(result.schema.pets.virtual, true);
370
413
  assert.equal(result.normalizeId, normalizeId);
414
+ assert.equal(result.rowPolicy, rowPolicy);
371
415
  assert.equal(result.schema.name.maxLength, 190);
372
416
  assert.equal(result.schema.name.operations.output.required, true);
373
417
  assert.equal(result.operations.view.method, "GET");