@jskit-ai/kernel 0.1.244 → 0.1.246
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/client/appConfig.js +2 -1
- package/client/asyncModuleRecovery.js +2 -4
- package/client/index.d.ts +18 -76
- package/client/index.js +7 -2
- package/client/logging.js +8 -2
- package/client/moduleBootstrap.js +41 -33
- package/client/moduleBootstrap.test.js +35 -0
- package/client/shellBootstrap.js +38 -10
- package/client/shellBootstrap.test.js +85 -6
- package/client/shellRouting.js +16 -61
- package/client/shellRouting.test.js +30 -1
- package/client/vite/clientBootstrapPlugin.js +0 -6
- package/client/vite/clientBootstrapPlugin.test.js +2 -3
- package/internal/node/installedPackages.js +14 -58
- package/package.json +2 -4
- package/server/actions/actionCatalogue.js +13 -34
- package/{shared → server}/actions/actionContributorHelpers.js +0 -5
- package/{shared → server}/actions/actionDefinitions.js +24 -131
- package/{shared → server}/actions/actionDefinitions.test.js +75 -21
- package/server/actions/actionEvents.js +97 -2
- package/server/actions/actionEvents.test.js +79 -0
- package/{shared → server}/actions/executionContext.js +3 -13
- package/server/actions/idempotency.js +24 -0
- package/server/actions/pipeline.js +87 -0
- package/{shared → server}/actions/policies.js +20 -33
- package/{shared → server}/actions/policies.test.js +6 -6
- package/{shared → server}/actions/registry.js +3 -22
- package/{shared → server}/actions/registry.test.js +70 -32
- package/server/actions/requestMeta.js +17 -0
- package/server/http/capabilityHttpRuntime.js +1 -1
- package/server/http/capabilityHttpRuntime.test.js +56 -0
- package/server/http/errorHandling.js +291 -0
- package/server/{runtime/fastifyBootstrap.test.js → http/errorHandling.test.js} +72 -120
- package/server/http/lib/routeRegistration.js +36 -150
- package/server/http/lib/routeTransport.js +2 -0
- package/server/http/lib/routeValidator.js +5 -47
- package/server/http/lib/routeValidator.test.js +15 -17
- package/server/http/lib/router.js +10 -94
- package/server/platform/providerRuntime/capabilityProviderLoader.js +2 -1
- package/server/platform/providerRuntime/helpers.js +1 -34
- package/server/runtime/integers.js +1 -5
- package/server/runtime/serviceAuthorization.js +4 -9
- package/server/support/appConfig.js +2 -1
- package/server/support/appConfigFiles.js +1 -38
- package/server/support/appConfigFiles.test.js +3 -39
- package/server/support/index.js +1 -20
- package/shared/capabilities/defineProvider.js +1 -1
- package/shared/capabilities/index.js +1 -1
- package/shared/index.js +1 -1
- package/shared/support/index.js +1 -4
- package/shared/support/mobileConfig.js +99 -0
- package/shared/support/mobileConfig.test.js +113 -0
- package/shared/support/normalize.js +0 -108
- package/shared/support/normalize.test.js +0 -134
- package/shared/{actions/actionContributorHelpers.test.js → support/permissions.test.js} +1 -1
- package/shared/support/returnToPath.js +16 -20
- package/shared/support/returnToPath.test.js +5 -33
- package/shared/support/shellLayoutTargets.js +2 -140
- package/shared/support/shellLayoutTargets.test.js +1 -110
- package/shared/support/sorting.js +1 -9
- package/shared/surface/apiPaths.js +1 -82
- package/shared/surface/paths.js +38 -171
- package/shared/surface/registry.js +2 -1
- package/shared/surface/runtime.js +18 -109
- package/shared/surface/runtime.test.js +57 -0
- package/shared/validators/index.js +1 -4
- package/shared/validators/jsonRestSchemaSupport.js +0 -9
- package/shared/validators/recordIdParamsValidator.js +0 -6
- package/shared/validators/schemaDefinitions.js +4 -30
- package/shared/validators/schemaPayloadValidation.js +2 -6
- package/test/barrelExposure.test.js +5 -8
- package/test/exportsContract.test.js +1 -3
- package/client/mobileLaunchRouting.js +0 -231
- package/client/mobileLaunchRouting.test.js +0 -230
- package/server/http/lib/controller.js +0 -183
- package/server/http/lib/controller.test.js +0 -143
- package/server/http/lib/index.js +0 -5
- package/server/runtime/canonicalJson.js +0 -74
- package/server/runtime/entityChangeEvents.js +0 -307
- package/server/runtime/entityChangeEvents.test.js +0 -274
- package/server/runtime/fastifyBootstrap.js +0 -553
- package/server/runtime/moduleConfig.js +0 -223
- package/server/runtime/moduleConfig.test.js +0 -165
- package/server/runtime/pagination.js +0 -13
- package/server/runtime/realtimeNormalization.js +0 -21
- package/server/runtime/routeUtils.js +0 -20
- package/server/runtime/securityAudit.js +0 -269
- package/server/runtime/securityAudit.test.js +0 -41
- package/server/support/pageTargets.js +0 -772
- package/server/support/pageTargets.test.js +0 -659
- package/server/support/shellOutlets.js +0 -576
- package/server/support/shellOutlets.test.js +0 -336
- package/server/surface/index.js +0 -18
- package/shared/actions/audit.js +0 -7
- package/shared/actions/idempotency.js +0 -62
- package/shared/actions/observability.js +0 -10
- package/shared/actions/pipeline.js +0 -309
- package/shared/actions/requestMeta.js +0 -36
- package/shared/actions/textNormalization.js +0 -3
- package/shared/actions/withActionDefaults.js +0 -34
- /package/{shared → server}/actions/executionContext.test.js +0 -0
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { tmpdir } from "node:os";
|
|
5
|
-
import test from "node:test";
|
|
6
|
-
import {
|
|
7
|
-
discoverShellOutletSourcePathsFromApp,
|
|
8
|
-
discoverShellOutletTargetsFromApp,
|
|
9
|
-
resolveShellOutletPlacementTargetFromApp
|
|
10
|
-
} from "./shellOutlets.js";
|
|
11
|
-
|
|
12
|
-
async function withTempApp(run) {
|
|
13
|
-
const appRoot = await mkdtemp(path.join(tmpdir(), "kernel-shell-outlets-"));
|
|
14
|
-
try {
|
|
15
|
-
return await run(appRoot);
|
|
16
|
-
} finally {
|
|
17
|
-
await rm(appRoot, { recursive: true, force: true });
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function writeFileInApp(appRoot, relativePath, source) {
|
|
22
|
-
const absoluteFilePath = path.join(appRoot, relativePath);
|
|
23
|
-
await mkdir(path.dirname(absoluteFilePath), { recursive: true });
|
|
24
|
-
await writeFile(absoluteFilePath, source, "utf8");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
test("resolveShellOutletPlacementTargetFromApp reads outlets across app Vue files", async () => {
|
|
28
|
-
await withTempApp(async (appRoot) => {
|
|
29
|
-
await writeFileInApp(
|
|
30
|
-
appRoot,
|
|
31
|
-
"src/components/ShellLayout.vue",
|
|
32
|
-
`<template>
|
|
33
|
-
<div>
|
|
34
|
-
<ShellOutlet target="shell-layout:primary-menu" />
|
|
35
|
-
<ShellOutlet target="shell-layout:top-right" />
|
|
36
|
-
</div>
|
|
37
|
-
</template>
|
|
38
|
-
`
|
|
39
|
-
);
|
|
40
|
-
await writeFileInApp(
|
|
41
|
-
appRoot,
|
|
42
|
-
"src/pages/admin/workspace/settings/index.vue",
|
|
43
|
-
`<template>
|
|
44
|
-
<section>
|
|
45
|
-
<ShellOutlet target="admin-settings:forms" default />
|
|
46
|
-
</section>
|
|
47
|
-
</template>
|
|
48
|
-
`
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
const target = await resolveShellOutletPlacementTargetFromApp({
|
|
52
|
-
appRoot,
|
|
53
|
-
context: "ui-generator"
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
assert.equal(target.id, "admin-settings:forms");
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("discoverShellOutletTargetsFromApp includes installed package placement outlets", async () => {
|
|
61
|
-
await withTempApp(async (appRoot) => {
|
|
62
|
-
await writeFileInApp(
|
|
63
|
-
appRoot,
|
|
64
|
-
"src/components/ShellLayout.vue",
|
|
65
|
-
`<template>
|
|
66
|
-
<div>
|
|
67
|
-
<ShellOutlet target="shell-layout:primary-menu" default />
|
|
68
|
-
</div>
|
|
69
|
-
</template>
|
|
70
|
-
`
|
|
71
|
-
);
|
|
72
|
-
await writeFileInApp(
|
|
73
|
-
appRoot,
|
|
74
|
-
"package.json",
|
|
75
|
-
`${JSON.stringify(
|
|
76
|
-
{
|
|
77
|
-
name: "fixture-app",
|
|
78
|
-
private: true,
|
|
79
|
-
dependencies: {
|
|
80
|
-
"@example/users-web": "1.0.0"
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
null,
|
|
84
|
-
2
|
|
85
|
-
)}\n`
|
|
86
|
-
);
|
|
87
|
-
await writeFileInApp(
|
|
88
|
-
appRoot,
|
|
89
|
-
"node_modules/@example/users-web/package.json",
|
|
90
|
-
`${JSON.stringify({
|
|
91
|
-
name: "@example/users-web",
|
|
92
|
-
version: "1.0.0",
|
|
93
|
-
jskit: {
|
|
94
|
-
metadata: {
|
|
95
|
-
ui: {
|
|
96
|
-
placements: {
|
|
97
|
-
outlets: [
|
|
98
|
-
{
|
|
99
|
-
target: "admin-cog:primary-menu",
|
|
100
|
-
source: "src/client/components/UsersWorkspaceToolsWidget.vue"
|
|
101
|
-
}
|
|
102
|
-
]
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}, null, 2)}\n`
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
const discovered = await discoverShellOutletTargetsFromApp({ appRoot });
|
|
111
|
-
assert.deepEqual(
|
|
112
|
-
discovered.targets.map((entry) => entry.id),
|
|
113
|
-
["admin-cog:primary-menu", "shell-layout:primary-menu"]
|
|
114
|
-
);
|
|
115
|
-
assert.deepEqual(discovered.targets[0], {
|
|
116
|
-
id: "admin-cog:primary-menu",
|
|
117
|
-
default: false,
|
|
118
|
-
sourcePath: "package:@example/users-web:src/client/components/UsersWorkspaceToolsWidget.vue",
|
|
119
|
-
sourcePackageId: "@example/users-web"
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const target = await resolveShellOutletPlacementTargetFromApp({
|
|
123
|
-
appRoot,
|
|
124
|
-
placement: "admin-cog:primary-menu",
|
|
125
|
-
context: "ui-generator"
|
|
126
|
-
});
|
|
127
|
-
assert.equal(target.id, "admin-cog:primary-menu");
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test("discoverShellOutletTargetsFromApp returns targets with sourcePath and default marker", async () => {
|
|
132
|
-
await withTempApp(async (appRoot) => {
|
|
133
|
-
await writeFileInApp(
|
|
134
|
-
appRoot,
|
|
135
|
-
"src/components/ShellLayout.vue",
|
|
136
|
-
`<template>
|
|
137
|
-
<div>
|
|
138
|
-
<ShellOutlet target="shell-layout:primary-menu" />
|
|
139
|
-
</div>
|
|
140
|
-
</template>
|
|
141
|
-
`
|
|
142
|
-
);
|
|
143
|
-
await writeFileInApp(
|
|
144
|
-
appRoot,
|
|
145
|
-
"src/pages/admin/toolbox/index.vue",
|
|
146
|
-
`<template>
|
|
147
|
-
<section>
|
|
148
|
-
<ShellOutlet target="admin-toolbox:widgets" default />
|
|
149
|
-
</section>
|
|
150
|
-
</template>
|
|
151
|
-
`
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
const discovered = await discoverShellOutletTargetsFromApp({ appRoot });
|
|
155
|
-
assert.equal(discovered.defaultTargetId, "admin-toolbox:widgets");
|
|
156
|
-
assert.deepEqual(discovered.targets, [
|
|
157
|
-
{
|
|
158
|
-
id: "admin-toolbox:widgets",
|
|
159
|
-
default: true,
|
|
160
|
-
sourcePath: "src/pages/admin/toolbox/index.vue"
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
id: "shell-layout:primary-menu",
|
|
164
|
-
default: false,
|
|
165
|
-
sourcePath: "src/components/ShellLayout.vue"
|
|
166
|
-
}
|
|
167
|
-
]);
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
test("discoverShellOutletTargetsFromApp discovers route meta placement outlets", async () => {
|
|
172
|
-
await withTempApp(async (appRoot) => {
|
|
173
|
-
await writeFileInApp(
|
|
174
|
-
appRoot,
|
|
175
|
-
"src/pages/w/[workspaceSlug]/admin/contacts/[contactId]/contact-tools.vue",
|
|
176
|
-
`<template><section /></template>
|
|
177
|
-
|
|
178
|
-
<route lang="json">
|
|
179
|
-
{
|
|
180
|
-
"meta": {
|
|
181
|
-
"jskit": {
|
|
182
|
-
"placements": {
|
|
183
|
-
"outlets": [
|
|
184
|
-
{
|
|
185
|
-
"target": "contact-tools:sub-pages"
|
|
186
|
-
}
|
|
187
|
-
]
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
</route>
|
|
193
|
-
`
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
const discovered = await discoverShellOutletTargetsFromApp({ appRoot });
|
|
197
|
-
assert.deepEqual(discovered.targets, [
|
|
198
|
-
{
|
|
199
|
-
id: "contact-tools:sub-pages",
|
|
200
|
-
default: false,
|
|
201
|
-
sourcePath: "src/pages/w/[workspaceSlug]/admin/contacts/[contactId]/contact-tools.vue"
|
|
202
|
-
}
|
|
203
|
-
]);
|
|
204
|
-
|
|
205
|
-
const target = await resolveShellOutletPlacementTargetFromApp({
|
|
206
|
-
appRoot,
|
|
207
|
-
placement: "contact-tools:sub-pages",
|
|
208
|
-
context: "ui-generator"
|
|
209
|
-
});
|
|
210
|
-
assert.equal(target.id, "contact-tools:sub-pages");
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
test("resolveShellOutletPlacementTargetFromApp supports explicit placement override", async () => {
|
|
215
|
-
await withTempApp(async (appRoot) => {
|
|
216
|
-
await writeFileInApp(
|
|
217
|
-
appRoot,
|
|
218
|
-
"src/components/ShellLayout.vue",
|
|
219
|
-
`<template>
|
|
220
|
-
<div>
|
|
221
|
-
<ShellOutlet target="shell-layout:primary-menu" default />
|
|
222
|
-
<ShellOutlet target="shell-layout:top-right" />
|
|
223
|
-
</div>
|
|
224
|
-
</template>
|
|
225
|
-
`
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
const target = await resolveShellOutletPlacementTargetFromApp({
|
|
229
|
-
appRoot,
|
|
230
|
-
context: "ui-generator",
|
|
231
|
-
placement: "shell-layout:top-right"
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
assert.equal(target.id, "shell-layout:top-right");
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test("resolveShellOutletPlacementTargetFromApp validates placement format", async () => {
|
|
239
|
-
await withTempApp(async (appRoot) => {
|
|
240
|
-
await writeFileInApp(
|
|
241
|
-
appRoot,
|
|
242
|
-
"src/components/ShellLayout.vue",
|
|
243
|
-
`<template>
|
|
244
|
-
<div>
|
|
245
|
-
<ShellOutlet target="shell-layout:primary-menu" default />
|
|
246
|
-
</div>
|
|
247
|
-
</template>
|
|
248
|
-
`
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
await assert.rejects(
|
|
252
|
-
() =>
|
|
253
|
-
resolveShellOutletPlacementTargetFromApp({
|
|
254
|
-
appRoot,
|
|
255
|
-
context: "ui-generator",
|
|
256
|
-
placement: "invalid-placement"
|
|
257
|
-
}),
|
|
258
|
-
/option "placement" must be a target in "host:position" format/
|
|
259
|
-
);
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
test("resolveShellOutletPlacementTargetFromApp throws when multiple default outlets exist", async () => {
|
|
264
|
-
await withTempApp(async (appRoot) => {
|
|
265
|
-
await writeFileInApp(
|
|
266
|
-
appRoot,
|
|
267
|
-
"src/components/ShellLayout.vue",
|
|
268
|
-
`<template>
|
|
269
|
-
<div>
|
|
270
|
-
<ShellOutlet target="shell-layout:primary-menu" default />
|
|
271
|
-
</div>
|
|
272
|
-
</template>
|
|
273
|
-
`
|
|
274
|
-
);
|
|
275
|
-
await writeFileInApp(
|
|
276
|
-
appRoot,
|
|
277
|
-
"src/pages/admin/workspace/settings/index.vue",
|
|
278
|
-
`<template>
|
|
279
|
-
<section>
|
|
280
|
-
<ShellOutlet target="admin-settings:forms" default />
|
|
281
|
-
</section>
|
|
282
|
-
</template>
|
|
283
|
-
`
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
await assert.rejects(
|
|
287
|
-
() =>
|
|
288
|
-
resolveShellOutletPlacementTargetFromApp({
|
|
289
|
-
appRoot,
|
|
290
|
-
context: "ui-generator"
|
|
291
|
-
}),
|
|
292
|
-
/Multiple default ShellOutlet targets found in app source/
|
|
293
|
-
);
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
test("discoverShellOutletSourcePathsFromApp ignores default conflicts while keeping source paths", async () => {
|
|
298
|
-
await withTempApp(async (appRoot) => {
|
|
299
|
-
await writeFileInApp(
|
|
300
|
-
appRoot,
|
|
301
|
-
"src/components/ShellLayout.vue",
|
|
302
|
-
`<template>
|
|
303
|
-
<div>
|
|
304
|
-
<ShellOutlet target="shell-layout:primary-menu" default />
|
|
305
|
-
<ShellOutlet target="shell-layout:primary-bottom-nav" default />
|
|
306
|
-
</div>
|
|
307
|
-
</template>
|
|
308
|
-
`
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
const discovered = await discoverShellOutletSourcePathsFromApp({ appRoot });
|
|
312
|
-
assert.deepEqual(discovered.targets, [
|
|
313
|
-
{
|
|
314
|
-
id: "shell-layout:primary-bottom-nav",
|
|
315
|
-
default: true,
|
|
316
|
-
sourcePath: "src/components/ShellLayout.vue"
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
id: "shell-layout:primary-menu",
|
|
320
|
-
default: true,
|
|
321
|
-
sourcePath: "src/components/ShellLayout.vue"
|
|
322
|
-
}
|
|
323
|
-
]);
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
test("resolveShellOutletPlacementTargetFromApp requires appRoot", async () => {
|
|
328
|
-
await assert.rejects(
|
|
329
|
-
() =>
|
|
330
|
-
resolveShellOutletPlacementTargetFromApp({
|
|
331
|
-
appRoot: "",
|
|
332
|
-
context: "ui-generator"
|
|
333
|
-
}),
|
|
334
|
-
/requires appRoot/
|
|
335
|
-
);
|
|
336
|
-
});
|
package/server/surface/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export { createSurfaceRegistry, normalizeSurfaceId } from "../../shared/surface/registry.js";
|
|
2
|
-
export { createSurfacePathHelpers } from "../../shared/surface/paths.js";
|
|
3
|
-
export { createSurfaceRuntime, filterRoutesBySurface } from "../../shared/surface/runtime.js";
|
|
4
|
-
export { escapeRegExp } from "../../shared/surface/escapeRegExp.js";
|
|
5
|
-
export {
|
|
6
|
-
API_BASE_PATH,
|
|
7
|
-
API_PREFIX,
|
|
8
|
-
API_PREFIX_SLASH,
|
|
9
|
-
API_DOCS_PATH,
|
|
10
|
-
API_REALTIME_PATH,
|
|
11
|
-
normalizePathname,
|
|
12
|
-
isApiPath,
|
|
13
|
-
isVersionedApiPath,
|
|
14
|
-
toVersionedApiPath,
|
|
15
|
-
toVersionedApiPrefix,
|
|
16
|
-
buildVersionedApiPath,
|
|
17
|
-
isVersionedApiPrefixMatch
|
|
18
|
-
} from "../../shared/surface/apiPaths.js";
|
package/shared/actions/audit.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { createActionRuntimeError } from "./actionDefinitions.js";
|
|
2
|
-
import { normalizeText } from "./textNormalization.js";
|
|
3
|
-
|
|
4
|
-
function resolveRequestIdempotencyKey(context) {
|
|
5
|
-
return normalizeText(context?.requestMeta?.idempotencyKey || context?.requestMeta?.commandId || "");
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function resolveActionIdempotencyKey(definition, context) {
|
|
9
|
-
const policy = normalizeText(definition?.idempotency || "none").toLowerCase();
|
|
10
|
-
if (policy === "none") {
|
|
11
|
-
return "";
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return resolveRequestIdempotencyKey(context);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function createNoopIdempotencyAdapter() {
|
|
18
|
-
return {
|
|
19
|
-
async claimOrReplay() {
|
|
20
|
-
return {
|
|
21
|
-
type: "proceed",
|
|
22
|
-
idempotencyReplay: false,
|
|
23
|
-
claim: null,
|
|
24
|
-
replayResult: null
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
async markSucceeded() {},
|
|
28
|
-
async markFailed() {}
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function ensureIdempotencyKeyIfRequired(definition, context, key) {
|
|
33
|
-
const policy = normalizeText(definition?.idempotency || "none").toLowerCase();
|
|
34
|
-
if (policy !== "required") {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (normalizeText(key)) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
throw createActionRuntimeError(400, "Validation failed.", {
|
|
43
|
-
code: "ACTION_IDEMPOTENCY_KEY_REQUIRED",
|
|
44
|
-
details: {
|
|
45
|
-
fieldErrors: {
|
|
46
|
-
idempotencyKey: "Idempotency key is required for this action."
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const __testables = {
|
|
53
|
-
normalizeText,
|
|
54
|
-
resolveRequestIdempotencyKey
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export {
|
|
58
|
-
resolveActionIdempotencyKey,
|
|
59
|
-
ensureIdempotencyKeyIfRequired,
|
|
60
|
-
createNoopIdempotencyAdapter,
|
|
61
|
-
__testables
|
|
62
|
-
};
|