@jskit-ai/users-web 0.1.65 → 0.1.67

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.
@@ -3,7 +3,7 @@ import { HOME_TOOLS_OUTLET } from "./src/shared/toolsOutletContracts.js";
3
3
  export default Object.freeze({
4
4
  packageVersion: 1,
5
5
  packageId: "@jskit-ai/users-web",
6
- version: "0.1.65",
6
+ version: "0.1.67",
7
7
  kind: "runtime",
8
8
  description: "Users web module: account/profile UI plus shared users web widgets.",
9
9
  dependsOn: [
@@ -154,12 +154,12 @@ export default Object.freeze({
154
154
  runtime: {
155
155
  "@tanstack/vue-query": "5.92.12",
156
156
  "@mdi/js": "^7.4.47",
157
- "@jskit-ai/http-runtime": "0.1.49",
158
- "@jskit-ai/realtime": "0.1.49",
159
- "@jskit-ai/kernel": "0.1.50",
160
- "@jskit-ai/shell-web": "0.1.49",
161
- "@jskit-ai/uploads-image-web": "0.1.28",
162
- "@jskit-ai/users-core": "0.1.60",
157
+ "@jskit-ai/http-runtime": "0.1.51",
158
+ "@jskit-ai/realtime": "0.1.51",
159
+ "@jskit-ai/kernel": "0.1.52",
160
+ "@jskit-ai/shell-web": "0.1.51",
161
+ "@jskit-ai/uploads-image-web": "0.1.30",
162
+ "@jskit-ai/users-core": "0.1.62",
163
163
  vuetify: "^4.0.0"
164
164
  },
165
165
  dev: {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/users-web",
3
- "version": "0.1.65",
3
+ "version": "0.1.67",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -35,12 +35,12 @@
35
35
  "dependencies": {
36
36
  "@tanstack/vue-query": "5.92.12",
37
37
  "@mdi/js": "^7.4.47",
38
- "@jskit-ai/http-runtime": "0.1.49",
39
- "@jskit-ai/kernel": "0.1.50",
40
- "@jskit-ai/realtime": "0.1.49",
41
- "@jskit-ai/shell-web": "0.1.49",
42
- "@jskit-ai/uploads-image-web": "0.1.28",
43
- "@jskit-ai/users-core": "0.1.60",
38
+ "@jskit-ai/http-runtime": "0.1.51",
39
+ "@jskit-ai/kernel": "0.1.52",
40
+ "@jskit-ai/realtime": "0.1.51",
41
+ "@jskit-ai/shell-web": "0.1.51",
42
+ "@jskit-ai/uploads-image-web": "0.1.30",
43
+ "@jskit-ai/users-core": "0.1.62",
44
44
  "vuetify": "^4.0.0"
45
45
  }
46
46
  }
@@ -6,6 +6,12 @@ import { useEndpointResource } from "../runtime/useEndpointResource.js";
6
6
  import { resolveOperationAdapter } from "../runtime/operationAdapters.js";
7
7
  import { setupOperationErrorReporting } from "../runtime/operationUiHelpers.js";
8
8
  import { createViewUiRuntime } from "../runtime/viewUiRuntime.js";
9
+ import {
10
+ resolveQueryParamDescriptors,
11
+ resolveActiveQueryParamEntries,
12
+ buildQueryParamEntriesToken
13
+ } from "../support/listQueryParamSupport.js";
14
+ import { appendRequestQueryEntriesToPath } from "../support/requestQueryPathSupport.js";
9
15
  import { resolveRouteParamNamesInOrder } from "../support/routeTemplateHelpers.js";
10
16
 
11
17
  function useView({
@@ -23,6 +29,7 @@ function useView({
23
29
  notFoundMessage = "Record not found.",
24
30
  model,
25
31
  mapLoadedToModel,
32
+ requestQueryParams = null,
26
33
  recordIdParam = "recordId",
27
34
  routeParams = null,
28
35
  routeRecordId = null,
@@ -62,20 +69,46 @@ function useView({
62
69
  },
63
70
  realtime
64
71
  });
72
+ const queryParamsContext = computed(() => {
73
+ return Object.freeze({
74
+ surfaceId: operationScope.routeContext.currentSurfaceId.value,
75
+ scopeParamValue: operationScope.scopeParamValue.value,
76
+ ownershipFilter: operationScope.normalizedOwnershipFilter
77
+ });
78
+ });
79
+ const requestQueryParamDescriptors = computed(() => {
80
+ return resolveQueryParamDescriptors(requestQueryParams, queryParamsContext.value);
81
+ });
82
+ const activeRequestQueryParamEntries = computed(() => {
83
+ return resolveActiveQueryParamEntries(requestQueryParamDescriptors.value);
84
+ });
85
+ const activeRequestQueryParamsToken = computed(() => {
86
+ return buildQueryParamEntriesToken(activeRequestQueryParamEntries.value);
87
+ });
65
88
  const queryKey = computed(() => {
66
89
  const source = Array.isArray(operationScope.queryKey.value) ? operationScope.queryKey.value : [];
90
+ const next = [...source];
91
+ if (activeRequestQueryParamsToken.value) {
92
+ next.push("__request_query__", activeRequestQueryParamsToken.value);
93
+ }
67
94
  if (!includeRecordIdInQueryKey) {
68
- return source;
95
+ return next;
69
96
  }
70
97
 
71
98
  const recordIdToken = String(viewUiRuntime.recordId.value || "").trim();
72
- return [...source, recordIdToken];
99
+ return [...next, recordIdToken];
100
+ });
101
+ const requestPath = computed(() => {
102
+ return appendRequestQueryEntriesToPath(
103
+ operationScope.apiPath.value,
104
+ activeRequestQueryParamEntries.value
105
+ );
73
106
  });
74
107
  const canView = operationScope.permissionGate("view");
75
108
 
76
109
  const resource = useEndpointResource({
77
110
  queryKey,
78
- path: operationScope.apiPath,
111
+ path: requestPath,
79
112
  enabled: operationScope.queryCanRun(canView),
80
113
  readMethod,
81
114
  fallbackLoadError
@@ -0,0 +1,31 @@
1
+ import { appendQueryString } from "@jskit-ai/kernel/shared/support";
2
+
3
+ function appendRequestQueryEntriesToPath(path = "", entries = []) {
4
+ const normalizedPath = String(path || "").trim();
5
+ if (!normalizedPath) {
6
+ return "";
7
+ }
8
+
9
+ const sourceEntries = Array.isArray(entries) ? entries : [];
10
+ const searchParams = new URLSearchParams();
11
+ for (const entry of sourceEntries) {
12
+ const key = String(entry?.key || "").trim();
13
+ const values = Array.isArray(entry?.values) ? entry.values : [];
14
+ if (!key || values.length < 1) {
15
+ continue;
16
+ }
17
+
18
+ for (const value of values) {
19
+ searchParams.append(key, value);
20
+ }
21
+ }
22
+
23
+ const serializedSearch = searchParams.toString();
24
+ if (!serializedSearch) {
25
+ return normalizedPath;
26
+ }
27
+
28
+ return appendQueryString(normalizedPath, serializedSearch);
29
+ }
30
+
31
+ export { appendRequestQueryEntriesToPath };
@@ -0,0 +1,20 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { appendRequestQueryEntriesToPath } from "../src/client/composables/support/requestQueryPathSupport.js";
4
+
5
+ test("appendRequestQueryEntriesToPath appends request query params deterministically", () => {
6
+ assert.equal(
7
+ appendRequestQueryEntriesToPath("/api/w/dev-admin/contacts/1", [
8
+ { key: "include", values: ["vetId", "linkedUserId", "pets", "pets.breedId"] },
9
+ { key: "limit", values: ["10"] }
10
+ ]),
11
+ "/api/w/dev-admin/contacts/1?include=vetId&include=linkedUserId&include=pets&include=pets.breedId&limit=10"
12
+ );
13
+ });
14
+
15
+ test("appendRequestQueryEntriesToPath leaves the base path unchanged when no request params are active", () => {
16
+ assert.equal(
17
+ appendRequestQueryEntriesToPath("/api/w/dev-admin/contacts/1", []),
18
+ "/api/w/dev-admin/contacts/1"
19
+ );
20
+ });