@adobe/aio-commerce-lib-app 0.3.1 → 1.0.0
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/CHANGELOG.md +39 -0
- package/README.md +1 -4
- package/bin/cli.mjs +24 -0
- package/dist/cjs/actions/app-config.cjs +27 -0
- package/dist/cjs/actions/app-config.d.cts +15 -0
- package/dist/cjs/actions/config.cjs +79 -0
- package/dist/cjs/actions/config.d.cts +15 -0
- package/dist/cjs/actions/installation.cjs +424 -0
- package/dist/cjs/actions/{index.d.cts → installation.d.cts} +4 -3
- package/dist/cjs/actions/scope-tree.cjs +97 -0
- package/dist/cjs/actions/scope-tree.d.cts +8 -0
- package/dist/cjs/{app-Dx0ca6oL.d.cts → app-PTKvEBea.d.cts} +6 -6
- package/dist/cjs/commands/generate/actions/templates/app-management/app-config.js.template +22 -0
- package/dist/cjs/commands/generate/actions/templates/app-management/installation.js.template +1 -1
- package/dist/cjs/commands/generate/actions/templates/business-configuration/config.js.template +22 -0
- package/dist/cjs/commands/generate/actions/templates/business-configuration/scope-tree.js.template +18 -0
- package/dist/cjs/commands/index.cjs +105 -113
- package/dist/cjs/config/index.cjs +21 -19
- package/dist/cjs/config/index.d.cts +32 -332
- package/dist/cjs/error-DJ2UAPH2.cjs +24 -0
- package/dist/cjs/installation-nwF2RC7F.cjs +241 -0
- package/dist/cjs/{logging-DYwr5WQk.cjs → logging-IDRQG0as.cjs} +2 -2
- package/dist/cjs/management/index.cjs +9 -8
- package/dist/cjs/management/index.d.cts +2 -2
- package/dist/cjs/parser-DIchX9SL.cjs +267 -0
- package/dist/cjs/router-DCw7oEQ9.cjs +417 -0
- package/dist/cjs/{management-Dm5h0E6l.cjs → runner-CUJ8RHzY.cjs} +24 -30
- package/dist/{es/index-Bxr3zvCT.d.mts → cjs/runner-Ds2m27Q4.d.cts} +49 -95
- package/dist/cjs/schemas-CZ6c8Id9.cjs +98 -0
- package/dist/cjs/validate-BegMfe-i.cjs +235 -0
- package/dist/es/actions/app-config.d.mts +15 -0
- package/dist/es/actions/app-config.mjs +25 -0
- package/dist/es/actions/config.d.mts +15 -0
- package/dist/es/actions/config.mjs +77 -0
- package/dist/es/actions/{index.d.mts → installation.d.mts} +4 -3
- package/dist/es/actions/{index.mjs → installation.mjs} +27 -427
- package/dist/es/actions/scope-tree.d.mts +8 -0
- package/dist/es/actions/scope-tree.mjs +95 -0
- package/dist/es/{app-Cx1-6dn0.d.mts → app-vKXaAr6f.d.mts} +6 -6
- package/dist/es/commands/generate/actions/templates/app-management/app-config.js.template +22 -0
- package/dist/es/commands/generate/actions/templates/app-management/installation.js.template +1 -1
- package/dist/es/commands/generate/actions/templates/business-configuration/config.js.template +22 -0
- package/dist/es/commands/generate/actions/templates/business-configuration/scope-tree.js.template +18 -0
- package/dist/es/commands/index.mjs +82 -91
- package/dist/es/config/index.d.mts +32 -332
- package/dist/es/config/index.mjs +3 -2
- package/dist/es/error-CMV3IjBz.mjs +18 -0
- package/dist/es/{error-P7JgUTds.mjs → installation-SWIwhpKT.mjs} +72 -124
- package/dist/es/management/index.d.mts +2 -3
- package/dist/es/management/index.mjs +1 -1
- package/dist/es/parser-CKQyrTB7.mjs +201 -0
- package/dist/es/router-CJ4VWoCt.mjs +404 -0
- package/dist/es/{management-Y7pwEbNI.mjs → runner-DB2tDBQS.mjs} +17 -24
- package/dist/{cjs/index-C5SutkJQ.d.cts → es/runner-Uk7263hG.d.mts} +49 -95
- package/dist/es/schemas-B8yIv0_b.mjs +41 -0
- package/dist/es/validate-DXI6gwZ2.mjs +187 -0
- package/package.json +39 -25
- package/dist/cjs/actions/index.cjs +0 -824
- package/dist/cjs/commands/generate/actions/templates/app-management/get-app-config.js.template +0 -62
- package/dist/cjs/commands/generate/actions/templates/business-configuration/get-config-schema.js.template +0 -63
- package/dist/cjs/commands/generate/actions/templates/business-configuration/get-configuration.js.template +0 -104
- package/dist/cjs/commands/generate/actions/templates/business-configuration/get-scope-tree.js.template +0 -69
- package/dist/cjs/commands/generate/actions/templates/business-configuration/set-configuration.js.template +0 -125
- package/dist/cjs/commands/generate/actions/templates/business-configuration/set-custom-scope-tree.js.template +0 -83
- package/dist/cjs/commands/generate/actions/templates/business-configuration/sync-commerce-scopes.js.template +0 -113
- package/dist/cjs/commands/generate/actions/templates/business-configuration/unsync-commerce-scopes.js.template +0 -56
- package/dist/cjs/config-JQ_n-5Nk.cjs +0 -565
- package/dist/cjs/error-Byj1DVHZ.cjs +0 -344
- package/dist/es/commands/generate/actions/templates/app-management/get-app-config.js.template +0 -62
- package/dist/es/commands/generate/actions/templates/business-configuration/get-config-schema.js.template +0 -63
- package/dist/es/commands/generate/actions/templates/business-configuration/get-configuration.js.template +0 -104
- package/dist/es/commands/generate/actions/templates/business-configuration/get-scope-tree.js.template +0 -69
- package/dist/es/commands/generate/actions/templates/business-configuration/set-configuration.js.template +0 -125
- package/dist/es/commands/generate/actions/templates/business-configuration/set-custom-scope-tree.js.template +0 -83
- package/dist/es/commands/generate/actions/templates/business-configuration/sync-commerce-scopes.js.template +0 -113
- package/dist/es/commands/generate/actions/templates/business-configuration/unsync-commerce-scopes.js.template +0 -56
- package/dist/es/config-BSGerqCG.mjs +0 -457
- /package/dist/es/{logging-VgerMhp6.mjs → logging-CzmXDzxI.mjs} +0 -0
|
@@ -1,824 +0,0 @@
|
|
|
1
|
-
const require_error = require('../error-Byj1DVHZ.cjs');
|
|
2
|
-
const require_management = require('../management-Dm5h0E6l.cjs');
|
|
3
|
-
let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
|
|
4
|
-
let _adobe_aio_lib_core_logging = require("@adobe/aio-lib-core-logging");
|
|
5
|
-
_adobe_aio_lib_core_logging = require_error.__toESM(_adobe_aio_lib_core_logging);
|
|
6
|
-
let regexparam = require("regexparam");
|
|
7
|
-
let _adobe_aio_lib_files = require("@adobe/aio-lib-files");
|
|
8
|
-
let _adobe_aio_lib_state = require("@adobe/aio-lib-state");
|
|
9
|
-
let openwhisk = require("openwhisk");
|
|
10
|
-
openwhisk = require_error.__toESM(openwhisk);
|
|
11
|
-
let valibot = require("valibot");
|
|
12
|
-
valibot = require_error.__toESM(valibot);
|
|
13
|
-
|
|
14
|
-
//#region ../../packages-private/common-utils/source/actions/http/middleware/logger.ts
|
|
15
|
-
/**
|
|
16
|
-
* Creates a logger middleware that adds logging capabilities to the context.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```typescript
|
|
20
|
-
* router.use(logger({ level: "debug", name: () => "my-logger-name" }));
|
|
21
|
-
*
|
|
22
|
-
* router.get("/test", {
|
|
23
|
-
* handler: (req, ctx) => {
|
|
24
|
-
* ctx.logger.info("Hello world");
|
|
25
|
-
* return ok({ body: {} });
|
|
26
|
-
* },
|
|
27
|
-
* });
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
function logger({ name, ...restOptions } = {}) {
|
|
31
|
-
return (ctx) => {
|
|
32
|
-
const params = ctx.rawParams;
|
|
33
|
-
return { logger: (0, _adobe_aio_lib_core_logging.default)(`${params.__ow_method}-${name?.(ctx) ?? process.env.__OW_ACTION_NAME}`, {
|
|
34
|
-
level: `${params.LOG_LEVEL ?? "info"}`,
|
|
35
|
-
...restOptions
|
|
36
|
-
}) };
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region ../../packages-private/common-utils/source/actions/http/utils.ts
|
|
42
|
-
/**
|
|
43
|
-
* Validates input against a Standard Schema and returns a result.
|
|
44
|
-
*
|
|
45
|
-
* @template TInput - The input type expected by the schema
|
|
46
|
-
* @template TOutput - The output type produced by the schema
|
|
47
|
-
* @param schema - A Standard Schema v1 compliant schema
|
|
48
|
-
* @param input - The input data to validate
|
|
49
|
-
* @returns A promise resolving to either success with validated data or failure with issues
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```typescript
|
|
53
|
-
* const result = await validateSchema(mySchema, userInput);
|
|
54
|
-
* if (result.success) {
|
|
55
|
-
* console.log(result.data); // Typed as TOutput
|
|
56
|
-
* } else {
|
|
57
|
-
* console.error(result.issues); // Validation errors
|
|
58
|
-
* }
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
async function validateSchema(schema, input) {
|
|
62
|
-
const result = await schema["~standard"].validate(input);
|
|
63
|
-
if (result.issues) return {
|
|
64
|
-
success: false,
|
|
65
|
-
issues: result.issues.map((issue) => ({
|
|
66
|
-
message: issue.message,
|
|
67
|
-
path: issue.path?.map((segment) => typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment)
|
|
68
|
-
}))
|
|
69
|
-
};
|
|
70
|
-
return {
|
|
71
|
-
success: true,
|
|
72
|
-
data: result.value
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Parses a request body from OpenWhisk/Runtime.
|
|
77
|
-
* Handles multiple formats:
|
|
78
|
-
* - Base64-encoded strings (__ow_body)
|
|
79
|
-
* - Already-parsed objects
|
|
80
|
-
* - Body properties mixed into args (web actions with JSON content-type)
|
|
81
|
-
*
|
|
82
|
-
* @param owBody - Body from __ow_body (base64 string, JSON string, or object)
|
|
83
|
-
* @param args - Full args object to extract body from if __ow_body is not present
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* ```typescript
|
|
87
|
-
* const body = parseRequestBody(params.__ow_body, params);
|
|
88
|
-
* ```
|
|
89
|
-
*/
|
|
90
|
-
function parseRequestBody(owBody, args) {
|
|
91
|
-
if (owBody) {
|
|
92
|
-
if (typeof owBody === "object") return owBody;
|
|
93
|
-
if (typeof owBody === "string") {
|
|
94
|
-
try {
|
|
95
|
-
return JSON.parse(owBody);
|
|
96
|
-
} catch {}
|
|
97
|
-
try {
|
|
98
|
-
const decoded = Buffer.from(owBody, "base64").toString();
|
|
99
|
-
return JSON.parse(decoded);
|
|
100
|
-
} catch {}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (args && typeof args === "object") {
|
|
104
|
-
const body = {};
|
|
105
|
-
for (const [key, value] of Object.entries(args)) if (!key.startsWith("__ow_")) body[key] = value;
|
|
106
|
-
return body;
|
|
107
|
-
}
|
|
108
|
-
return {};
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Parses query parameters from OpenWhisk/Runtime format.
|
|
112
|
-
*
|
|
113
|
-
* @param queryString - Query string from __ow_query
|
|
114
|
-
* @param fallbackParams - Fallback params object (used when __ow_query is not present)
|
|
115
|
-
* @returns Parsed query parameters as a record
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```typescript
|
|
119
|
-
* const query = parseQueryParams(params.__ow_query, params);
|
|
120
|
-
* ```
|
|
121
|
-
*/
|
|
122
|
-
function parseQueryParams(queryString, fallbackParams) {
|
|
123
|
-
if (queryString) return Object.fromEntries(new URLSearchParams(queryString));
|
|
124
|
-
if (fallbackParams) {
|
|
125
|
-
const { __ow_method, __ow_path, __ow_headers, __ow_body, __ow_query, ...rest } = fallbackParams;
|
|
126
|
-
return rest;
|
|
127
|
-
}
|
|
128
|
-
return {};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
//#endregion
|
|
132
|
-
//#region ../../packages-private/common-utils/source/actions/http/router.ts
|
|
133
|
-
/**
|
|
134
|
-
* HTTP router for Adobe I/O Runtime actions.
|
|
135
|
-
* Provides type-safe routing with schema validation and OpenWhisk integration.
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
* ```typescript
|
|
139
|
-
* const router = new HttpActionRouter();
|
|
140
|
-
*
|
|
141
|
-
* router.get("/users/:id", {
|
|
142
|
-
* handler: (req) => ok({ id: req.params.id, context: req.context })
|
|
143
|
-
* });
|
|
144
|
-
*
|
|
145
|
-
* // Add context builders
|
|
146
|
-
* router.use(async (base) => ({
|
|
147
|
-
* user: await getUser(base.rawParams.__ow_headers?.authorization),
|
|
148
|
-
* }));
|
|
149
|
-
*
|
|
150
|
-
* export const main = router.handler();
|
|
151
|
-
* ```
|
|
152
|
-
*/
|
|
153
|
-
var HttpActionRouter = class {
|
|
154
|
-
constructor() {
|
|
155
|
-
this.routes = [];
|
|
156
|
-
this.contextBuilders = [];
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Internal method to add a route to the router.
|
|
160
|
-
*/
|
|
161
|
-
addRoute(method, path, config) {
|
|
162
|
-
const { pattern, keys } = (0, regexparam.parse)(path);
|
|
163
|
-
this.routes.push({
|
|
164
|
-
method,
|
|
165
|
-
pattern,
|
|
166
|
-
keys,
|
|
167
|
-
params: config.params,
|
|
168
|
-
body: config.body,
|
|
169
|
-
query: config.query,
|
|
170
|
-
handler: config.handler
|
|
171
|
-
});
|
|
172
|
-
return this;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Register a GET route.
|
|
176
|
-
*
|
|
177
|
-
* @example
|
|
178
|
-
* ```typescript
|
|
179
|
-
* router.get("/users/:id", {
|
|
180
|
-
* handler: (req) => ok({ id: req.params.id })
|
|
181
|
-
* });
|
|
182
|
-
* ```
|
|
183
|
-
*/
|
|
184
|
-
get(path, config) {
|
|
185
|
-
return this.addRoute("GET", path, config);
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Register a POST route.
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```typescript
|
|
192
|
-
* router.post("/users", {
|
|
193
|
-
* body: userSchema,
|
|
194
|
-
* handler: (req) => created(req.body)
|
|
195
|
-
* });
|
|
196
|
-
* ```
|
|
197
|
-
*/
|
|
198
|
-
post(path, config) {
|
|
199
|
-
return this.addRoute("POST", path, config);
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Register a PUT route.
|
|
203
|
-
*
|
|
204
|
-
* @example
|
|
205
|
-
* ```typescript
|
|
206
|
-
* router.put("/users/:id", {
|
|
207
|
-
* body: userSchema,
|
|
208
|
-
* handler: (req) => ok(req.body)
|
|
209
|
-
* });
|
|
210
|
-
* ```
|
|
211
|
-
*/
|
|
212
|
-
put(path, config) {
|
|
213
|
-
return this.addRoute("PUT", path, config);
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Register a PATCH route.
|
|
217
|
-
*
|
|
218
|
-
* @example
|
|
219
|
-
* ```typescript
|
|
220
|
-
* router.patch("/users/:id", {
|
|
221
|
-
* body: partialUserSchema,
|
|
222
|
-
* handler: (req) => ok(req.body)
|
|
223
|
-
* });
|
|
224
|
-
* ```
|
|
225
|
-
*/
|
|
226
|
-
patch(path, config) {
|
|
227
|
-
return this.addRoute("PATCH", path, config);
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Register a DELETE route.
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* ```typescript
|
|
234
|
-
* router.delete("/users/:id", {
|
|
235
|
-
* handler: (req) => noContent()
|
|
236
|
-
* });
|
|
237
|
-
* ```
|
|
238
|
-
*/
|
|
239
|
-
delete(path, config) {
|
|
240
|
-
return this.addRoute("DELETE", path, config);
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Register a context builder that runs before route handlers.
|
|
244
|
-
* Context builders can add properties to the request context.
|
|
245
|
-
* Multiple builders are executed in order and their results are merged.
|
|
246
|
-
*
|
|
247
|
-
* The returned router has an updated context type that includes the new properties,
|
|
248
|
-
* enabling type-safe access in route handlers.
|
|
249
|
-
*
|
|
250
|
-
* @param builder - Function that receives base context and returns additional context
|
|
251
|
-
* @returns The router instance with updated context type for chaining
|
|
252
|
-
*
|
|
253
|
-
* @example
|
|
254
|
-
* ```typescript
|
|
255
|
-
* const router = new HttpActionRouter()
|
|
256
|
-
* .use(logger()) // HttpActionRouter<BaseContext & { logger: Logger }>
|
|
257
|
-
* .use(auth()); // HttpActionRouter<BaseContext & { logger: Logger } & { user: User }>
|
|
258
|
-
*
|
|
259
|
-
* router.get("/me", {
|
|
260
|
-
* handler: (req, ctx) => {
|
|
261
|
-
* ctx.logger.info("Hello"); // ✅ typed
|
|
262
|
-
* return ok({ body: ctx.user }); // ✅ typed
|
|
263
|
-
* },
|
|
264
|
-
* });
|
|
265
|
-
* ```
|
|
266
|
-
*/
|
|
267
|
-
use(builder) {
|
|
268
|
-
this.contextBuilders.push(builder);
|
|
269
|
-
return this;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Builds the full context by running all context builders.
|
|
273
|
-
*/
|
|
274
|
-
async buildContext(args) {
|
|
275
|
-
let context = { rawParams: args };
|
|
276
|
-
for (const builder of this.contextBuilders) {
|
|
277
|
-
const result = await builder(context);
|
|
278
|
-
if (result) context = {
|
|
279
|
-
...context,
|
|
280
|
-
...result
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
return context;
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Validates and extracts route parameters.
|
|
287
|
-
*/
|
|
288
|
-
async validateParams(route, params) {
|
|
289
|
-
if (!route.params) return {
|
|
290
|
-
success: true,
|
|
291
|
-
data: params
|
|
292
|
-
};
|
|
293
|
-
const result = await validateSchema(route.params, params);
|
|
294
|
-
if (!result.success) return {
|
|
295
|
-
success: false,
|
|
296
|
-
issues: result.issues
|
|
297
|
-
};
|
|
298
|
-
return {
|
|
299
|
-
success: true,
|
|
300
|
-
data: result.data
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Validates request body.
|
|
305
|
-
*/
|
|
306
|
-
async validateBody(route, body) {
|
|
307
|
-
if (!route.body) return {
|
|
308
|
-
success: true,
|
|
309
|
-
data: body
|
|
310
|
-
};
|
|
311
|
-
const result = await validateSchema(route.body, body);
|
|
312
|
-
if (!result.success) return {
|
|
313
|
-
success: false,
|
|
314
|
-
issues: result.issues
|
|
315
|
-
};
|
|
316
|
-
return {
|
|
317
|
-
success: true,
|
|
318
|
-
data: result.data
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Validates query parameters.
|
|
323
|
-
*/
|
|
324
|
-
async validateQuery(route, query) {
|
|
325
|
-
if (!route.query) return {
|
|
326
|
-
success: true,
|
|
327
|
-
data: query
|
|
328
|
-
};
|
|
329
|
-
const result = await validateSchema(route.query, query);
|
|
330
|
-
if (!result.success) return {
|
|
331
|
-
success: false,
|
|
332
|
-
issues: result.issues
|
|
333
|
-
};
|
|
334
|
-
return {
|
|
335
|
-
success: true,
|
|
336
|
-
data: result.data
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
/** Handles a matched route by validating inputs and calling the handler. */
|
|
340
|
-
async handleRoute(route, match, body, query, headers, method, path, context) {
|
|
341
|
-
const params = {};
|
|
342
|
-
route.keys.forEach((key, i) => {
|
|
343
|
-
params[key] = decodeURIComponent(match[i + 1] || "");
|
|
344
|
-
});
|
|
345
|
-
const paramsResult = await this.validateParams(route, params);
|
|
346
|
-
if (!paramsResult.success) return (0, _adobe_aio_commerce_lib_core_responses.badRequest)({ body: {
|
|
347
|
-
message: "Invalid route parameters",
|
|
348
|
-
issues: paramsResult.issues
|
|
349
|
-
} });
|
|
350
|
-
const bodyResult = await this.validateBody(route, body);
|
|
351
|
-
if (!bodyResult.success) return (0, _adobe_aio_commerce_lib_core_responses.badRequest)({ body: {
|
|
352
|
-
message: "Invalid request body",
|
|
353
|
-
issues: bodyResult.issues
|
|
354
|
-
} });
|
|
355
|
-
const queryResult = await this.validateQuery(route, query);
|
|
356
|
-
if (!queryResult.success) return (0, _adobe_aio_commerce_lib_core_responses.badRequest)({ body: {
|
|
357
|
-
message: "Invalid query parameters",
|
|
358
|
-
issues: queryResult.issues
|
|
359
|
-
} });
|
|
360
|
-
try {
|
|
361
|
-
return await route.handler({
|
|
362
|
-
params: paramsResult.data,
|
|
363
|
-
body: bodyResult.data,
|
|
364
|
-
query: queryResult.data,
|
|
365
|
-
headers,
|
|
366
|
-
method,
|
|
367
|
-
path
|
|
368
|
-
}, context);
|
|
369
|
-
} catch (err) {
|
|
370
|
-
console.error("Handler error:", err);
|
|
371
|
-
return (0, _adobe_aio_commerce_lib_core_responses.internalServerError)({ body: {
|
|
372
|
-
message: "Internal server error",
|
|
373
|
-
error: err instanceof Error ? err.message : "Unknown error"
|
|
374
|
-
} });
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Creates an OpenWhisk/Runtime action handler from the registered routes.
|
|
379
|
-
*
|
|
380
|
-
* @example
|
|
381
|
-
* ```typescript
|
|
382
|
-
* const router = new HttpActionRouter();
|
|
383
|
-
* router.get("/hello", { handler: () => ok({ message: "Hello!" }) });
|
|
384
|
-
*
|
|
385
|
-
* export const main = router.handler();
|
|
386
|
-
* ```
|
|
387
|
-
*/
|
|
388
|
-
handler() {
|
|
389
|
-
return async (args) => {
|
|
390
|
-
const method = (args.__ow_method ?? "get").toUpperCase();
|
|
391
|
-
const rawPath = args.__ow_path ?? "/";
|
|
392
|
-
const path = rawPath.startsWith("/") ? rawPath : `/${rawPath}`;
|
|
393
|
-
const headers = args.__ow_headers ?? {};
|
|
394
|
-
const body = parseRequestBody(args.__ow_body, args);
|
|
395
|
-
const query = parseQueryParams(args.__ow_query, args);
|
|
396
|
-
const context = await this.buildContext(args);
|
|
397
|
-
const matchedMethods = [];
|
|
398
|
-
for (const route of this.routes) {
|
|
399
|
-
const match = route.pattern.exec(path);
|
|
400
|
-
if (!match) continue;
|
|
401
|
-
matchedMethods.push(route.method);
|
|
402
|
-
if (route.method !== method) continue;
|
|
403
|
-
const response = await this.handleRoute(route, match, body, query, headers, method, path, context);
|
|
404
|
-
if (response) return response;
|
|
405
|
-
}
|
|
406
|
-
if (matchedMethods.length > 0) return (0, _adobe_aio_commerce_lib_core_responses.methodNotAllowed)(`Method ${method} not allowed`);
|
|
407
|
-
return (0, _adobe_aio_commerce_lib_core_responses.notFound)(`No route matches ${path}`);
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
//#endregion
|
|
413
|
-
//#region ../../packages-private/common-utils/source/storage/files-store.ts
|
|
414
|
-
/** Default directory prefix. */
|
|
415
|
-
const DEFAULT_DIR_PREFIX = "store";
|
|
416
|
-
/**
|
|
417
|
-
* Creates a generic key-value store backed by @adobe/aio-lib-files.
|
|
418
|
-
* Provides persistent storage that survives beyond TTL.
|
|
419
|
-
*
|
|
420
|
-
* @typeParam T - The type of data to store.
|
|
421
|
-
* @param options - Configuration options for the store.
|
|
422
|
-
* @returns A KeyValueStore implementation.
|
|
423
|
-
*
|
|
424
|
-
* @example
|
|
425
|
-
* ```typescript
|
|
426
|
-
* interface UserProfile {
|
|
427
|
-
* id: string;
|
|
428
|
-
* name: string;
|
|
429
|
-
* email: string;
|
|
430
|
-
* }
|
|
431
|
-
*
|
|
432
|
-
* const store = await createFilesStore<UserProfile>({
|
|
433
|
-
* dirPrefix: "profiles",
|
|
434
|
-
* });
|
|
435
|
-
*
|
|
436
|
-
* await store.put("user-123", { id: "123", name: "John", email: "john@example.com" });
|
|
437
|
-
* const profile = await store.get("user-123");
|
|
438
|
-
* ```
|
|
439
|
-
*/
|
|
440
|
-
async function createFilesStore(options = {}) {
|
|
441
|
-
const { dirPrefix = DEFAULT_DIR_PREFIX } = options;
|
|
442
|
-
return new FilesStore(await (0, _adobe_aio_lib_files.init)(), dirPrefix);
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Key-value store implementation using @adobe/aio-lib-files.
|
|
446
|
-
*/
|
|
447
|
-
var FilesStore = class {
|
|
448
|
-
constructor(files, dirPrefix) {
|
|
449
|
-
this.files = files;
|
|
450
|
-
this.dirPrefix = dirPrefix;
|
|
451
|
-
}
|
|
452
|
-
async get(key) {
|
|
453
|
-
const filePath = this.buildFilePath(key);
|
|
454
|
-
try {
|
|
455
|
-
const content = await this.files.read(filePath);
|
|
456
|
-
if (!content) return null;
|
|
457
|
-
return JSON.parse(content.toString("utf8"));
|
|
458
|
-
} catch {
|
|
459
|
-
return null;
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
async put(key, data) {
|
|
463
|
-
const filePath = this.buildFilePath(key);
|
|
464
|
-
await this.files.write(filePath, JSON.stringify(data));
|
|
465
|
-
}
|
|
466
|
-
async delete(key) {
|
|
467
|
-
const filePath = this.buildFilePath(key);
|
|
468
|
-
try {
|
|
469
|
-
const result = await this.files.delete(filePath);
|
|
470
|
-
return Array.isArray(result) && result.length > 0;
|
|
471
|
-
} catch {
|
|
472
|
-
return false;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
buildFilePath(key) {
|
|
476
|
-
return `${this.dirPrefix}/${key}.json`;
|
|
477
|
-
}
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
//#endregion
|
|
481
|
-
//#region ../../packages-private/common-utils/source/storage/state-store.ts
|
|
482
|
-
/** Default TTL for state entries (3 hours in seconds). */
|
|
483
|
-
const DEFAULT_TTL_SECONDS = 10800;
|
|
484
|
-
/** Default key prefix. */
|
|
485
|
-
const DEFAULT_KEY_PREFIX = "store";
|
|
486
|
-
/**
|
|
487
|
-
* Creates a generic key-value store backed by @adobe/aio-lib-state.
|
|
488
|
-
* Provides fast, TTL-based caching for temporary data.
|
|
489
|
-
*
|
|
490
|
-
* @typeParam T - The type of data to store.
|
|
491
|
-
* @param options - Configuration options for the store.
|
|
492
|
-
* @returns A KeyValueStore implementation.
|
|
493
|
-
*
|
|
494
|
-
* @example
|
|
495
|
-
* ```typescript
|
|
496
|
-
* interface UserSession {
|
|
497
|
-
* userId: string;
|
|
498
|
-
* token: string;
|
|
499
|
-
* }
|
|
500
|
-
*
|
|
501
|
-
* const store = await createStateStore<UserSession>({
|
|
502
|
-
* keyPrefix: "session",
|
|
503
|
-
* ttlSeconds: 3600, // 1 hour
|
|
504
|
-
* });
|
|
505
|
-
*
|
|
506
|
-
* await store.put("user-123", { userId: "123", token: "abc" });
|
|
507
|
-
* const session = await store.get("user-123");
|
|
508
|
-
* ```
|
|
509
|
-
*/
|
|
510
|
-
async function createStateStore(options = {}) {
|
|
511
|
-
const { keyPrefix = DEFAULT_KEY_PREFIX, ttlSeconds = DEFAULT_TTL_SECONDS } = options;
|
|
512
|
-
return new StateStore(await (0, _adobe_aio_lib_state.init)(), keyPrefix, ttlSeconds);
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Key-value store implementation using @adobe/aio-lib-state.
|
|
516
|
-
*/
|
|
517
|
-
var StateStore = class {
|
|
518
|
-
constructor(state, keyPrefix, ttlSeconds) {
|
|
519
|
-
this.state = state;
|
|
520
|
-
this.keyPrefix = keyPrefix;
|
|
521
|
-
this.ttlSeconds = ttlSeconds;
|
|
522
|
-
}
|
|
523
|
-
async get(key) {
|
|
524
|
-
const fullKey = this.buildKey(key);
|
|
525
|
-
const result = await this.state.get(fullKey);
|
|
526
|
-
if (!result?.value) return null;
|
|
527
|
-
try {
|
|
528
|
-
return JSON.parse(result.value);
|
|
529
|
-
} catch {
|
|
530
|
-
return null;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
async put(key, data) {
|
|
534
|
-
const fullKey = this.buildKey(key);
|
|
535
|
-
const value = JSON.stringify(data);
|
|
536
|
-
await this.state.put(fullKey, value, { ttl: this.ttlSeconds });
|
|
537
|
-
}
|
|
538
|
-
async delete(key) {
|
|
539
|
-
const fullKey = this.buildKey(key);
|
|
540
|
-
try {
|
|
541
|
-
await this.state.delete(fullKey);
|
|
542
|
-
return true;
|
|
543
|
-
} catch {
|
|
544
|
-
return false;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
buildKey(key) {
|
|
548
|
-
return `${this.keyPrefix}-${key}`;
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
|
|
552
|
-
//#endregion
|
|
553
|
-
//#region ../../packages-private/common-utils/source/storage/combined-store.ts
|
|
554
|
-
/** Default TTL for cache (10 minutes). */
|
|
555
|
-
const DEFAULT_CACHE_TTL_SECONDS = 600;
|
|
556
|
-
/**
|
|
557
|
-
* Creates a combined key-value store that uses:
|
|
558
|
-
* - lib-state for fast cache during active operations
|
|
559
|
-
* - lib-files for persistent storage
|
|
560
|
-
*
|
|
561
|
-
* Read strategy: cache first, then persistent storage
|
|
562
|
-
* Write strategy:
|
|
563
|
-
* - Always write to cache for fast reads
|
|
564
|
-
* - Write to persistent storage based on shouldPersist predicate
|
|
565
|
-
*
|
|
566
|
-
* @typeParam T - The type of data to store.
|
|
567
|
-
* @param options - Configuration options for the stores.
|
|
568
|
-
*
|
|
569
|
-
* @example
|
|
570
|
-
* ```typescript
|
|
571
|
-
* interface Task {
|
|
572
|
-
* id: string;
|
|
573
|
-
* status: "pending" | "completed";
|
|
574
|
-
* result?: unknown;
|
|
575
|
-
* }
|
|
576
|
-
*
|
|
577
|
-
* const store = await createCombinedStore<Task>({
|
|
578
|
-
* cache: { keyPrefix: "task", ttlSeconds: 600 },
|
|
579
|
-
* persistent: {
|
|
580
|
-
* dirPrefix: "tasks",
|
|
581
|
-
* shouldPersist: (task) => task.status === "completed",
|
|
582
|
-
* },
|
|
583
|
-
* });
|
|
584
|
-
*
|
|
585
|
-
* // During processing: writes to cache only
|
|
586
|
-
* await store.put("task-1", { id: "1", status: "pending" });
|
|
587
|
-
*
|
|
588
|
-
* // On completion (as shouldPersist indicates): writes to both cache and persistent
|
|
589
|
-
* await store.put("task-1", { id: "1", status: "completed", result: {} });
|
|
590
|
-
* ```
|
|
591
|
-
*/
|
|
592
|
-
async function createCombinedStore(options = {}) {
|
|
593
|
-
const { cache = {}, persistent = {} } = options;
|
|
594
|
-
const { shouldPersist, ...filesOptions } = persistent;
|
|
595
|
-
const cacheOptions = {
|
|
596
|
-
ttlSeconds: DEFAULT_CACHE_TTL_SECONDS,
|
|
597
|
-
...cache
|
|
598
|
-
};
|
|
599
|
-
const [cacheStore, persistentStore] = await Promise.all([createStateStore(cacheOptions), createFilesStore(filesOptions)]);
|
|
600
|
-
return new CombinedStore(cacheStore, persistentStore, shouldPersist);
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Combined key-value store implementation.
|
|
604
|
-
* Uses lib-state for cache and lib-files for persistence.
|
|
605
|
-
*/
|
|
606
|
-
var CombinedStore = class {
|
|
607
|
-
constructor(cache, persistent, shouldPersist) {
|
|
608
|
-
this.cache = cache;
|
|
609
|
-
this.persistent = persistent;
|
|
610
|
-
this.shouldPersist = shouldPersist;
|
|
611
|
-
}
|
|
612
|
-
async get(key) {
|
|
613
|
-
const cached = await this.cache.get(key);
|
|
614
|
-
if (cached !== null && cached !== void 0) return cached;
|
|
615
|
-
const persisted = await this.persistent.get(key);
|
|
616
|
-
if (persisted !== null && persisted !== void 0) {
|
|
617
|
-
await this.cache.put(key, persisted).catch(() => {});
|
|
618
|
-
return persisted;
|
|
619
|
-
}
|
|
620
|
-
return null;
|
|
621
|
-
}
|
|
622
|
-
async put(key, data) {
|
|
623
|
-
await this.cache.put(key, data);
|
|
624
|
-
if (!this.shouldPersist || this.shouldPersist(data)) await this.persistent.put(key, data);
|
|
625
|
-
}
|
|
626
|
-
async delete(key) {
|
|
627
|
-
const [cacheDeleted, persistentDeleted] = await Promise.all([this.cache.delete?.(key) ?? Promise.resolve(false), this.persistent.delete?.(key) ?? Promise.resolve(false)]);
|
|
628
|
-
return cacheDeleted || persistentDeleted;
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
//#endregion
|
|
633
|
-
//#region source/management/installation/schema.ts
|
|
634
|
-
/** Schema for validating Adobe I/O app credentials required for installation. */
|
|
635
|
-
const AppDataSchema = valibot.object({
|
|
636
|
-
consumerOrgId: require_error.nonEmptyStringValueSchema("consumerOrgId"),
|
|
637
|
-
orgName: require_error.nonEmptyStringValueSchema("orgName"),
|
|
638
|
-
projectId: require_error.nonEmptyStringValueSchema("projectId"),
|
|
639
|
-
projectName: require_error.nonEmptyStringValueSchema("projectName"),
|
|
640
|
-
projectTitle: require_error.nonEmptyStringValueSchema("projectTitle"),
|
|
641
|
-
workspaceId: require_error.nonEmptyStringValueSchema("workspaceId"),
|
|
642
|
-
workspaceName: require_error.nonEmptyStringValueSchema("workspaceName"),
|
|
643
|
-
workspaceTitle: require_error.nonEmptyStringValueSchema("workspaceTitle")
|
|
644
|
-
});
|
|
645
|
-
|
|
646
|
-
//#endregion
|
|
647
|
-
//#region source/actions/installation.ts
|
|
648
|
-
const DEFAULT_ACTION_NAME = "app-management/installation";
|
|
649
|
-
/** Creates an installation state store using lib-core combined storage. */
|
|
650
|
-
function createInstallationStore() {
|
|
651
|
-
return createCombinedStore({
|
|
652
|
-
cache: { keyPrefix: "installation" },
|
|
653
|
-
persistent: {
|
|
654
|
-
dirPrefix: "installation",
|
|
655
|
-
shouldPersist: require_management.isCompletedState
|
|
656
|
-
}
|
|
657
|
-
});
|
|
658
|
-
}
|
|
659
|
-
/** Returns the storage key used to store the current installation ID. */
|
|
660
|
-
function getStorageKey() {
|
|
661
|
-
return "current";
|
|
662
|
-
}
|
|
663
|
-
/**
|
|
664
|
-
* Creates hooks to sync installation state to storage.
|
|
665
|
-
*/
|
|
666
|
-
function createInstallationHooks(store, logFn) {
|
|
667
|
-
const logAndSave = async (message, data) => {
|
|
668
|
-
logFn(message);
|
|
669
|
-
await store.put(getStorageKey(), data);
|
|
670
|
-
};
|
|
671
|
-
return {
|
|
672
|
-
onInstallationStart: (state) => logAndSave("Installation started", state),
|
|
673
|
-
onInstallationFailure: (state) => logAndSave("Installation failed", state),
|
|
674
|
-
onInstallationSuccess: (state) => logAndSave("Installation succeeded", state),
|
|
675
|
-
onStepStart: (event, state) => logAndSave(`Step started: ${event.stepName}`, state),
|
|
676
|
-
onStepSuccess: (event, state) => logAndSave(`Step succeeded: ${event.stepName}`, state),
|
|
677
|
-
onStepFailure: (event, state) => logAndSave(`Step failed: ${event.stepName}`, state)
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* Installation action router.
|
|
682
|
-
*
|
|
683
|
-
* Routes:
|
|
684
|
-
* - POST /installation - Start installation (creates plan, invokes execution async)
|
|
685
|
-
* - GET /installation/execution - Get current execution status
|
|
686
|
-
* - POST /installation/execution - Execute installation (internal, called async)
|
|
687
|
-
*/
|
|
688
|
-
const router = new HttpActionRouter().use(logger({ name: () => "installation" }));
|
|
689
|
-
/**
|
|
690
|
-
* GET /installation/execution - Get current execution status
|
|
691
|
-
*
|
|
692
|
-
* Flow:
|
|
693
|
-
* 1. Find execution in state store
|
|
694
|
-
* 2. If found: return execution plan with step statuses
|
|
695
|
-
* 3. If not found: return empty status
|
|
696
|
-
*/
|
|
697
|
-
router.get("/", { handler: async (_req, { logger: logger$1 }) => {
|
|
698
|
-
logger$1.debug("Getting installation execution status...");
|
|
699
|
-
const state = await (await createInstallationStore()).get(getStorageKey());
|
|
700
|
-
if (state) {
|
|
701
|
-
logger$1.debug(`Found execution: ${state.status}`);
|
|
702
|
-
return (0, _adobe_aio_commerce_lib_core_responses.ok)({ body: state });
|
|
703
|
-
}
|
|
704
|
-
logger$1.debug("No execution found");
|
|
705
|
-
return (0, _adobe_aio_commerce_lib_core_responses.noContent)();
|
|
706
|
-
} });
|
|
707
|
-
/**
|
|
708
|
-
* POST / - Start installation
|
|
709
|
-
*
|
|
710
|
-
* Flow:
|
|
711
|
-
* 1. Find execution in state store
|
|
712
|
-
* 2. If found and (pending/in-progress or succeeded): return 409 Conflict
|
|
713
|
-
* 3. If not found or failed: create plan, invoke execution async, return 202 Accepted
|
|
714
|
-
*/
|
|
715
|
-
router.post("/", {
|
|
716
|
-
body: (0, valibot.object)({
|
|
717
|
-
appData: AppDataSchema,
|
|
718
|
-
commerceBaseUrl: (0, valibot.string)(),
|
|
719
|
-
commerceEnv: (0, valibot.string)(),
|
|
720
|
-
ioEventsUrl: (0, valibot.string)(),
|
|
721
|
-
ioEventsEnv: (0, valibot.string)()
|
|
722
|
-
}),
|
|
723
|
-
handler: async (req, { logger: logger$1, rawParams }) => {
|
|
724
|
-
logger$1.debug("Starting installation...");
|
|
725
|
-
const store = await createInstallationStore();
|
|
726
|
-
const existingState = await store.get(getStorageKey());
|
|
727
|
-
if (existingState) {
|
|
728
|
-
if (require_management.isInProgressState(existingState)) {
|
|
729
|
-
logger$1.debug(`Installation already in progress: ${existingState.status}`);
|
|
730
|
-
return (0, _adobe_aio_commerce_lib_core_responses.conflict)(`Installation is already ${existingState.status}. Wait for it to complete.`);
|
|
731
|
-
}
|
|
732
|
-
if (require_management.isSucceededState(existingState)) {
|
|
733
|
-
logger$1.debug("Installation already succeeded");
|
|
734
|
-
return (0, _adobe_aio_commerce_lib_core_responses.conflict)("Installation has already completed successfully.");
|
|
735
|
-
}
|
|
736
|
-
logger$1.debug("Previous installation failed, allowing retry");
|
|
737
|
-
}
|
|
738
|
-
const appConfig = rawParams.appConfig;
|
|
739
|
-
if (!appConfig) return (0, _adobe_aio_commerce_lib_core_responses.internalServerError)("Could not find or parse the app.commerce.manifest.json file, is it present and valid?");
|
|
740
|
-
const initialState = require_management.createInitialInstallationState({ config: appConfig });
|
|
741
|
-
logger$1.debug(`Created initial state: ${initialState.id}`);
|
|
742
|
-
await store.put(getStorageKey(), initialState);
|
|
743
|
-
const activation = await (0, openwhisk.default)().actions.invoke({
|
|
744
|
-
name: DEFAULT_ACTION_NAME,
|
|
745
|
-
blocking: false,
|
|
746
|
-
result: false,
|
|
747
|
-
params: {
|
|
748
|
-
...rawParams,
|
|
749
|
-
appData: req.body.appData,
|
|
750
|
-
AIO_EVENTS_API_BASE_URL: req.body.ioEventsUrl,
|
|
751
|
-
AIO_COMMERCE_AUTH_IMS_ENVIRONMENT: req.body.ioEventsEnv,
|
|
752
|
-
AIO_COMMERCE_API_BASE_URL: req.body.commerceBaseUrl,
|
|
753
|
-
AIO_COMMERCE_API_FLAVOR: req.body.commerceEnv,
|
|
754
|
-
initialState,
|
|
755
|
-
appConfig,
|
|
756
|
-
__ow_path: "/execution",
|
|
757
|
-
__ow_method: "post"
|
|
758
|
-
}
|
|
759
|
-
});
|
|
760
|
-
logger$1.debug(`Async execution started: ${activation.activationId}`);
|
|
761
|
-
return (0, _adobe_aio_commerce_lib_core_responses.accepted)({ body: {
|
|
762
|
-
message: "Installation started",
|
|
763
|
-
activationId: activation.activationId,
|
|
764
|
-
...initialState
|
|
765
|
-
} });
|
|
766
|
-
}
|
|
767
|
-
});
|
|
768
|
-
/**
|
|
769
|
-
* POST /installation/execution - Execute installation (internal)
|
|
770
|
-
*
|
|
771
|
-
* This endpoint is called asynchronously by POST /installation.
|
|
772
|
-
* It runs the actual installation workflow and saves state.
|
|
773
|
-
*/
|
|
774
|
-
router.post("/execution", { handler: async (_req, { logger: logger$1, rawParams }) => {
|
|
775
|
-
const { appData, ...params } = rawParams;
|
|
776
|
-
const { initialState, appConfig } = params;
|
|
777
|
-
if (!initialState) return (0, _adobe_aio_commerce_lib_core_responses.badRequest)("initialState is required for execution");
|
|
778
|
-
if (!appConfig) return (0, _adobe_aio_commerce_lib_core_responses.badRequest)("appConfig is required for execution");
|
|
779
|
-
const store = await createInstallationStore();
|
|
780
|
-
const hooks = createInstallationHooks(store, (msg) => logger$1.debug(msg));
|
|
781
|
-
const installationContext = {
|
|
782
|
-
appData,
|
|
783
|
-
params,
|
|
784
|
-
logger: logger$1,
|
|
785
|
-
customScripts: params.customScriptsLoader?.(appConfig, logger$1) || {}
|
|
786
|
-
};
|
|
787
|
-
logger$1.debug(`Executing installation: ${initialState.id}`);
|
|
788
|
-
const result = await require_management.runInstallation({
|
|
789
|
-
installationContext,
|
|
790
|
-
config: appConfig,
|
|
791
|
-
initialState,
|
|
792
|
-
hooks
|
|
793
|
-
});
|
|
794
|
-
await store.put(getStorageKey(), result);
|
|
795
|
-
logger$1.debug(`Installation completed: ${result.status}`);
|
|
796
|
-
if (require_management.isFailedState(result)) return (0, _adobe_aio_commerce_lib_core_responses.internalServerError)({ body: {
|
|
797
|
-
message: "Installation failed",
|
|
798
|
-
error: result.error,
|
|
799
|
-
state: result
|
|
800
|
-
} });
|
|
801
|
-
return (0, _adobe_aio_commerce_lib_core_responses.ok)({ body: result });
|
|
802
|
-
} });
|
|
803
|
-
/**
|
|
804
|
-
* DELETE / - Clear installation state
|
|
805
|
-
*
|
|
806
|
-
* This endpoint allows clearing the installation state.
|
|
807
|
-
*/
|
|
808
|
-
router.delete("/", { handler: async (_req, { logger: logger$1 }) => {
|
|
809
|
-
logger$1.debug("Clearing installation state...");
|
|
810
|
-
await (await createInstallationStore()).delete(getStorageKey());
|
|
811
|
-
logger$1.debug("Installation state cleared");
|
|
812
|
-
return (0, _adobe_aio_commerce_lib_core_responses.noContent)();
|
|
813
|
-
} });
|
|
814
|
-
/** The route handler for the runtime action. */
|
|
815
|
-
const installationRuntimeAction = ({ appConfig, customScriptsLoader }) => async (params) => {
|
|
816
|
-
return await router.handler()({
|
|
817
|
-
...params,
|
|
818
|
-
appConfig,
|
|
819
|
-
customScriptsLoader
|
|
820
|
-
});
|
|
821
|
-
};
|
|
822
|
-
|
|
823
|
-
//#endregion
|
|
824
|
-
exports.installationRuntimeAction = installationRuntimeAction;
|