@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.
- package/README.md +64 -2
- package/dist/icon.png +0 -0
- package/dist/index.js +218 -0
- package/npm-dist/icon.png +0 -0
- package/npm-dist/index.cjs +4466 -0
- package/npm-dist/index.d.cts +2012 -0
- package/package.json +51 -4
|
@@ -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
|
+
"&": "&",
|
|
3532
|
+
"<": "<",
|
|
3533
|
+
">": ">",
|
|
3534
|
+
""": "\"",
|
|
3535
|
+
"'": "'"
|
|
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;
|