@prismatic-io/components-adobe-experience-manager 0.0.0-stage → 0.0.1

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.
@@ -0,0 +1,4466 @@
1
+ let _prismatic_io_spectral = require("@prismatic-io/spectral");
2
+ let _prismatic_io_spectral_http = require("@prismatic-io/spectral/http");
3
+ let node_dns = require("node:dns");
4
+ let node_https = require("node:https");
5
+ let node_net = require("node:net");
6
+ let node_crypto = require("node:crypto");
7
+ //#region src/constants.ts
8
+ const SERVER_TO_SERVER_CONNECTION_KEY = "aemOAuthServerToServer";
9
+ const WEB_APP_CONNECTION_KEY = "aemOAuthWebApp";
10
+ const DEFAULT_TOKEN_URL = "https://ims-na1.adobelogin.com/ims/token/v3";
11
+ const DEFAULT_AUTHORIZE_URL = "https://ims-na1.adobelogin.com/ims/authorize/v2";
12
+ const WEB_APP_DEFAULT_SCOPES = "openid,AdobeID,aem.assets.author,aem.folders";
13
+ const AEM_HOST_SUFFIX = ".adobeaemcloud.com";
14
+ const SITES_API_PATH = "/adobe/sites";
15
+ const FOLDERS_API_PATH = "/adobe/folders";
16
+ const ASSETS_API_PATH = "/adobe/assets";
17
+ const IO_EVENTS_BASE_URL = "https://api.adobe.io/events";
18
+ const IO_EVENTS_PUBLIC_KEY_BASE_URL = "https://static.adobeioevents.com";
19
+ const DEFAULT_DAM_ROOT = "/content/dam";
20
+ const RETRYABLE_STATUS_CODES = [429, 503];
21
+ const SETTLE_LAG_MS = 120 * 1e3;
22
+ const MAX_FOLDER_WALK = 1e3;
23
+ const MAX_DATA_SOURCE_ITEMS = 1e3;
24
+ const ASSET_MODIFY_DATE_FIELD = "repositoryMetadata.repo:modifyDate";
25
+ const ASSET_CREATE_DATE_FIELD = "repositoryMetadata.repo:createDate";
26
+ const ASSET_ANCESTORS_FIELD = "repositoryMetadata.repo:ancestors";
27
+ const ASSET_FORMAT_FIELD = "repositoryMetadata.dc:format";
28
+ const CONTENT_FRAGMENT_STATUSES = [
29
+ {
30
+ label: "New",
31
+ value: "NEW"
32
+ },
33
+ {
34
+ label: "Draft",
35
+ value: "DRAFT"
36
+ },
37
+ {
38
+ label: "Published",
39
+ value: "PUBLISHED"
40
+ },
41
+ {
42
+ label: "Modified",
43
+ value: "MODIFIED"
44
+ },
45
+ {
46
+ label: "Unpublished",
47
+ value: "UNPUBLISHED"
48
+ }
49
+ ];
50
+ const DEFAULT_TRIGGER_FRAGMENT_STATUSES = ["PUBLISHED", "MODIFIED"];
51
+ const CONTENT_FRAGMENT_PROJECTIONS = [
52
+ {
53
+ label: "Minimal",
54
+ value: "minimal"
55
+ },
56
+ {
57
+ label: "Summary",
58
+ value: "summary"
59
+ },
60
+ {
61
+ label: "Full",
62
+ value: "full"
63
+ }
64
+ ];
65
+ const CONTENT_FRAGMENT_REFERENCES = [
66
+ {
67
+ label: "Direct",
68
+ value: "direct"
69
+ },
70
+ {
71
+ label: "Direct (Hydrated)",
72
+ value: "direct-hydrated"
73
+ },
74
+ {
75
+ label: "All",
76
+ value: "all"
77
+ },
78
+ {
79
+ label: "All (Hydrated)",
80
+ value: "all-hydrated"
81
+ }
82
+ ];
83
+ const CONTENT_FRAGMENT_SORT_FIELDS = [
84
+ {
85
+ label: "Title",
86
+ value: "title"
87
+ },
88
+ {
89
+ label: "Created",
90
+ value: "created"
91
+ },
92
+ {
93
+ label: "Modified",
94
+ value: "modified"
95
+ },
96
+ {
97
+ label: "Modified or Created",
98
+ value: "modifiedOrCreated"
99
+ }
100
+ ];
101
+ const SORT_ORDERS = [{
102
+ label: "Ascending",
103
+ value: "ASC"
104
+ }, {
105
+ label: "Descending",
106
+ value: "DESC"
107
+ }];
108
+ const FOLDER_LISTING_TYPES = [
109
+ {
110
+ label: "Folders and Assets",
111
+ value: "FOLDER,ASSET"
112
+ },
113
+ {
114
+ label: "Folders",
115
+ value: "FOLDER"
116
+ },
117
+ {
118
+ label: "Assets",
119
+ value: "ASSET"
120
+ }
121
+ ];
122
+ const FOLDER_ORDER_BY = [
123
+ {
124
+ label: "Name",
125
+ value: "name"
126
+ },
127
+ {
128
+ label: "Size",
129
+ value: "size"
130
+ },
131
+ {
132
+ label: "Last Modified",
133
+ value: "lastModifiedAt"
134
+ }
135
+ ];
136
+ const ASSET_SORT_FIELDS = [
137
+ {
138
+ label: "Modified",
139
+ value: ASSET_MODIFY_DATE_FIELD
140
+ },
141
+ {
142
+ label: "Created",
143
+ value: ASSET_CREATE_DATE_FIELD
144
+ },
145
+ {
146
+ label: "Name",
147
+ value: "repositoryMetadata.repo:name"
148
+ }
149
+ ];
150
+ const AEM_EVENT_BRANCHES = ["Notification", "URL Verification"];
151
+ const AEM_SITES_EVENT_TYPES = [
152
+ {
153
+ label: "Content Fragment Created",
154
+ value: "aem.sites.contentFragment.created"
155
+ },
156
+ {
157
+ label: "Content Fragment Modified",
158
+ value: "aem.sites.contentFragment.modified"
159
+ },
160
+ {
161
+ label: "Content Fragment Published",
162
+ value: "aem.sites.contentFragment.published"
163
+ },
164
+ {
165
+ label: "Content Fragment Unpublished",
166
+ value: "aem.sites.contentFragment.unpublished"
167
+ },
168
+ {
169
+ label: "Content Fragment Deleted",
170
+ value: "aem.sites.contentFragment.deleted"
171
+ },
172
+ {
173
+ label: "Page Created",
174
+ value: "aem.sites.page.created"
175
+ },
176
+ {
177
+ label: "Page Modified",
178
+ value: "aem.sites.page.modified"
179
+ },
180
+ {
181
+ label: "Page Published",
182
+ value: "aem.sites.page.published"
183
+ },
184
+ {
185
+ label: "Page Unpublished",
186
+ value: "aem.sites.page.unpublished"
187
+ },
188
+ {
189
+ label: "Page Deleted",
190
+ value: "aem.sites.page.deleted"
191
+ }
192
+ ];
193
+ const AEM_ASSETS_EVENT_TYPES = [
194
+ {
195
+ label: "Asset Processing Completed",
196
+ value: "aem.assets.asset.processing_completed"
197
+ },
198
+ {
199
+ label: "Asset Metadata Updated",
200
+ value: "aem.assets.asset.metadata_updated"
201
+ },
202
+ {
203
+ label: "Asset Published",
204
+ value: "aem.assets.asset.published"
205
+ },
206
+ {
207
+ label: "Asset Unpublished",
208
+ value: "aem.assets.asset.unpublished"
209
+ },
210
+ {
211
+ label: "Asset Deleted",
212
+ value: "aem.assets.asset.deleted"
213
+ }
214
+ ];
215
+ const DATE_ONLY_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
216
+ //#endregion
217
+ //#region src/connections/aemOAuthServerToServer.ts
218
+ const aemOAuthServerToServer = (0, _prismatic_io_spectral.oauth2Connection)({
219
+ key: SERVER_TO_SERVER_CONNECTION_KEY,
220
+ display: {
221
+ label: "OAuth 2.0 Client Credentials",
222
+ description: "Authenticate to AEM as a Cloud Service with an OAuth Server-to-Server credential from the Adobe Developer Console."
223
+ },
224
+ oauth2Type: _prismatic_io_spectral.OAuth2Type.ClientCredentials,
225
+ inputs: {
226
+ aemHost: {
227
+ label: "AEM Author Host",
228
+ placeholder: "Enter AEM author host",
229
+ type: "string",
230
+ required: true,
231
+ shown: true,
232
+ comments: "The host name of the AEM as a Cloud Service author environment, without https://. Shown in Cloud Manager as the author URL.",
233
+ example: "author-p12345-e123456.adobeaemcloud.com"
234
+ },
235
+ clientId: {
236
+ label: "Client ID",
237
+ placeholder: "Enter client ID",
238
+ type: "string",
239
+ required: true,
240
+ shown: true,
241
+ comments: "The Client ID of the OAuth Server-to-Server credential in the [Adobe Developer Console](https://developer.adobe.com/console) project. Also sent as the X-Api-Key header.",
242
+ example: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
243
+ },
244
+ clientSecret: {
245
+ label: "Client Secret",
246
+ placeholder: "Enter client secret",
247
+ type: "password",
248
+ required: true,
249
+ shown: true,
250
+ comments: "The Client Secret of the OAuth Server-to-Server credential in the Adobe Developer Console project."
251
+ },
252
+ scopes: {
253
+ label: "Scopes",
254
+ placeholder: "Enter scopes",
255
+ type: "string",
256
+ required: true,
257
+ shown: true,
258
+ comments: "The space or comma separated scopes listed on the OAuth Server-to-Server credential in the Adobe Developer Console. Copy them exactly as shown.",
259
+ example: "openid, AdobeID"
260
+ },
261
+ tokenUrl: {
262
+ label: "Token URL",
263
+ placeholder: "Enter token URL",
264
+ type: "string",
265
+ required: true,
266
+ shown: true,
267
+ comments: "The Adobe IMS token endpoint. Change only when Adobe directs a different region.",
268
+ example: DEFAULT_TOKEN_URL,
269
+ default: DEFAULT_TOKEN_URL
270
+ }
271
+ }
272
+ });
273
+ //#endregion
274
+ //#region src/connections/aemOAuthWebApp.ts
275
+ const aemOAuthWebApp = (0, _prismatic_io_spectral.oauth2Connection)({
276
+ key: WEB_APP_CONNECTION_KEY,
277
+ display: {
278
+ label: "OAuth 2.0",
279
+ description: "Authenticate to AEM as a Cloud Service as an Adobe user with an OAuth Web App credential from the Adobe Developer Console. Requests run with that user's AEM permissions."
280
+ },
281
+ oauth2Type: _prismatic_io_spectral.OAuth2Type.AuthorizationCode,
282
+ inputs: {
283
+ aemHost: {
284
+ label: "AEM Author Host",
285
+ placeholder: "Enter AEM author host",
286
+ type: "string",
287
+ required: true,
288
+ shown: true,
289
+ comments: "The host name of the AEM as a Cloud Service author environment, without https://. Shown in Cloud Manager as the author URL.",
290
+ example: "author-p12345-e123456.adobeaemcloud.com"
291
+ },
292
+ clientId: {
293
+ label: "Client ID",
294
+ placeholder: "Enter client ID",
295
+ type: "string",
296
+ required: true,
297
+ shown: true,
298
+ comments: "The Client ID of the OAuth Web App credential in the [Adobe Developer Console](https://developer.adobe.com/console) project. Also sent as the X-Api-Key header.",
299
+ example: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
300
+ },
301
+ clientSecret: {
302
+ label: "Client Secret",
303
+ placeholder: "Enter client secret",
304
+ type: "password",
305
+ required: true,
306
+ shown: true,
307
+ comments: "The Client Secret of the OAuth Web App credential in the Adobe Developer Console project."
308
+ },
309
+ scopes: {
310
+ label: "Scopes",
311
+ placeholder: "Enter scopes",
312
+ type: "string",
313
+ required: true,
314
+ shown: true,
315
+ comments: "The comma separated scopes to request, exactly as the credential's Scopes tab in the Adobe Developer Console lists them. Adobe rejects the authorization when a scope the credential does not list is requested.",
316
+ example: WEB_APP_DEFAULT_SCOPES,
317
+ default: WEB_APP_DEFAULT_SCOPES
318
+ },
319
+ authorizeUrl: {
320
+ label: "Authorize URL",
321
+ placeholder: "Enter authorize URL",
322
+ type: "string",
323
+ required: true,
324
+ shown: true,
325
+ comments: "The Adobe IMS authorization endpoint. Change only when Adobe directs a different region.",
326
+ example: DEFAULT_AUTHORIZE_URL,
327
+ default: DEFAULT_AUTHORIZE_URL
328
+ },
329
+ tokenUrl: {
330
+ label: "Token URL",
331
+ placeholder: "Enter token URL",
332
+ type: "string",
333
+ required: true,
334
+ shown: true,
335
+ comments: "The Adobe IMS token endpoint. Change only when Adobe directs a different region.",
336
+ example: DEFAULT_TOKEN_URL,
337
+ default: DEFAULT_TOKEN_URL
338
+ }
339
+ }
340
+ });
341
+ //#endregion
342
+ //#region src/connections/index.ts
343
+ var connections_default = [aemOAuthServerToServer, aemOAuthWebApp];
344
+ //#endregion
345
+ //#region src/utils/network.ts
346
+ const blockedRanges = new node_net.BlockList();
347
+ for (const [network, prefix] of [
348
+ ["0.0.0.0", 8],
349
+ ["10.0.0.0", 8],
350
+ ["100.64.0.0", 10],
351
+ ["127.0.0.0", 8],
352
+ ["169.254.0.0", 16],
353
+ ["172.16.0.0", 12],
354
+ ["192.0.0.0", 24],
355
+ ["192.168.0.0", 16],
356
+ ["198.18.0.0", 15],
357
+ ["224.0.0.0", 4],
358
+ ["240.0.0.0", 4]
359
+ ]) blockedRanges.addSubnet(network, prefix, "ipv4");
360
+ for (const [network, prefix] of [
361
+ ["::", 128],
362
+ ["::1", 128],
363
+ ["fc00::", 7],
364
+ ["fe80::", 10],
365
+ ["ff00::", 8]
366
+ ]) blockedRanges.addSubnet(network, prefix, "ipv6");
367
+ const assertPublicUrl = (url) => {
368
+ const parsed = new URL(url);
369
+ if (parsed.protocol !== "https:") throw new Error(`Only https:// URLs may be fetched. Received: ${url}`);
370
+ if (isBlockedAddress(parsed.hostname.replace(/^\[|\]$/g, ""))) throw new Error(`Refusing to fetch a non-public address: ${parsed.hostname}`);
371
+ };
372
+ const guardedLookup = (hostname, options, callback) => {
373
+ (0, node_dns.lookup)(hostname, {
374
+ ...options,
375
+ all: true
376
+ }, (error, addresses) => {
377
+ if (error) return callback(error, "", 0);
378
+ const resolved = addresses;
379
+ if (resolved.find((entry) => isBlockedAddress(entry.address)) || !resolved.length) return callback(/* @__PURE__ */ new Error(`Refusing to fetch ${hostname}: it resolves to a non-public address.`), "", 0);
380
+ if (options.all) return callback(null, resolved);
381
+ return callback(null, resolved[0].address, resolved[0].family);
382
+ });
383
+ };
384
+ const publicHttpsAgent = new node_https.Agent({ lookup: guardedLookup });
385
+ const toIpv6Groups = (address) => {
386
+ let text = address.toLowerCase();
387
+ const dotted = text.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
388
+ const ipv4Groups = [];
389
+ if (dotted) {
390
+ const [a, b, c, d] = dotted.slice(1).map((part) => _prismatic_io_spectral.util.types.toInt(part));
391
+ ipv4Groups.push(a << 8 | b, c << 8 | d);
392
+ text = `${text.slice(0, dotted.index)}0:0`;
393
+ }
394
+ const [head, tail] = text.includes("::") ? text.split("::") : [text, void 0];
395
+ const headGroups = head ? head.split(":") : [];
396
+ const tailGroups = tail ? tail.split(":") : [];
397
+ const fill = tail === void 0 ? [] : Array(8 - headGroups.length - tailGroups.length).fill("0");
398
+ const groups = [
399
+ ...headGroups,
400
+ ...fill,
401
+ ...tailGroups
402
+ ].map((group) => _prismatic_io_spectral.util.types.toNumber(`0x${group}`));
403
+ return ipv4Groups.length ? [...groups.slice(0, 6), ...ipv4Groups] : groups;
404
+ };
405
+ const embeddedIpv4 = (groups) => {
406
+ const toIpv4 = (high, low) => [
407
+ high >> 8,
408
+ high & 255,
409
+ low >> 8,
410
+ low & 255
411
+ ].join(".");
412
+ const zeros = (from, to) => groups.slice(from, to).every((group) => group === 0);
413
+ if (groups[0] === 8194) return toIpv4(groups[1], groups[2]);
414
+ if (groups[0] === 100 && groups[1] === 65435 && zeros(2, 6)) return toIpv4(groups[6], groups[7]);
415
+ if (zeros(0, 5) && (groups[5] === 0 || groups[5] === 65535)) return toIpv4(groups[6], groups[7]);
416
+ };
417
+ function isBlockedAddress(address) {
418
+ const family = (0, node_net.isIP)(address);
419
+ if (family === 4) return blockedRanges.check(address, "ipv4");
420
+ if (family !== 6) return false;
421
+ if (blockedRanges.check(address, "ipv6")) return true;
422
+ const ipv4 = embeddedIpv4(toIpv6Groups(address));
423
+ return ipv4 !== void 0 && blockedRanges.check(ipv4, "ipv4");
424
+ }
425
+ //#endregion
426
+ //#region src/client.ts
427
+ const SETUP_HINT = "AEM returned 403 Forbidden. Confirm the connection's Client ID is listed under allowedClientIDs.author in the environment's config/api.yaml, and that the Developer Console credential includes a product profile with access to this API.";
428
+ const WEB_APP_SETUP_HINT = "AEM returned 403 Forbidden. Confirm the connection's Client ID is listed under allowedClientIDs.author in the environment's config/api.yaml, and that the signed-in Adobe user has AEM access to this content.";
429
+ const GATEWAY_INVALID_API_KEY = "403003";
430
+ const GATEWAY_HINT = "Adobe's API gateway rejected the connection's Client ID for this endpoint (Api Key is invalid). Confirm the Developer Console project behind the credential includes the AEM API that serves this request.";
431
+ const retryConfig = {
432
+ retries: 5,
433
+ useExponentialBackoff: true,
434
+ retryCondition: (error) => RETRYABLE_STATUS_CODES.includes(error.response?.status ?? 0)
435
+ };
436
+ const getAemHost = (connection) => {
437
+ const raw = _prismatic_io_spectral.util.types.toString(connection.fields.aemHost).trim();
438
+ let parsed;
439
+ try {
440
+ parsed = new URL(/^https?:\/\//i.test(raw) ? raw : `https://${raw}`);
441
+ } catch {
442
+ parsed = void 0;
443
+ }
444
+ const host = (parsed?.hostname ?? raw).toLowerCase().replace(/\.$/, "");
445
+ if (!parsed || parsed.username || parsed.password || parsed.port || !/^[a-z0-9-]+(\.[a-z0-9-]+)*$/.test(host) || !host.endsWith(".adobeaemcloud.com")) throw new _prismatic_io_spectral.ConnectionError(connection, `AEM Author Host must be an AEM as a Cloud Service host ending in ${AEM_HOST_SUFFIX}, such as author-p12345-e123456${AEM_HOST_SUFFIX}. Received: "${host}"`);
446
+ return host;
447
+ };
448
+ const getAuthHeaders = (connection) => {
449
+ if (connection.key !== aemOAuthServerToServer.key && connection.key !== aemOAuthWebApp.key) throw new _prismatic_io_spectral.ConnectionError(connection, `Unexpected connection type: ${connection.key}`);
450
+ return {
451
+ Authorization: `Bearer ${_prismatic_io_spectral.util.types.toString(connection.token?.access_token)}`,
452
+ "X-Api-Key": _prismatic_io_spectral.util.types.toString(connection.fields.clientId)
453
+ };
454
+ };
455
+ const MISSING_SCOPES_DETAIL = /missing required scopes/i;
456
+ const WEB_APP_SCOPES_HINT = "This request needs a scope the OAuth Web App credential is not granted, so use the OAuth 2.0 Client Credentials connection for it: content fragment actions and the New and Updated Fragments trigger need it.";
457
+ const HTML_PAGE_HINT = "Adobe returned an HTML error page instead of a JSON problem, which it does for a job or asset ID it does not know.";
458
+ const UNAVAILABLE_STATUS_CODES = [
459
+ 502,
460
+ 503,
461
+ 504
462
+ ];
463
+ const UNAVAILABLE_HINT = "The Adobe Experience Manager environment is unavailable. A sandbox environment answers this way for several minutes while it de-hibernates or restarts: check its status in Cloud Manager and retry.";
464
+ const HTML_SUCCESS_MESSAGE = "Adobe Experience Manager returned an HTML page instead of a JSON response. A hibernated sandbox environment answers this way: de-hibernate it in Cloud Manager and retry.";
465
+ const HTML_PAGE_PATTERN = /^\s*(<!doctype html|<html)/i;
466
+ const addSetupHint = (client, connection) => {
467
+ const hint = connection.key === aemOAuthWebApp.key ? WEB_APP_SETUP_HINT : SETUP_HINT;
468
+ client.interceptors.response.use(void 0, (error) => {
469
+ if (typeof error.response?.data === "string" && HTML_PAGE_PATTERN.test(error.response.data)) {
470
+ error.response.data = "(HTML error page omitted)";
471
+ const unavailable = UNAVAILABLE_STATUS_CODES.includes(error.response.status ?? 0);
472
+ error.message = `${error.message}. ${unavailable ? UNAVAILABLE_HINT : HTML_PAGE_HINT}`;
473
+ }
474
+ if (error.response?.status === 403) {
475
+ const body = error.response.data;
476
+ const detail = typeof body?.detail === "string" ? body.detail : void 0;
477
+ error.message = `${body?.error_code === GATEWAY_INVALID_API_KEY ? GATEWAY_HINT : connection.key === aemOAuthWebApp.key && detail && MISSING_SCOPES_DETAIL.test(detail) ? WEB_APP_SCOPES_HINT : hint}${detail ? ` Adobe: ${detail}` : ""} ${error.message}`;
478
+ }
479
+ return Promise.reject(error);
480
+ });
481
+ };
482
+ const getAemBaseUrl = (connection) => `https://${getAemHost(connection)}`;
483
+ const createAemClient = (connection, debug = false) => {
484
+ const client = (0, _prismatic_io_spectral_http.createClient)({
485
+ baseUrl: getAemBaseUrl(connection),
486
+ headers: getAuthHeaders(connection),
487
+ debug,
488
+ retryConfig,
489
+ responseType: "json"
490
+ });
491
+ client.interceptors.response.use((response) => {
492
+ if (typeof response.data === "string" && HTML_PAGE_PATTERN.test(response.data)) throw new Error(HTML_SUCCESS_MESSAGE);
493
+ return response;
494
+ });
495
+ addSetupHint(client, connection);
496
+ return client;
497
+ };
498
+ const createAemDownloadClient = (connection, debug = false) => {
499
+ const client = (0, _prismatic_io_spectral_http.createClient)({
500
+ baseUrl: getAemBaseUrl(connection),
501
+ headers: getAuthHeaders(connection),
502
+ debug,
503
+ retryConfig,
504
+ responseType: "arraybuffer"
505
+ });
506
+ addSetupHint(client, connection);
507
+ return client;
508
+ };
509
+ const isIoEventsConnection = (connection) => connection.key === aemOAuthServerToServer.key;
510
+ const createIoEventsClient = (connection, debug = false) => {
511
+ if (!isIoEventsConnection(connection)) throw new _prismatic_io_spectral.ConnectionError(connection, "Adobe I/O Events registrations require the OAuth 2.0 Client Credentials connection.");
512
+ return (0, _prismatic_io_spectral_http.createClient)({
513
+ baseUrl: IO_EVENTS_BASE_URL,
514
+ headers: getAuthHeaders(connection),
515
+ debug,
516
+ retryConfig,
517
+ responseType: "json"
518
+ });
519
+ };
520
+ const createPublicClient = (debug = false) => {
521
+ const client = (0, _prismatic_io_spectral_http.createClient)({
522
+ baseUrl: "",
523
+ debug,
524
+ retryConfig,
525
+ responseType: "text"
526
+ });
527
+ client.defaults.httpsAgent = publicHttpsAgent;
528
+ client.defaults.beforeRedirect = (options) => {
529
+ assertPublicUrl(_prismatic_io_spectral.util.types.toString(options.href));
530
+ };
531
+ client.interceptors.request.use((config) => {
532
+ assertPublicUrl(_prismatic_io_spectral.util.types.toString(config.url));
533
+ return config;
534
+ });
535
+ return client;
536
+ };
537
+ //#endregion
538
+ //#region src/examplePayloads/assets.ts
539
+ const exampleAssetSearchHit$1 = {
540
+ assetId: "urn:aaid:aem:4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
541
+ repositoryMetadata: {
542
+ "repo:name": "city.jpeg",
543
+ "repo:path": "/content/dam/wknd-shared/en/city.jpeg",
544
+ "repo:assetId": "urn:aaid:aem:4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
545
+ "repo:createDate": "2026-04-14T06:31:07.174Z",
546
+ "repo:modifyDate": "2026-04-15T05:01:44.229Z",
547
+ "repo:ancestors": ["urn:aaid:aem:abcd1234-ab12-ab12-ab12-abcdef123456"],
548
+ "dc:format": "image/jpeg",
549
+ "repo:size": 338049,
550
+ "aem:published": "2026-04-15T05:03:47.229Z"
551
+ },
552
+ assetMetadata: {
553
+ "dc:title": "City Skyline",
554
+ "xcm:keywords": [{
555
+ tagId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
556
+ value: "WKND Shared : Region / City",
557
+ "repo:ancestors": [
558
+ "wknd-shared",
559
+ "region",
560
+ "city"
561
+ ]
562
+ }]
563
+ }
564
+ };
565
+ const searchAssetsExamplePayload = { data: {
566
+ hits: { results: [exampleAssetSearchHit$1] },
567
+ cursor: "eyJzZWFyY2hBZnRlciI6WzE3MTMxNTc3MDQyMjldfQ",
568
+ search_metadata: {
569
+ count: 1,
570
+ totalCount: {
571
+ total: 1,
572
+ relation: "eq"
573
+ },
574
+ searchDuration: 42
575
+ }
576
+ } };
577
+ const getAssetMetadataExamplePayload = { data: {
578
+ assetId: exampleAssetSearchHit$1.assetId,
579
+ repositoryMetadata: exampleAssetSearchHit$1.repositoryMetadata,
580
+ assetMetadata: exampleAssetSearchHit$1.assetMetadata
581
+ } };
582
+ const listAssetRenditionsExamplePayload = { data: {
583
+ assetId: "urn:aaid:aem:4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
584
+ "repo:name": "city.jpeg",
585
+ items: [{
586
+ name: "cq5dam.web.1280.1280.jpeg",
587
+ format: "image/jpeg",
588
+ size: 102400,
589
+ dimensions: {
590
+ width: 1280,
591
+ height: 998
592
+ }
593
+ }, {
594
+ name: "cq5dam.thumbnail.319.319.png",
595
+ format: "image/png",
596
+ size: 40960,
597
+ dimensions: {
598
+ width: 319,
599
+ height: 249
600
+ }
601
+ }]
602
+ } };
603
+ const downloadAssetExamplePayload = {
604
+ data: Buffer.from("example binary content"),
605
+ contentType: "image/jpeg"
606
+ };
607
+ const downloadAssetRenditionExamplePayload = {
608
+ data: Buffer.from("example binary content"),
609
+ contentType: "image/jpeg"
610
+ };
611
+ const importAssetFromUrlExamplePayload = { data: {
612
+ id: "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
613
+ operation: "aem.assets.import.fromurl",
614
+ state: "PROCESSING",
615
+ data: {
616
+ id: "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
617
+ config: {
618
+ folder: "/content/dam/wknd-shared/en",
619
+ items: ["https://www.example.com/images/city.jpeg"]
620
+ },
621
+ progress: {
622
+ step: "QUEUED",
623
+ total: 1,
624
+ imported: 0,
625
+ failed: 0,
626
+ skipped: 0,
627
+ size: 338049,
628
+ transferred: 0,
629
+ started: "2026-04-15T05:00:12.418Z",
630
+ lastUpdated: "2026-04-15T05:00:12.418Z"
631
+ }
632
+ }
633
+ } };
634
+ const getImportJobStatusExamplePayload = { data: {
635
+ id: "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
636
+ operation: "aem.assets.import.fromurl",
637
+ status: 202,
638
+ description: "OK",
639
+ state: "PROCESSING",
640
+ progress: {
641
+ step: "IMPORTING",
642
+ total: 1,
643
+ imported: 0,
644
+ failed: 0,
645
+ skipped: 0,
646
+ size: 338049,
647
+ transferred: 169024,
648
+ started: "2026-04-15T05:00:12.418Z",
649
+ lastUpdated: "2026-04-15T05:00:14.902Z"
650
+ },
651
+ errors: []
652
+ } };
653
+ const updateAssetMetadataExamplePayload = getAssetMetadataExamplePayload;
654
+ const getAssetJobStatusExamplePayload = { data: {
655
+ jobId: "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
656
+ state: "PROCESSING"
657
+ } };
658
+ const deleteAssetExamplePayload = { data: {
659
+ assetId: "urn:aaid:aem:4f2e8b1a-6c3d-4e5f-9a7b-8c9d0e1f2a3b",
660
+ deleted: true
661
+ } };
662
+ const selectAssetExamplePayload = { result: [{
663
+ key: "urn:aaid:aem:4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
664
+ label: "/content/dam/wknd-shared/en/city.jpeg"
665
+ }] };
666
+ const selectAssetRenditionExamplePayload = { result: [{
667
+ key: "cq5dam.thumbnail.319.319.png",
668
+ label: "cq5dam.thumbnail.319.319.png"
669
+ }, {
670
+ key: "cq5dam.web.1280.1280.jpeg",
671
+ label: "cq5dam.web.1280.1280.jpeg"
672
+ }] };
673
+ //#endregion
674
+ //#region src/examplePayloads/contentFragments.ts
675
+ const exampleContentFragment$1 = {
676
+ id: "4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
677
+ path: "/content/dam/wknd-shared/en/adventures/surf-camp-in-costa-rica/surf-camp-in-costa-rica",
678
+ title: "Surf Camp in Costa Rica",
679
+ description: "A week of surfing on the Pacific coast.",
680
+ status: "PUBLISHED",
681
+ created: {
682
+ at: "2026-03-02T15:04:11.000Z",
683
+ by: "admin",
684
+ fullName: "Admin User"
685
+ },
686
+ modified: {
687
+ at: "2026-09-18T09:21:44.000Z",
688
+ by: "jdoe",
689
+ fullName: "Jane Doe"
690
+ },
691
+ published: {
692
+ at: "2026-09-18T09:25:02.000Z",
693
+ by: "jdoe",
694
+ fullName: "Jane Doe"
695
+ },
696
+ model: {
697
+ id: "L2NvbmYvd2tuZC1zaGFyZWQvc2V0dGluZ3MvZGFtL2NmbS9tb2RlbHMvYWR2ZW50dXJl",
698
+ path: "/conf/wknd-shared/settings/dam/cfm/models/adventure",
699
+ name: "adventure",
700
+ title: "Adventure"
701
+ },
702
+ tags: [{
703
+ id: "wknd-shared:activity/surfing",
704
+ title: "Surfing",
705
+ titlePath: "WKND Shared : Activity / Surfing"
706
+ }],
707
+ fields: [{
708
+ name: "title",
709
+ type: "text",
710
+ multiple: false,
711
+ values: ["Surf Camp in Costa Rica"]
712
+ }, {
713
+ name: "description",
714
+ type: "long-text",
715
+ multiple: false,
716
+ mimeType: "text/html",
717
+ values: ["<p>A week of surfing on the Pacific coast.</p>"]
718
+ }]
719
+ };
720
+ const listContentFragmentsExamplePayload = { data: {
721
+ items: [exampleContentFragment$1],
722
+ cursor: "eyJsYXN0SWQiOiI0ZjJiNmMxZSJ9"
723
+ } };
724
+ const searchContentFragmentsExamplePayload = { data: {
725
+ items: [exampleContentFragment$1],
726
+ cursor: "eyJsYXN0SWQiOiI0ZjJiNmMxZSJ9"
727
+ } };
728
+ const getContentFragmentExamplePayload = { data: exampleContentFragment$1 };
729
+ const listContentFragmentVariationsExamplePayload = { data: { items: [{
730
+ name: "summer",
731
+ title: "Summer",
732
+ description: "Seasonal variation for the summer campaign.",
733
+ fields: [{
734
+ name: "title",
735
+ type: "text",
736
+ multiple: false,
737
+ values: ["Summer Surf Camp"]
738
+ }],
739
+ tags: [],
740
+ modified: {
741
+ at: "2026-09-10T12:00:00.000Z",
742
+ by: "jdoe"
743
+ }
744
+ }] } };
745
+ const listContentFragmentModelsExamplePayload = { data: { items: [{
746
+ id: "L2NvbmYvd2tuZC1zaGFyZWQvc2V0dGluZ3MvZGFtL2NmbS9tb2RlbHMvYWR2ZW50dXJl",
747
+ path: "/conf/wknd-shared/settings/dam/cfm/models/adventure",
748
+ name: "Adventure",
749
+ description: "An adventure offered by WKND."
750
+ }] } };
751
+ const selectContentFragmentModelExamplePayload = { result: [{
752
+ key: "L2NvbmYvd2tuZC1zaGFyZWQvc2V0dGluZ3MvZGFtL2NmbS9tb2RlbHMvYWR2ZW50dXJl",
753
+ label: "Adventure"
754
+ }] };
755
+ const selectContentFragmentExamplePayload = { result: [{
756
+ key: exampleContentFragment$1.id,
757
+ label: `${exampleContentFragment$1.title} (${exampleContentFragment$1.path})`
758
+ }] };
759
+ //#endregion
760
+ //#region src/examplePayloads/folders.ts
761
+ const listFolderContentsExamplePayload = { data: {
762
+ self: {
763
+ type: "FOLDER",
764
+ folderId: "urn:aaid:aem:abcd1234-ab12-ab12-ab12-abcdef123456",
765
+ name: "en",
766
+ title: "English",
767
+ path: "/content/dam/wknd-shared/en"
768
+ },
769
+ children: [{
770
+ type: "FOLDER",
771
+ folderId: "urn:aaid:aem:bcde2345-bc23-bc23-bc23-bcdef2345678",
772
+ name: "adventures",
773
+ title: "Adventures",
774
+ path: "/content/dam/wknd-shared/en/adventures"
775
+ }, {
776
+ type: "ASSET",
777
+ assetId: "urn:aaid:aem:4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
778
+ name: "city.jpeg",
779
+ size: 338049,
780
+ lastModifiedAt: "2026-04-15T05:01:44.229Z"
781
+ }],
782
+ cursor: "eyJvZmZzZXQiOjUwfQ"
783
+ } };
784
+ const listAssetsInFolderTreeExamplePayload = { data: [{
785
+ type: "ASSET",
786
+ assetId: "urn:aaid:aem:4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
787
+ name: "city.jpeg",
788
+ size: 338049,
789
+ lastModifiedAt: "2026-04-15T05:01:44.229Z",
790
+ folderPath: "/content/dam/wknd-shared/en"
791
+ }] };
792
+ const folderJobExamplePayload = { data: {
793
+ jobId: "5f8b2c1e-3a4d-4e6f-9b7a-1c2d3e4f5a6b",
794
+ state: "PROCESSING"
795
+ } };
796
+ const deleteFoldersExamplePayload = folderJobExamplePayload;
797
+ const getFolderJobStatusExamplePayload = folderJobExamplePayload;
798
+ const createFoldersExamplePayload = { data: {
799
+ operation: "adobe.folders.createFolders",
800
+ status: 200,
801
+ description: "Created folders",
802
+ data: { values: { successes: [{
803
+ type: "FOLDER",
804
+ name: "adventures",
805
+ folderId: "urn:aaid:aem:72583e15-33e8-4c86-bc8c-1f0557d7aa7b",
806
+ path: "/content/dam/wknd-shared/en/adventures"
807
+ }] } },
808
+ errors: [],
809
+ warnings: []
810
+ } };
811
+ const selectFolderExamplePayload = { result: [{
812
+ key: "urn:aaid:aem:abcd1234-ab12-ab12-ab12-abcdef123456",
813
+ label: "/content/dam/wknd-shared/en"
814
+ }] };
815
+ const selectFolderPathExamplePayload = { result: [{
816
+ key: "/content/dam",
817
+ label: "/content/dam"
818
+ }, {
819
+ key: "/content/dam/wknd-shared/en",
820
+ label: "/content/dam/wknd-shared/en"
821
+ }] };
822
+ //#endregion
823
+ //#region src/examplePayloads/misc.ts
824
+ const rawRequestExamplePayload = { data: { items: [] } };
825
+ //#endregion
826
+ //#region src/examplePayloads/pages.ts
827
+ const listSitemapUrlsExamplePayload = { data: [{
828
+ loc: "https://www.example.com/en/adventures/surf-camp.html",
829
+ lastmod: "2026-09-18T09:25:02.000Z"
830
+ }, {
831
+ loc: "https://www.example.com/en/about-us.html",
832
+ lastmod: null
833
+ }] };
834
+ const getPublishedPageHtmlExamplePayload = { data: {
835
+ url: "https://www.example.com/en/adventures/surf-camp.html",
836
+ finalUrl: "https://www.example.com/en/adventures/surf-camp.html",
837
+ statusCode: 200,
838
+ contentType: "text/html;charset=utf-8",
839
+ lastModified: "Thu, 18 Sep 2026 09:25:02 GMT",
840
+ etag: "\"a1b2c3d4\"",
841
+ html: "<!DOCTYPE html><html><head><title>Surf Camp</title></head><body><h1>Surf Camp</h1></body></html>"
842
+ } };
843
+ const selectSitemapPageExamplePayload = { result: [{
844
+ key: "https://www.example.com/en/about-us.html",
845
+ label: "https://www.example.com/en/about-us.html"
846
+ }, {
847
+ key: "https://www.example.com/en/adventures/surf-camp.html",
848
+ label: "https://www.example.com/en/adventures/surf-camp.html"
849
+ }] };
850
+ //#endregion
851
+ //#region src/examplePayloads/triggers.ts
852
+ const exampleAssetSearchHit = searchAssetsExamplePayload.data.hits.results[0];
853
+ const exampleContentFragment = getContentFragmentExamplePayload.data;
854
+ const exampleTriggerPayloadBase = {
855
+ queryParameters: {},
856
+ rawBody: { data: null },
857
+ pathFragment: "",
858
+ webhookUrls: {},
859
+ webhookApiKeys: {},
860
+ invokeUrl: "",
861
+ executionId: "RXhhbXBsZUV4ZWN1dGlvblJlc3VsdElk",
862
+ customer: {
863
+ id: "testCustomerId",
864
+ name: "Test Customer",
865
+ externalId: "testExternalId"
866
+ },
867
+ instance: {
868
+ id: "testInstanceId",
869
+ name: "Test Instance"
870
+ },
871
+ user: {
872
+ id: "testUserId",
873
+ email: "user@example.com",
874
+ name: "Test User",
875
+ externalId: "testUserExternalId"
876
+ },
877
+ integration: {
878
+ id: "testIntegrationId",
879
+ name: "Test Integration",
880
+ versionSequenceId: "1",
881
+ externalVersion: ""
882
+ },
883
+ flow: {
884
+ id: "testFlowId",
885
+ name: "Test Flow",
886
+ stableId: "testFlowStableId"
887
+ },
888
+ startedAt: "2024-01-15T00:00:00.000Z",
889
+ globalDebug: false
890
+ };
891
+ const contentFragmentItem = {
892
+ changeType: "published",
893
+ record: {
894
+ resourceType: "contentFragment",
895
+ id: exampleContentFragment.id,
896
+ path: exampleContentFragment.path,
897
+ url: `https://www.example.com${exampleContentFragment.path}`,
898
+ title: exampleContentFragment.title,
899
+ tags: [{
900
+ id: "wknd-shared:activity/surfing",
901
+ title: "Surfing",
902
+ titlePath: "WKND Shared : Activity / Surfing"
903
+ }],
904
+ created: "2026-03-02T15:04:11.000Z",
905
+ modified: "2026-09-18T09:21:44.000Z",
906
+ published: "2026-09-18T09:25:02.000Z",
907
+ scope: "/content/dam/wknd-shared/en",
908
+ data: exampleContentFragment
909
+ }
910
+ };
911
+ const contentFragmentChangesExamplePayload = {
912
+ payload: {
913
+ ...exampleTriggerPayloadBase,
914
+ headers: {},
915
+ body: { data: { items: [contentFragmentItem] } }
916
+ },
917
+ polledNoChanges: false
918
+ };
919
+ const assetItem = {
920
+ changeType: "published",
921
+ record: {
922
+ resourceType: "asset",
923
+ id: exampleAssetSearchHit.assetId,
924
+ path: "/content/dam/wknd-shared/en/city.jpeg",
925
+ url: "https://www.example.com/content/dam/wknd-shared/en/city.jpeg",
926
+ title: "City Skyline",
927
+ tags: [{
928
+ id: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
929
+ title: "City",
930
+ titlePath: "WKND Shared : Region / City"
931
+ }],
932
+ created: "2026-04-14T06:31:07.174Z",
933
+ modified: "2026-04-15T05:01:44.229Z",
934
+ published: "2026-04-15T05:03:47.229Z",
935
+ scope: "urn:aaid:aem:abcd1234-ab12-ab12-ab12-abcdef123456",
936
+ data: exampleAssetSearchHit
937
+ }
938
+ };
939
+ const assetChangesExamplePayload = {
940
+ payload: {
941
+ ...exampleTriggerPayloadBase,
942
+ headers: {},
943
+ body: { data: { items: [assetItem] } }
944
+ },
945
+ polledNoChanges: false
946
+ };
947
+ const exampleEvent = {
948
+ specversion: "1.0",
949
+ id: "1b4f6d3e-2a5c-4e8f-9b7a-0c1d2e3f4a5b",
950
+ source: "acct:aem-p12345-e123456@adobe.com",
951
+ type: "aem.sites.page.modified",
952
+ datacontenttype: "application/json",
953
+ time: "2026-09-18T09:25:02.374Z",
954
+ recipientclientid: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
955
+ data: {
956
+ user: {
957
+ imsUserId: "ims-0123456789ABCDEF01234567@techacct.adobe.com",
958
+ principalId: "5f0e1d2c-3b4a-5968-7a8b-9c0d1e2f3a4b@techacct.adobe.com",
959
+ displayName: "5f0e1d2c-3b4a-5968-7a8b-9c0d1e2f3a4b@techacct.adobe.com"
960
+ },
961
+ path: "/content/wknd/us/en/adventures/surf-camp",
962
+ template: { id: "/conf/wknd/settings/wcm/templates/page-content" },
963
+ properties: [{
964
+ name: "cq:lastModified",
965
+ changeType: "modified"
966
+ }, {
967
+ name: "jcr:title",
968
+ changeType: "modified"
969
+ }]
970
+ }
971
+ };
972
+ const eventItem = {
973
+ changeType: "modified",
974
+ record: {
975
+ resourceType: "page",
976
+ id: "/content/wknd/us/en/adventures/surf-camp",
977
+ path: "/content/wknd/us/en/adventures/surf-camp",
978
+ url: "https://www.example.com/content/wknd/us/en/adventures/surf-camp.html",
979
+ title: null,
980
+ tags: [],
981
+ created: null,
982
+ modified: "2026-09-18T09:25:02.374Z",
983
+ published: null,
984
+ scope: "4566206088344853970",
985
+ data: exampleEvent
986
+ },
987
+ eventId: exampleEvent.id,
988
+ eventSource: exampleEvent.source,
989
+ eventType: exampleEvent.type
990
+ };
991
+ const aemSitesEventWebhookExamplePayload = {
992
+ payload: {
993
+ ...exampleTriggerPayloadBase,
994
+ headers: { "content-type": "application/cloudevents+json" },
995
+ body: { data: eventItem }
996
+ },
997
+ branch: "Notification"
998
+ };
999
+ const exampleAssetEvent = {
1000
+ specversion: "1.0",
1001
+ id: "7c2e9a41-5d3b-4f6a-8e1c-2b9d0f4a6c83",
1002
+ source: "acct:aem-p12345-e123456@adobe.com",
1003
+ type: "aem.assets.asset.metadata_updated",
1004
+ datacontenttype: "application/json",
1005
+ time: "2026-09-18T09:31:47.364Z",
1006
+ recipientclientid: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
1007
+ data: {
1008
+ user: {
1009
+ imsUserId: "ims-0123456789ABCDEF01234567@techacct.adobe.com",
1010
+ principalId: "5f0e1d2c-3b4a-5968-7a8b-9c0d1e2f3a4b@techacct.adobe.com"
1011
+ },
1012
+ repositoryMetadata: {
1013
+ "repo:repositoryId": "author-p12345-e123456.adobeaemcloud.com",
1014
+ "repo:assetId": "urn:aaid:aem:5b8f3e2a-9c1d-4e7f-a6b2-3d4c5e6f7a8b",
1015
+ "repo:name": "surf-camp-hero.jpg",
1016
+ "repo:path": "/content/dam/wknd/en/adventures/surf-camp/surf-camp-hero.jpg",
1017
+ "repo:ancestors": ["urn:aaid:aem:1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"],
1018
+ "repo:state": "ACTIVE",
1019
+ "repo:createDate": "2026-09-01T14:02:11.985Z",
1020
+ "repo:modifyDate": "2026-09-01T14:02:43.218Z",
1021
+ "dc:format": "image/jpeg",
1022
+ "aem:assetState": "processed"
1023
+ },
1024
+ assetMetadata: { "dc:title": "Surf Camp Hero" }
1025
+ }
1026
+ };
1027
+ const assetEventItem = {
1028
+ changeType: "modified",
1029
+ record: {
1030
+ resourceType: "asset",
1031
+ id: "urn:aaid:aem:5b8f3e2a-9c1d-4e7f-a6b2-3d4c5e6f7a8b",
1032
+ path: "/content/dam/wknd/en/adventures/surf-camp/surf-camp-hero.jpg",
1033
+ url: "https://www.example.com/content/dam/wknd/en/adventures/surf-camp/surf-camp-hero.jpg",
1034
+ title: "Surf Camp Hero",
1035
+ tags: [],
1036
+ created: null,
1037
+ modified: "2026-09-18T09:31:47.364Z",
1038
+ published: null,
1039
+ scope: "4566206088344853970",
1040
+ data: exampleAssetEvent
1041
+ },
1042
+ eventId: exampleAssetEvent.id,
1043
+ eventSource: exampleAssetEvent.source,
1044
+ eventType: exampleAssetEvent.type
1045
+ };
1046
+ const aemAssetsEventWebhookExamplePayload = {
1047
+ payload: {
1048
+ ...exampleTriggerPayloadBase,
1049
+ headers: { "content-type": "application/cloudevents+json" },
1050
+ body: { data: assetEventItem }
1051
+ },
1052
+ branch: "Notification"
1053
+ };
1054
+ //#endregion
1055
+ //#region src/utils/dates.ts
1056
+ const toIsoDate = (value) => _prismatic_io_spectral.util.types.toDate(DATE_ONLY_PATTERN.test(value) ? `${value}T00:00:00Z` : value);
1057
+ //#endregion
1058
+ //#region src/utils/clean.ts
1059
+ const cleanString = (value) => {
1060
+ const str = _prismatic_io_spectral.util.types.toString(value).trim();
1061
+ return str ? str : void 0;
1062
+ };
1063
+ const cleanRequiredString = (value) => _prismatic_io_spectral.util.types.toString(value).trim();
1064
+ const DAM_ROOT_RELATIVE = DEFAULT_DAM_ROOT.replace(/^\/+/, "");
1065
+ const toDamPath = (value) => {
1066
+ const relative = value.replace(/^\/+/, "").replace(/\/+$/, "");
1067
+ return `/${relative === DAM_ROOT_RELATIVE || relative.startsWith(`${DAM_ROOT_RELATIVE}/`) ? relative : `${DAM_ROOT_RELATIVE}/${relative}`}`.replace(/\/+$/, "");
1068
+ };
1069
+ const cleanDamPath = (value) => {
1070
+ const str = _prismatic_io_spectral.util.types.toString(value).trim();
1071
+ return str ? toDamPath(str) : void 0;
1072
+ };
1073
+ const cleanRequiredDamPath = (value) => {
1074
+ const str = _prismatic_io_spectral.util.types.toString(value).trim();
1075
+ return str ? toDamPath(str) : "";
1076
+ };
1077
+ const cleanStringList = (value) => (Array.isArray(value) ? value : []).map((item) => _prismatic_io_spectral.util.types.toString(item).trim()).filter((item) => item.length > 0);
1078
+ const cleanLimit = (value) => {
1079
+ const str = _prismatic_io_spectral.util.types.toString(value).trim() || void 0;
1080
+ if (str === void 0) return void 0;
1081
+ const limit = /^\d+$/.test(str) ? _prismatic_io_spectral.util.types.toInt(str) : void 0;
1082
+ if (limit === void 0 || limit < 1 || limit > 50) throw new Error(`Limit must be a whole number from 1 to 50. Received: ${str}`);
1083
+ return limit;
1084
+ };
1085
+ const cleanOptionalDateTime = (value) => {
1086
+ const str = _prismatic_io_spectral.util.types.toString(value).trim() || void 0;
1087
+ if (str === void 0) return void 0;
1088
+ let parsed;
1089
+ try {
1090
+ parsed = toIsoDate(str);
1091
+ } catch {
1092
+ throw new Error(`"${str}" is not a valid ISO 8601 date-time.`);
1093
+ }
1094
+ return parsed.toISOString();
1095
+ };
1096
+ const cleanHttpsUrl = (value) => {
1097
+ const str = _prismatic_io_spectral.util.types.toString(value).trim() || void 0;
1098
+ let parsed;
1099
+ try {
1100
+ parsed = str ? new URL(str) : void 0;
1101
+ } catch {
1102
+ parsed = void 0;
1103
+ }
1104
+ if (parsed?.protocol !== "https:") throw new Error(`"${str ?? ""}" must be an absolute https:// URL.`);
1105
+ return parsed.href;
1106
+ };
1107
+ const cleanOptionalHttpsUrl = (value) => _prismatic_io_spectral.util.types.toString(value).trim() ? cleanHttpsUrl(value).replace(/\/$/, "") : void 0;
1108
+ const lookBackDateClean = (value) => {
1109
+ const raw = cleanString(value);
1110
+ if (raw === void 0) return "";
1111
+ const match = typeof value === "string" ? raw.match(DATE_ONLY_PATTERN) : null;
1112
+ if (!match) throw new Error(`Look-back Date must be a date in YYYY-MM-DD format. Received: ${raw}`);
1113
+ const [, yearStr, monthStr, dayStr] = match;
1114
+ const year = _prismatic_io_spectral.util.types.toInt(yearStr);
1115
+ const month = _prismatic_io_spectral.util.types.toInt(monthStr);
1116
+ const day = _prismatic_io_spectral.util.types.toInt(dayStr);
1117
+ const parsed = new Date(Date.UTC(year, month - 1, day));
1118
+ if (parsed.getUTCFullYear() !== year || parsed.getUTCMonth() !== month - 1 || parsed.getUTCDate() !== day) throw new Error(`Look-back Date must be a date in YYYY-MM-DD format. Received: ${raw}`);
1119
+ if (parsed.getTime() > Date.now()) throw new Error(`Look-back Date cannot be a future date. Received: ${raw}`);
1120
+ return parsed.toISOString();
1121
+ };
1122
+ const cleanFolderPaths = (value) => {
1123
+ const paths = (Array.isArray(value) ? value : []).map((item) => _prismatic_io_spectral.util.types.toString(item).trim()).filter((item) => item.length > 0).map(toDamPath);
1124
+ if (!paths.length) throw new Error("Folder Paths must contain at least one folder path.");
1125
+ return paths;
1126
+ };
1127
+ const cleanKeyValueRecord = (value) => {
1128
+ const pairs = (Array.isArray(value) ? value : []).map((pair) => ({
1129
+ key: _prismatic_io_spectral.util.types.toString(pair.key).trim(),
1130
+ value: pair.value
1131
+ })).filter((pair) => pair.key.length > 0);
1132
+ return _prismatic_io_spectral.util.types.keyValPairListToObject(pairs, _prismatic_io_spectral.util.types.toString);
1133
+ };
1134
+ //#endregion
1135
+ //#region src/inputs/common.ts
1136
+ const connection = (0, _prismatic_io_spectral.input)({
1137
+ label: "Connection",
1138
+ type: "connection",
1139
+ required: true,
1140
+ comments: "The AEM as a Cloud Service connection to use."
1141
+ });
1142
+ const fetchAll = (0, _prismatic_io_spectral.input)({
1143
+ label: "Fetch All",
1144
+ type: "boolean",
1145
+ required: false,
1146
+ default: "false",
1147
+ comments: `When true, automatically fetches all pages of results using pagination, up to 500 pages of 50. Limit is ignored; when Cursor is set, fetching starts from that page. When more results remain, the output includes a cursor to continue from.`,
1148
+ clean: _prismatic_io_spectral.util.types.toBool
1149
+ });
1150
+ const cursor = (0, _prismatic_io_spectral.input)({
1151
+ label: "Cursor",
1152
+ placeholder: "Enter cursor",
1153
+ type: "string",
1154
+ required: false,
1155
+ comments: "The cursor returned by a previous page, used to fetch the next page.",
1156
+ example: "eyJsYXN0SWQiOiIxMjM0NSJ9",
1157
+ clean: cleanString
1158
+ });
1159
+ const limit = (0, _prismatic_io_spectral.input)({
1160
+ label: "Limit",
1161
+ placeholder: "Enter limit",
1162
+ type: "string",
1163
+ required: false,
1164
+ comments: `The maximum number of results to return per page, from 1 to 50.`,
1165
+ example: "25",
1166
+ clean: cleanLimit
1167
+ });
1168
+ const pagination = (0, _prismatic_io_spectral.structuredObjectInput)({
1169
+ label: "Pagination",
1170
+ required: false,
1171
+ comments: "Cursor and page-size controls for paging through results.",
1172
+ inputs: {
1173
+ cursor,
1174
+ limit
1175
+ }
1176
+ });
1177
+ const sortOrder = (0, _prismatic_io_spectral.input)({
1178
+ label: "Sort Order",
1179
+ type: "string",
1180
+ required: false,
1181
+ default: "ASC",
1182
+ model: SORT_ORDERS,
1183
+ comments: "The direction to sort results in. Used only when Sort By is set.",
1184
+ clean: cleanString
1185
+ });
1186
+ //#endregion
1187
+ //#region src/inputs/folders.ts
1188
+ const folderPath = (0, _prismatic_io_spectral.input)({
1189
+ label: "Folder Path",
1190
+ placeholder: "Enter folder path",
1191
+ type: "string",
1192
+ required: true,
1193
+ default: DEFAULT_DAM_ROOT,
1194
+ dataSource: "selectFolderPath",
1195
+ comments: "The folder path below /content/dam, such as wknd-shared/en. A full repository path starting with /content/dam is also accepted.",
1196
+ example: "wknd-shared/en",
1197
+ clean: cleanRequiredDamPath
1198
+ });
1199
+ const listFolderContentsInputs = {
1200
+ connection,
1201
+ path: folderPath,
1202
+ fetchAll,
1203
+ pagination,
1204
+ types: (0, _prismatic_io_spectral.input)({
1205
+ label: "Item Types",
1206
+ type: "string",
1207
+ required: false,
1208
+ default: "FOLDER,ASSET",
1209
+ model: FOLDER_LISTING_TYPES,
1210
+ comments: "Which kinds of items to list.",
1211
+ clean: cleanString
1212
+ }),
1213
+ orderBy: (0, _prismatic_io_spectral.input)({
1214
+ label: "Order By",
1215
+ type: "string",
1216
+ required: false,
1217
+ model: FOLDER_ORDER_BY,
1218
+ comments: "The field to order items by. Leave empty for the API default order.",
1219
+ clean: cleanString
1220
+ })
1221
+ };
1222
+ const listAssetsInFolderTreeInputs = {
1223
+ connection,
1224
+ path: {
1225
+ ...folderPath,
1226
+ label: "Root Folder Path",
1227
+ dataSource: "selectFolderPath",
1228
+ comments: "The path of the folder to walk, below /content/dam, such as wknd-shared/en. Assets in every subfolder are included. A full repository path starting with /content/dam is also accepted."
1229
+ }
1230
+ };
1231
+ const folderPaths = (0, _prismatic_io_spectral.input)({
1232
+ label: "Folder Paths",
1233
+ placeholder: "Enter folder path",
1234
+ type: "string",
1235
+ collection: "valuelist",
1236
+ required: true,
1237
+ comments: "The folder paths below /content/dam, such as wknd-shared/en/new-folder. A full repository path starting with /content/dam is also accepted.",
1238
+ example: "wknd-shared/en/new-folder",
1239
+ clean: cleanFolderPaths
1240
+ });
1241
+ const recursive = (0, _prismatic_io_spectral.input)({
1242
+ label: "Recursive",
1243
+ type: "boolean",
1244
+ required: false,
1245
+ default: "false",
1246
+ comments: "When true, deletes each folder and everything inside it.",
1247
+ clean: _prismatic_io_spectral.util.types.toBool
1248
+ });
1249
+ const force = (0, _prismatic_io_spectral.input)({
1250
+ label: "Force",
1251
+ type: "boolean",
1252
+ required: false,
1253
+ default: "false",
1254
+ comments: "When true, deletes even when assets in the folders are referenced elsewhere.",
1255
+ clean: _prismatic_io_spectral.util.types.toBool
1256
+ });
1257
+ const jobId = (0, _prismatic_io_spectral.input)({
1258
+ label: "Job ID",
1259
+ placeholder: "Enter job ID",
1260
+ type: "string",
1261
+ required: true,
1262
+ comments: "The job ID returned by the action that started the job.",
1263
+ example: "5f8b2c1e-3a4d-4e6f-9b7a-1c2d3e4f5a6b",
1264
+ clean: cleanRequiredString
1265
+ });
1266
+ const createFoldersInputs = {
1267
+ connection,
1268
+ folderPaths
1269
+ };
1270
+ const deleteFoldersInputs = {
1271
+ connection,
1272
+ folderPaths: {
1273
+ ...folderPaths,
1274
+ dataSource: "selectFolderPath"
1275
+ },
1276
+ recursive,
1277
+ force
1278
+ };
1279
+ const getFolderJobStatusInputs = {
1280
+ connection,
1281
+ jobId
1282
+ };
1283
+ //#endregion
1284
+ //#region src/inputs/assets.ts
1285
+ const assetId = (0, _prismatic_io_spectral.input)({
1286
+ label: "Asset ID",
1287
+ placeholder: "Enter asset ID",
1288
+ type: "string",
1289
+ required: true,
1290
+ dataSource: "selectAsset",
1291
+ comments: "The ID of the asset, in urn:aaid:aem:... form.",
1292
+ example: "urn:aaid:aem:4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
1293
+ clean: cleanRequiredString
1294
+ });
1295
+ const seoName = (0, _prismatic_io_spectral.input)({
1296
+ label: "File Name",
1297
+ placeholder: "Enter file name",
1298
+ type: "string",
1299
+ required: true,
1300
+ comments: "The file name to request the binary under, usually the asset's own name.",
1301
+ example: "city.jpeg",
1302
+ clean: cleanRequiredString
1303
+ });
1304
+ const renditionName = (0, _prismatic_io_spectral.input)({
1305
+ label: "Rendition Name",
1306
+ placeholder: "Enter rendition name",
1307
+ type: "string",
1308
+ required: true,
1309
+ dataSource: "selectAssetRendition",
1310
+ comments: "The name of the rendition, as returned by List Asset Renditions.",
1311
+ example: "cq5dam.web.1280.1280.jpeg",
1312
+ clean: cleanRequiredString
1313
+ });
1314
+ const folderIds = (0, _prismatic_io_spectral.input)({
1315
+ label: "Folders",
1316
+ placeholder: "Select folder",
1317
+ type: "string",
1318
+ collection: "valuelist",
1319
+ required: false,
1320
+ default: [],
1321
+ dataSource: "selectFolder",
1322
+ comments: "Only include assets inside one of these folder IDs, at any depth.",
1323
+ example: "urn:aaid:aem:abcd1234-ab12-ab12-ab12-abcdef123456",
1324
+ clean: cleanStringList
1325
+ });
1326
+ const mimeTypes = (0, _prismatic_io_spectral.input)({
1327
+ label: "MIME Types",
1328
+ placeholder: "Enter MIME type",
1329
+ type: "string",
1330
+ collection: "valuelist",
1331
+ required: false,
1332
+ default: [],
1333
+ comments: "Only include assets with one of these exact MIME types.",
1334
+ example: "application/pdf",
1335
+ clean: cleanStringList
1336
+ });
1337
+ const searchAssetsInputs = {
1338
+ connection,
1339
+ fetchAll,
1340
+ pagination,
1341
+ folderIds,
1342
+ mimeTypes,
1343
+ modifiedAfter: (0, _prismatic_io_spectral.input)({
1344
+ label: "Modified After",
1345
+ placeholder: "Enter date-time (ISO 8601)",
1346
+ type: "string",
1347
+ required: false,
1348
+ comments: "Only return assets modified at or after this ISO 8601 date-time.",
1349
+ example: "2026-01-01T00:00:00Z",
1350
+ clean: cleanOptionalDateTime
1351
+ }),
1352
+ modifiedBefore: (0, _prismatic_io_spectral.input)({
1353
+ label: "Modified Before",
1354
+ placeholder: "Enter date-time (ISO 8601)",
1355
+ type: "string",
1356
+ required: false,
1357
+ comments: "Only return assets modified before this ISO 8601 date-time.",
1358
+ example: "2026-02-01T00:00:00Z",
1359
+ clean: cleanOptionalDateTime
1360
+ }),
1361
+ filters: (0, _prismatic_io_spectral.structuredObjectInput)({
1362
+ label: "Filters",
1363
+ required: false,
1364
+ comments: "Optional query controls to sort and refine the results.",
1365
+ inputs: {
1366
+ searchText: (0, _prismatic_io_spectral.input)({
1367
+ label: "Search Text",
1368
+ placeholder: "Enter search text",
1369
+ type: "string",
1370
+ required: false,
1371
+ comments: "Full-text search across asset metadata. Leave empty to match every asset.",
1372
+ example: "city skyline",
1373
+ clean: cleanString
1374
+ }),
1375
+ sortField: (0, _prismatic_io_spectral.input)({
1376
+ label: "Sort By",
1377
+ type: "string",
1378
+ required: false,
1379
+ model: ASSET_SORT_FIELDS,
1380
+ comments: "The field to sort results by. Leave empty to sort by relevance.",
1381
+ clean: cleanString
1382
+ }),
1383
+ sortOrder
1384
+ }
1385
+ })
1386
+ };
1387
+ const getAssetMetadataInputs = {
1388
+ connection,
1389
+ assetId
1390
+ };
1391
+ const listAssetRenditionsInputs = {
1392
+ connection,
1393
+ assetId
1394
+ };
1395
+ const downloadAssetInputs = {
1396
+ connection,
1397
+ assetId,
1398
+ seoName
1399
+ };
1400
+ const downloadAssetRenditionInputs = {
1401
+ connection,
1402
+ assetId,
1403
+ renditionName,
1404
+ seoName
1405
+ };
1406
+ const destinationFolder = (0, _prismatic_io_spectral.input)({
1407
+ label: "Destination Folder Path",
1408
+ placeholder: "Enter folder path",
1409
+ type: "string",
1410
+ required: true,
1411
+ dataSource: "selectFolderPath",
1412
+ comments: "The path of the folder to import into, below /content/dam, such as wknd-shared/en. A full repository path starting with /content/dam is also accepted.",
1413
+ example: "wknd-shared/en",
1414
+ clean: cleanRequiredDamPath
1415
+ });
1416
+ const fileUrl = (0, _prismatic_io_spectral.input)({
1417
+ label: "File URL",
1418
+ placeholder: "Enter file URL",
1419
+ type: "string",
1420
+ required: true,
1421
+ comments: "The https:// URL AEM downloads the file from. It must be reachable from AEM.",
1422
+ example: "https://cdn.example.com/city.jpeg",
1423
+ clean: cleanHttpsUrl
1424
+ });
1425
+ const importMimeType = (0, _prismatic_io_spectral.input)({
1426
+ label: "MIME Type",
1427
+ placeholder: "Enter MIME type",
1428
+ type: "string",
1429
+ required: false,
1430
+ comments: "The file's MIME type. Leave empty to let AEM detect it.",
1431
+ example: "image/jpeg",
1432
+ clean: cleanString
1433
+ });
1434
+ const metadataValues = (0, _prismatic_io_spectral.input)({
1435
+ label: "Metadata Values",
1436
+ placeholder: "Enter metadata field and value",
1437
+ type: "string",
1438
+ collection: "keyvaluelist",
1439
+ required: false,
1440
+ default: [],
1441
+ comments: "Metadata fields to set, keyed by field name such as dc:title. Only asset metadata is writable; repository metadata is read-only.",
1442
+ example: "dc:title",
1443
+ clean: cleanKeyValueRecord
1444
+ });
1445
+ const removeFields = (0, _prismatic_io_spectral.input)({
1446
+ label: "Fields to Remove",
1447
+ placeholder: "Enter field name",
1448
+ type: "string",
1449
+ collection: "valuelist",
1450
+ required: false,
1451
+ default: [],
1452
+ comments: "Metadata field names to remove from the asset, such as dc:description.",
1453
+ example: "dc:description",
1454
+ clean: cleanStringList
1455
+ });
1456
+ const forceDelete = (0, _prismatic_io_spectral.input)({
1457
+ label: "Force",
1458
+ type: "boolean",
1459
+ required: false,
1460
+ default: "false",
1461
+ comments: "When true, deletes the asset even when it is referenced elsewhere.",
1462
+ clean: _prismatic_io_spectral.util.types.toBool
1463
+ });
1464
+ const importAssetFromUrlInputs = {
1465
+ connection,
1466
+ folder: destinationFolder,
1467
+ fileUrl,
1468
+ fileName: {
1469
+ ...seoName,
1470
+ comments: "The name the asset is created with."
1471
+ },
1472
+ mimeType: importMimeType
1473
+ };
1474
+ const getImportJobStatusInputs = {
1475
+ connection,
1476
+ jobId
1477
+ };
1478
+ const updateAssetMetadataInputs = {
1479
+ connection,
1480
+ assetId,
1481
+ metadataValues,
1482
+ removeFields
1483
+ };
1484
+ const deleteAssetInputs = {
1485
+ connection,
1486
+ assetId,
1487
+ force: forceDelete
1488
+ };
1489
+ const getAssetJobStatusInputs = {
1490
+ connection,
1491
+ jobId
1492
+ };
1493
+ //#endregion
1494
+ //#region src/inputs/contentFragments.ts
1495
+ const fragmentId = (0, _prismatic_io_spectral.input)({
1496
+ label: "Content Fragment ID",
1497
+ placeholder: "Select content fragment",
1498
+ type: "string",
1499
+ required: true,
1500
+ dataSource: "selectContentFragment",
1501
+ comments: "The unique identifier for the content fragment, a UUID as returned by List Content Fragments or Search Content Fragments.",
1502
+ example: "4f2b6c1e-8d3a-4b5c-9e7f-0a1b2c3d4e5f",
1503
+ clean: cleanRequiredString
1504
+ });
1505
+ const tags = (0, _prismatic_io_spectral.input)({
1506
+ label: "Tags",
1507
+ placeholder: "Enter tag ID",
1508
+ type: "string",
1509
+ collection: "valuelist",
1510
+ required: false,
1511
+ default: [],
1512
+ comments: "Only return content fragments with at least one of these tag IDs.",
1513
+ example: "wknd-shared:season/summer",
1514
+ clean: cleanStringList
1515
+ });
1516
+ const locales = (0, _prismatic_io_spectral.input)({
1517
+ label: "Locales",
1518
+ placeholder: "Enter locale",
1519
+ type: "string",
1520
+ collection: "valuelist",
1521
+ required: false,
1522
+ default: [],
1523
+ comments: "Only return content fragments in one of these locales.",
1524
+ example: "en",
1525
+ clean: cleanStringList
1526
+ });
1527
+ const fragmentPath = (0, _prismatic_io_spectral.input)({
1528
+ label: "Path",
1529
+ placeholder: "Enter path",
1530
+ type: "string",
1531
+ required: false,
1532
+ dataSource: "selectFolderPath",
1533
+ comments: "Only return content fragments under this folder path below /content/dam, such as wknd/en/adventures. A full repository path starting with /content/dam is also accepted.",
1534
+ example: "wknd/en/adventures",
1535
+ clean: cleanDamPath
1536
+ });
1537
+ const onlyDirectChildren = (0, _prismatic_io_spectral.input)({
1538
+ label: "Only Direct Children",
1539
+ type: "boolean",
1540
+ required: false,
1541
+ default: "false",
1542
+ comments: "When true, only returns content fragments directly under Path, not in its subfolders.",
1543
+ clean: _prismatic_io_spectral.util.types.toBool
1544
+ });
1545
+ const projection = (0, _prismatic_io_spectral.input)({
1546
+ label: "Projection",
1547
+ type: "string",
1548
+ required: false,
1549
+ model: CONTENT_FRAGMENT_PROJECTIONS,
1550
+ comments: "How much of each content fragment to return. Leave empty for the API default.",
1551
+ clean: cleanString
1552
+ });
1553
+ const includeMetadata = (0, _prismatic_io_spectral.input)({
1554
+ label: "Include Metadata",
1555
+ type: "boolean",
1556
+ required: false,
1557
+ default: "false",
1558
+ comments: "When true, includes each content fragment's metadata in the response.",
1559
+ clean: _prismatic_io_spectral.util.types.toBool
1560
+ });
1561
+ const references = (0, _prismatic_io_spectral.input)({
1562
+ label: "References",
1563
+ type: "string",
1564
+ required: false,
1565
+ model: CONTENT_FRAGMENT_REFERENCES,
1566
+ comments: "Which referenced content to include. Leave empty to omit references.",
1567
+ clean: cleanString
1568
+ });
1569
+ const statuses = (0, _prismatic_io_spectral.input)({
1570
+ label: "Statuses",
1571
+ type: "string",
1572
+ collection: "valuelist",
1573
+ required: false,
1574
+ default: [],
1575
+ model: CONTENT_FRAGMENT_STATUSES,
1576
+ comments: "Only return content fragments in one of these statuses.",
1577
+ clean: cleanStringList
1578
+ });
1579
+ const modelIds = (0, _prismatic_io_spectral.input)({
1580
+ label: "Content Fragment Models",
1581
+ placeholder: "Select content fragment model",
1582
+ type: "string",
1583
+ collection: "valuelist",
1584
+ required: false,
1585
+ default: [],
1586
+ dataSource: "selectContentFragmentModel",
1587
+ comments: "Only return content fragments based on one of these model IDs.",
1588
+ example: "L2NvbmYvd2tuZC1zaGFyZWQvc2V0dGluZ3MvZGFtL2NmbS9tb2RlbHMvYWR2ZW50dXJl",
1589
+ clean: cleanStringList
1590
+ });
1591
+ const modifiedAfter$1 = (0, _prismatic_io_spectral.input)({
1592
+ label: "Modified After",
1593
+ placeholder: "Enter date-time (ISO 8601)",
1594
+ type: "string",
1595
+ required: false,
1596
+ comments: "Only return content fragments modified after this ISO 8601 date-time.",
1597
+ example: "2026-01-01T00:00:00Z",
1598
+ clean: cleanOptionalDateTime
1599
+ });
1600
+ const modifiedBefore = (0, _prismatic_io_spectral.input)({
1601
+ label: "Modified Before",
1602
+ placeholder: "Enter date-time (ISO 8601)",
1603
+ type: "string",
1604
+ required: false,
1605
+ comments: "Only return content fragments modified before this ISO 8601 date-time.",
1606
+ example: "2026-02-01T00:00:00Z",
1607
+ clean: cleanOptionalDateTime
1608
+ });
1609
+ const publishedAfter = (0, _prismatic_io_spectral.input)({
1610
+ label: "Published After",
1611
+ placeholder: "Enter date-time (ISO 8601)",
1612
+ type: "string",
1613
+ required: false,
1614
+ comments: "Only return content fragments published after this ISO 8601 date-time.",
1615
+ example: "2026-01-01T00:00:00Z",
1616
+ clean: cleanOptionalDateTime
1617
+ });
1618
+ const publishedBefore = (0, _prismatic_io_spectral.input)({
1619
+ label: "Published Before",
1620
+ placeholder: "Enter date-time (ISO 8601)",
1621
+ type: "string",
1622
+ required: false,
1623
+ comments: "Only return content fragments published before this ISO 8601 date-time.",
1624
+ example: "2026-02-01T00:00:00Z",
1625
+ clean: cleanOptionalDateTime
1626
+ });
1627
+ const fullText = (0, _prismatic_io_spectral.input)({
1628
+ label: "Full Text",
1629
+ placeholder: "Enter search text",
1630
+ type: "string",
1631
+ required: false,
1632
+ comments: "Only return content fragments whose content matches this text.",
1633
+ example: "summer camping",
1634
+ clean: cleanString
1635
+ });
1636
+ const sortOn = (0, _prismatic_io_spectral.input)({
1637
+ label: "Sort By",
1638
+ type: "string",
1639
+ required: false,
1640
+ model: CONTENT_FRAGMENT_SORT_FIELDS,
1641
+ comments: "The field to sort results by. Leave empty for the API default order.",
1642
+ clean: cleanString
1643
+ });
1644
+ const dateRangeFilters = (0, _prismatic_io_spectral.structuredObjectInput)({
1645
+ label: "Date Range Filters",
1646
+ required: false,
1647
+ comments: "Optional date-range filters. Narrow results by when content fragments were last modified or published.",
1648
+ inputs: {
1649
+ modifiedAfter: modifiedAfter$1,
1650
+ modifiedBefore,
1651
+ publishedAfter,
1652
+ publishedBefore
1653
+ }
1654
+ });
1655
+ const filters = (0, _prismatic_io_spectral.structuredObjectInput)({
1656
+ label: "Filters",
1657
+ required: false,
1658
+ comments: "Optional query controls to sort and refine the results.",
1659
+ inputs: {
1660
+ fullText,
1661
+ sortOn,
1662
+ sortOrder
1663
+ }
1664
+ });
1665
+ const listContentFragmentsInputs = {
1666
+ connection,
1667
+ fetchAll,
1668
+ pagination,
1669
+ path: fragmentPath,
1670
+ projection,
1671
+ includeMetadata,
1672
+ references
1673
+ };
1674
+ const searchContentFragmentsInputs = {
1675
+ connection,
1676
+ fetchAll,
1677
+ pagination,
1678
+ path: fragmentPath,
1679
+ onlyDirectChildren,
1680
+ statuses,
1681
+ modelIds,
1682
+ tags,
1683
+ locales,
1684
+ dateRangeFilters,
1685
+ filters,
1686
+ projection,
1687
+ includeMetadata
1688
+ };
1689
+ const getContentFragmentInputs = {
1690
+ connection,
1691
+ fragmentId,
1692
+ includeMetadata,
1693
+ references
1694
+ };
1695
+ const listContentFragmentVariationsInputs = {
1696
+ connection,
1697
+ fragmentId,
1698
+ fetchAll,
1699
+ pagination
1700
+ };
1701
+ const listContentFragmentModelsInputs = {
1702
+ connection,
1703
+ fetchAll,
1704
+ pagination,
1705
+ projection
1706
+ };
1707
+ //#endregion
1708
+ //#region src/inputs/pages.ts
1709
+ const sitemapUrl = (0, _prismatic_io_spectral.input)({
1710
+ label: "Sitemap URL",
1711
+ placeholder: "Enter sitemap URL",
1712
+ type: "string",
1713
+ required: true,
1714
+ comments: "The https:// URL of the site's sitemap or sitemap index. Child sitemaps on the same host are followed.",
1715
+ example: "https://www.example.com/sitemap.xml",
1716
+ clean: cleanHttpsUrl
1717
+ });
1718
+ const modifiedAfter = (0, _prismatic_io_spectral.input)({
1719
+ label: "Modified After",
1720
+ placeholder: "Enter date-time (ISO 8601)",
1721
+ type: "string",
1722
+ required: false,
1723
+ comments: "Only return pages whose sitemap lastmod is after this ISO 8601 date-time. Pages without a lastmod are excluded when set.",
1724
+ example: "2026-01-01T00:00:00Z",
1725
+ clean: cleanOptionalDateTime
1726
+ });
1727
+ const includePathPrefixes = (0, _prismatic_io_spectral.input)({
1728
+ label: "Include Path Prefixes",
1729
+ placeholder: "Enter path prefix",
1730
+ type: "string",
1731
+ collection: "valuelist",
1732
+ required: false,
1733
+ default: [],
1734
+ comments: "Only return pages whose URL path starts with one of these prefixes.",
1735
+ example: "/en/adventures",
1736
+ clean: cleanStringList
1737
+ });
1738
+ const excludePathPrefixes = (0, _prismatic_io_spectral.input)({
1739
+ label: "Exclude Path Prefixes",
1740
+ placeholder: "Enter path prefix",
1741
+ type: "string",
1742
+ collection: "valuelist",
1743
+ required: false,
1744
+ default: [],
1745
+ comments: "Leave out pages whose URL path starts with one of these prefixes.",
1746
+ example: "/en/legal",
1747
+ clean: cleanStringList
1748
+ });
1749
+ const pageUrl = (0, _prismatic_io_spectral.input)({
1750
+ label: "Page URL",
1751
+ placeholder: "Enter page URL",
1752
+ type: "string",
1753
+ required: true,
1754
+ dataSource: "selectSitemapPage",
1755
+ comments: "The https:// URL of the published page to fetch.",
1756
+ example: "https://www.example.com/en/adventures/surf-camp.html",
1757
+ clean: cleanHttpsUrl
1758
+ });
1759
+ const listSitemapUrlsInputs = {
1760
+ connection,
1761
+ sitemapUrl,
1762
+ modifiedAfter,
1763
+ includePathPrefixes,
1764
+ excludePathPrefixes
1765
+ };
1766
+ const getPublishedPageHtmlInputs = {
1767
+ connection,
1768
+ sitemapUrl: (0, _prismatic_io_spectral.input)({
1769
+ ...sitemapUrl,
1770
+ required: false,
1771
+ clean: cleanOptionalHttpsUrl,
1772
+ comments: "The https:// URL of the site's sitemap or sitemap index. Used only to populate the Page URL dropdown; this action does not send it."
1773
+ }),
1774
+ pageUrl
1775
+ };
1776
+ //#endregion
1777
+ //#region src/inputs/dataSources.ts
1778
+ const selectContentFragmentModelInputs = { connection };
1779
+ const selectFolderInputs = { connection };
1780
+ const selectContentFragmentInputs = {
1781
+ connection,
1782
+ path: {
1783
+ ...fragmentPath,
1784
+ dataSource: void 0
1785
+ }
1786
+ };
1787
+ const selectFolderPathInputs = { connection };
1788
+ const selectAssetInputs = { connection };
1789
+ const selectAssetRenditionInputs = {
1790
+ connection,
1791
+ assetId: {
1792
+ ...assetId,
1793
+ dataSource: void 0
1794
+ }
1795
+ };
1796
+ const selectSitemapPageInputs = {
1797
+ connection,
1798
+ sitemapUrl
1799
+ };
1800
+ //#endregion
1801
+ //#region src/inputs/misc.ts
1802
+ const { debugRequest: _debugRequest, ...httpInputs } = _prismatic_io_spectral_http.inputs;
1803
+ const rawRequestInputs = {
1804
+ connection,
1805
+ ...httpInputs,
1806
+ url: {
1807
+ ...httpInputs.url,
1808
+ comments: "Input the path only (for example, /adobe/sites/cf/fragments). The AEM author host is already included.",
1809
+ example: "/adobe/sites/cf/fragments"
1810
+ }
1811
+ };
1812
+ //#endregion
1813
+ //#region src/inputs/triggers.ts
1814
+ const lookBackDate = (0, _prismatic_io_spectral.input)({
1815
+ label: "Look-back Date",
1816
+ placeholder: "Enter look-back date (YYYY-MM-DD)",
1817
+ type: "string",
1818
+ required: false,
1819
+ comments: "The date the initial sync starts from, in YYYY-MM-DD format. Cannot be a future date. Leave empty to start from the first recurrence with no backfill. When set, the initial sync seeds each record modified on or after this date once.",
1820
+ example: "2026-01-01",
1821
+ clean: lookBackDateClean
1822
+ });
1823
+ const publishBaseUrl = (0, _prismatic_io_spectral.input)({
1824
+ label: "Publish Base URL",
1825
+ placeholder: "Enter publish base URL",
1826
+ type: "string",
1827
+ required: false,
1828
+ comments: "The public base URL of the published site, used to build each record's URL from its path. Leave empty to omit URLs.",
1829
+ example: "https://www.example.com",
1830
+ clean: cleanOptionalHttpsUrl
1831
+ });
1832
+ const triggerStatuses = (0, _prismatic_io_spectral.input)({
1833
+ label: "Statuses",
1834
+ type: "string",
1835
+ collection: "valuelist",
1836
+ required: false,
1837
+ default: DEFAULT_TRIGGER_FRAGMENT_STATUSES,
1838
+ model: CONTENT_FRAGMENT_STATUSES,
1839
+ comments: "Only emit content fragments in one of these statuses. The default covers live content: Published, and Modified (published, then edited).",
1840
+ clean: cleanStringList
1841
+ });
1842
+ const consumerOrgId = (0, _prismatic_io_spectral.input)({
1843
+ label: "Consumer Organization ID",
1844
+ placeholder: "Enter consumer organization ID",
1845
+ type: "string",
1846
+ required: true,
1847
+ comments: "The Adobe Developer Console consumer organization ID that owns the project.",
1848
+ example: "123456",
1849
+ clean: cleanRequiredString
1850
+ });
1851
+ const projectId = (0, _prismatic_io_spectral.input)({
1852
+ label: "Project ID",
1853
+ placeholder: "Enter project ID",
1854
+ type: "string",
1855
+ required: true,
1856
+ comments: "The ID of the Adobe Developer Console project with AEM Events enabled.",
1857
+ example: "4566206088344794931",
1858
+ clean: cleanRequiredString
1859
+ });
1860
+ const workspaceId = (0, _prismatic_io_spectral.input)({
1861
+ label: "Workspace ID",
1862
+ placeholder: "Enter workspace ID",
1863
+ type: "string",
1864
+ required: true,
1865
+ comments: "The ID of the Adobe Developer Console workspace within the project.",
1866
+ example: "4566206088344853970",
1867
+ clean: cleanRequiredString
1868
+ });
1869
+ const providerId = (0, _prismatic_io_spectral.input)({
1870
+ label: "Event Provider ID",
1871
+ placeholder: "Enter AEM Sites event provider ID",
1872
+ type: "string",
1873
+ required: true,
1874
+ comments: "The ID of the environment's AEM Sites event provider. Adobe creates one AEM Sites provider and one AEM Assets provider per environment once AEM Events is enabled for it.",
1875
+ example: "61378e83-878f-409c-ade1-0e3482aa90a7",
1876
+ clean: cleanRequiredString
1877
+ });
1878
+ const sitesEventTypes = (0, _prismatic_io_spectral.input)({
1879
+ label: "Event Types",
1880
+ type: "string",
1881
+ collection: "valuelist",
1882
+ required: true,
1883
+ default: AEM_SITES_EVENT_TYPES.map((eventType) => eventType.value),
1884
+ model: AEM_SITES_EVENT_TYPES,
1885
+ comments: "The AEM Sites content fragment and page events to subscribe to.",
1886
+ clean: cleanStringList
1887
+ });
1888
+ const assetsEventTypes = (0, _prismatic_io_spectral.input)({
1889
+ label: "Event Types",
1890
+ type: "string",
1891
+ collection: "valuelist",
1892
+ required: true,
1893
+ default: AEM_ASSETS_EVENT_TYPES.map((eventType) => eventType.value),
1894
+ model: AEM_ASSETS_EVENT_TYPES,
1895
+ comments: "The AEM Assets events to subscribe to.",
1896
+ clean: cleanStringList
1897
+ });
1898
+ const contentFragmentChangesInputs = {
1899
+ connection,
1900
+ lookBackDate: {
1901
+ ...lookBackDate,
1902
+ comments: "The date the initial sync starts from, in YYYY-MM-DD format. Cannot be a future date. Leave empty to start from the first recurrence with no backfill. When set, the initial sync seeds each content fragment modified on or after this date once."
1903
+ },
1904
+ path: fragmentPath,
1905
+ statuses: triggerStatuses,
1906
+ modelIds,
1907
+ tags,
1908
+ locales,
1909
+ publishBaseUrl
1910
+ };
1911
+ const assetChangesInputs = {
1912
+ connection,
1913
+ lookBackDate: {
1914
+ ...lookBackDate,
1915
+ comments: "The date the initial sync starts from, in YYYY-MM-DD format. Cannot be a future date. Leave empty to start from the first recurrence with no backfill. When set, the initial sync seeds each asset modified on or after this date once."
1916
+ },
1917
+ folderIds,
1918
+ mimeTypes,
1919
+ publishBaseUrl
1920
+ };
1921
+ const aemSitesEventWebhookInputs = {
1922
+ connection,
1923
+ consumerOrgId,
1924
+ projectId,
1925
+ workspaceId,
1926
+ providerId,
1927
+ eventTypes: sitesEventTypes,
1928
+ publishBaseUrl
1929
+ };
1930
+ const aemAssetsEventWebhookInputs = {
1931
+ connection,
1932
+ consumerOrgId,
1933
+ projectId,
1934
+ workspaceId,
1935
+ providerId: {
1936
+ ...providerId,
1937
+ placeholder: "Enter AEM Assets event provider ID",
1938
+ comments: "The ID of the environment's AEM Assets event provider. Adobe creates one AEM Sites provider and one AEM Assets provider per environment once AEM Events is enabled for it.",
1939
+ example: "5b0beec8-725f-4881-97f4-bfb8bfb4b6d5"
1940
+ },
1941
+ eventTypes: assetsEventTypes,
1942
+ publishBaseUrl
1943
+ };
1944
+ //#endregion
1945
+ //#region src/outputSchemas/shared.ts
1946
+ const auditStampSchema = {
1947
+ type: "object",
1948
+ properties: {
1949
+ at: {
1950
+ type: "string",
1951
+ format: "date-time"
1952
+ },
1953
+ by: { type: "string" },
1954
+ fullName: { type: "string" },
1955
+ firstName: { type: "string" },
1956
+ lastName: { type: "string" }
1957
+ }
1958
+ };
1959
+ const replicationStatusSchema = {
1960
+ type: "string",
1961
+ enum: [
1962
+ "PUBLISHED",
1963
+ "UNPUBLISHED",
1964
+ "MODIFIED",
1965
+ "NEVER_PUBLISHED"
1966
+ ]
1967
+ };
1968
+ const previewStatusSchema = {
1969
+ type: "string",
1970
+ enum: ["IN_SYNC", "OUT_OF_SYNC"]
1971
+ };
1972
+ const contentFragmentStatusSchema = {
1973
+ type: "string",
1974
+ enum: [
1975
+ "NEW",
1976
+ "DRAFT",
1977
+ "PUBLISHED",
1978
+ "MODIFIED",
1979
+ "UNPUBLISHED"
1980
+ ]
1981
+ };
1982
+ const dataTypeSchema = {
1983
+ type: "string",
1984
+ enum: [
1985
+ "text",
1986
+ "long-text",
1987
+ "number",
1988
+ "float-number",
1989
+ "date-time",
1990
+ "date",
1991
+ "time",
1992
+ "boolean",
1993
+ "enumeration",
1994
+ "tag",
1995
+ "content-fragment",
1996
+ "content-reference",
1997
+ "json"
1998
+ ]
1999
+ };
2000
+ const tagSchema = {
2001
+ type: "object",
2002
+ properties: {
2003
+ id: { type: "string" },
2004
+ title: { type: "string" },
2005
+ i18n: {
2006
+ type: "array",
2007
+ items: {
2008
+ type: "object",
2009
+ properties: {
2010
+ locale: { type: "string" },
2011
+ title: { type: "string" },
2012
+ titlePath: { type: "string" }
2013
+ }
2014
+ }
2015
+ },
2016
+ titlePath: { type: "string" },
2017
+ name: { type: "string" },
2018
+ path: { type: "string" },
2019
+ description: { type: "string" }
2020
+ },
2021
+ required: ["id"]
2022
+ };
2023
+ const validationStatusSchema = {
2024
+ type: "array",
2025
+ items: {
2026
+ type: "object",
2027
+ properties: {
2028
+ property: { type: "string" },
2029
+ message: { type: "string" }
2030
+ }
2031
+ }
2032
+ };
2033
+ const assetValueSchema = {
2034
+ type: ["string", "object"],
2035
+ properties: {
2036
+ repository: { type: "string" },
2037
+ assetId: { type: "string" }
2038
+ }
2039
+ };
2040
+ const fragmentFieldSchema = {
2041
+ type: "object",
2042
+ properties: {
2043
+ name: { type: "string" },
2044
+ type: dataTypeSchema,
2045
+ multiple: { type: "boolean" },
2046
+ locked: { type: "boolean" },
2047
+ mimeType: {
2048
+ type: "string",
2049
+ enum: [
2050
+ "text/html",
2051
+ "text/plain",
2052
+ "text/x-markdown",
2053
+ "text/markdown"
2054
+ ]
2055
+ },
2056
+ values: {
2057
+ type: "array",
2058
+ items: {
2059
+ type: [
2060
+ "string",
2061
+ "number",
2062
+ "boolean",
2063
+ "object"
2064
+ ],
2065
+ properties: {
2066
+ repository: { type: "string" },
2067
+ assetId: { type: "string" }
2068
+ }
2069
+ }
2070
+ }
2071
+ },
2072
+ required: ["name", "type"]
2073
+ };
2074
+ const cardSchema = {
2075
+ type: "object",
2076
+ properties: {
2077
+ assets: {
2078
+ type: "array",
2079
+ items: assetValueSchema
2080
+ },
2081
+ texts: {
2082
+ type: "array",
2083
+ items: { type: "string" }
2084
+ }
2085
+ }
2086
+ };
2087
+ const modelIdentifierSchema = {
2088
+ type: "object",
2089
+ properties: {
2090
+ id: { type: "string" },
2091
+ path: { type: "string" },
2092
+ name: { type: "string" },
2093
+ technicalName: { type: "string" },
2094
+ title: { type: "string" },
2095
+ description: { type: "string" },
2096
+ tagIds: {
2097
+ type: "array",
2098
+ items: { type: "string" }
2099
+ }
2100
+ },
2101
+ required: [
2102
+ "id",
2103
+ "path",
2104
+ "name"
2105
+ ]
2106
+ };
2107
+ const referenceSchema = {
2108
+ type: "object",
2109
+ properties: {
2110
+ name: { type: "string" },
2111
+ fieldName: { type: "string" },
2112
+ type: {
2113
+ type: "string",
2114
+ enum: [
2115
+ "content-fragment",
2116
+ "experience-fragment",
2117
+ "asset",
2118
+ "page"
2119
+ ]
2120
+ },
2121
+ title: { type: "string" },
2122
+ description: { type: "string" },
2123
+ path: { type: "string" },
2124
+ created: auditStampSchema,
2125
+ modified: auditStampSchema,
2126
+ published: auditStampSchema,
2127
+ status: contentFragmentStatusSchema,
2128
+ previewReplicationStatus: replicationStatusSchema,
2129
+ previewStatus: previewStatusSchema,
2130
+ assetId: { type: "string" },
2131
+ "repo:size": { type: "integer" },
2132
+ "dc:format": { type: "string" },
2133
+ "tiff:ImageWidth": { type: "integer" },
2134
+ "tiff:ImageHeight": { type: "integer" },
2135
+ id: {
2136
+ type: "string",
2137
+ format: "uuid"
2138
+ },
2139
+ references: {
2140
+ type: "array",
2141
+ items: { type: "object" }
2142
+ },
2143
+ model: modelIdentifierSchema,
2144
+ fields: {
2145
+ type: "array",
2146
+ items: fragmentFieldSchema
2147
+ },
2148
+ variations: {
2149
+ type: "array",
2150
+ items: { type: "object" }
2151
+ },
2152
+ tags: {
2153
+ type: "array",
2154
+ items: tagSchema
2155
+ }
2156
+ },
2157
+ required: ["type", "path"]
2158
+ };
2159
+ const contentFragmentVariationSchema = {
2160
+ type: "object",
2161
+ properties: {
2162
+ name: { type: "string" },
2163
+ title: { type: "string" },
2164
+ description: { type: "string" },
2165
+ fields: {
2166
+ type: "array",
2167
+ items: fragmentFieldSchema
2168
+ },
2169
+ tags: {
2170
+ type: "array",
2171
+ items: tagSchema
2172
+ },
2173
+ validationStatus: validationStatusSchema,
2174
+ references: {
2175
+ type: "array",
2176
+ items: referenceSchema
2177
+ },
2178
+ fieldTags: {
2179
+ type: "array",
2180
+ items: tagSchema
2181
+ },
2182
+ created: auditStampSchema,
2183
+ modified: auditStampSchema,
2184
+ card: cardSchema
2185
+ },
2186
+ required: ["title"]
2187
+ };
2188
+ const contentFragmentSchema = {
2189
+ type: "object",
2190
+ properties: {
2191
+ id: { type: "string" },
2192
+ path: { type: "string" },
2193
+ title: { type: "string" },
2194
+ description: { type: "string" },
2195
+ status: contentFragmentStatusSchema,
2196
+ previewReplicationStatus: replicationStatusSchema,
2197
+ previewStatus: previewStatusSchema,
2198
+ created: auditStampSchema,
2199
+ modified: auditStampSchema,
2200
+ published: auditStampSchema,
2201
+ model: modelIdentifierSchema,
2202
+ checkedOutBy: { type: "string" },
2203
+ validationStatus: validationStatusSchema,
2204
+ fields: {
2205
+ type: "array",
2206
+ items: fragmentFieldSchema
2207
+ },
2208
+ variations: {
2209
+ type: "array",
2210
+ items: contentFragmentVariationSchema
2211
+ },
2212
+ tags: {
2213
+ type: "array",
2214
+ items: tagSchema
2215
+ },
2216
+ fieldTags: {
2217
+ type: "array",
2218
+ items: tagSchema
2219
+ },
2220
+ references: {
2221
+ type: "array",
2222
+ items: referenceSchema
2223
+ },
2224
+ card: cardSchema,
2225
+ metadata: {
2226
+ type: ["object", "null"],
2227
+ properties: {
2228
+ schemaId: { type: "string" },
2229
+ fields: {
2230
+ type: "array",
2231
+ items: {
2232
+ type: "object",
2233
+ properties: {
2234
+ name: { type: "string" },
2235
+ type: {
2236
+ type: "string",
2237
+ enum: [
2238
+ "string",
2239
+ "integer",
2240
+ "number",
2241
+ "boolean",
2242
+ "array",
2243
+ "object"
2244
+ ]
2245
+ },
2246
+ value: { type: [
2247
+ "string",
2248
+ "number",
2249
+ "boolean",
2250
+ "array",
2251
+ "object"
2252
+ ] },
2253
+ title: { type: "string" }
2254
+ },
2255
+ required: ["name", "value"]
2256
+ }
2257
+ }
2258
+ }
2259
+ }
2260
+ },
2261
+ required: [
2262
+ "id",
2263
+ "path",
2264
+ "title",
2265
+ "status",
2266
+ "created",
2267
+ "model"
2268
+ ]
2269
+ };
2270
+ const minMaxSchema = {
2271
+ type: "object",
2272
+ properties: {
2273
+ min: { type: "integer" },
2274
+ max: { type: "integer" }
2275
+ }
2276
+ };
2277
+ const fileSizeSchema = {
2278
+ type: "object",
2279
+ properties: {
2280
+ size: { type: "integer" },
2281
+ unit: {
2282
+ type: "string",
2283
+ enum: [
2284
+ "B",
2285
+ "KB",
2286
+ "MB",
2287
+ "GB",
2288
+ "TB"
2289
+ ]
2290
+ }
2291
+ },
2292
+ required: ["size", "unit"]
2293
+ };
2294
+ const contentFragmentModelSchema = {
2295
+ type: "object",
2296
+ properties: {
2297
+ id: { type: "string" },
2298
+ path: { type: "string" },
2299
+ name: { type: "string" },
2300
+ technicalName: { type: "string" },
2301
+ description: { type: "string" },
2302
+ etag: { type: "string" },
2303
+ created: auditStampSchema,
2304
+ modified: auditStampSchema,
2305
+ published: auditStampSchema,
2306
+ locked: { type: "boolean" },
2307
+ status: {
2308
+ type: "string",
2309
+ enum: [
2310
+ "enabled",
2311
+ "disabled",
2312
+ "draft"
2313
+ ]
2314
+ },
2315
+ replicationStatus: replicationStatusSchema,
2316
+ previewReplicationStatus: replicationStatusSchema,
2317
+ previewStatus: previewStatusSchema,
2318
+ previewUrlPattern: { type: "string" },
2319
+ tagsCount: { type: "integer" },
2320
+ tags: {
2321
+ type: "array",
2322
+ items: tagSchema
2323
+ },
2324
+ fields: {
2325
+ type: "array",
2326
+ items: {
2327
+ type: "object",
2328
+ properties: {
2329
+ name: { type: "string" },
2330
+ label: { type: "string" },
2331
+ description: { type: "string" },
2332
+ required: { type: "boolean" },
2333
+ multiple: { type: "boolean" },
2334
+ minItems: { type: "integer" },
2335
+ maxItems: { type: "integer" },
2336
+ type: dataTypeSchema,
2337
+ extensionConfig: {
2338
+ type: "object",
2339
+ additionalProperties: { type: [
2340
+ "string",
2341
+ "boolean",
2342
+ "number",
2343
+ "array"
2344
+ ] }
2345
+ },
2346
+ placeholder: { type: "string" },
2347
+ defaultValue: { type: [
2348
+ "string",
2349
+ "number",
2350
+ "boolean"
2351
+ ] },
2352
+ maxLength: { type: "integer" },
2353
+ unique: { type: "boolean" },
2354
+ translatable: { type: "boolean" },
2355
+ validationType: {
2356
+ type: "string",
2357
+ enum: [
2358
+ "none",
2359
+ "email",
2360
+ "url",
2361
+ "custom"
2362
+ ]
2363
+ },
2364
+ customValidationRegex: { type: "string" },
2365
+ customErrorMessage: { type: "string" },
2366
+ mimeType: {
2367
+ type: "string",
2368
+ enum: [
2369
+ "text/html",
2370
+ "text/plain",
2371
+ "text/x-markdown",
2372
+ "text/markdown"
2373
+ ]
2374
+ },
2375
+ allowFragmentReference: { type: "boolean" },
2376
+ allowedModels: {
2377
+ type: "array",
2378
+ items: { type: "string" }
2379
+ },
2380
+ min: { type: "number" },
2381
+ max: { type: "number" },
2382
+ root: { type: "string" },
2383
+ allowFragmentCreation: { type: "boolean" },
2384
+ items: {
2385
+ type: "array",
2386
+ items: { type: "string" }
2387
+ },
2388
+ tags: {
2389
+ type: "array",
2390
+ items: { type: "string" }
2391
+ },
2392
+ uuidBased: { type: "boolean" },
2393
+ showThumbnail: { type: "boolean" },
2394
+ imageWidth: minMaxSchema,
2395
+ imageHeight: minMaxSchema,
2396
+ fileSizeMin: fileSizeSchema,
2397
+ fileSizeMax: fileSizeSchema,
2398
+ allowedContentTypes: {
2399
+ type: "array",
2400
+ items: {
2401
+ type: "string",
2402
+ enum: [
2403
+ "plaintext",
2404
+ "richtext",
2405
+ "image",
2406
+ "audio",
2407
+ "video",
2408
+ "pdf",
2409
+ "spreadsheet",
2410
+ "presentation",
2411
+ "archive",
2412
+ "markup",
2413
+ "contentfragment"
2414
+ ]
2415
+ }
2416
+ },
2417
+ hint: {
2418
+ type: "string",
2419
+ enum: [
2420
+ "select",
2421
+ "checkbox",
2422
+ "radio"
2423
+ ]
2424
+ },
2425
+ values: {
2426
+ type: "array",
2427
+ items: {
2428
+ type: "object",
2429
+ properties: {
2430
+ key: { type: "string" },
2431
+ value: { type: "string" }
2432
+ },
2433
+ required: ["key", "value"]
2434
+ }
2435
+ }
2436
+ },
2437
+ required: [
2438
+ "name",
2439
+ "label",
2440
+ "type"
2441
+ ]
2442
+ }
2443
+ }
2444
+ },
2445
+ required: [
2446
+ "id",
2447
+ "path",
2448
+ "name"
2449
+ ]
2450
+ };
2451
+ const assetMetadataResourceSchema = {
2452
+ type: "object",
2453
+ properties: {
2454
+ assetId: { type: "string" },
2455
+ repositoryMetadata: {
2456
+ type: "object",
2457
+ properties: {
2458
+ "repo:name": { type: "string" },
2459
+ "repo:path": { type: "string" },
2460
+ "repo:assetId": { type: "string" },
2461
+ "repo:parent": { type: "string" },
2462
+ "repo:ancestors": {
2463
+ type: "array",
2464
+ items: { type: "string" }
2465
+ },
2466
+ "repo:createDate": {
2467
+ type: "string",
2468
+ format: "date-time"
2469
+ },
2470
+ "repo:createdBy": { type: "string" },
2471
+ "repo:modifyDate": {
2472
+ type: "string",
2473
+ format: "date-time"
2474
+ },
2475
+ "repo:modifiedBy": { type: "string" },
2476
+ "dc:format": { type: "string" },
2477
+ "repo:size": { type: "integer" },
2478
+ "dam:sha1": { type: "string" },
2479
+ "tiff:imageLength": { type: "integer" },
2480
+ "tiff:imageWidth": { type: "integer" },
2481
+ isPublishedToAemPublish: { type: "boolean" },
2482
+ isPublishedToDynamicMedia: { type: "boolean" },
2483
+ lastPublishedToAemPublish: {
2484
+ type: "string",
2485
+ format: "date-time"
2486
+ },
2487
+ lastPublishedToDynamicMedia: {
2488
+ type: "string",
2489
+ format: "date-time"
2490
+ },
2491
+ "aem:published": {
2492
+ type: "string",
2493
+ format: "date-time"
2494
+ },
2495
+ "aem:assetState": { type: "string" },
2496
+ "aem:checkedOutBy": { type: "string" },
2497
+ "repo:state": { type: "string" },
2498
+ "repo:repositoryId": { type: "string" },
2499
+ "repo:etag": { type: "string" },
2500
+ "repo:scene7Domain": { type: "string" },
2501
+ "repo:scene7File": { type: "string" },
2502
+ "repo:scene7FileStatus": { type: "string" },
2503
+ "repo:scene7Folder": { type: "string" },
2504
+ "repo:scene7FontStyle": { type: "string" },
2505
+ "repo:scene7FontType": { type: "string" },
2506
+ "repo:scene7LastModified": { type: "string" },
2507
+ "repo:scene7Name": { type: "string" },
2508
+ "repo:scene7RTFName": { type: "string" },
2509
+ "repo:scene7Type": { type: "string" }
2510
+ },
2511
+ additionalProperties: true
2512
+ },
2513
+ assetMetadata: {
2514
+ type: "object",
2515
+ properties: {
2516
+ "xcm:keywords": {
2517
+ type: "array",
2518
+ items: {
2519
+ type: "object",
2520
+ properties: {
2521
+ tagId: { type: "string" },
2522
+ ancestorIds: {
2523
+ type: "array",
2524
+ items: { type: "string" }
2525
+ },
2526
+ value: { type: "string" },
2527
+ "repo:ancestors": {
2528
+ type: "array",
2529
+ items: { type: "string" }
2530
+ },
2531
+ "@lang": { type: "string" }
2532
+ }
2533
+ }
2534
+ },
2535
+ "dc:creator": {
2536
+ type: "array",
2537
+ items: { type: "string" }
2538
+ },
2539
+ "dc:description": {
2540
+ type: ["string", "array"],
2541
+ items: { type: "string" }
2542
+ },
2543
+ "dc:title": {
2544
+ type: ["string", "array"],
2545
+ items: { type: "string" }
2546
+ },
2547
+ "exif:GPSLatitude": { type: "string" },
2548
+ "exif:GPSLongitude": { type: "string" },
2549
+ "photoshop:ColorMode": { type: "number" },
2550
+ "photoshop:DateCreated": {
2551
+ type: "string",
2552
+ format: "date-time"
2553
+ },
2554
+ "xcm:machineKeywords": {
2555
+ type: "array",
2556
+ items: {
2557
+ type: "object",
2558
+ properties: {
2559
+ value: { type: "string" },
2560
+ confidence: { type: "number" },
2561
+ localeCode: { type: "string" }
2562
+ }
2563
+ }
2564
+ },
2565
+ "tiff:BitsPerSample": {
2566
+ type: "array",
2567
+ items: { type: "integer" }
2568
+ },
2569
+ "tiff:Orientation": { type: "number" },
2570
+ "xmp:CreateDate": {
2571
+ type: "string",
2572
+ format: "date-time"
2573
+ },
2574
+ "xmp:CreatorTool": { type: "string" },
2575
+ "xmp:ModifyDate": {
2576
+ type: "string",
2577
+ format: "date-time"
2578
+ }
2579
+ },
2580
+ additionalProperties: true
2581
+ }
2582
+ }
2583
+ };
2584
+ const commandResultMessageSchema = {
2585
+ type: "object",
2586
+ properties: {
2587
+ type: { type: "string" },
2588
+ title: { type: "string" },
2589
+ detail: { type: "string" },
2590
+ context: { type: "object" }
2591
+ },
2592
+ required: ["type", "title"]
2593
+ };
2594
+ const folderListingItemSchema = {
2595
+ type: "object",
2596
+ properties: {
2597
+ type: {
2598
+ type: "string",
2599
+ enum: ["FOLDER", "ASSET"]
2600
+ },
2601
+ folderId: { type: "string" },
2602
+ assetId: { type: "string" },
2603
+ name: { type: "string" },
2604
+ title: { type: ["string", "null"] },
2605
+ path: { type: "string" },
2606
+ size: { type: "integer" },
2607
+ lastModifiedAt: {
2608
+ type: "string",
2609
+ format: "date-time"
2610
+ }
2611
+ },
2612
+ required: ["type"]
2613
+ };
2614
+ const jobStateSchema = {
2615
+ type: "string",
2616
+ enum: [
2617
+ "QUEUED",
2618
+ "PROCESSING",
2619
+ "COMPLETED",
2620
+ "COMPLETED_WITH_ERRORS",
2621
+ "FAILED"
2622
+ ]
2623
+ };
2624
+ //#endregion
2625
+ //#region src/outputSchemas/assets.ts
2626
+ const searchAssetsOutputSchema = {
2627
+ type: "object",
2628
+ properties: {
2629
+ hits: {
2630
+ type: "object",
2631
+ properties: { results: {
2632
+ type: "array",
2633
+ items: assetMetadataResourceSchema
2634
+ } }
2635
+ },
2636
+ cursor: { type: "string" },
2637
+ facets: {
2638
+ type: "array",
2639
+ items: {
2640
+ type: "object",
2641
+ properties: {
2642
+ type: {
2643
+ type: "string",
2644
+ enum: ["CATEGORY", "STAT"]
2645
+ },
2646
+ field: { type: "string" },
2647
+ id: { type: "string" },
2648
+ values: {
2649
+ type: ["array", "object"],
2650
+ items: {
2651
+ type: "object",
2652
+ properties: {
2653
+ value: { type: "string" },
2654
+ count: { type: "integer" }
2655
+ },
2656
+ required: ["value", "count"]
2657
+ },
2658
+ properties: {
2659
+ min: { type: "string" },
2660
+ max: { type: "string" }
2661
+ }
2662
+ }
2663
+ },
2664
+ required: [
2665
+ "id",
2666
+ "field",
2667
+ "type"
2668
+ ]
2669
+ }
2670
+ },
2671
+ search_metadata: {
2672
+ type: "object",
2673
+ properties: {
2674
+ count: { type: "integer" },
2675
+ totalCount: {
2676
+ type: "object",
2677
+ properties: {
2678
+ total: { type: "integer" },
2679
+ relation: {
2680
+ type: "string",
2681
+ enum: ["eq", "gte"]
2682
+ }
2683
+ }
2684
+ },
2685
+ searchDuration: { type: "integer" }
2686
+ }
2687
+ }
2688
+ }
2689
+ };
2690
+ const getAssetMetadataOutputSchema = assetMetadataResourceSchema;
2691
+ const listAssetRenditionsOutputSchema = {
2692
+ type: "object",
2693
+ properties: {
2694
+ assetId: { type: "string" },
2695
+ "repo:name": { type: "string" },
2696
+ items: {
2697
+ type: "array",
2698
+ items: {
2699
+ type: "object",
2700
+ properties: {
2701
+ name: { type: "string" },
2702
+ format: { type: "string" },
2703
+ size: { type: "integer" },
2704
+ dimensions: {
2705
+ type: "object",
2706
+ properties: {
2707
+ width: { type: "integer" },
2708
+ height: { type: "integer" }
2709
+ }
2710
+ }
2711
+ },
2712
+ required: [
2713
+ "name",
2714
+ "size",
2715
+ "format"
2716
+ ]
2717
+ }
2718
+ }
2719
+ },
2720
+ required: [
2721
+ "assetId",
2722
+ "items",
2723
+ "repo:name"
2724
+ ]
2725
+ };
2726
+ const aemJobOutputSchema = {
2727
+ type: "object",
2728
+ properties: {
2729
+ jobId: { type: "string" },
2730
+ state: jobStateSchema,
2731
+ status: { type: "string" }
2732
+ },
2733
+ required: ["jobId", "state"]
2734
+ };
2735
+ const deleteAssetOutputSchema = {
2736
+ type: "object",
2737
+ properties: {
2738
+ jobId: { type: "string" },
2739
+ state: jobStateSchema,
2740
+ status: { type: "string" },
2741
+ assetId: { type: "string" },
2742
+ deleted: { type: "boolean" }
2743
+ }
2744
+ };
2745
+ const importJobProgressSchema = {
2746
+ type: "object",
2747
+ properties: {
2748
+ failed: { type: "integer" },
2749
+ imported: { type: "integer" },
2750
+ lastImported: { type: "string" },
2751
+ lastUpdated: {
2752
+ type: "string",
2753
+ format: "date-time"
2754
+ },
2755
+ skipped: { type: "number" },
2756
+ started: {
2757
+ type: "string",
2758
+ format: "date-time"
2759
+ },
2760
+ total: { type: "number" },
2761
+ size: { type: "number" },
2762
+ step: {
2763
+ type: "string",
2764
+ enum: [
2765
+ "QUEUED",
2766
+ "SCANNING",
2767
+ "IMPORTING",
2768
+ "DONE"
2769
+ ]
2770
+ },
2771
+ transferred: { type: "number" }
2772
+ },
2773
+ required: [
2774
+ "failed",
2775
+ "imported",
2776
+ "lastUpdated",
2777
+ "skipped",
2778
+ "started",
2779
+ "size",
2780
+ "step",
2781
+ "total",
2782
+ "transferred"
2783
+ ]
2784
+ };
2785
+ const importJobOutputSchema = {
2786
+ type: "object",
2787
+ properties: {
2788
+ id: { type: "string" },
2789
+ operation: {
2790
+ type: "string",
2791
+ enum: ["aem.assets.import.fromurl"]
2792
+ },
2793
+ state: {
2794
+ type: "string",
2795
+ enum: [
2796
+ "PROCESSING",
2797
+ "COMPLETED",
2798
+ "FAILED"
2799
+ ]
2800
+ },
2801
+ status: { type: "number" },
2802
+ description: { type: "string" },
2803
+ progress: importJobProgressSchema,
2804
+ data: {
2805
+ type: "object",
2806
+ properties: {
2807
+ id: { type: "string" },
2808
+ config: {
2809
+ type: "object",
2810
+ properties: {
2811
+ folder: { type: "string" },
2812
+ items: {
2813
+ type: "array",
2814
+ items: { type: "string" }
2815
+ },
2816
+ assetMetadata: {
2817
+ type: "object",
2818
+ additionalProperties: true
2819
+ }
2820
+ },
2821
+ required: ["folder", "items"]
2822
+ },
2823
+ processedFiles: {
2824
+ type: "array",
2825
+ items: { type: "object" }
2826
+ },
2827
+ progress: importJobProgressSchema
2828
+ },
2829
+ required: [
2830
+ "id",
2831
+ "config",
2832
+ "progress"
2833
+ ]
2834
+ },
2835
+ errors: {
2836
+ type: "array",
2837
+ items: commandResultMessageSchema
2838
+ },
2839
+ warnings: {
2840
+ type: "array",
2841
+ items: commandResultMessageSchema
2842
+ }
2843
+ }
2844
+ };
2845
+ const listContentFragmentsOutputSchema = {
2846
+ type: "object",
2847
+ properties: {
2848
+ items: {
2849
+ type: "array",
2850
+ items: {
2851
+ ...contentFragmentSchema,
2852
+ properties: {
2853
+ ...contentFragmentSchema.properties,
2854
+ etag: { type: "string" },
2855
+ tagsCount: { type: "integer" }
2856
+ },
2857
+ required: [],
2858
+ additionalProperties: true
2859
+ }
2860
+ },
2861
+ cursor: {
2862
+ type: "string",
2863
+ description: "Present when more pages remain."
2864
+ }
2865
+ },
2866
+ required: ["items"]
2867
+ };
2868
+ const searchContentFragmentsOutputSchema = listContentFragmentsOutputSchema;
2869
+ const getContentFragmentOutputSchema = contentFragmentSchema;
2870
+ const listContentFragmentVariationsOutputSchema = {
2871
+ type: "object",
2872
+ properties: {
2873
+ items: {
2874
+ type: "array",
2875
+ items: contentFragmentVariationSchema
2876
+ },
2877
+ cursor: { type: "string" }
2878
+ },
2879
+ required: ["items"]
2880
+ };
2881
+ const listContentFragmentModelsOutputSchema = {
2882
+ type: "object",
2883
+ properties: {
2884
+ items: {
2885
+ type: "array",
2886
+ items: contentFragmentModelSchema
2887
+ },
2888
+ cursor: { type: "string" }
2889
+ },
2890
+ required: ["items"]
2891
+ };
2892
+ //#endregion
2893
+ //#region src/outputSchemas/folders.ts
2894
+ const listFolderContentsOutputSchema = {
2895
+ type: "object",
2896
+ properties: {
2897
+ self: folderListingItemSchema,
2898
+ children: {
2899
+ type: "array",
2900
+ items: folderListingItemSchema
2901
+ },
2902
+ cursor: { type: "string" }
2903
+ }
2904
+ };
2905
+ const listAssetsInFolderTreeOutputSchema = {
2906
+ type: "array",
2907
+ items: {
2908
+ ...folderListingItemSchema,
2909
+ properties: {
2910
+ ...folderListingItemSchema.properties,
2911
+ folderPath: { type: "string" }
2912
+ },
2913
+ required: ["type", "folderPath"]
2914
+ }
2915
+ };
2916
+ const failedFolderItemSchema = {
2917
+ type: "object",
2918
+ properties: {
2919
+ path: { type: "string" },
2920
+ id: { type: "string" },
2921
+ type: { type: "string" },
2922
+ title: { type: "string" },
2923
+ detail: { type: "string" },
2924
+ context: { type: "object" }
2925
+ },
2926
+ required: ["type", "title"]
2927
+ };
2928
+ const folderCommandOutputSchema = (data) => ({
2929
+ type: "object",
2930
+ properties: {
2931
+ jobId: { type: "string" },
2932
+ state: jobStateSchema,
2933
+ status: { type: ["string", "integer"] },
2934
+ operation: { type: "string" },
2935
+ description: { type: "string" },
2936
+ data,
2937
+ errors: {
2938
+ type: "array",
2939
+ items: commandResultMessageSchema
2940
+ },
2941
+ warnings: {
2942
+ type: "array",
2943
+ items: commandResultMessageSchema
2944
+ }
2945
+ }
2946
+ });
2947
+ const createFoldersOutputSchema = folderCommandOutputSchema({
2948
+ type: "object",
2949
+ properties: { values: {
2950
+ type: "object",
2951
+ properties: {
2952
+ successes: {
2953
+ type: "array",
2954
+ items: {
2955
+ type: "object",
2956
+ properties: {
2957
+ type: {
2958
+ type: "string",
2959
+ enum: ["FOLDER", "ASSET"]
2960
+ },
2961
+ folderId: { type: "string" },
2962
+ name: { type: "string" },
2963
+ title: { type: ["string", "null"] },
2964
+ path: { type: "string" }
2965
+ },
2966
+ required: [
2967
+ "type",
2968
+ "folderId",
2969
+ "name",
2970
+ "path"
2971
+ ]
2972
+ }
2973
+ },
2974
+ failedFolders: {
2975
+ type: "array",
2976
+ items: failedFolderItemSchema
2977
+ }
2978
+ }
2979
+ } }
2980
+ });
2981
+ const deleteFoldersOutputSchema = folderCommandOutputSchema({
2982
+ type: "object",
2983
+ properties: {
2984
+ deletedFolders: {
2985
+ type: "array",
2986
+ items: { type: "string" }
2987
+ },
2988
+ failedFolders: {
2989
+ type: "array",
2990
+ items: failedFolderItemSchema
2991
+ }
2992
+ }
2993
+ });
2994
+ //#endregion
2995
+ //#region src/outputSchemas/pages.ts
2996
+ const listSitemapUrlsOutputSchema = {
2997
+ type: "array",
2998
+ items: {
2999
+ type: "object",
3000
+ properties: {
3001
+ loc: {
3002
+ type: "string",
3003
+ format: "uri"
3004
+ },
3005
+ lastmod: {
3006
+ type: ["string", "null"],
3007
+ format: "date-time"
3008
+ }
3009
+ },
3010
+ required: ["loc", "lastmod"]
3011
+ }
3012
+ };
3013
+ const getPublishedPageHtmlOutputSchema = {
3014
+ type: "object",
3015
+ properties: {
3016
+ url: {
3017
+ type: "string",
3018
+ format: "uri"
3019
+ },
3020
+ finalUrl: {
3021
+ type: "string",
3022
+ format: "uri"
3023
+ },
3024
+ statusCode: { type: "integer" },
3025
+ contentType: { type: ["string", "null"] },
3026
+ lastModified: { type: ["string", "null"] },
3027
+ etag: { type: ["string", "null"] },
3028
+ html: { type: "string" }
3029
+ },
3030
+ required: [
3031
+ "url",
3032
+ "finalUrl",
3033
+ "statusCode",
3034
+ "html"
3035
+ ]
3036
+ };
3037
+ //#endregion
3038
+ //#region src/actions/assets/deleteAsset.ts
3039
+ const deleteAsset = (0, _prismatic_io_spectral.action)({
3040
+ display: {
3041
+ label: "Delete Asset",
3042
+ description: "Delete an asset. Usually completes immediately; when AEM runs the delete as a job, returns a job ID to check with Get Asset Job Status."
3043
+ },
3044
+ performSafety: "notAllowed",
3045
+ perform: async (context, { connection, assetId, force }) => {
3046
+ const { data, status } = await createAemClient(connection, context.debug.enabled).delete(`${ASSETS_API_PATH}/${encodeURIComponent(assetId)}`, { params: { force } });
3047
+ return { data: status === 204 ? {
3048
+ assetId,
3049
+ deleted: true
3050
+ } : data };
3051
+ },
3052
+ inputs: deleteAssetInputs,
3053
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3054
+ type: "actionOutput",
3055
+ schema: deleteAssetOutputSchema
3056
+ }),
3057
+ examplePerform: async () => deleteAssetExamplePayload,
3058
+ examplePayload: deleteAssetExamplePayload
3059
+ });
3060
+ //#endregion
3061
+ //#region src/utils/assetFilters.ts
3062
+ const buildAssetFilterClauses = ({ folderIds, mimeTypes }) => [...folderIds.length ? [{ term: { [ASSET_ANCESTORS_FIELD]: folderIds } }] : [], ...mimeTypes.length ? [{ term: { [ASSET_FORMAT_FIELD]: mimeTypes } }] : []];
3063
+ //#endregion
3064
+ //#region src/utils/contentFragmentFilters.ts
3065
+ const buildContentFragmentTriggerFilter = (params) => ({
3066
+ path: params.path,
3067
+ status: params.statuses.length ? params.statuses : void 0,
3068
+ modelIds: params.modelIds.length ? params.modelIds : void 0,
3069
+ tags: params.tags.length ? params.tags : void 0,
3070
+ locale: params.locales.length ? params.locales : void 0
3071
+ });
3072
+ const toTimeInterval = (after, before) => after || before ? {
3073
+ after,
3074
+ before
3075
+ } : void 0;
3076
+ //#endregion
3077
+ //#region src/utils/downloads.ts
3078
+ const toDownloadedFile = (response) => ({
3079
+ data: Buffer.from(response.data),
3080
+ contentType: typeof response.headers["content-type"] === "string" ? response.headers["content-type"] : "application/octet-stream"
3081
+ });
3082
+ //#endregion
3083
+ //#region src/utils/elements.ts
3084
+ const compareElementLabels = (a, b) => _prismatic_io_spectral.util.types.toString(a.label ?? a.key).localeCompare(_prismatic_io_spectral.util.types.toString(b.label ?? b.key));
3085
+ //#endregion
3086
+ //#region src/utils/records.ts
3087
+ const toPublishUrl = (publishBaseUrl, path) => publishBaseUrl && path ? `${publishBaseUrl}${path}` : null;
3088
+ const toContentFragmentRecord = (fragment, scope, publishBaseUrl) => ({
3089
+ resourceType: "contentFragment",
3090
+ id: fragment.id,
3091
+ path: fragment.path ?? null,
3092
+ url: toPublishUrl(publishBaseUrl, fragment.path ?? null),
3093
+ title: fragment.title ?? null,
3094
+ tags: (fragment.tags ?? []).map((tag) => ({
3095
+ id: tag.id,
3096
+ title: tag.title ?? null,
3097
+ titlePath: tag.titlePath ?? null
3098
+ })),
3099
+ created: fragment.created?.at ?? null,
3100
+ modified: fragment.modified?.at ?? null,
3101
+ published: fragment.published?.at ?? null,
3102
+ scope,
3103
+ data: fragment
3104
+ });
3105
+ const toAssetRecord = (hit, scope, publishBaseUrl) => {
3106
+ const repo = hit.repositoryMetadata ?? {};
3107
+ const meta = hit.assetMetadata ?? {};
3108
+ const path = repo["repo:path"] ?? null;
3109
+ const keywords = Array.isArray(meta["xcm:keywords"]) ? meta["xcm:keywords"] : [];
3110
+ return {
3111
+ resourceType: "asset",
3112
+ id: hit.assetId,
3113
+ path,
3114
+ url: toPublishUrl(publishBaseUrl, path),
3115
+ title: typeof meta["dc:title"] === "string" ? meta["dc:title"] : repo["repo:name"] ?? null,
3116
+ tags: keywords.map((keyword) => {
3117
+ const entry = keyword;
3118
+ return {
3119
+ id: entry.tagId ?? entry.value ?? _prismatic_io_spectral.util.types.toString(keyword),
3120
+ title: entry.value ? entry.value.split(/\s*[/:]\s*/).pop() ?? null : null,
3121
+ titlePath: entry.value ?? null
3122
+ };
3123
+ }),
3124
+ created: repo["repo:createDate"] ?? null,
3125
+ modified: repo["repo:modifyDate"] ?? null,
3126
+ published: repo["aem:published"] ?? null,
3127
+ scope,
3128
+ data: hit
3129
+ };
3130
+ };
3131
+ //#endregion
3132
+ //#region src/utils/events.ts
3133
+ const RESOURCE_PREFIXES = [
3134
+ ["aem.sites.contentFragment.", "contentFragment"],
3135
+ ["aem.sites.page.", "page"],
3136
+ ["aem.assets.asset.", "asset"]
3137
+ ];
3138
+ const ACTION_CHANGE_TYPES = {
3139
+ created: "created",
3140
+ modified: "modified",
3141
+ published: "published",
3142
+ unpublished: "unpublished",
3143
+ deleted: "deleted",
3144
+ processing_completed: "created",
3145
+ metadata_updated: "modified"
3146
+ };
3147
+ const asString = (value) => typeof value === "string" ? value : null;
3148
+ const asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
3149
+ const asResourceUrl = (value) => {
3150
+ const url = asString(value);
3151
+ if (!url) return null;
3152
+ try {
3153
+ return new URL(url).pathname.length > 1 ? url : null;
3154
+ } catch {
3155
+ return null;
3156
+ }
3157
+ };
3158
+ const parseAemCloudEvent = (body, rawBody) => {
3159
+ if (body && typeof body === "object" && !Array.isArray(body) && !(body instanceof Uint8Array)) return body;
3160
+ try {
3161
+ const parsed = JSON.parse(rawBody);
3162
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
3163
+ } catch {}
3164
+ throw new Error("Adobe I/O Events delivered a body that is not a JSON CloudEvent.");
3165
+ };
3166
+ const toAemEventItem = (event, scope, publishBaseUrl) => {
3167
+ const code = event.type ?? "";
3168
+ const prefix = RESOURCE_PREFIXES.find(([value]) => code.startsWith(value));
3169
+ const resourceType = prefix?.[1] ?? "unknown";
3170
+ const action = prefix ? code.slice(prefix[0].length) : code.split(".").pop() ?? "";
3171
+ const data = event.data ?? {};
3172
+ const repository = asRecord(data.repositoryMetadata);
3173
+ const path = asString(data.path) ?? asString(repository["repo:path"]);
3174
+ const id = asString(data.id) ?? asString(repository["repo:assetId"]) ?? path ?? event.id ?? "";
3175
+ return {
3176
+ changeType: ACTION_CHANGE_TYPES[action] ?? "modified",
3177
+ record: {
3178
+ resourceType,
3179
+ id,
3180
+ path,
3181
+ url: asResourceUrl(data.sourceUrl) ?? toPublishUrl(publishBaseUrl, resourceType === "page" && path ? `${path}.html` : path),
3182
+ title: asString(data.title) ?? asString(asRecord(data.assetMetadata)["dc:title"]),
3183
+ tags: (Array.isArray(data.tags) ? data.tags : []).map((tag) => ({
3184
+ id: _prismatic_io_spectral.util.types.toString(tag),
3185
+ title: null,
3186
+ titlePath: null
3187
+ })),
3188
+ created: null,
3189
+ modified: event.time ?? null,
3190
+ published: null,
3191
+ scope,
3192
+ data: event
3193
+ },
3194
+ eventId: event.id ?? null,
3195
+ eventSource: event.source ?? null,
3196
+ eventType: event.type ?? null
3197
+ };
3198
+ };
3199
+ //#endregion
3200
+ //#region src/utils/signature.ts
3201
+ const keyCache = /* @__PURE__ */ new Map();
3202
+ const getPublicKey = async (client, keyPath) => {
3203
+ const cached = keyCache.get(keyPath);
3204
+ if (cached && Date.now() - cached.fetchedAt < 864e5) return cached.pem;
3205
+ const { data } = await client.get(`${IO_EVENTS_PUBLIC_KEY_BASE_URL}${keyPath}`);
3206
+ const pem = _prismatic_io_spectral.util.types.toString(data);
3207
+ keyCache.set(keyPath, {
3208
+ pem,
3209
+ fetchedAt: Date.now()
3210
+ });
3211
+ return pem;
3212
+ };
3213
+ const verifyOne = (rawBody, signature, pem) => {
3214
+ try {
3215
+ const verifier = (0, node_crypto.createVerify)("RSA-SHA256");
3216
+ verifier.update(rawBody);
3217
+ return verifier.verify(pem, signature, "base64");
3218
+ } catch {
3219
+ return false;
3220
+ }
3221
+ };
3222
+ const verifyAdobeSignature = async (client, headers, rawBody) => {
3223
+ const pairs = [[headers["x-adobe-digital-signature-1"], headers["x-adobe-public-key1-path"]], [headers["x-adobe-digital-signature-2"], headers["x-adobe-public-key2-path"]]].filter((pair) => pair[0] !== void 0 && pair[0] !== "" && pair[1] !== void 0 && pair[1] !== "");
3224
+ for (const [signature, keyPath] of pairs) {
3225
+ if (!keyPath.startsWith("/")) continue;
3226
+ let pem;
3227
+ try {
3228
+ pem = await getPublicKey(client, keyPath);
3229
+ } catch {
3230
+ continue;
3231
+ }
3232
+ if (verifyOne(rawBody, signature, pem)) return;
3233
+ }
3234
+ throw new Error("Adobe I/O Events signature verification failed.");
3235
+ };
3236
+ //#endregion
3237
+ //#region src/utils/webhooks.ts
3238
+ const workspacePath = ({ consumerOrgId, projectId, workspaceId }) => `/${encodeURIComponent(consumerOrgId)}/${encodeURIComponent(projectId)}/${encodeURIComponent(workspaceId)}`;
3239
+ const webhookStateKey = (context) => `aemEventSubscription:${context.flow.id}`;
3240
+ const getWebhookUrl = (context) => context.webhookUrls[context.flow.name];
3241
+ const sameConfig = (state, params) => state.previousWorkspace === workspacePath(params) && state.previousProviderId === params.providerId && state.previousClientId === _prismatic_io_spectral.util.types.toString(params.connection.fields.clientId) && [...state.previousEventTypes].sort().join(",") === [...params.eventTypes].sort().join(",");
3242
+ const deleteRegistrationsForUrl = async (client, params, webhookUrl) => {
3243
+ const base = `${workspacePath(params)}/registrations`;
3244
+ const { data } = await client.get(base);
3245
+ const matches = (data._embedded?.registrations ?? []).filter((registration) => registration.webhook_url === webhookUrl);
3246
+ for (const registration of matches) await client.delete(`${base}/${encodeURIComponent(registration.registration_id)}`);
3247
+ return matches.length;
3248
+ };
3249
+ const ensureRegistration = async (context, client, params) => {
3250
+ const webhookUrl = getWebhookUrl(context);
3251
+ const existing = context.crossFlowState[webhookStateKey(context)];
3252
+ if (existing?.registrationId && sameConfig(existing, params)) {
3253
+ context.logger.info("AEM event registration already exists with the same settings; skipping.");
3254
+ return;
3255
+ }
3256
+ const oldParams = existing ? (() => {
3257
+ const [, org, project, workspace] = existing.previousWorkspace.split("/");
3258
+ return {
3259
+ ...params,
3260
+ consumerOrgId: decodeURIComponent(org),
3261
+ projectId: decodeURIComponent(project),
3262
+ workspaceId: decodeURIComponent(workspace)
3263
+ };
3264
+ })() : params;
3265
+ let removed = await deleteRegistrationsForUrl(client, oldParams, webhookUrl);
3266
+ if (workspacePath(oldParams) !== workspacePath(params)) removed += await deleteRegistrationsForUrl(client, params, webhookUrl);
3267
+ context.logger.info(existing ? `Settings changed; removed ${removed} AEM event registration(s) and recreating.` : `Creating AEM event registration (removed ${removed} stale registration(s) for this URL).`);
3268
+ const { data } = await client.post(`${workspacePath(params)}/registrations`, {
3269
+ client_id: _prismatic_io_spectral.util.types.toString(params.connection.fields.clientId),
3270
+ name: `AEM events: ${context.flow.name}`.slice(0, 80),
3271
+ description: "Adobe Experience Manager events for an integration flow.",
3272
+ delivery_type: "webhook",
3273
+ webhook_url: webhookUrl,
3274
+ events_of_interest: params.eventTypes.map((eventCode) => ({
3275
+ provider_id: params.providerId,
3276
+ event_code: eventCode
3277
+ })),
3278
+ enabled: true
3279
+ });
3280
+ return {
3281
+ registrationId: data.registration_id,
3282
+ previousClientId: _prismatic_io_spectral.util.types.toString(params.connection.fields.clientId),
3283
+ previousEventTypes: params.eventTypes,
3284
+ previousProviderId: params.providerId,
3285
+ previousWorkspace: workspacePath(params)
3286
+ };
3287
+ };
3288
+ //#endregion
3289
+ //#region src/utils/eventTriggers.ts
3290
+ const aemEventLifecycleHandlers = (label) => ({
3291
+ create: async (context, params) => {
3292
+ if (!isIoEventsConnection(params.connection)) throw new Error(`${label} requires the OAuth 2.0 Client Credentials connection. Adobe I/O Events registrations are documented for OAuth Server-to-Server credentials only.`);
3293
+ if (!params.eventTypes.length) throw new Error(`${label} needs at least one event type. Select the events to subscribe to in Event Types.`);
3294
+ const state = await ensureRegistration(context, createIoEventsClient(params.connection, context.debug.enabled), params);
3295
+ return state ? { crossFlowState: { [webhookStateKey(context)]: state } } : void 0;
3296
+ },
3297
+ delete: async (context, params) => {
3298
+ if (!isIoEventsConnection(params.connection)) return { crossFlowState: { [webhookStateKey(context)]: null } };
3299
+ await deleteRegistrationsForUrl(createIoEventsClient(params.connection, context.debug.enabled), params, getWebhookUrl(context));
3300
+ return { crossFlowState: { [webhookStateKey(context)]: null } };
3301
+ }
3302
+ });
3303
+ const performAemEvent = async (context, payload, params) => {
3304
+ const challenge = payload.queryParameters?.challenge;
3305
+ if (challenge) return {
3306
+ payload: {
3307
+ ...payload,
3308
+ body: { data: null }
3309
+ },
3310
+ branch: "URL Verification",
3311
+ response: {
3312
+ statusCode: 200,
3313
+ contentType: "text/plain",
3314
+ body: challenge
3315
+ }
3316
+ };
3317
+ const rawBody = _prismatic_io_spectral.util.types.toString(payload.rawBody.data);
3318
+ const event = parseAemCloudEvent(payload.body.data, rawBody);
3319
+ if (!context.isSimulatedTestExecution) {
3320
+ const headers = _prismatic_io_spectral.util.types.lowerCaseHeaders(payload.headers);
3321
+ await verifyAdobeSignature(createPublicClient(context.debug.enabled), headers, rawBody);
3322
+ const clientId = _prismatic_io_spectral.util.types.toString(params.connection.fields.clientId);
3323
+ if (event.recipientclientid && event.recipientclientid !== clientId) throw new Error("AEM event was addressed to a different Adobe client ID.");
3324
+ }
3325
+ const item = toAemEventItem(event, params.workspaceId, params.publishBaseUrl);
3326
+ return {
3327
+ payload: {
3328
+ ...payload,
3329
+ body: { data: item }
3330
+ },
3331
+ branch: "Notification"
3332
+ };
3333
+ };
3334
+ //#endregion
3335
+ //#region src/utils/folders.ts
3336
+ const isAemJob = (value) => typeof value === "object" && value !== null && "jobId" in value;
3337
+ const assertFolderCommandProgress = (result, succeeded, failures) => {
3338
+ if (succeeded === 0 && failures.length) {
3339
+ const reasons = failures.map((f) => f.detail ?? f.title ?? f.path ?? "unknown error");
3340
+ const summary = "description" in result ? result.description : void 0;
3341
+ throw new Error(`${summary ?? "The folder request failed."} ${reasons.join("; ")}`);
3342
+ }
3343
+ return result;
3344
+ };
3345
+ const walkFolderTree = async (client, rootPath, { collectAssets, maxFolders = MAX_FOLDER_WALK }) => {
3346
+ const tree = {
3347
+ folders: [],
3348
+ assets: [],
3349
+ truncated: false
3350
+ };
3351
+ const queue = [rootPath];
3352
+ let visited = 0;
3353
+ while (queue.length && visited < maxFolders) {
3354
+ const folderPath = queue.shift();
3355
+ visited++;
3356
+ let cursor;
3357
+ do {
3358
+ const { data } = await client.get(`${FOLDERS_API_PATH}/`, { params: {
3359
+ path: folderPath,
3360
+ types: collectAssets ? "FOLDER,ASSET" : "FOLDER",
3361
+ limit: 50,
3362
+ cursor
3363
+ } });
3364
+ for (const child of data.children ?? []) if (child.type === "FOLDER") {
3365
+ tree.folders.push(child);
3366
+ queue.push(child.path);
3367
+ } else if (collectAssets) tree.assets.push({
3368
+ ...child,
3369
+ folderPath
3370
+ });
3371
+ cursor = data.cursor;
3372
+ } while (cursor);
3373
+ }
3374
+ tree.truncated = queue.length > 0;
3375
+ return tree;
3376
+ };
3377
+ //#endregion
3378
+ //#region src/utils/metadata.ts
3379
+ const toPointerSegment = (field) => field.replace(/~/g, "~0").replace(/\//g, "~1");
3380
+ const buildMetadataPatch = (values, removals) => {
3381
+ const operations = [...Object.entries(values).map(([field, value]) => ({
3382
+ op: "add",
3383
+ path: `/${toPointerSegment(field)}`,
3384
+ value
3385
+ })), ...removals.map((field) => ({
3386
+ op: "remove",
3387
+ path: `/${toPointerSegment(field)}`
3388
+ }))];
3389
+ if (!operations.length) throw new Error("Update Asset Metadata needs at least one metadata value or field to remove.");
3390
+ return operations;
3391
+ };
3392
+ //#endregion
3393
+ //#region src/utils/pagination.ts
3394
+ const fetchCursorPages = async (client, url, query, { fetchAll, cursor, limit }) => {
3395
+ if (!fetchAll) {
3396
+ const { data } = await client.get(url, { params: {
3397
+ ...query,
3398
+ cursor,
3399
+ limit
3400
+ } });
3401
+ return {
3402
+ items: data.items ?? [],
3403
+ cursor: data.cursor
3404
+ };
3405
+ }
3406
+ const items = [];
3407
+ let next = cursor;
3408
+ let pages = 0;
3409
+ do {
3410
+ const { data } = await client.get(url, { params: {
3411
+ ...query,
3412
+ cursor: next,
3413
+ limit: 50
3414
+ } });
3415
+ items.push(...data.items ?? []);
3416
+ next = data.cursor;
3417
+ pages++;
3418
+ } while (next && pages < 500);
3419
+ return {
3420
+ items,
3421
+ cursor: next
3422
+ };
3423
+ };
3424
+ //#endregion
3425
+ //#region src/utils/polling.ts
3426
+ const windowNow = (nowMs = Date.now()) => (/* @__PURE__ */ new Date(nowMs - SETTLE_LAG_MS)).toISOString();
3427
+ const resolvePollWindow = (state, incoming, lookBackDate, now) => {
3428
+ const resume = incoming ?? state.cursor;
3429
+ const isInitialSync = state.lastPolledAt === void 0 && lookBackDate !== "";
3430
+ if (resume) return {
3431
+ windowStart: resume.windowStart,
3432
+ windowEnd: resume.windowEnd,
3433
+ cursor: resume.cursor,
3434
+ isInitialSync
3435
+ };
3436
+ return {
3437
+ windowStart: state.lastPolledAt ?? (lookBackDate || now),
3438
+ windowEnd: now,
3439
+ isInitialSync
3440
+ };
3441
+ };
3442
+ const nextPollingState = (state, window, nextCursor) => nextCursor ? {
3443
+ ...state.lastPolledAt ? { lastPolledAt: state.lastPolledAt } : {},
3444
+ cursor: nextCursor
3445
+ } : { lastPolledAt: window.windowEnd };
3446
+ const readWindow = async (readPage, startCursor, isBatching) => {
3447
+ const maxPages = isBatching ? 1 : 20;
3448
+ const records = [];
3449
+ let cursor = startCursor;
3450
+ for (let page = 0; page < maxPages; page++) {
3451
+ const result = await readPage(cursor);
3452
+ records.push(...result.records);
3453
+ cursor = result.cursor;
3454
+ if (!cursor) break;
3455
+ }
3456
+ return {
3457
+ records,
3458
+ cursor
3459
+ };
3460
+ };
3461
+ const isInWindow = (value, window) => {
3462
+ if (!value) return false;
3463
+ const time = toIsoDate(value).getTime();
3464
+ return time >= toIsoDate(window.windowStart).getTime() && time < toIsoDate(window.windowEnd).getTime();
3465
+ };
3466
+ const listChangedContentFragments = async (client, baseFilter, window, isBatching) => {
3467
+ const after = (/* @__PURE__ */ new Date(toIsoDate(window.windowStart).getTime() - 1)).toISOString();
3468
+ const before = new Date(toIsoDate(window.windowEnd).getTime() + 1).toISOString();
3469
+ const query = JSON.stringify({
3470
+ filter: {
3471
+ ...baseFilter,
3472
+ modifiedOrCreated: {
3473
+ after,
3474
+ before
3475
+ }
3476
+ },
3477
+ sort: [{
3478
+ on: "modifiedOrCreated",
3479
+ order: "ASC"
3480
+ }]
3481
+ });
3482
+ const result = await readWindow(async (cursor) => {
3483
+ const { data } = await client.get(`${SITES_API_PATH}/cf/fragments/search`, { params: {
3484
+ query,
3485
+ cursor,
3486
+ limit: 50
3487
+ } });
3488
+ return {
3489
+ records: data.items ?? [],
3490
+ cursor: data.cursor
3491
+ };
3492
+ }, window.cursor, isBatching);
3493
+ return {
3494
+ records: result.records.filter((fragment) => isInWindow(fragment.modified?.at ?? fragment.created?.at, window)),
3495
+ cursor: result.cursor
3496
+ };
3497
+ };
3498
+ const listChangedAssets = async (client, filters, window, isBatching) => readWindow(async (cursor) => {
3499
+ const body = {
3500
+ query: [...buildAssetFilterClauses(filters), { range: { [ASSET_MODIFY_DATE_FIELD]: {
3501
+ gte: window.windowStart,
3502
+ lt: window.windowEnd
3503
+ } } }],
3504
+ sort: [{
3505
+ field: ASSET_MODIFY_DATE_FIELD,
3506
+ order: "ASC"
3507
+ }],
3508
+ limit: 50,
3509
+ cursor
3510
+ };
3511
+ const { data } = await client.post(`${ASSETS_API_PATH}/search`, body);
3512
+ return {
3513
+ records: data.hits?.results ?? [],
3514
+ cursor: data.cursor
3515
+ };
3516
+ }, window.cursor, isBatching);
3517
+ const classifyChange = (record, windowStart, isInitialSync) => {
3518
+ if (isInitialSync) return "initialSync";
3519
+ const start = toIsoDate(windowStart).getTime();
3520
+ const isAfterStart = (value) => value !== null && toIsoDate(value).getTime() >= start;
3521
+ if (isAfterStart(record.created)) return "created";
3522
+ if (isAfterStart(record.published)) return "published";
3523
+ return "modified";
3524
+ };
3525
+ const resolveAemChangeItems = (data) => {
3526
+ return [...(data ?? {}).items ?? []];
3527
+ };
3528
+ //#endregion
3529
+ //#region src/utils/sitemap.ts
3530
+ const XML_ENTITIES = {
3531
+ "&amp;": "&",
3532
+ "&lt;": "<",
3533
+ "&gt;": ">",
3534
+ "&quot;": "\"",
3535
+ "&apos;": "'"
3536
+ };
3537
+ const decodeXml = (value) => value.replace(/^<!\[CDATA\[([\s\S]*)\]\]>$/, "$1").replace(/&(amp|lt|gt|quot|apos);/g, (entity) => XML_ENTITIES[entity] ?? entity).trim();
3538
+ const readTag = (block, tag) => {
3539
+ const match = block.match(new RegExp(`<(?:\\w+:)?${tag}[^>]*>([\\s\\S]*?)</(?:\\w+:)?${tag}>`));
3540
+ return match ? decodeXml(match[1]) : null;
3541
+ };
3542
+ const readBlocks = (xml, tag) => xml.match(new RegExp(`<(?:\\w+:)?${tag}[\\s>][\\s\\S]*?</(?:\\w+:)?${tag}>`, "g")) ?? [];
3543
+ const parseSitemap = (xml) => {
3544
+ const toIsoOrNull = (value) => {
3545
+ if (value === null || value === "") return null;
3546
+ try {
3547
+ return toIsoDate(value).toISOString();
3548
+ } catch {
3549
+ return null;
3550
+ }
3551
+ };
3552
+ return {
3553
+ sitemaps: readBlocks(xml, "sitemap").map((block) => readTag(block, "loc")).filter((loc) => loc !== null && loc !== ""),
3554
+ pages: readBlocks(xml, "url").map((block) => ({
3555
+ loc: readTag(block, "loc"),
3556
+ lastmod: toIsoOrNull(readTag(block, "lastmod"))
3557
+ })).filter((page) => page.loc !== null && page.loc !== "")
3558
+ };
3559
+ };
3560
+ const filterPages = (pages, { modifiedAfter, includePathPrefixes = [], excludePathPrefixes = [] }) => pages.filter((page) => {
3561
+ let path;
3562
+ try {
3563
+ path = new URL(page.loc).pathname;
3564
+ } catch {
3565
+ return false;
3566
+ }
3567
+ if (includePathPrefixes.length && !includePathPrefixes.some((prefix) => path.startsWith(prefix))) return false;
3568
+ if (excludePathPrefixes.some((prefix) => path.startsWith(prefix))) return false;
3569
+ if (!modifiedAfter) return true;
3570
+ return page.lastmod !== null && toIsoDate(page.lastmod) > toIsoDate(modifiedAfter);
3571
+ });
3572
+ //#endregion
3573
+ //#region src/actions/assets/index.ts
3574
+ var assets_default = {
3575
+ deleteAsset,
3576
+ downloadAsset: (0, _prismatic_io_spectral.action)({
3577
+ display: {
3578
+ label: "Download Asset",
3579
+ description: "Download the original binary of an asset."
3580
+ },
3581
+ performSafety: "notAllowed",
3582
+ perform: async (context, { connection, assetId, seoName }) => {
3583
+ return toDownloadedFile(await createAemDownloadClient(connection, context.debug.enabled).get(`${ASSETS_API_PATH}/${encodeURIComponent(assetId)}/original/as/${encodeURIComponent(seoName)}`));
3584
+ },
3585
+ inputs: downloadAssetInputs,
3586
+ examplePerform: async () => downloadAssetExamplePayload,
3587
+ examplePayload: downloadAssetExamplePayload
3588
+ }),
3589
+ downloadAssetRendition: (0, _prismatic_io_spectral.action)({
3590
+ display: {
3591
+ label: "Download Asset Rendition",
3592
+ description: "Download a rendition of an asset, such as a web-optimized image or text version."
3593
+ },
3594
+ performSafety: "notAllowed",
3595
+ perform: async (context, { connection, assetId, renditionName, seoName }) => {
3596
+ return toDownloadedFile(await createAemDownloadClient(connection, context.debug.enabled).get(`${ASSETS_API_PATH}/${encodeURIComponent(assetId)}/renditions/${encodeURIComponent(renditionName)}/as/${encodeURIComponent(seoName)}`));
3597
+ },
3598
+ inputs: downloadAssetRenditionInputs,
3599
+ examplePerform: async () => downloadAssetRenditionExamplePayload,
3600
+ examplePayload: downloadAssetRenditionExamplePayload
3601
+ }),
3602
+ getAssetJobStatus: (0, _prismatic_io_spectral.action)({
3603
+ display: {
3604
+ label: "Get Asset Job Status",
3605
+ description: "Retrieve the state of a Delete Asset job."
3606
+ },
3607
+ performSafety: "safe",
3608
+ perform: async (context, { connection, jobId }) => {
3609
+ const { data } = await createAemClient(connection, context.debug.enabled).get(`${ASSETS_API_PATH}/jobs/${encodeURIComponent(jobId)}/status`);
3610
+ return { data };
3611
+ },
3612
+ inputs: getAssetJobStatusInputs,
3613
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3614
+ type: "actionOutput",
3615
+ schema: aemJobOutputSchema
3616
+ }),
3617
+ examplePayload: getAssetJobStatusExamplePayload
3618
+ }),
3619
+ getAssetMetadata: (0, _prismatic_io_spectral.action)({
3620
+ display: {
3621
+ label: "Get Asset Metadata",
3622
+ description: "Retrieve the repository and asset metadata of an asset."
3623
+ },
3624
+ performSafety: "safe",
3625
+ perform: async (context, { connection, assetId }) => {
3626
+ const { data } = await createAemClient(connection, context.debug.enabled).get(`${ASSETS_API_PATH}/${encodeURIComponent(assetId)}/metadata`);
3627
+ return { data };
3628
+ },
3629
+ inputs: getAssetMetadataInputs,
3630
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3631
+ type: "actionOutput",
3632
+ schema: getAssetMetadataOutputSchema
3633
+ }),
3634
+ examplePayload: getAssetMetadataExamplePayload
3635
+ }),
3636
+ getImportJobStatus: (0, _prismatic_io_spectral.action)({
3637
+ display: {
3638
+ label: "Get Import Job Status",
3639
+ description: "Retrieve the state and progress of an Import Asset from URL job."
3640
+ },
3641
+ performSafety: "safe",
3642
+ perform: async (context, { connection, jobId }) => {
3643
+ const { data } = await createAemClient(connection, context.debug.enabled).get(`${ASSETS_API_PATH}/import/jobs/${encodeURIComponent(jobId)}/status`);
3644
+ return { data };
3645
+ },
3646
+ inputs: getImportJobStatusInputs,
3647
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3648
+ type: "actionOutput",
3649
+ schema: importJobOutputSchema
3650
+ }),
3651
+ examplePayload: getImportJobStatusExamplePayload
3652
+ }),
3653
+ importAssetFromUrl: (0, _prismatic_io_spectral.action)({
3654
+ display: {
3655
+ label: "Import Asset from URL",
3656
+ description: "Create an asset by having AEM download a file from a URL. Runs as a job; check it with Get Import Job Status."
3657
+ },
3658
+ performSafety: "notAllowed",
3659
+ perform: async (context, { connection, folder, fileUrl, fileName, mimeType }) => {
3660
+ const { data } = await createAemClient(connection, context.debug.enabled).post(`${ASSETS_API_PATH}/import/fromUrl`, {
3661
+ folder,
3662
+ files: [{
3663
+ url: fileUrl,
3664
+ fileName,
3665
+ ...mimeType ? { mimeType } : {}
3666
+ }]
3667
+ });
3668
+ return { data };
3669
+ },
3670
+ inputs: importAssetFromUrlInputs,
3671
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3672
+ type: "actionOutput",
3673
+ schema: importJobOutputSchema
3674
+ }),
3675
+ examplePerform: async () => importAssetFromUrlExamplePayload,
3676
+ examplePayload: importAssetFromUrlExamplePayload
3677
+ }),
3678
+ listAssetRenditions: (0, _prismatic_io_spectral.action)({
3679
+ display: {
3680
+ label: "List Asset Renditions",
3681
+ description: "List the renditions available for an asset."
3682
+ },
3683
+ performSafety: "notAllowed",
3684
+ perform: async (context, { connection, assetId }) => {
3685
+ const { data } = await createAemClient(connection, context.debug.enabled).get(`${ASSETS_API_PATH}/${encodeURIComponent(assetId)}/renditions`);
3686
+ return { data };
3687
+ },
3688
+ inputs: listAssetRenditionsInputs,
3689
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3690
+ type: "actionOutput",
3691
+ schema: listAssetRenditionsOutputSchema
3692
+ }),
3693
+ examplePerform: async () => listAssetRenditionsExamplePayload,
3694
+ examplePayload: listAssetRenditionsExamplePayload
3695
+ }),
3696
+ searchAssets: (0, _prismatic_io_spectral.action)({
3697
+ display: {
3698
+ label: "Search Assets",
3699
+ description: "Search assets by folder, MIME type, modified date, and text."
3700
+ },
3701
+ performSafety: "notAllowed",
3702
+ perform: async (context, params) => {
3703
+ const client = createAemClient(params.connection, context.debug.enabled);
3704
+ const range = params.modifiedAfter || params.modifiedBefore ? {
3705
+ gte: params.modifiedAfter,
3706
+ lt: params.modifiedBefore
3707
+ } : void 0;
3708
+ const query = [
3709
+ { match: { text: params.filters?.searchText ?? "" } },
3710
+ ...buildAssetFilterClauses(params),
3711
+ ...range ? [{ range: { [ASSET_MODIFY_DATE_FIELD]: range } }] : []
3712
+ ];
3713
+ const sort = params.filters?.sortField ? [{
3714
+ field: params.filters.sortField,
3715
+ order: params.filters?.sortOrder === "DESC" ? "DESC" : "ASC"
3716
+ }] : void 0;
3717
+ if (!params.fetchAll) {
3718
+ const { data } = await client.post(`${ASSETS_API_PATH}/search`, {
3719
+ query,
3720
+ sort,
3721
+ limit: params.pagination?.limit,
3722
+ cursor: params.pagination?.cursor
3723
+ });
3724
+ return { data };
3725
+ }
3726
+ const results = [];
3727
+ let cursor = params.pagination?.cursor;
3728
+ let pages = 0;
3729
+ do {
3730
+ const { data } = await client.post(`${ASSETS_API_PATH}/search`, {
3731
+ query,
3732
+ sort,
3733
+ limit: 50,
3734
+ cursor
3735
+ });
3736
+ results.push(...data.hits?.results ?? []);
3737
+ cursor = data.cursor;
3738
+ pages++;
3739
+ } while (cursor && pages < 500);
3740
+ return { data: {
3741
+ hits: { results },
3742
+ cursor
3743
+ } };
3744
+ },
3745
+ inputs: searchAssetsInputs,
3746
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3747
+ type: "actionOutput",
3748
+ schema: searchAssetsOutputSchema
3749
+ }),
3750
+ examplePerform: async () => searchAssetsExamplePayload,
3751
+ examplePayload: searchAssetsExamplePayload
3752
+ }),
3753
+ updateAssetMetadata: (0, _prismatic_io_spectral.action)({
3754
+ display: {
3755
+ label: "Update Asset Metadata",
3756
+ description: "Set or remove asset metadata fields, such as dc:title, on an asset."
3757
+ },
3758
+ performSafety: "notAllowed",
3759
+ perform: async (context, { connection, assetId, metadataValues, removeFields }) => {
3760
+ const operations = buildMetadataPatch(metadataValues, removeFields);
3761
+ const client = createAemClient(connection, context.debug.enabled);
3762
+ const path = `${ASSETS_API_PATH}/${encodeURIComponent(assetId)}/metadata`;
3763
+ const { data } = await client.patch(path, operations, { headers: {
3764
+ "If-Match": "*",
3765
+ "Content-Type": "application/json-patch+json"
3766
+ } });
3767
+ return { data };
3768
+ },
3769
+ inputs: updateAssetMetadataInputs,
3770
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3771
+ type: "actionOutput",
3772
+ schema: getAssetMetadataOutputSchema
3773
+ }),
3774
+ examplePerform: async () => updateAssetMetadataExamplePayload,
3775
+ examplePayload: updateAssetMetadataExamplePayload
3776
+ })
3777
+ };
3778
+ //#endregion
3779
+ //#region src/actions/contentFragments/getContentFragment.ts
3780
+ const getContentFragment = (0, _prismatic_io_spectral.action)({
3781
+ display: {
3782
+ label: "Get Content Fragment",
3783
+ description: "Retrieve a content fragment by ID."
3784
+ },
3785
+ performSafety: "safe",
3786
+ perform: async (context, { connection, fragmentId, includeMetadata, references }) => {
3787
+ const { data } = await createAemClient(connection, context.debug.enabled).get(`${SITES_API_PATH}/cf/fragments/${encodeURIComponent(fragmentId)}`, { params: {
3788
+ includeMetadata: includeMetadata || void 0,
3789
+ references
3790
+ } });
3791
+ return { data };
3792
+ },
3793
+ inputs: getContentFragmentInputs,
3794
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3795
+ type: "actionOutput",
3796
+ schema: getContentFragmentOutputSchema
3797
+ }),
3798
+ examplePayload: getContentFragmentExamplePayload
3799
+ });
3800
+ //#endregion
3801
+ //#region src/actions/contentFragments/listContentFragmentModels.ts
3802
+ const listContentFragmentModels = (0, _prismatic_io_spectral.action)({
3803
+ display: {
3804
+ label: "List Content Fragment Models",
3805
+ description: "List the content fragment models available in the environment."
3806
+ },
3807
+ performSafety: "notAllowed",
3808
+ perform: async (context, params) => {
3809
+ return { data: await fetchCursorPages(createAemClient(params.connection, context.debug.enabled), `${SITES_API_PATH}/cf/models`, { projection: params.projection }, {
3810
+ fetchAll: params.fetchAll,
3811
+ ...params.pagination
3812
+ }) };
3813
+ },
3814
+ inputs: listContentFragmentModelsInputs,
3815
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3816
+ type: "actionOutput",
3817
+ schema: listContentFragmentModelsOutputSchema
3818
+ }),
3819
+ examplePerform: async () => listContentFragmentModelsExamplePayload,
3820
+ examplePayload: listContentFragmentModelsExamplePayload
3821
+ });
3822
+ //#endregion
3823
+ //#region src/actions/contentFragments/listContentFragments.ts
3824
+ const listContentFragments = (0, _prismatic_io_spectral.action)({
3825
+ display: {
3826
+ label: "List Content Fragments",
3827
+ description: "List content fragments, optionally under a path."
3828
+ },
3829
+ performSafety: "notAllowed",
3830
+ perform: async (context, params) => {
3831
+ return { data: await fetchCursorPages(createAemClient(params.connection, context.debug.enabled), `${SITES_API_PATH}/cf/fragments`, {
3832
+ path: params.path,
3833
+ projection: params.projection,
3834
+ includeMetadata: params.includeMetadata || void 0,
3835
+ references: params.references
3836
+ }, {
3837
+ fetchAll: params.fetchAll,
3838
+ ...params.pagination
3839
+ }) };
3840
+ },
3841
+ inputs: listContentFragmentsInputs,
3842
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3843
+ type: "actionOutput",
3844
+ schema: listContentFragmentsOutputSchema
3845
+ }),
3846
+ examplePerform: async () => listContentFragmentsExamplePayload,
3847
+ examplePayload: listContentFragmentsExamplePayload
3848
+ });
3849
+ //#endregion
3850
+ //#region src/actions/contentFragments/index.ts
3851
+ var contentFragments_default = {
3852
+ getContentFragment,
3853
+ listContentFragmentModels,
3854
+ listContentFragmentVariations: (0, _prismatic_io_spectral.action)({
3855
+ display: {
3856
+ label: "List Content Fragment Variations",
3857
+ description: "List the variations of a content fragment."
3858
+ },
3859
+ performSafety: "notAllowed",
3860
+ perform: async (context, params) => {
3861
+ return { data: await fetchCursorPages(createAemClient(params.connection, context.debug.enabled), `${SITES_API_PATH}/cf/fragments/${encodeURIComponent(params.fragmentId)}/variations`, {}, {
3862
+ fetchAll: params.fetchAll,
3863
+ ...params.pagination
3864
+ }) };
3865
+ },
3866
+ inputs: listContentFragmentVariationsInputs,
3867
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3868
+ type: "actionOutput",
3869
+ schema: listContentFragmentVariationsOutputSchema
3870
+ }),
3871
+ examplePerform: async () => listContentFragmentVariationsExamplePayload,
3872
+ examplePayload: listContentFragmentVariationsExamplePayload
3873
+ }),
3874
+ listContentFragments,
3875
+ searchContentFragments: (0, _prismatic_io_spectral.action)({
3876
+ display: {
3877
+ label: "Search Content Fragments",
3878
+ description: "Search content fragments by path, status, model, tag, locale, modified or published date, and text."
3879
+ },
3880
+ performSafety: "notAllowed",
3881
+ perform: async (context, params) => {
3882
+ const client = createAemClient(params.connection, context.debug.enabled);
3883
+ const query = {
3884
+ filter: {
3885
+ path: params.path,
3886
+ onlyDirectChildren: params.onlyDirectChildren || void 0,
3887
+ status: params.statuses.length ? params.statuses : void 0,
3888
+ modelIds: params.modelIds.length ? params.modelIds : void 0,
3889
+ tags: params.tags.length ? params.tags : void 0,
3890
+ locale: params.locales.length ? params.locales : void 0,
3891
+ modified: toTimeInterval(params.dateRangeFilters?.modifiedAfter, params.dateRangeFilters?.modifiedBefore),
3892
+ published: toTimeInterval(params.dateRangeFilters?.publishedAfter, params.dateRangeFilters?.publishedBefore),
3893
+ fullText: params.filters?.fullText ? { text: params.filters.fullText } : void 0
3894
+ },
3895
+ sort: params.filters?.sortOn ? [{
3896
+ on: params.filters.sortOn,
3897
+ order: params.filters?.sortOrder === "DESC" ? "DESC" : "ASC"
3898
+ }] : void 0
3899
+ };
3900
+ return { data: await fetchCursorPages(client, `${SITES_API_PATH}/cf/fragments/search`, {
3901
+ query: JSON.stringify(query),
3902
+ projection: params.projection,
3903
+ includeMetadata: params.includeMetadata || void 0
3904
+ }, {
3905
+ fetchAll: params.fetchAll,
3906
+ ...params.pagination
3907
+ }) };
3908
+ },
3909
+ inputs: searchContentFragmentsInputs,
3910
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3911
+ type: "actionOutput",
3912
+ schema: searchContentFragmentsOutputSchema
3913
+ }),
3914
+ examplePerform: async () => searchContentFragmentsExamplePayload,
3915
+ examplePayload: searchContentFragmentsExamplePayload
3916
+ })
3917
+ };
3918
+ //#endregion
3919
+ //#region src/actions/folders/index.ts
3920
+ var folders_default = {
3921
+ createFolders: (0, _prismatic_io_spectral.action)({
3922
+ display: {
3923
+ label: "Create Folders",
3924
+ description: "Create one or more asset folders. Fails when no folder could be created; when only some fail, they are listed in failedFolders. A request that runs as a job returns a job ID; check it with Get Folder Job Status."
3925
+ },
3926
+ performSafety: "notAllowed",
3927
+ perform: async (context, { connection, folderPaths }) => {
3928
+ const { data } = await createAemClient(connection, context.debug.enabled).post(`${FOLDERS_API_PATH}/`, folderPaths.map((path) => ({ path })));
3929
+ if (isAemJob(data)) return { data };
3930
+ const values = data.data?.values;
3931
+ return { data: assertFolderCommandProgress(data, values?.successes?.length ?? 0, [...values?.failedFolders ?? [], ...data.errors ?? []]) };
3932
+ },
3933
+ inputs: createFoldersInputs,
3934
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3935
+ type: "actionOutput",
3936
+ schema: createFoldersOutputSchema
3937
+ }),
3938
+ examplePerform: async () => createFoldersExamplePayload,
3939
+ examplePayload: createFoldersExamplePayload
3940
+ }),
3941
+ deleteFolders: (0, _prismatic_io_spectral.action)({
3942
+ display: {
3943
+ label: "Delete Folders",
3944
+ description: "Delete one or more asset folders by path. Fails when no folder could be deleted; when only some fail, they are listed in failedFolders. A request that runs as a job returns a job ID; check it with Get Folder Job Status."
3945
+ },
3946
+ performSafety: "notAllowed",
3947
+ perform: async (context, { connection, folderPaths, recursive, force }) => {
3948
+ const { data } = await createAemClient(connection, context.debug.enabled).post(`${FOLDERS_API_PATH}/delete`, {
3949
+ paths: folderPaths,
3950
+ recursive,
3951
+ force
3952
+ });
3953
+ if (isAemJob(data)) return { data };
3954
+ return { data: assertFolderCommandProgress(data, data.data?.deletedFolders?.length ?? 0, [...data.data?.failedFolders ?? [], ...data.errors ?? []]) };
3955
+ },
3956
+ inputs: deleteFoldersInputs,
3957
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3958
+ type: "actionOutput",
3959
+ schema: deleteFoldersOutputSchema
3960
+ }),
3961
+ examplePerform: async () => deleteFoldersExamplePayload,
3962
+ examplePayload: deleteFoldersExamplePayload
3963
+ }),
3964
+ getFolderJobStatus: (0, _prismatic_io_spectral.action)({
3965
+ display: {
3966
+ label: "Get Folder Job Status",
3967
+ description: "Retrieve the state of a Create Folders or Delete Folders job."
3968
+ },
3969
+ performSafety: "safe",
3970
+ perform: async (context, { connection, jobId }) => {
3971
+ const { data } = await createAemClient(connection, context.debug.enabled).get(`${FOLDERS_API_PATH}/jobs/${encodeURIComponent(jobId)}/status`);
3972
+ return { data };
3973
+ },
3974
+ inputs: getFolderJobStatusInputs,
3975
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3976
+ type: "actionOutput",
3977
+ schema: aemJobOutputSchema
3978
+ }),
3979
+ examplePayload: getFolderJobStatusExamplePayload
3980
+ }),
3981
+ listAssetsInFolderTree: (0, _prismatic_io_spectral.action)({
3982
+ display: {
3983
+ label: "List Assets in Folder Tree",
3984
+ description: "List every asset in a folder and all of its subfolders."
3985
+ },
3986
+ performSafety: "notAllowed",
3987
+ perform: async (context, { connection, path }) => {
3988
+ const { assets, truncated } = await walkFolderTree(createAemClient(connection, context.debug.enabled), path, { collectAssets: true });
3989
+ if (truncated) throw new Error(`The folder tree under ${path} has more than ${MAX_FOLDER_WALK} folders. Choose a narrower folder path.`);
3990
+ return { data: assets };
3991
+ },
3992
+ inputs: listAssetsInFolderTreeInputs,
3993
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
3994
+ type: "actionOutput",
3995
+ schema: listAssetsInFolderTreeOutputSchema
3996
+ }),
3997
+ examplePerform: async () => listAssetsInFolderTreeExamplePayload,
3998
+ examplePayload: listAssetsInFolderTreeExamplePayload
3999
+ }),
4000
+ listFolderContents: (0, _prismatic_io_spectral.action)({
4001
+ display: {
4002
+ label: "List Folder Contents",
4003
+ description: "List the folders and assets directly inside a folder."
4004
+ },
4005
+ performSafety: "notAllowed",
4006
+ perform: async (context, { connection, path, fetchAll, pagination, types, orderBy }) => {
4007
+ const client = createAemClient(connection, context.debug.enabled);
4008
+ const url = `${FOLDERS_API_PATH}/`;
4009
+ if (!fetchAll) {
4010
+ const { data } = await client.get(url, { params: {
4011
+ path,
4012
+ types,
4013
+ orderBy,
4014
+ cursor: pagination?.cursor,
4015
+ limit: pagination?.limit
4016
+ } });
4017
+ return { data };
4018
+ }
4019
+ const children = [];
4020
+ let self;
4021
+ let next = pagination?.cursor;
4022
+ do {
4023
+ const { data } = await client.get(url, { params: {
4024
+ path,
4025
+ types,
4026
+ orderBy,
4027
+ cursor: next,
4028
+ limit: 50
4029
+ } });
4030
+ self = self ?? data.self;
4031
+ children.push(...data.children ?? []);
4032
+ next = data.cursor;
4033
+ } while (next);
4034
+ return { data: {
4035
+ self,
4036
+ children
4037
+ } };
4038
+ },
4039
+ inputs: listFolderContentsInputs,
4040
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
4041
+ type: "actionOutput",
4042
+ schema: listFolderContentsOutputSchema
4043
+ }),
4044
+ examplePerform: async () => listFolderContentsExamplePayload,
4045
+ examplePayload: listFolderContentsExamplePayload
4046
+ })
4047
+ };
4048
+ //#endregion
4049
+ //#region src/actions/misc/index.ts
4050
+ var misc_default = { rawRequest: (0, _prismatic_io_spectral.action)({
4051
+ display: {
4052
+ label: "Raw Request",
4053
+ description: "Send raw HTTP request to Adobe Experience Manager."
4054
+ },
4055
+ performSafety: "notAllowed",
4056
+ inputs: rawRequestInputs,
4057
+ perform: async ({ debug: { enabled: debug } }, { connection, ...params }) => {
4058
+ const client = createAemClient(connection, debug);
4059
+ const { data } = await (0, _prismatic_io_spectral_http.sendRawRequest)(getAemBaseUrl(connection), {
4060
+ ...params,
4061
+ debugRequest: debug
4062
+ }, client.defaults?.headers ?? {});
4063
+ return { data };
4064
+ },
4065
+ examplePayload: rawRequestExamplePayload
4066
+ }) };
4067
+ //#endregion
4068
+ //#region src/pageSources/sitemapPageSource.ts
4069
+ const headerOrNull = (headers, name) => {
4070
+ const value = headers[name];
4071
+ return typeof value === "string" ? value : null;
4072
+ };
4073
+ const createSitemapPageSource = (client) => ({
4074
+ async listPages(params) {
4075
+ const rootHost = new URL(params.sitemapUrl).host;
4076
+ const queue = [params.sitemapUrl];
4077
+ const visited = /* @__PURE__ */ new Set();
4078
+ const pages = [];
4079
+ while (queue.length && visited.size < 50) {
4080
+ const url = queue.shift();
4081
+ if (visited.has(url)) continue;
4082
+ visited.add(url);
4083
+ const { data } = await client.get(url);
4084
+ const parsed = parseSitemap(_prismatic_io_spectral.util.types.toString(data));
4085
+ queue.push(...parsed.sitemaps.filter((child) => {
4086
+ try {
4087
+ const childUrl = new URL(child);
4088
+ return childUrl.protocol === "https:" && childUrl.host === rootHost;
4089
+ } catch {
4090
+ return false;
4091
+ }
4092
+ }));
4093
+ pages.push(...parsed.pages);
4094
+ }
4095
+ return filterPages(pages, params);
4096
+ },
4097
+ async getPageContent(url) {
4098
+ const response = await client.get(url);
4099
+ const headers = response.headers;
4100
+ return {
4101
+ url,
4102
+ finalUrl: response.request?.res?.responseUrl ?? url,
4103
+ statusCode: response.status,
4104
+ contentType: headerOrNull(headers, "content-type"),
4105
+ lastModified: headerOrNull(headers, "last-modified"),
4106
+ etag: headerOrNull(headers, "etag"),
4107
+ html: _prismatic_io_spectral.util.types.toString(response.data)
4108
+ };
4109
+ }
4110
+ });
4111
+ //#endregion
4112
+ //#region src/actions/pages/index.ts
4113
+ var pages_default = {
4114
+ getPublishedPageHtml: (0, _prismatic_io_spectral.action)({
4115
+ display: {
4116
+ label: "Get Published Page HTML",
4117
+ description: "Retrieve the published HTML of a page by URL. Accepts URLs from List Sitemap URLs or AEM Sites Event Subscription page events."
4118
+ },
4119
+ performSafety: "notAllowed",
4120
+ perform: async (context, { pageUrl }) => {
4121
+ return { data: await createSitemapPageSource(createPublicClient(context.debug.enabled)).getPageContent(pageUrl) };
4122
+ },
4123
+ inputs: getPublishedPageHtmlInputs,
4124
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
4125
+ type: "actionOutput",
4126
+ schema: getPublishedPageHtmlOutputSchema
4127
+ }),
4128
+ examplePerform: async () => getPublishedPageHtmlExamplePayload,
4129
+ examplePayload: getPublishedPageHtmlExamplePayload
4130
+ }),
4131
+ listSitemapUrls: (0, _prismatic_io_spectral.action)({
4132
+ display: {
4133
+ label: "List Sitemap URLs",
4134
+ description: "List page URLs and their last-modified dates from a site's sitemap, following a sitemap index. Pass the URLs to Get Published Page HTML."
4135
+ },
4136
+ performSafety: "notAllowed",
4137
+ perform: async (context, { sitemapUrl, modifiedAfter, includePathPrefixes, excludePathPrefixes }) => {
4138
+ return { data: await createSitemapPageSource(createPublicClient(context.debug.enabled)).listPages({
4139
+ sitemapUrl,
4140
+ modifiedAfter,
4141
+ includePathPrefixes,
4142
+ excludePathPrefixes
4143
+ }) };
4144
+ },
4145
+ inputs: listSitemapUrlsInputs,
4146
+ outputSchema: (0, _prismatic_io_spectral.outputSchema)({
4147
+ type: "actionOutput",
4148
+ schema: listSitemapUrlsOutputSchema
4149
+ }),
4150
+ examplePerform: async () => listSitemapUrlsExamplePayload,
4151
+ examplePayload: listSitemapUrlsExamplePayload
4152
+ })
4153
+ };
4154
+ //#endregion
4155
+ //#region src/actions/index.ts
4156
+ var actions_default = {
4157
+ ...contentFragments_default,
4158
+ ...folders_default,
4159
+ ...assets_default,
4160
+ ...pages_default,
4161
+ ...misc_default
4162
+ };
4163
+ //#endregion
4164
+ //#region src/dataSources/index.ts
4165
+ var dataSources_default = {
4166
+ selectAsset: (0, _prismatic_io_spectral.dataSource)({
4167
+ display: {
4168
+ label: "Select Asset",
4169
+ description: "Select an asset from the list of assets."
4170
+ },
4171
+ inputs: selectAssetInputs,
4172
+ examplePayload: selectAssetExamplePayload,
4173
+ perform: async (_context, { connection }) => {
4174
+ const client = createAemClient(connection, false);
4175
+ const query = [{ match: { text: "" } }];
4176
+ const hits = [];
4177
+ let cursor;
4178
+ do {
4179
+ const { data } = await client.post(`${ASSETS_API_PATH}/search`, {
4180
+ query,
4181
+ limit: 50,
4182
+ cursor
4183
+ });
4184
+ hits.push(...data.hits?.results ?? []);
4185
+ cursor = data.cursor;
4186
+ } while (cursor && hits.length < 1e3);
4187
+ return { result: hits.slice(0, MAX_DATA_SOURCE_ITEMS).map((hit) => ({
4188
+ label: hit.repositoryMetadata?.["repo:path"] ?? hit.repositoryMetadata?.["repo:name"] ?? hit.assetId,
4189
+ key: hit.assetId
4190
+ })).sort(compareElementLabels) };
4191
+ },
4192
+ dataSourceType: "picklist"
4193
+ }),
4194
+ selectAssetRendition: (0, _prismatic_io_spectral.dataSource)({
4195
+ display: {
4196
+ label: "Select Asset Rendition",
4197
+ description: "Select a rendition from the renditions available for an asset."
4198
+ },
4199
+ inputs: selectAssetRenditionInputs,
4200
+ examplePayload: selectAssetRenditionExamplePayload,
4201
+ perform: async (_context, { connection, assetId }) => {
4202
+ const { data } = await createAemClient(connection, false).get(`${ASSETS_API_PATH}/${encodeURIComponent(assetId)}/renditions`);
4203
+ return { result: (data.items ?? []).map((rendition) => ({
4204
+ label: rendition.name,
4205
+ key: rendition.name
4206
+ })).sort(compareElementLabels) };
4207
+ },
4208
+ dataSourceType: "picklist"
4209
+ }),
4210
+ selectContentFragment: (0, _prismatic_io_spectral.dataSource)({
4211
+ display: {
4212
+ label: "Select Content Fragment",
4213
+ description: "Select a content fragment from the list of content fragments."
4214
+ },
4215
+ inputs: selectContentFragmentInputs,
4216
+ examplePayload: selectContentFragmentExamplePayload,
4217
+ perform: async (_context, { connection, path }) => {
4218
+ const client = createAemClient(connection, false);
4219
+ const fragments = [];
4220
+ let cursor;
4221
+ do {
4222
+ const page = await fetchCursorPages(client, `${SITES_API_PATH}/cf/fragments`, { path }, {
4223
+ fetchAll: false,
4224
+ cursor,
4225
+ limit: 50
4226
+ });
4227
+ fragments.push(...page.items);
4228
+ cursor = page.cursor;
4229
+ } while (cursor && fragments.length < 1e3);
4230
+ return { result: fragments.slice(0, MAX_DATA_SOURCE_ITEMS).map((fragment) => ({
4231
+ label: fragment.title ? `${fragment.title} (${fragment.path})` : fragment.path,
4232
+ key: fragment.id
4233
+ })).sort(compareElementLabels) };
4234
+ },
4235
+ dataSourceType: "picklist"
4236
+ }),
4237
+ selectContentFragmentModel: (0, _prismatic_io_spectral.dataSource)({
4238
+ display: {
4239
+ label: "Select Content Fragment Model",
4240
+ description: "Select a content fragment model from the list of models."
4241
+ },
4242
+ inputs: selectContentFragmentModelInputs,
4243
+ examplePayload: selectContentFragmentModelExamplePayload,
4244
+ perform: async (_context, { connection }) => {
4245
+ const { items } = await fetchCursorPages(createAemClient(connection, false), `${SITES_API_PATH}/cf/models`, {}, { fetchAll: true });
4246
+ return { result: items.map((model) => ({
4247
+ label: model.title ?? model.name,
4248
+ key: model.id
4249
+ })).sort(compareElementLabels) };
4250
+ },
4251
+ dataSourceType: "picklist"
4252
+ }),
4253
+ selectFolder: (0, _prismatic_io_spectral.dataSource)({
4254
+ display: {
4255
+ label: "Select Folder",
4256
+ description: "Select an asset folder from the folders under /content/dam."
4257
+ },
4258
+ inputs: selectFolderInputs,
4259
+ examplePayload: selectFolderExamplePayload,
4260
+ perform: async (_context, { connection }) => {
4261
+ const { folders } = await walkFolderTree(createAemClient(connection, false), DEFAULT_DAM_ROOT, { collectAssets: false });
4262
+ return { result: folders.filter((folder) => folder.folderId).map((folder) => ({
4263
+ label: folder.path ?? folder.name ?? _prismatic_io_spectral.util.types.toString(folder.folderId),
4264
+ key: _prismatic_io_spectral.util.types.toString(folder.folderId)
4265
+ })).sort(compareElementLabels) };
4266
+ },
4267
+ dataSourceType: "picklist"
4268
+ }),
4269
+ selectFolderPath: (0, _prismatic_io_spectral.dataSource)({
4270
+ display: {
4271
+ label: "Select Folder Path",
4272
+ description: "Select an asset folder path from /content/dam and the folders under it."
4273
+ },
4274
+ inputs: selectFolderPathInputs,
4275
+ examplePayload: selectFolderPathExamplePayload,
4276
+ perform: async (_context, { connection }) => {
4277
+ const { folders } = await walkFolderTree(createAemClient(connection, false), DEFAULT_DAM_ROOT, { collectAssets: false });
4278
+ const paths = /* @__PURE__ */ new Set([DEFAULT_DAM_ROOT]);
4279
+ for (const folder of folders) if (folder.path) paths.add(folder.path);
4280
+ return { result: [...paths].map((path) => ({
4281
+ label: path,
4282
+ key: path
4283
+ })).sort(compareElementLabels) };
4284
+ },
4285
+ dataSourceType: "picklist"
4286
+ }),
4287
+ selectSitemapPage: (0, _prismatic_io_spectral.dataSource)({
4288
+ display: {
4289
+ label: "Select Sitemap Page",
4290
+ description: "Select a published page URL from a site's sitemap."
4291
+ },
4292
+ inputs: selectSitemapPageInputs,
4293
+ examplePayload: selectSitemapPageExamplePayload,
4294
+ perform: async (_context, { sitemapUrl }) => {
4295
+ return { result: (await createSitemapPageSource(createPublicClient(false)).listPages({ sitemapUrl })).slice(0, MAX_DATA_SOURCE_ITEMS).map((page) => ({
4296
+ label: page.loc,
4297
+ key: page.loc
4298
+ })).sort(compareElementLabels) };
4299
+ },
4300
+ dataSourceType: "picklist"
4301
+ })
4302
+ };
4303
+ //#endregion
4304
+ //#region src/triggers/aemAssetsEventWebhook.ts
4305
+ const LABEL$1 = "AEM Assets Event Subscription";
4306
+ const aemAssetsEventWebhook = (0, _prismatic_io_spectral.trigger)({
4307
+ display: {
4308
+ label: LABEL$1,
4309
+ description: "Receive and validate asset events from Adobe Experience Manager, including metadata updates that the New and Updated Assets trigger cannot detect. Handles URL verification challenges automatically, and automatically creates and manages an Adobe I/O Events webhook registration with the environment's AEM Assets event provider when the instance is deployed, removing it when the instance is deleted."
4310
+ },
4311
+ inputs: aemAssetsEventWebhookInputs,
4312
+ scheduleSupport: "invalid",
4313
+ synchronousResponseSupport: "valid",
4314
+ allowsBranching: true,
4315
+ staticBranchNames: AEM_EVENT_BRANCHES,
4316
+ webhookLifecycleHandlers: aemEventLifecycleHandlers(LABEL$1),
4317
+ perform: performAemEvent,
4318
+ examplePayload: aemAssetsEventWebhookExamplePayload
4319
+ });
4320
+ //#endregion
4321
+ //#region src/triggers/aemSitesEventWebhook.ts
4322
+ const LABEL = "AEM Sites Event Subscription";
4323
+ const aemSitesEventWebhook = (0, _prismatic_io_spectral.trigger)({
4324
+ display: {
4325
+ label: LABEL,
4326
+ description: "Receive and validate content fragment and page events from Adobe Experience Manager. Handles URL verification challenges automatically, and automatically creates and manages an Adobe I/O Events webhook registration with the environment's AEM Sites event provider when the instance is deployed, removing it when the instance is deleted. With a Publish Base URL, page events carry the published page URL for Get Published Page HTML."
4327
+ },
4328
+ inputs: aemSitesEventWebhookInputs,
4329
+ scheduleSupport: "invalid",
4330
+ synchronousResponseSupport: "valid",
4331
+ allowsBranching: true,
4332
+ staticBranchNames: AEM_EVENT_BRANCHES,
4333
+ webhookLifecycleHandlers: aemEventLifecycleHandlers(LABEL),
4334
+ perform: performAemEvent,
4335
+ examplePayload: aemSitesEventWebhookExamplePayload
4336
+ });
4337
+ //#endregion
4338
+ //#region src/triggers/assetChanges.ts
4339
+ const assetChanges = (0, _prismatic_io_spectral.pollingTrigger)({
4340
+ display: {
4341
+ label: "New and Updated Assets",
4342
+ description: "Retrieves existing and ongoing assets from Adobe Experience Manager. Load history once, check for changes on a schedule, or both."
4343
+ },
4344
+ inputs: assetChangesInputs,
4345
+ triggerResolverSupport: "valid",
4346
+ batchConfig: { batchSize: 50 },
4347
+ triggerResolver: {
4348
+ resolveItems: (_context, { payload }) => resolveAemChangeItems(payload.body.data),
4349
+ getNextPaginationState: (_context, { payload }) => payload.paginationState ?? null
4350
+ },
4351
+ perform: async (context, payload, params) => {
4352
+ const isBatching = context.batch?.enabled === true;
4353
+ const incoming = payload.paginationState;
4354
+ const state = context.polling.getState() ?? {};
4355
+ const window = resolvePollWindow(state, incoming, params.lookBackDate, windowNow());
4356
+ const windowIsEmpty = window.windowStart >= window.windowEnd;
4357
+ const client = createAemClient(params.connection, context.debug.enabled);
4358
+ const { records, cursor } = windowIsEmpty ? {
4359
+ records: [],
4360
+ cursor: void 0
4361
+ } : await listChangedAssets(client, params, window, isBatching);
4362
+ const nextCursor = cursor ? {
4363
+ windowStart: window.windowStart,
4364
+ windowEnd: window.windowEnd,
4365
+ cursor
4366
+ } : void 0;
4367
+ context.polling.setState(nextPollingState(state, window, nextCursor));
4368
+ const scope = params.folderIds.length ? params.folderIds.join(",") : DEFAULT_DAM_ROOT;
4369
+ const items = records.map((hit) => {
4370
+ const record = toAssetRecord(hit, scope, params.publishBaseUrl);
4371
+ return {
4372
+ changeType: classifyChange(record, window.windowStart, window.isInitialSync),
4373
+ record
4374
+ };
4375
+ });
4376
+ if (context.debug.enabled) context.logger.debug(`Assets ${window.windowStart} to ${window.windowEnd}: ${items.length} changed; ${nextCursor ? "more pages remain" : "window drained"}`);
4377
+ return {
4378
+ payload: {
4379
+ ...payload,
4380
+ paginationState: nextCursor,
4381
+ body: { data: { items } }
4382
+ },
4383
+ polledNoChanges: items.length === 0 && !nextCursor && !incoming
4384
+ };
4385
+ },
4386
+ examplePayload: assetChangesExamplePayload
4387
+ });
4388
+ //#endregion
4389
+ //#region src/triggers/index.ts
4390
+ var triggers_default = {
4391
+ contentFragmentChanges: (0, _prismatic_io_spectral.pollingTrigger)({
4392
+ display: {
4393
+ label: "New and Updated Fragments",
4394
+ description: "Retrieves existing and ongoing content fragments from Adobe Experience Manager. Load history once, check for changes on a schedule, or both."
4395
+ },
4396
+ inputs: contentFragmentChangesInputs,
4397
+ triggerResolverSupport: "valid",
4398
+ batchConfig: { batchSize: 50 },
4399
+ triggerResolver: {
4400
+ resolveItems: (_context, { payload }) => resolveAemChangeItems(payload.body.data),
4401
+ getNextPaginationState: (_context, { payload }) => payload.paginationState ?? null
4402
+ },
4403
+ perform: async (context, payload, params) => {
4404
+ const isBatching = context.batch?.enabled === true;
4405
+ const incoming = payload.paginationState;
4406
+ const state = context.polling.getState() ?? {};
4407
+ const window = resolvePollWindow(state, incoming, params.lookBackDate, windowNow());
4408
+ const windowIsEmpty = window.windowStart >= window.windowEnd;
4409
+ const client = createAemClient(params.connection, context.debug.enabled);
4410
+ const { records, cursor } = windowIsEmpty ? {
4411
+ records: [],
4412
+ cursor: void 0
4413
+ } : await listChangedContentFragments(client, buildContentFragmentTriggerFilter(params), window, isBatching);
4414
+ const nextCursor = cursor ? {
4415
+ windowStart: window.windowStart,
4416
+ windowEnd: window.windowEnd,
4417
+ cursor
4418
+ } : void 0;
4419
+ context.polling.setState(nextPollingState(state, window, nextCursor));
4420
+ const scope = params.path ?? "/content/dam";
4421
+ const items = records.map((fragment) => {
4422
+ const record = toContentFragmentRecord(fragment, scope, params.publishBaseUrl);
4423
+ return {
4424
+ changeType: classifyChange(record, window.windowStart, window.isInitialSync),
4425
+ record
4426
+ };
4427
+ });
4428
+ if (context.debug.enabled) context.logger.debug(`Content fragments ${window.windowStart} to ${window.windowEnd}: ${items.length} changed; ${nextCursor ? "more pages remain" : "window drained"}`);
4429
+ return {
4430
+ payload: {
4431
+ ...payload,
4432
+ paginationState: nextCursor,
4433
+ body: { data: { items } }
4434
+ },
4435
+ polledNoChanges: items.length === 0 && !nextCursor && !incoming
4436
+ };
4437
+ },
4438
+ examplePayload: contentFragmentChangesExamplePayload
4439
+ }),
4440
+ assetChanges,
4441
+ aemSitesEventWebhook,
4442
+ aemAssetsEventWebhook
4443
+ };
4444
+ //#endregion
4445
+ //#region src/index.ts
4446
+ var src_default = (0, _prismatic_io_spectral.component)({
4447
+ key: "adobe-experience-manager",
4448
+ public: true,
4449
+ documentationUrl: "https://prismatic.io/docs/components/adobe-experience-manager/",
4450
+ display: {
4451
+ label: "Adobe Experience Manager",
4452
+ description: "Read content fragments, assets, and published pages from Adobe Experience Manager as a Cloud Service, and detect content changes.",
4453
+ iconPath: "icon.png",
4454
+ category: "Application Connectors"
4455
+ },
4456
+ connections: connections_default,
4457
+ actions: actions_default,
4458
+ dataSources: dataSources_default,
4459
+ triggers: triggers_default,
4460
+ hooks: { error: _prismatic_io_spectral_http.handleErrors }
4461
+ });
4462
+ //#endregion
4463
+ //#region npm-dist/.entry.ts
4464
+ var _entry_default = (0, _prismatic_io_spectral.callableComponent)(src_default);
4465
+ //#endregion
4466
+ module.exports = _entry_default;