@jskit-ai/http-web 0.1.80 → 0.1.81
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/http-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.81",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test --test-concurrency=1"
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"./client/support/contractGuards": "./src/client/support/contractGuards.js"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
47
|
+
"@jskit-ai/resource-crud-core": "0.1.178",
|
|
48
48
|
"@mdi/js": "^7.4.47"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
52
|
-
"@jskit-ai/kernel": "0.1.
|
|
53
|
-
"@jskit-ai/realtime": "0.1.
|
|
54
|
-
"@jskit-ai/shell-web": "0.1.
|
|
51
|
+
"@jskit-ai/http-runtime": "0.1.234",
|
|
52
|
+
"@jskit-ai/kernel": "0.1.236",
|
|
53
|
+
"@jskit-ai/realtime": "0.1.233",
|
|
54
|
+
"@jskit-ai/shell-web": "0.1.240",
|
|
55
55
|
"@tanstack/vue-query": "^5.90.5",
|
|
56
56
|
"vue": "^3.5.13",
|
|
57
57
|
"vue-router": "^5.0.4",
|
|
@@ -2,6 +2,7 @@ import { computed, proxyRefs, ref, unref } from "vue";
|
|
|
2
2
|
import { useRouter } from "vue-router";
|
|
3
3
|
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
4
|
import { resolveCrudJsonApiTransport } from "./crud/crudJsonApiTransportSupport.js";
|
|
5
|
+
import { resolveCrudHttpClient } from "./crud/crudHttpClientSupport.js";
|
|
5
6
|
import { toQueryErrorMessage } from "./support/errorMessageHelpers.js";
|
|
6
7
|
import { useCommand } from "./useCommand.js";
|
|
7
8
|
|
|
@@ -86,7 +87,7 @@ function useCrudDeleteAction({
|
|
|
86
87
|
access,
|
|
87
88
|
apiSuffix: deleteApiSuffix,
|
|
88
89
|
writeMethod: deleteOperation.method,
|
|
89
|
-
client,
|
|
90
|
+
client: resolveCrudHttpClient(resource, { client }),
|
|
90
91
|
transport: resolveCrudJsonApiTransport(undefined, resource, {
|
|
91
92
|
mode: "delete"
|
|
92
93
|
}),
|
|
@@ -4,6 +4,7 @@ import { QueryClient, VueQueryPlugin } from "@tanstack/vue-query";
|
|
|
4
4
|
import { createSSRApp, h, nextTick, ref } from "vue";
|
|
5
5
|
import { renderToString } from "vue/server-renderer";
|
|
6
6
|
import { createMemoryHistory, createRouter } from "vue-router";
|
|
7
|
+
import { configureHttpWebClient, resetHttpWebClientForTests } from "../src/client/lib/httpClient.js";
|
|
7
8
|
import {
|
|
8
9
|
requireCrudDeleteOperation,
|
|
9
10
|
useCrudDeleteAction
|
|
@@ -43,7 +44,7 @@ function createScreen() {
|
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
async function renderDeleteAction({ client, queryClient = new QueryClient() } = {}) {
|
|
47
|
+
async function renderDeleteAction({ client, resource = deleteResource, queryClient = new QueryClient() } = {}) {
|
|
47
48
|
const router = createTestRouter();
|
|
48
49
|
await router.push("/notes/42");
|
|
49
50
|
await router.isReady();
|
|
@@ -53,7 +54,7 @@ async function renderDeleteAction({ client, queryClient = new QueryClient() } =
|
|
|
53
54
|
setup() {
|
|
54
55
|
deleteAction = useCrudDeleteAction({
|
|
55
56
|
screen: createScreen(),
|
|
56
|
-
resource
|
|
57
|
+
resource,
|
|
57
58
|
resourceNamespace: "notes",
|
|
58
59
|
apiUrlTemplate: "/notes/:noteId",
|
|
59
60
|
client
|
|
@@ -127,6 +128,74 @@ test("useCrudDeleteAction keeps the record dialog open with useful error feedbac
|
|
|
127
128
|
assert.equal(router.currentRoute.value.path, "/notes/42");
|
|
128
129
|
});
|
|
129
130
|
|
|
131
|
+
test("public deletion resolves the configured client without session CSRF", async (t) => {
|
|
132
|
+
t.after(resetHttpWebClientForTests);
|
|
133
|
+
const requests = [];
|
|
134
|
+
configureHttpWebClient({
|
|
135
|
+
async request(path, options) {
|
|
136
|
+
requests.push({ path, options });
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
const { deleteAction, router } = await renderDeleteAction({
|
|
141
|
+
resource: { ...deleteResource, apiAccess: "public" }
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
deleteAction.request();
|
|
145
|
+
await deleteAction.confirm();
|
|
146
|
+
|
|
147
|
+
assert.equal(requests.length, 1);
|
|
148
|
+
assert.match(requests[0].path, /\/notes\/42$/);
|
|
149
|
+
assert.equal(requests[0].options.method, "DELETE");
|
|
150
|
+
assert.equal(requests[0].options.csrf, false);
|
|
151
|
+
assert.equal(router.currentRoute.value.path, "/notes");
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test("authenticated deletion retains configured-client CSRF behavior", async (t) => {
|
|
155
|
+
t.after(resetHttpWebClientForTests);
|
|
156
|
+
const requests = [];
|
|
157
|
+
configureHttpWebClient({
|
|
158
|
+
async request(path, options) {
|
|
159
|
+
requests.push({ path, options });
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
const { deleteAction } = await renderDeleteAction();
|
|
164
|
+
|
|
165
|
+
deleteAction.request();
|
|
166
|
+
await deleteAction.confirm();
|
|
167
|
+
|
|
168
|
+
assert.equal(requests.length, 1);
|
|
169
|
+
assert.equal(requests[0].options.method, "DELETE");
|
|
170
|
+
assert.equal(Object.hasOwn(requests[0].options, "csrf"), false);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("public deletion honors an explicit client override", async (t) => {
|
|
174
|
+
t.after(resetHttpWebClientForTests);
|
|
175
|
+
configureHttpWebClient({
|
|
176
|
+
request() {
|
|
177
|
+
assert.fail("The configured client must not replace the explicit override.");
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
const requests = [];
|
|
181
|
+
const { deleteAction } = await renderDeleteAction({
|
|
182
|
+
resource: { ...deleteResource, apiAccess: "public" },
|
|
183
|
+
client: {
|
|
184
|
+
async request(path, options) {
|
|
185
|
+
requests.push({ path, options });
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
deleteAction.request();
|
|
192
|
+
await deleteAction.confirm();
|
|
193
|
+
|
|
194
|
+
assert.equal(requests.length, 1);
|
|
195
|
+
assert.equal(requests[0].options.method, "DELETE");
|
|
196
|
+
assert.equal(requests[0].options.csrf, false);
|
|
197
|
+
});
|
|
198
|
+
|
|
130
199
|
test("useCrudDeleteAction rejects resources without the canonical DELETE operation", () => {
|
|
131
200
|
assert.throws(
|
|
132
201
|
() => requireCrudDeleteOperation({ operations: {} }),
|