@code.store/arcxp-sdk-ts 4.49.1 → 5.0.0-beta

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.
Files changed (192) hide show
  1. package/dist/api/abstract-api.d.ts +2 -2
  2. package/dist/api/author/index.d.ts +2 -2
  3. package/dist/api/author/types.d.ts +32 -1
  4. package/dist/api/content/index.d.ts +4 -4
  5. package/dist/api/content/types.d.ts +3 -4
  6. package/dist/api/content-ops/index.d.ts +2 -2
  7. package/dist/api/custom/index.d.ts +1 -1
  8. package/dist/api/draft/index.d.ts +4 -4
  9. package/dist/api/draft/types.d.ts +4 -4
  10. package/dist/api/global-settings/index.d.ts +2 -2
  11. package/dist/api/identity/index.d.ts +2 -2
  12. package/dist/api/ifx/index.d.ts +2 -2
  13. package/dist/api/index.d.ts +19 -20
  14. package/dist/api/migration-center/index.d.ts +2 -2
  15. package/dist/api/migration-center/types.d.ts +4 -38
  16. package/dist/api/photo-center/index.d.ts +8 -9
  17. package/dist/api/photo-center/types.d.ts +3 -4
  18. package/dist/api/redirect/index.d.ts +2 -2
  19. package/dist/api/retail-events/index.d.ts +2 -2
  20. package/dist/api/sales/index.d.ts +2 -2
  21. package/dist/api/signing-service/index.d.ts +2 -2
  22. package/dist/api/site/index.d.ts +3 -4
  23. package/dist/api/site/types.d.ts +88 -1
  24. package/dist/api/tags/index.d.ts +2 -2
  25. package/dist/api/websked/index.d.ts +2 -2
  26. package/dist/api/ws.client.d.ts +1 -1
  27. package/dist/content-elements/content-elements.d.ts +54 -54
  28. package/dist/content-elements/html/html.processor.d.ts +7 -7
  29. package/dist/content-elements/html/html.utils.d.ts +2 -2
  30. package/dist/content-elements/html/index.d.ts +3 -3
  31. package/dist/content-elements/index.d.ts +2 -2
  32. package/dist/content-elements/types.d.ts +4 -0
  33. package/dist/index.cjs +1905 -0
  34. package/dist/index.cjs.map +1 -0
  35. package/dist/index.d.ts +9 -20
  36. package/dist/index.js +1872 -62
  37. package/dist/index.js.map +1 -1
  38. package/dist/lib/axios-rate-limiter.d.ts +2 -0
  39. package/dist/lib/platform/index.d.ts +6 -0
  40. package/dist/lib/platform/node.d.ts +6 -0
  41. package/dist/mapper/doc.d.ts +26 -25
  42. package/dist/mapper/index.d.ts +2 -2
  43. package/dist/mapper/story.d.ts +4 -4
  44. package/dist/types/ans-types.d.ts +2287 -0
  45. package/dist/types/gallery.d.ts +1 -1
  46. package/dist/types/index.d.ts +15 -7
  47. package/dist/types/section.d.ts +1 -1
  48. package/dist/utils/arc/ans.d.ts +2 -2
  49. package/dist/utils/arc/content.d.ts +1 -1
  50. package/dist/utils/arc/index.d.ts +3 -3
  51. package/dist/utils/decorator.d.ts +1 -1
  52. package/package.json +28 -18
  53. package/dist/api/abstract-api.js +0 -61
  54. package/dist/api/abstract-api.js.map +0 -1
  55. package/dist/api/author/index.js +0 -19
  56. package/dist/api/author/index.js.map +0 -1
  57. package/dist/api/author/types.js +0 -3
  58. package/dist/api/author/types.js.map +0 -1
  59. package/dist/api/content/index.js +0 -29
  60. package/dist/api/content/index.js.map +0 -1
  61. package/dist/api/content/types.js +0 -3
  62. package/dist/api/content/types.js.map +0 -1
  63. package/dist/api/content-ops/index.js +0 -27
  64. package/dist/api/content-ops/index.js.map +0 -1
  65. package/dist/api/content-ops/types.js +0 -3
  66. package/dist/api/content-ops/types.js.map +0 -1
  67. package/dist/api/custom/index.js +0 -18
  68. package/dist/api/custom/index.js.map +0 -1
  69. package/dist/api/draft/index.js +0 -63
  70. package/dist/api/draft/index.js.map +0 -1
  71. package/dist/api/draft/types.js +0 -3
  72. package/dist/api/draft/types.js.map +0 -1
  73. package/dist/api/error.js +0 -26
  74. package/dist/api/error.js.map +0 -1
  75. package/dist/api/global-settings/index.js +0 -19
  76. package/dist/api/global-settings/index.js.map +0 -1
  77. package/dist/api/global-settings/types.js +0 -3
  78. package/dist/api/global-settings/types.js.map +0 -1
  79. package/dist/api/identity/index.js +0 -35
  80. package/dist/api/identity/index.js.map +0 -1
  81. package/dist/api/identity/types.js +0 -3
  82. package/dist/api/identity/types.js.map +0 -1
  83. package/dist/api/ifx/index.js +0 -94
  84. package/dist/api/ifx/index.js.map +0 -1
  85. package/dist/api/ifx/types.js +0 -3
  86. package/dist/api/ifx/types.js.map +0 -1
  87. package/dist/api/index.js +0 -49
  88. package/dist/api/index.js.map +0 -1
  89. package/dist/api/migration-center/index.js +0 -45
  90. package/dist/api/migration-center/index.js.map +0 -1
  91. package/dist/api/migration-center/types.js +0 -41
  92. package/dist/api/migration-center/types.js.map +0 -1
  93. package/dist/api/photo-center/index.js +0 -64
  94. package/dist/api/photo-center/index.js.map +0 -1
  95. package/dist/api/photo-center/types.js +0 -3
  96. package/dist/api/photo-center/types.js.map +0 -1
  97. package/dist/api/redirect/index.js +0 -23
  98. package/dist/api/redirect/index.js.map +0 -1
  99. package/dist/api/redirect/types.js +0 -3
  100. package/dist/api/redirect/types.js.map +0 -1
  101. package/dist/api/retail-events/index.js +0 -18
  102. package/dist/api/retail-events/index.js.map +0 -1
  103. package/dist/api/sales/index.js +0 -25
  104. package/dist/api/sales/index.js.map +0 -1
  105. package/dist/api/sales/types.js +0 -3
  106. package/dist/api/sales/types.js.map +0 -1
  107. package/dist/api/signing-service/index.js +0 -15
  108. package/dist/api/signing-service/index.js.map +0 -1
  109. package/dist/api/signing-service/types.js +0 -3
  110. package/dist/api/signing-service/types.js.map +0 -1
  111. package/dist/api/site/index.js +0 -44
  112. package/dist/api/site/index.js.map +0 -1
  113. package/dist/api/site/types.js +0 -3
  114. package/dist/api/site/types.js.map +0 -1
  115. package/dist/api/tags/index.js +0 -36
  116. package/dist/api/tags/index.js.map +0 -1
  117. package/dist/api/tags/types.js +0 -3
  118. package/dist/api/tags/types.js.map +0 -1
  119. package/dist/api/websked/index.js +0 -47
  120. package/dist/api/websked/index.js.map +0 -1
  121. package/dist/api/websked/types.js +0 -3
  122. package/dist/api/websked/types.js.map +0 -1
  123. package/dist/api/ws.client.js +0 -68
  124. package/dist/api/ws.client.js.map +0 -1
  125. package/dist/content-elements/content-elements.js +0 -235
  126. package/dist/content-elements/content-elements.js.map +0 -1
  127. package/dist/content-elements/html/html.constants.js +0 -40
  128. package/dist/content-elements/html/html.constants.js.map +0 -1
  129. package/dist/content-elements/html/html.processor.js +0 -370
  130. package/dist/content-elements/html/html.processor.js.map +0 -1
  131. package/dist/content-elements/html/html.utils.js +0 -79
  132. package/dist/content-elements/html/html.utils.js.map +0 -1
  133. package/dist/content-elements/html/index.js +0 -41
  134. package/dist/content-elements/html/index.js.map +0 -1
  135. package/dist/content-elements/index.js +0 -42
  136. package/dist/content-elements/index.js.map +0 -1
  137. package/dist/mapper/doc.js +0 -146
  138. package/dist/mapper/doc.js.map +0 -1
  139. package/dist/mapper/index.js +0 -8
  140. package/dist/mapper/index.js.map +0 -1
  141. package/dist/mapper/story.js +0 -111
  142. package/dist/mapper/story.js.map +0 -1
  143. package/dist/scripts/json-schema-to-ts.js +0 -8
  144. package/dist/scripts/json-schema-to-ts.js.map +0 -1
  145. package/dist/tests/ans/mapper.test.d.ts +0 -1
  146. package/dist/tests/ans/mapper.test.js +0 -93
  147. package/dist/tests/ans/mapper.test.js.map +0 -1
  148. package/dist/tests/api/basic.test.d.ts +0 -1
  149. package/dist/tests/api/basic.test.js +0 -20
  150. package/dist/tests/api/basic.test.js.map +0 -1
  151. package/dist/tests/api/retry.test.d.ts +0 -1
  152. package/dist/tests/api/retry.test.js +0 -51
  153. package/dist/tests/api/retry.test.js.map +0 -1
  154. package/dist/tests/api/utils.test.d.ts +0 -1
  155. package/dist/tests/api/utils.test.js +0 -255
  156. package/dist/tests/api/utils.test.js.map +0 -1
  157. package/dist/tests/content-elements/html.processor.test.d.ts +0 -1
  158. package/dist/tests/content-elements/html.processor.test.js +0 -35
  159. package/dist/tests/content-elements/html.processor.test.js.map +0 -1
  160. package/dist/types/author.js +0 -8
  161. package/dist/types/author.js.map +0 -1
  162. package/dist/types/content-elements.d.ts +0 -4
  163. package/dist/types/content-elements.js +0 -3
  164. package/dist/types/content-elements.js.map +0 -1
  165. package/dist/types/gallery.js +0 -3
  166. package/dist/types/gallery.js.map +0 -1
  167. package/dist/types/index.js +0 -44
  168. package/dist/types/index.js.map +0 -1
  169. package/dist/types/section.js +0 -3
  170. package/dist/types/section.js.map +0 -1
  171. package/dist/types/story.js +0 -8
  172. package/dist/types/story.js.map +0 -1
  173. package/dist/types/utils.js +0 -3
  174. package/dist/types/utils.js.map +0 -1
  175. package/dist/types/video.js +0 -8
  176. package/dist/types/video.js.map +0 -1
  177. package/dist/utils/arc/ans.js +0 -14
  178. package/dist/utils/arc/ans.js.map +0 -1
  179. package/dist/utils/arc/content.js +0 -79
  180. package/dist/utils/arc/content.js.map +0 -1
  181. package/dist/utils/arc/id.js +0 -40
  182. package/dist/utils/arc/id.js.map +0 -1
  183. package/dist/utils/arc/index.js +0 -45
  184. package/dist/utils/arc/index.js.map +0 -1
  185. package/dist/utils/cache.js +0 -63
  186. package/dist/utils/cache.js.map +0 -1
  187. package/dist/utils/decorator.js +0 -20
  188. package/dist/utils/decorator.js.map +0 -1
  189. package/dist/utils/duration.js +0 -21
  190. package/dist/utils/duration.js.map +0 -1
  191. package/dist/utils/index.js +0 -52
  192. package/dist/utils/index.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,64 +1,1874 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
1
+ import axios from 'axios';
2
+ import * as rateLimit from 'axios-rate-limit';
3
+ import axiosRetry from 'axios-retry';
4
+ import * as ws from 'ws';
5
+ import FormData from 'form-data';
6
+ import encode from 'base32-encode';
7
+ import { v5 } from 'uuid';
8
+ import { TextNode, HTMLElement, CommentNode, parse } from 'node-html-parser';
9
+ import { decode } from 'html-entities';
10
+
11
+ const safeJSONStringify = (data) => {
12
+ try {
13
+ return JSON.stringify(data) || '';
14
+ }
15
+ catch {
16
+ return '';
17
+ }
18
+ };
19
+ const AxiosResponseErrorInterceptor = (errorConstructor) => {
20
+ return [
21
+ (response) => response,
22
+ (error) => {
23
+ throw errorConstructor(error);
24
+ },
25
+ ];
26
+ };
27
+
28
+ class ArcError extends Error {
29
+ constructor(service, e) {
30
+ const ratelimitRemaining = e.response?.headers['arcpub-ratelimit-remaining'];
31
+ const ratelimitReset = e.response?.headers['arcpub-ratelimit-reset'];
32
+ const data = {
33
+ name: `${service}Error`,
34
+ message: e.message,
35
+ responseData: e.response?.data,
36
+ responseStatus: e.response?.status,
37
+ responseConfig: e.response?.config,
38
+ ratelimitRemaining,
39
+ ratelimitReset,
40
+ service,
41
+ };
42
+ const message = safeJSONStringify(data);
43
+ super(message);
44
+ Object.assign(this, data);
45
+ this.stack = e.stack;
46
+ }
47
+ }
48
+
49
+ class ArcAbstractAPI {
50
+ constructor(options) {
51
+ this.name = this.constructor.name;
52
+ this.token = '';
53
+ this.host = '';
54
+ this.headers = {
55
+ Authorization: '',
56
+ };
57
+ this.host = `api.${options.credentials.organizationName}.arcpublishing.com`;
58
+ this.token = `Bearer ${options.credentials.accessToken}`;
59
+ this.headers.Authorization = this.token;
60
+ const instance = axios.create({
61
+ baseURL: `https://${this.host}/${options.apiPath}`,
62
+ headers: this.headers,
63
+ });
64
+ // apply rate limiting
65
+ this.client = rateLimit.default(instance, { maxRPS: options.maxRPS || 10 });
66
+ // apply retry
67
+ const retry = typeof axiosRetry === 'function' ? axiosRetry : axiosRetry.default;
68
+ retry(this.client, {
69
+ retries: 5,
70
+ retryDelay: axiosRetry.exponentialDelay,
71
+ retryCondition: (err) => this.retryCondition(err),
72
+ });
73
+ // wrap response errors
74
+ this.client.interceptors.response.use(...AxiosResponseErrorInterceptor((e) => {
75
+ if (e instanceof ArcError)
76
+ return e;
77
+ return new ArcError(this.name, e);
78
+ }));
79
+ }
80
+ setMaxRPS(rps) {
81
+ this.client.setMaxRPS(rps);
82
+ }
83
+ retryCondition(error) {
84
+ const status = error.response?.status;
85
+ switch (status) {
86
+ case axios.HttpStatusCode.RequestTimeout:
87
+ case axios.HttpStatusCode.TooManyRequests:
88
+ case axios.HttpStatusCode.InternalServerError:
89
+ case axios.HttpStatusCode.BadGateway:
90
+ case axios.HttpStatusCode.ServiceUnavailable:
91
+ case axios.HttpStatusCode.GatewayTimeout:
92
+ return true;
93
+ default:
94
+ return false;
95
+ }
96
+ }
97
+ }
98
+
99
+ class ArcAuthor extends ArcAbstractAPI {
100
+ constructor(options) {
101
+ super({ ...options, apiPath: 'author' });
102
+ }
103
+ async listAuthors(params) {
104
+ const { data } = await this.client.get('/v2/author-service', { params });
105
+ return data;
106
+ }
107
+ async delete(userId) {
108
+ const { data } = await this.client.delete(`/v2/author-service/${userId}`);
109
+ return data;
110
+ }
111
+ }
112
+
113
+ class ArcContentOps extends ArcAbstractAPI {
114
+ constructor(options) {
115
+ super({ ...options, apiPath: 'contentops/v1' });
116
+ }
117
+ async schedulePublish(payload) {
118
+ const { data } = await this.client.put('/publish', payload);
119
+ return data;
120
+ }
121
+ async scheduleUnpublish(payload) {
122
+ const { data } = await this.client.put('/unpublish', payload);
123
+ return data;
124
+ }
125
+ async unscheduleUnpublish(payload) {
126
+ const { data } = await this.client.put('/unschedule_unpublish', payload);
127
+ return data;
128
+ }
129
+ async unschedulePublish(payload) {
130
+ const { data } = await this.client.put('/unschedule_publish', payload);
131
+ return data;
132
+ }
133
+ }
134
+
135
+ class ArcContent extends ArcAbstractAPI {
136
+ constructor(options) {
137
+ super({ ...options, apiPath: 'content/v4' });
138
+ }
139
+ async getStory(params) {
140
+ const { data } = await this.client.get('/stories', { params });
141
+ return data;
142
+ }
143
+ async search(params) {
144
+ const { data } = await this.client.get('/search', { params });
145
+ return data;
146
+ }
147
+ async scan(params) {
148
+ const { data } = await this.client.get('/scan', { params });
149
+ return data;
150
+ }
151
+ async getStoriesByIds(params) {
152
+ const { data } = await this.client.get('/ids', {
153
+ params: { ...params, ids: params.ids.join(',') },
154
+ });
155
+ return data;
156
+ }
157
+ }
158
+
159
+ class Custom extends ArcAbstractAPI {
160
+ constructor(options) {
161
+ super({ ...options, apiPath: '' });
162
+ }
163
+ async request(endpoint, config = {}) {
164
+ const response = await this.client.request({
165
+ url: endpoint,
166
+ ...config,
167
+ });
168
+ return response;
169
+ }
170
+ }
171
+
172
+ class ArcDraft extends ArcAbstractAPI {
173
+ constructor(options) {
174
+ super({ ...options, apiPath: 'draft/v1' });
175
+ }
176
+ async generateId(id) {
177
+ const { data } = await this.client.get('/arcuuid', { params: { id } });
178
+ return data.id;
179
+ }
180
+ async createDocument(ans, type = 'story') {
181
+ const { data } = await this.client.post(`/${type}`, ans);
182
+ return data;
183
+ }
184
+ async publishDocument(id, type = 'story') {
185
+ const { data } = await this.client.post(`/${type}/${id}/revision/published`);
186
+ return data;
187
+ }
188
+ async unpublishDocument(id, type = 'story') {
189
+ const { data } = await this.client.delete(`/${type}/${id}/revision/published`);
190
+ return data;
191
+ }
192
+ async deleteDocument(id, type = 'story') {
193
+ const { data } = await this.client.delete(`/${type}/${id}`);
194
+ return data;
195
+ }
196
+ async getPublishedRevision(id, type = 'story') {
197
+ const { data } = await this.client.get(`/${type}/${id}/revision/published`);
198
+ return data;
199
+ }
200
+ async getDraftRevision(id, type = 'story') {
201
+ const { data } = await this.client.get(`/${type}/${id}/revision/draft`);
202
+ return data;
203
+ }
204
+ async getCirculations(id, type = 'story', after) {
205
+ const { data } = await this.client.get(`/${type}/${id}/circulation`, { params: { after } });
206
+ return data;
207
+ }
208
+ async getRevisions(id, type = 'story', after) {
209
+ const { data } = await this.client.get(`/${type}/${id}/revision`, { params: { after } });
210
+ return data;
211
+ }
212
+ async getRevision(id, revisionId, type = 'story') {
213
+ const { data } = await this.client.get(`/${type}/${id}/revision/${revisionId}`);
214
+ return data;
215
+ }
216
+ async createRedirect(website, websiteUrl, payload) {
217
+ const { data } = await this.client.post(`/redirect/${website}/${websiteUrl}`, payload);
218
+ return data;
219
+ }
220
+ async getRedirect(website, websiteUrl) {
221
+ const { data } = await this.client.get(`/redirect/${website}/${websiteUrl}`);
222
+ return data;
223
+ }
224
+ async updateDraftRevision(id, payload, type = 'story') {
225
+ const { data } = await this.client.put(`/${type}/${id}/revision/draft`, payload);
226
+ return data;
227
+ }
228
+ }
229
+
230
+ class GlobalSettings extends ArcAbstractAPI {
231
+ constructor(options) {
232
+ super({ ...options, apiPath: 'settings/v1' });
233
+ }
234
+ async getDistributors(params) {
235
+ const { data } = await this.client.get('/distributor', { params });
236
+ return data;
237
+ }
238
+ async createDistributors(payload) {
239
+ const { data } = await this.client.post('/distributor', payload);
240
+ return data;
241
+ }
242
+ }
243
+
244
+ class ArcIdentity extends ArcAbstractAPI {
245
+ constructor(options) {
246
+ super({ ...options, apiPath: 'identity/api/v1' });
247
+ }
248
+ async migrateBatch(payload) {
249
+ const { data } = await this.client.post('/migrate', payload);
250
+ return data;
251
+ }
252
+ async *migrateBatchGenerator(payload, batchSize = 100) {
253
+ const copy = [...payload.records];
254
+ while (copy.length) {
255
+ const records = copy.splice(0, batchSize);
256
+ const response = await this.migrateBatch({ records });
257
+ yield response;
258
+ }
259
+ }
260
+ async getUser(id) {
261
+ const { data } = await this.client.get(`/user?search=uuid=${id}`);
262
+ return data;
263
+ }
264
+ async getUserByEmail(email) {
265
+ const { data } = await this.client.get(`/user?search=email=${email}`);
266
+ return data;
267
+ }
268
+ async updateUserProfile(id, payload) {
269
+ const { data } = await this.client.patch(`/profile/${id}`, payload);
270
+ return data;
271
+ }
272
+ }
273
+
274
+ const importNodeModule = async (moduleId) => await import(moduleId);
275
+ const modules = {
276
+ // make it like that so static analyzer of webpack won't bundle it
277
+ fs: () => importNodeModule('node:fs'),
278
+ path: () => importNodeModule('node:path'),
279
+ form_data: () => importNodeModule('form-data'),
280
+ };
281
+
282
+ var platform = {
283
+ ...modules,
284
+ };
285
+
286
+ class ArcIFX extends ArcAbstractAPI {
287
+ constructor(options) {
288
+ super({ ...options, apiPath: 'ifx/api/v1' });
289
+ }
290
+ async createIntegration(payload) {
291
+ await this.client.post('/admin/integration', payload);
292
+ }
293
+ async updateIntegration(integrationName, payload) {
294
+ await this.client.put(`/admin/integration/${integrationName}`, payload);
295
+ }
296
+ async deleteIntegration(integrationName, token) {
297
+ await this.client.delete(`/admin/integration/${integrationName}`, { params: { token } });
298
+ }
299
+ async generateDeleteIntegrationToken(integrationName) {
300
+ const response = await this.client.get(`/admin/integration/${integrationName}/token`);
301
+ return response.data;
302
+ }
303
+ async getIntegrations() {
304
+ const { data } = await this.client.get('/admin/integrations');
305
+ return data;
306
+ }
307
+ async getJobs(integrationName) {
308
+ const { data } = await this.client.get(`/admin/jobs/status/${integrationName}`);
309
+ return data;
310
+ }
311
+ async getStatus(integrationName) {
312
+ const { data } = await this.client.get(`/admin/integration/${integrationName}/provisionStatus`);
313
+ return data;
314
+ }
315
+ async initializeQuery(integrationName, query) {
316
+ const { data } = await this.client.get(`/admin/logs/integration/${integrationName}?${query}`);
317
+ return data;
318
+ }
319
+ async getLogs(queryId, raw = true) {
320
+ const { data } = await this.client.get('/admin/logs/results', { params: { queryId, raw } });
321
+ return data;
322
+ }
323
+ async subscribe(payload) {
324
+ const { data } = await this.client.post('/admin/events/subscriptions', payload);
325
+ return data;
326
+ }
327
+ async updateSubscription(payload) {
328
+ const { data } = await this.client.put('/admin/events/subscriptions', payload);
329
+ return data;
330
+ }
331
+ async getSubscriptions() {
332
+ const { data } = await this.client.get('/admin/events/subscriptions');
333
+ return data;
334
+ }
335
+ async addSecret(payload) {
336
+ const { data } = await this.client.post(`/admin/secret?integrationName=${payload.integrationName}`, {
337
+ secretName: payload.secretName,
338
+ secretValue: payload.secretValue,
339
+ });
340
+ return data;
341
+ }
342
+ async getSecrets(integrationName) {
343
+ const { data } = await this.client.get(`/admin/secret?integrationName=${integrationName}`);
344
+ return data;
345
+ }
346
+ async getBundles(integrationName) {
347
+ const { data } = await this.client.get(`/admin/bundles/${integrationName}`);
348
+ return data;
349
+ }
350
+ async uploadBundle(integrationName, name, bundlePath) {
351
+ const fs = await platform.fs();
352
+ const FormData = await platform.form_data();
353
+ const form = new FormData();
354
+ console.log('platform', platform);
355
+ console.log(form);
356
+ const bundle = fs.createReadStream(bundlePath);
357
+ form.append('bundle', bundle);
358
+ form.append('name', name);
359
+ const { data } = await this.client.post(`/admin/bundles/${integrationName}`, form, {
360
+ headers: form.getHeaders(),
361
+ });
362
+ return data;
363
+ }
364
+ async deployBundle(integrationName, name) {
365
+ const { data } = await this.client.post(`/admin/bundles/${integrationName}/deploy/${name}`);
366
+ return data;
367
+ }
368
+ async promoteBundle(integrationName, version) {
369
+ const { data } = await this.client.post(`/admin/bundles/${integrationName}/promote/${version}`);
370
+ return data;
371
+ }
372
+ }
373
+
374
+ class ArcMigrationCenter extends ArcAbstractAPI {
375
+ constructor(options) {
376
+ super({ ...options, apiPath: 'migrations/v3' });
377
+ }
378
+ async summary(params) {
379
+ const { data, headers } = await this.client.get('/report/summary', { params });
380
+ const nextFromId = headers['amc-record-id'];
381
+ return { records: data, nextFromId };
382
+ }
383
+ async detailed(params) {
384
+ const { data } = await this.client.get('/report/detail', { params });
385
+ return data;
386
+ }
387
+ async count(params) {
388
+ const { data } = await this.client.get('/report/status/count', {
389
+ params: {
390
+ startDate: params?.startDate?.toISOString(),
391
+ endDate: params?.endDate?.toISOString(),
392
+ },
393
+ });
394
+ return data;
395
+ }
396
+ async postAns(params, payload) {
397
+ const { data } = await this.client.post('/content/ans', payload, { params });
398
+ return data;
399
+ }
400
+ async getAns(params) {
401
+ const { data } = await this.client.get('/content/ans', { params });
402
+ return data;
403
+ }
404
+ async getRemainingTime(params) {
405
+ const { data } = await this.client.get('/report/remaining-time', { params });
406
+ return data;
407
+ }
408
+ async getRecentGroupIds() {
409
+ const { data } = await this.client.get('/report/group-ids');
410
+ return data;
411
+ }
412
+ }
413
+
414
+ class ArcProtoCenter extends ArcAbstractAPI {
415
+ constructor(options) {
416
+ super({ ...options, apiPath: 'photo/api' });
417
+ }
418
+ async getImageDataById(imageId) {
419
+ const { data } = await this.client.get(`/v2/photos/${imageId}`);
420
+ return data;
421
+ }
422
+ async uploadImageANS(image) {
423
+ const FormData = await platform.form_data();
424
+ const form = new FormData();
425
+ form.append('ans', JSON.stringify(image), {
426
+ filename: 'ans.json',
427
+ contentType: 'application/json',
428
+ });
429
+ const { data } = await this.client.post('/v2/photos', form, { headers: form.getHeaders() });
430
+ return data;
431
+ }
432
+ async uploadImageStream(readableStream, options) {
433
+ const path = await platform.path();
434
+ const FormData = await platform.form_data();
435
+ const form = new FormData();
436
+ const contentType = options?.contentType ?? 'application/octet-stream';
437
+ const filename = path.basename(String(options?.filename || readableStream.path || 'file.jpg'));
438
+ form.append('file', readableStream, {
439
+ filename: filename,
440
+ contentType,
441
+ });
442
+ const { data } = await this.client.post('/v2/photos', form, { headers: form.getHeaders() });
443
+ return data;
444
+ }
445
+ async deleteImage(imageId) {
446
+ const { data } = await this.client.delete(`/v2/photos/${imageId}`);
447
+ return data;
448
+ }
449
+ async deleteGallery(galleryId) {
450
+ const { data } = await this.client.delete(`/v2/galleries/${galleryId}`);
451
+ return data;
452
+ }
453
+ async getImages(params) {
454
+ const { data } = await this.client.get('/v2/photos', { params });
455
+ return data;
456
+ }
457
+ async getGalleries(params) {
458
+ const { data } = await this.client.get('/v2/galleries', { params });
459
+ return data;
460
+ }
461
+ async getGallery(galleryId) {
462
+ const { data } = await this.client.get(`/v2/galleries/${galleryId}`);
463
+ return data;
464
+ }
465
+ async updateImage(imageId, photoDto) {
466
+ const { data } = await this.client.put(`/v2/photos/${imageId}`, photoDto);
467
+ return data;
468
+ }
469
+ }
470
+
471
+ class ArcRedirect extends ArcAbstractAPI {
472
+ constructor(options) {
473
+ super({ ...options, apiPath: 'delivery-api/v1/cloudlet/redirector/site' });
474
+ }
475
+ async getRedirects(orgSiteEnv) {
476
+ const { data } = await this.client.get(`/${orgSiteEnv}/rule?limit=1000`);
477
+ return data;
478
+ }
479
+ async updateArcRedirectRule(orgSiteEnv, redirectID, redirectRuleContent) {
480
+ const { data } = await this.client.put(`/${orgSiteEnv}/rule/${redirectID}`, redirectRuleContent);
481
+ return data;
482
+ }
483
+ async activateRedirectsVersion(orgSiteEnv) {
484
+ const { data } = await this.client.post(`/${orgSiteEnv}/version`);
485
+ return data;
486
+ }
487
+ }
488
+
489
+ class WsClient {
490
+ constructor(address, options) {
491
+ this.address = address;
492
+ this.options = options;
493
+ this._closing = false;
494
+ }
495
+ async connect() {
496
+ if (this.socket && this.socket.readyState === this.socket.OPEN)
497
+ return;
498
+ const socket = new ws.WebSocket(this.address, this.options);
499
+ this._closing = false;
500
+ socket.onclose = (event) => this.close(event);
501
+ await new Promise((resolve, reject) => {
502
+ socket.onerror = (error) => reject(error);
503
+ socket.onopen = () => resolve(true);
504
+ });
505
+ socket.onmessage = ({ data }) => {
506
+ let message;
507
+ try {
508
+ message = JSON.parse(data.toString());
509
+ }
510
+ catch {
511
+ throw new Error('failed to parse message');
512
+ }
513
+ this.onMessage?.(message);
514
+ };
515
+ this.socket = socket;
516
+ this.onOpen?.();
517
+ }
518
+ close(event) {
519
+ if (this._closing)
520
+ return;
521
+ this._closing = true;
522
+ this.socket?.close();
523
+ this.onClose?.(event);
524
+ }
525
+ async send(data) {
526
+ this.throwIfNotOpen();
527
+ await new Promise((resolve, reject) => {
528
+ this.socket.send(data, (error) => {
529
+ error ? reject(error) : resolve(undefined);
530
+ });
531
+ });
532
+ }
533
+ throwIfNotOpen() {
534
+ if (!this.socket) {
535
+ throw new Error('Client is not connected');
536
+ }
537
+ const { readyState, OPEN } = this.socket;
538
+ if (readyState === OPEN)
539
+ return;
540
+ if (readyState < OPEN) {
541
+ throw new Error('socket is still connecting');
542
+ }
543
+ if (readyState > OPEN) {
544
+ throw new Error('socket was closed');
545
+ }
546
+ }
547
+ }
548
+
549
+ class ArcRetailEvents {
550
+ constructor(options) {
551
+ this.options = options;
552
+ }
553
+ createWsClient(index = '0') {
554
+ const address = `wss://api.${this.options.credentials.organizationName}.arcpublishing.com/retail/api/v1/event/stream/${index}`;
555
+ const headers = {
556
+ Authorization: `Bearer ${this.options.credentials.accessToken}`,
557
+ };
558
+ return new WsClient(address, { headers });
559
+ }
560
+ }
561
+
562
+ class ArcSales extends ArcAbstractAPI {
563
+ constructor(options) {
564
+ super({ ...options, apiPath: 'sales/api/v1' });
565
+ }
566
+ async migrate(payload) {
567
+ const form = new FormData();
568
+ form.append('file', JSON.stringify(payload), { filename: 'subs.json', contentType: 'application/json' });
569
+ const { data } = await this.client.post('/migrate', form, {
570
+ headers: {
571
+ ...form.getHeaders(),
572
+ },
573
+ });
574
+ return data;
575
+ }
576
+ }
577
+
578
+ class ArcSigningService extends ArcAbstractAPI {
579
+ constructor(options) {
580
+ super({ ...options, apiPath: 'signing-service' });
581
+ }
582
+ async sign(service, serviceVersion, imageId) {
583
+ const { data } = await this.client.get(`/v2/sign/${service}/${serviceVersion}?value=${encodeURI(imageId)}`);
584
+ return data;
585
+ }
586
+ }
587
+
588
+ class ArcSite extends ArcAbstractAPI {
589
+ constructor(options) {
590
+ super({ ...options, apiPath: 'site/v3' });
591
+ }
592
+ async getSections(params) {
593
+ const { data } = await this.client.get(`/website/${params.website}/section`, {
594
+ params: { _website: params.website, ...params },
595
+ });
596
+ return data;
597
+ }
598
+ async getSection(id, website) {
599
+ const { data } = await this.client.get(`/website/${website}/section?_id=${id}`);
600
+ return data;
601
+ }
602
+ async deleteSection(id, website) {
603
+ await this.client.delete(`/website/${website}/section?_id=${id}`);
604
+ }
605
+ async putSection(section) {
606
+ const { data } = await this.client.put(`/website/${section.website}/section?_id=${section._id}`, section);
607
+ return data;
608
+ }
609
+ async getWebsites() {
610
+ const { data } = await this.client.get('/website');
611
+ return data;
612
+ }
613
+ async putLink(link) {
614
+ const { data } = await this.client.put(`/website/${link._website}/link/${link._id}`, link);
615
+ return data;
616
+ }
617
+ async deleteLink(id, website) {
618
+ const { data } = await this.client.delete(`/website/${website}/link/${id}`);
619
+ return data;
620
+ }
621
+ async getLinks(params) {
622
+ const { data } = await this.client.get(`/website/${params.website}/link`, { params });
623
+ return data;
624
+ }
625
+ }
626
+
627
+ class ArcTags extends ArcAbstractAPI {
628
+ constructor(options) {
629
+ super({ ...options, apiPath: 'tags' });
630
+ }
631
+ async getAllTags(params) {
632
+ const { data } = await this.client.get('/', { params });
633
+ return data;
634
+ }
635
+ /*
636
+ * @Deprecated
637
+ * May return incorrect results
638
+ * Use searchTagsV2 instead
639
+ */
640
+ async searchTags(params) {
641
+ const { data } = await this.client.get('/search', { params });
642
+ return data;
643
+ }
644
+ async searchTagsV2(params) {
645
+ const { data } = await this.client.get('/v2/search', { params });
646
+ return data;
647
+ }
648
+ async addTags(payload) {
649
+ const { data } = await this.client.post('/add', payload);
650
+ return data;
651
+ }
652
+ async deleteTags(payload) {
653
+ const { data } = await this.client.post('/delete', payload);
654
+ return data;
655
+ }
656
+ }
657
+
658
+ class ArcWebsked extends ArcAbstractAPI {
659
+ constructor(options) {
660
+ super({ ...options, apiPath: 'websked' });
661
+ }
662
+ async reportStatusChange(payload) {
663
+ const { data } = await this.client.post('/tasks/workflowStatusChange', payload);
664
+ return data;
665
+ }
666
+ async createTask(payload) {
667
+ const { data } = await this.client.post('/tasks', payload);
668
+ return data;
669
+ }
670
+ async getEditionTimes(publicationId, startDate, endDate, numEditions = 1) {
671
+ const { data } = await this.client.get(`/publications/${publicationId}/editionTimes`, {
672
+ params: { startDate, endDate, numEditions },
673
+ });
674
+ return data;
675
+ }
676
+ async getSectionStories(publicationId, sectionId, timestamp, includeStories = true) {
677
+ const { data } = await this.client.get(`/publications/${publicationId}/sections/${sectionId}/editions/${timestamp}`, { params: { includeStories } });
678
+ return data;
679
+ }
680
+ async getSectionEditions(publicationId, sectionId, startDate, numEditions = 100) {
681
+ const { data } = await this.client.get(`/publications/${publicationId}/sections/${sectionId}/editions`, {
682
+ params: { startDate, numEditions },
683
+ });
684
+ return data;
685
+ }
686
+ async getPublications(nameRegex) {
687
+ const { data } = await this.client.get('/publications', { params: { nameRegex } });
688
+ return data;
689
+ }
690
+ async getPublicationById(publicationId) {
691
+ const { data } = await this.client.get(`/publications/${publicationId}`);
692
+ return data;
693
+ }
694
+ async getStatuses() {
695
+ const { data } = await this.client.get('/statuses');
696
+ return data;
697
+ }
698
+ }
699
+
700
+ const ArcAPI = (options) => {
701
+ const API = {
702
+ Author: new ArcAuthor(options),
703
+ Draft: new ArcDraft(options),
704
+ Identity: new ArcIdentity(options),
705
+ IFX: new ArcIFX(options),
706
+ Redirect: new ArcRedirect(options),
707
+ MigrationCenter: new ArcMigrationCenter(options),
708
+ Sales: new ArcSales(options),
709
+ Site: new ArcSite(options),
710
+ Websked: new ArcWebsked(options),
711
+ Content: new ArcContent(options),
712
+ SigningService: new ArcSigningService(options),
713
+ PhotoCenter: new ArcProtoCenter(options),
714
+ GlobalSettings: new GlobalSettings(options),
715
+ Tags: new ArcTags(options),
716
+ ContentOps: new ArcContentOps(options),
717
+ RetailEvents: new ArcRetailEvents(options),
718
+ Custom: new Custom(options),
26
719
  };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
720
+ API.MigrationCenter.setMaxRPS(8);
721
+ API.Draft.setMaxRPS(4);
722
+ API.Content.setMaxRPS(3);
723
+ return API;
724
+ };
725
+
726
+ /* eslint-disable */
727
+ /**
728
+ * This file was automatically generated by json-schema-to-typescript.
729
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
730
+ * and run json-schema-to-typescript to regenerate this file.
731
+ */
732
+
733
+ var ansTypes = /*#__PURE__*/Object.freeze({
734
+ __proto__: null
735
+ });
736
+
737
+ var utils = /*#__PURE__*/Object.freeze({
738
+ __proto__: null
739
+ });
740
+
741
+ var ANSType;
742
+ (function (ANSType) {
743
+ ANSType["Story"] = "story";
744
+ ANSType["Video"] = "video";
745
+ ANSType["Tag"] = "tag";
746
+ ANSType["Author"] = "author";
747
+ ANSType["Gallery"] = "gallery";
748
+ ANSType["Image"] = "image";
749
+ ANSType["Redirect"] = "redirect";
750
+ })(ANSType || (ANSType = {}));
751
+ var MigrationStatus;
752
+ (function (MigrationStatus) {
753
+ MigrationStatus["Success"] = "Success";
754
+ MigrationStatus["Queued"] = "Queued";
755
+ MigrationStatus["Circulated"] = "Circulated";
756
+ MigrationStatus["Published"] = "Published";
757
+ MigrationStatus["Scheduled"] = "Scheduled";
758
+ MigrationStatus["FailVideo"] = "FailVideo";
759
+ MigrationStatus["FailImage"] = "FailImage";
760
+ MigrationStatus["FailPhoto"] = "FailPhoto";
761
+ MigrationStatus["FailStory"] = "FailStory";
762
+ MigrationStatus["FailGallery"] = "FailGallery";
763
+ MigrationStatus["FailAuthor"] = "FailAuthor";
764
+ MigrationStatus["FailTag"] = "FailTag";
765
+ MigrationStatus["ValidationFailed"] = "ValidationFailed";
766
+ })(MigrationStatus || (MigrationStatus = {}));
767
+ var SummarySortBy;
768
+ (function (SummarySortBy) {
769
+ SummarySortBy["CreateDate"] = "createDate";
770
+ SummarySortBy["UpdateDate"] = "updateDate";
771
+ SummarySortBy["Id"] = "id";
772
+ })(SummarySortBy || (SummarySortBy = {}));
773
+ var SummarySortOrder;
774
+ (function (SummarySortOrder) {
775
+ SummarySortOrder["ASC"] = "ASC";
776
+ SummarySortOrder["DESC"] = "DESC";
777
+ })(SummarySortOrder || (SummarySortOrder = {}));
778
+
779
+ var index$3 = /*#__PURE__*/Object.freeze({
780
+ __proto__: null,
781
+ ANS: ansTypes,
782
+ get ANSType () { return ANSType; },
783
+ get MigrationStatus () { return MigrationStatus; },
784
+ get SummarySortBy () { return SummarySortBy; },
785
+ get SummarySortOrder () { return SummarySortOrder; },
786
+ TypeUtils: utils
787
+ });
788
+
789
+ const reference = (ref) => {
790
+ return {
791
+ _id: ref.id,
792
+ type: 'reference',
793
+ referent: {
794
+ ...ref,
795
+ },
33
796
  };
34
- })();
35
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.ContentElements = exports.AnsMapper = exports.WsClient = exports.ArcError = exports.ArcUtils = exports.ArcAPI = exports.ArcTypes = void 0;
40
- exports.ArcTypes = __importStar(require("./types"));
41
- __exportStar(require("./api/identity/types"), exports);
42
- __exportStar(require("./api/draft/types"), exports);
43
- __exportStar(require("./api/site/types"), exports);
44
- __exportStar(require("./api/ifx/types"), exports);
45
- __exportStar(require("./api/redirect/types"), exports);
46
- __exportStar(require("./api/migration-center/types"), exports);
47
- __exportStar(require("./api/sales/types"), exports);
48
- __exportStar(require("./api/websked/types"), exports);
49
- __exportStar(require("./api/content/types"), exports);
50
- __exportStar(require("./api/photo-center/types"), exports);
51
- __exportStar(require("./api/global-settings/types"), exports);
52
- __exportStar(require("./api/tags/types"), exports);
53
- __exportStar(require("./api/content-ops/types"), exports);
54
- var api_1 = require("./api");
55
- Object.defineProperty(exports, "ArcAPI", { enumerable: true, get: function () { return api_1.ArcAPI; } });
56
- var arc_1 = require("./utils/arc");
57
- Object.defineProperty(exports, "ArcUtils", { enumerable: true, get: function () { return arc_1.ArcUtils; } });
58
- var error_1 = require("./api/error");
59
- Object.defineProperty(exports, "ArcError", { enumerable: true, get: function () { return error_1.ArcError; } });
60
- var ws_client_1 = require("./api/ws.client");
61
- Object.defineProperty(exports, "WsClient", { enumerable: true, get: function () { return ws_client_1.WsClient; } });
62
- exports.AnsMapper = __importStar(require("./mapper"));
63
- exports.ContentElements = __importStar(require("./content-elements"));
64
- //# sourceMappingURL=index.js.map
797
+ };
798
+
799
+ var ANS = /*#__PURE__*/Object.freeze({
800
+ __proto__: null,
801
+ reference: reference
802
+ });
803
+
804
+ const ContentElement = {
805
+ divider: () => {
806
+ return {
807
+ type: 'divider',
808
+ };
809
+ },
810
+ text: (content, alignment = 'left') => {
811
+ return {
812
+ type: 'text',
813
+ content,
814
+ alignment: alignment || undefined,
815
+ };
816
+ },
817
+ quote: (items, citation = '', subtype = 'pullquote') => {
818
+ return {
819
+ type: 'quote',
820
+ subtype,
821
+ citation: {
822
+ type: 'text',
823
+ content: citation,
824
+ },
825
+ content_elements: items,
826
+ };
827
+ },
828
+ interstitial_link: (url, content) => {
829
+ return {
830
+ type: 'interstitial_link',
831
+ url,
832
+ content,
833
+ };
834
+ },
835
+ header: (content, level) => {
836
+ return {
837
+ type: 'header',
838
+ content,
839
+ level,
840
+ };
841
+ },
842
+ raw_html: (content) => {
843
+ return {
844
+ type: 'raw_html',
845
+ content,
846
+ };
847
+ },
848
+ gallery: (id) => {
849
+ return {
850
+ type: 'reference',
851
+ referent: {
852
+ type: 'gallery',
853
+ id,
854
+ },
855
+ };
856
+ },
857
+ list: (type, items) => {
858
+ return {
859
+ type: 'list',
860
+ list_type: type,
861
+ items,
862
+ };
863
+ },
864
+ link_list: (title, links) => {
865
+ return {
866
+ type: 'link_list',
867
+ title,
868
+ items: links.map(({ content, url }) => {
869
+ return {
870
+ type: 'interstitial_link',
871
+ content,
872
+ url,
873
+ };
874
+ }),
875
+ };
876
+ },
877
+ image: (id, properties) => {
878
+ return {
879
+ referent: {
880
+ id,
881
+ type: 'image',
882
+ referent_properties: {
883
+ _id: id,
884
+ type: 'image',
885
+ ...properties,
886
+ },
887
+ },
888
+ type: 'reference',
889
+ };
890
+ },
891
+ jwPlayer: (id) => {
892
+ return {
893
+ embed: {
894
+ config: {},
895
+ id,
896
+ url: 'https://cdn.jwplayer.com/players',
897
+ },
898
+ subtype: 'jw_player',
899
+ type: 'custom_embed',
900
+ };
901
+ },
902
+ twitter: (id, provider = 'https://publish.twitter.com/oembed?url=') => {
903
+ return {
904
+ referent: {
905
+ id,
906
+ provider,
907
+ service: 'oembed',
908
+ type: 'twitter',
909
+ },
910
+ type: 'reference',
911
+ };
912
+ },
913
+ youtube: (id, provider = 'https://www.youtube.com/oembed?url=') => {
914
+ return {
915
+ referent: {
916
+ id,
917
+ provider,
918
+ service: 'oembed',
919
+ type: 'youtube',
920
+ },
921
+ type: 'reference',
922
+ };
923
+ },
924
+ facebook_video: (id, provider = 'https://www.facebook.com/plugins/post/oembed.json/?url=') => {
925
+ return {
926
+ referent: {
927
+ id,
928
+ provider,
929
+ service: 'oembed',
930
+ type: 'facebook-video',
931
+ },
932
+ type: 'reference',
933
+ };
934
+ },
935
+ facebook_post: (id, provider = 'https://www.facebook.com/plugins/post/oembed.json/?url=') => {
936
+ return {
937
+ referent: {
938
+ id,
939
+ provider,
940
+ service: 'oembed',
941
+ type: 'facebook-post',
942
+ },
943
+ type: 'reference',
944
+ };
945
+ },
946
+ soundcloud: (id, provider = 'https://soundcloud.com/oembed.json/?url=') => {
947
+ return {
948
+ referent: {
949
+ id,
950
+ provider,
951
+ service: 'oembed',
952
+ type: 'soundcloud',
953
+ },
954
+ type: 'reference',
955
+ };
956
+ },
957
+ vimeo: (id, provider = 'https://vimeo.com/api/oembed.json?url=') => {
958
+ return {
959
+ referent: {
960
+ id,
961
+ provider,
962
+ service: 'oembed',
963
+ type: 'vimeo',
964
+ },
965
+ type: 'reference',
966
+ };
967
+ },
968
+ instagram: (id, provider = 'https://api.instagram.com/oembed?url=') => {
969
+ return {
970
+ referent: {
971
+ id,
972
+ provider,
973
+ service: 'oembed',
974
+ type: 'instagram',
975
+ },
976
+ type: 'reference',
977
+ };
978
+ },
979
+ dailymotion: (id, provider = 'https://www.dailymotion.com/services/oembed?url=') => {
980
+ return {
981
+ referent: {
982
+ id,
983
+ provider,
984
+ service: 'oembed',
985
+ type: 'dailymotion',
986
+ },
987
+ type: 'reference',
988
+ };
989
+ },
990
+ tiktok: (id, provider = 'https://www.tiktok.com/oembed?url=') => {
991
+ return {
992
+ referent: {
993
+ id,
994
+ provider,
995
+ service: 'oembed',
996
+ type: 'tiktok',
997
+ },
998
+ type: 'reference',
999
+ };
1000
+ },
1001
+ issuu: (id, provider = 'https://issuu.com/oembed_wp?url=') => {
1002
+ return {
1003
+ referent: {
1004
+ id,
1005
+ provider,
1006
+ service: 'oembed',
1007
+ type: 'issuu',
1008
+ },
1009
+ type: 'reference',
1010
+ };
1011
+ },
1012
+ kickstarter: (id, provider = 'https://www.kickstarter.com/services/oembed?url=') => {
1013
+ return {
1014
+ referent: {
1015
+ id,
1016
+ provider,
1017
+ service: 'oembed',
1018
+ type: 'kickstarter',
1019
+ },
1020
+ type: 'reference',
1021
+ };
1022
+ },
1023
+ polldaddy: (id, provider = 'https://polldaddy.com/oembed/?url=') => {
1024
+ return {
1025
+ referent: {
1026
+ id,
1027
+ provider,
1028
+ service: 'oembed',
1029
+ type: 'polldaddy',
1030
+ },
1031
+ type: 'reference',
1032
+ };
1033
+ },
1034
+ };
1035
+
1036
+ const socialRegExps = {
1037
+ instagram: /(?:https?:\/\/)?(?:www.)?instagram.com\/?([a-zA-Z0-9\.\_\-]+)?\/([p]+)?([reel]+)?([tv]+)?([stories]+)?\/([a-zA-Z0-9\-\_\.]+)\/?([0-9]+)?/,
1038
+ twitter: /https:\/\/(?:www\.)?twitter\.com\/[^\/]+\/status(?:es)?\/(\d+)/,
1039
+ tiktok: /https:\/\/(?:m|www|vm)?\.?tiktok\.com\/((?:.*\b(?:(?:usr|v|embed|user|video)\/|\?shareId=|\&item_id=)(\d+))|\w+)/,
1040
+ facebookPost: /https:\/\/www\.facebook\.com\/(photo(\.php|s)|permalink\.php|media|questions|notes|[^\/]+\/(activity|posts))[\/?].*$/,
1041
+ facebookVideo: /https:\/\/www\.facebook\.com\/([^\/?].+\/)?video(s|\.php)[\/?].*/,
1042
+ };
1043
+ function match(url, regex) {
1044
+ return url.match(regex)?.[0];
1045
+ }
1046
+ function youtubeURLParser(url = '') {
1047
+ const regExp = /(?:youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]vi?=)|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
1048
+ const id = url?.match(regExp)?.[1];
1049
+ if (id) {
1050
+ return `https://youtu.be/${id}`;
1051
+ }
1052
+ const paylistMatch = url?.match(/[?&]list=([^#&?]+)/);
1053
+ if (paylistMatch?.[1]) {
1054
+ return `https://www.youtube.com/embed/videoseries?list=${paylistMatch?.[1]}`;
1055
+ }
1056
+ return undefined;
1057
+ }
1058
+ function twitterURLParser(url) {
1059
+ return match(url, socialRegExps.twitter);
1060
+ }
1061
+ function instagramURLParser(url) {
1062
+ return match(url, socialRegExps.instagram);
1063
+ }
1064
+ function tiktokURLParser(url) {
1065
+ return match(url, socialRegExps.tiktok);
1066
+ }
1067
+ function facebookVideoURLParser(url) {
1068
+ return match(url, socialRegExps.facebookVideo);
1069
+ }
1070
+ function facebookPostURLParser(url) {
1071
+ return match(url, socialRegExps.facebookPost);
1072
+ }
1073
+ function createSocial(url = '') {
1074
+ const embeds = [];
1075
+ const instagram = instagramURLParser(url);
1076
+ if (instagram) {
1077
+ embeds.push(ContentElement.instagram(instagram));
1078
+ }
1079
+ const twitter = twitterURLParser(url);
1080
+ if (twitter) {
1081
+ embeds.push(ContentElement.twitter(twitter));
1082
+ }
1083
+ const tiktok = tiktokURLParser(url);
1084
+ if (tiktok) {
1085
+ embeds.push(ContentElement.tiktok(tiktok));
1086
+ }
1087
+ const youtube = youtubeURLParser(url);
1088
+ if (youtube) {
1089
+ embeds.push(ContentElement.youtube(youtube));
1090
+ }
1091
+ const facebookPost = facebookPostURLParser(url);
1092
+ if (facebookPost) {
1093
+ embeds.push(ContentElement.facebook_post(facebookPost));
1094
+ }
1095
+ const facebookVideo = facebookVideoURLParser(url);
1096
+ if (facebookVideo) {
1097
+ embeds.push(ContentElement.facebook_video(facebookVideo));
1098
+ }
1099
+ return embeds;
1100
+ }
1101
+ const randomId = () => `${new Date().toISOString()}-${Math.random()}`;
1102
+
1103
+ var ContentElements = /*#__PURE__*/Object.freeze({
1104
+ __proto__: null,
1105
+ createSocial: createSocial,
1106
+ facebookPostURLParser: facebookPostURLParser,
1107
+ facebookVideoURLParser: facebookVideoURLParser,
1108
+ instagramURLParser: instagramURLParser,
1109
+ randomId: randomId,
1110
+ tiktokURLParser: tiktokURLParser,
1111
+ twitterURLParser: twitterURLParser,
1112
+ youtubeURLParser: youtubeURLParser
1113
+ });
1114
+
1115
+ const generateArcId = (identifier, orgHostname) => {
1116
+ const namespace = v5(orgHostname, v5.DNS);
1117
+ const buffer = v5(identifier, namespace, Buffer.alloc(16));
1118
+ return encode(buffer, 'RFC4648', { padding: false });
1119
+ };
1120
+ /**
1121
+ * Utility class for generating Arc IDs and source IDs
1122
+ *
1123
+ * @example
1124
+ * ```ts
1125
+ * const generator = new IdGenerator(['my-org']);
1126
+ * const arcId = generator.getArcId('123'); // Generates a unique for 'my-org' Arc ID
1127
+ * const sourceId = generator.getSourceId('123', ['my-site']); // Generates 'my-site-123'
1128
+ * ```
1129
+ */
1130
+ class IdGenerator {
1131
+ constructor(namespaces) {
1132
+ if (!namespaces.length) {
1133
+ throw new Error('At least 1 namespace is required');
1134
+ }
1135
+ this.namespace = namespaces.join('-');
1136
+ }
1137
+ getArcId(id) {
1138
+ return generateArcId(id.toString(), this.namespace);
1139
+ }
1140
+ getSourceId(id, prefixes = []) {
1141
+ return [...prefixes, id].join('-');
1142
+ }
1143
+ }
1144
+
1145
+ var Id = /*#__PURE__*/Object.freeze({
1146
+ __proto__: null,
1147
+ IdGenerator: IdGenerator,
1148
+ generateArcId: generateArcId
1149
+ });
1150
+
1151
+ const ArcUtils = {
1152
+ Id,
1153
+ ANS,
1154
+ ContentElements,
1155
+ };
1156
+
1157
+ /**
1158
+ * Base class for all arc entities, it provides common methods and properties
1159
+ * If you want to create a new entity subtype you should extend this class
1160
+ *
1161
+ * Use case: You want to migrate stories from BBC
1162
+ * You define `class BBCStory extends ArcDocument<ANS.AStory>` and implement all abstract methods
1163
+ * Then you can override the specific methods to enrich the story with the data from BBC
1164
+ *
1165
+ * To migrate it call .migrate() method
1166
+ */
1167
+ class Document {
1168
+ constructor() {
1169
+ this.ans = null;
1170
+ this.circulations = [];
1171
+ }
1172
+ async init() {
1173
+ // fetch necessary data and validate it here
1174
+ }
1175
+ async prepare() {
1176
+ await this.init();
1177
+ const payload = await this.payload();
1178
+ const params = await this.params();
1179
+ return { payload, params };
1180
+ }
1181
+ async payload() {
1182
+ this.ans = await this.getAns();
1183
+ this.circulations = await this.getCirculations();
1184
+ return {
1185
+ sourceId: await this.sourceId(),
1186
+ sourceType: await this.sourceType(),
1187
+ ANS: this.ans,
1188
+ circulations: this.circulations,
1189
+ arcAdditionalProperties: this.additionalProperties(),
1190
+ };
1191
+ }
1192
+ async params() {
1193
+ if (!this.websiteId()) {
1194
+ throw new Error('Website is not initialized! get params() should be called after payload()!');
1195
+ }
1196
+ return {
1197
+ website: await this.websiteId(),
1198
+ groupId: await this.groupId(),
1199
+ priority: this.priority(),
1200
+ };
1201
+ }
1202
+ additionalProperties() {
1203
+ return {
1204
+ story: {
1205
+ publish: false,
1206
+ },
1207
+ };
1208
+ }
1209
+ priority() {
1210
+ return 'historical';
1211
+ }
1212
+ getDistributor() {
1213
+ return;
1214
+ }
1215
+ getLanguage() {
1216
+ return 'en-GB';
1217
+ }
1218
+ getComments() {
1219
+ return;
1220
+ }
1221
+ async getSource() {
1222
+ return {
1223
+ name: 'code-store',
1224
+ system: 'code-store',
1225
+ source_id: await this.sourceId(),
1226
+ };
1227
+ }
1228
+ getSubheadlines() {
1229
+ return {
1230
+ basic: '',
1231
+ };
1232
+ }
1233
+ getDescription() {
1234
+ return this.getSubheadlines();
1235
+ }
1236
+ formatDate(date) {
1237
+ if (!date)
1238
+ return;
1239
+ return date.toISOString();
1240
+ }
1241
+ getDisplayDate() {
1242
+ return new Date();
1243
+ }
1244
+ async getContentElements() {
1245
+ return [];
1246
+ }
1247
+ getPublicationDate() {
1248
+ return new Date();
1249
+ }
1250
+ getHeadlines() {
1251
+ return {
1252
+ basic: '',
1253
+ };
1254
+ }
1255
+ getTags() {
1256
+ return;
1257
+ }
1258
+ getSubtype() {
1259
+ return;
1260
+ }
1261
+ getLabel() {
1262
+ return;
1263
+ }
1264
+ getRelatedContent() {
1265
+ return;
1266
+ }
1267
+ async getPromoItems() {
1268
+ return;
1269
+ }
1270
+ getWebskedStatusCode() {
1271
+ return;
1272
+ }
1273
+ getCreditsBy() {
1274
+ return [];
1275
+ }
1276
+ getCirculations() {
1277
+ return [];
1278
+ }
1279
+ getEditorNote() {
1280
+ return;
1281
+ }
1282
+ getContentRestrictions() {
1283
+ return;
1284
+ }
1285
+ getOwnerInformation() {
1286
+ return;
1287
+ }
1288
+ getSyndication() {
1289
+ return;
1290
+ }
1291
+ getSchedulingInformation() {
1292
+ return;
1293
+ }
1294
+ getTaxonomy() {
1295
+ return;
1296
+ }
1297
+ }
1298
+
1299
+ /**
1300
+ * Base class for all arc stories, it provides common methods and properties
1301
+ * If you want to create a new story subtype you should extend this class
1302
+ *
1303
+ * Use case: You want to migrate stories from BBC
1304
+ * You define `class BBCStory extends ArcStory` and implement all abstract methods
1305
+ * Then you need to override the specific methods to enrich the story with the data from BBC
1306
+ *
1307
+ * For example:
1308
+ * To add tag to BBC stories you need to override
1309
+ * protected getTags(): MaybePromise<ArcTypes.Story.Tag[]> {
1310
+ * return [{
1311
+ * slug: 'bbc',
1312
+ * text: 'bbc',
1313
+ * }];
1314
+ * }
1315
+ */
1316
+ class Story extends Document {
1317
+ type() {
1318
+ return 'story';
1319
+ }
1320
+ async getAns() {
1321
+ const id = await this.arcId();
1322
+ const version = this.version();
1323
+ const type = this.type();
1324
+ const publicationDate = await this.getPublicationDate();
1325
+ const displayDate = await this.getDisplayDate();
1326
+ const headlines = this.getHeadlines();
1327
+ const subheadlines = this.getSubheadlines();
1328
+ const description = this.getDescription();
1329
+ const language = this.getLanguage();
1330
+ const tags = await this.getTags();
1331
+ const subtype = await this.getSubtype();
1332
+ const label = await this.getLabel();
1333
+ const by = await this.getCreditsBy();
1334
+ const relatedContent = await this.getRelatedContent();
1335
+ const editorNote = await this.getEditorNote();
1336
+ const distributor = await this.getDistributor();
1337
+ const promoItems = await this.getPromoItems();
1338
+ const contentElements = await this.getContentElements();
1339
+ const webskedStatusCode = await this.getWebskedStatusCode();
1340
+ const websiteId = await this.websiteId();
1341
+ const source = await this.getSource();
1342
+ const comments = await this.getComments();
1343
+ const legacyUrl = await this.legacyUrl();
1344
+ const owner = await this.getOwnerInformation();
1345
+ const syndication = await this.getSyndication();
1346
+ const contentRestrictions = await this.getContentRestrictions();
1347
+ const planning = await this.getSchedulingInformation();
1348
+ const taxonomy = await this.getTaxonomy();
1349
+ const additionalMetaProperties = await this.getMigrationMetaProperties();
1350
+ return {
1351
+ type,
1352
+ _id: id,
1353
+ version,
1354
+ website: websiteId,
1355
+ canonical_website: websiteId,
1356
+ language,
1357
+ subtype,
1358
+ label,
1359
+ editor_note: editorNote,
1360
+ credits: {
1361
+ by,
1362
+ },
1363
+ headlines,
1364
+ subheadlines,
1365
+ description,
1366
+ distributor,
1367
+ planning,
1368
+ promo_items: promoItems,
1369
+ related_content: relatedContent,
1370
+ content_restrictions: contentRestrictions,
1371
+ created_date: this.formatDate(new Date()),
1372
+ first_publish_date: this.formatDate(publicationDate),
1373
+ publish_date: this.formatDate(publicationDate),
1374
+ display_date: this.formatDate(displayDate),
1375
+ source,
1376
+ comments,
1377
+ owner,
1378
+ syndication,
1379
+ taxonomy: {
1380
+ ...taxonomy,
1381
+ tags,
1382
+ },
1383
+ workflow: {
1384
+ status_code: webskedStatusCode,
1385
+ },
1386
+ content_elements: contentElements,
1387
+ additional_properties: {
1388
+ url: legacyUrl,
1389
+ ...additionalMetaProperties,
1390
+ },
1391
+ };
1392
+ }
1393
+ async getMigrationMetaProperties() {
1394
+ return {
1395
+ // used in dashboard for migration
1396
+ migration_source_id: await this.sourceId(),
1397
+ migration_source_type: await this.sourceType(),
1398
+ // used in dashboard to show the original url
1399
+ migration_url: await this.legacyUrl(),
1400
+ migration_group_id: await this.groupId(),
1401
+ };
1402
+ }
1403
+ }
1404
+
1405
+ var index$2 = /*#__PURE__*/Object.freeze({
1406
+ __proto__: null,
1407
+ Document: Document,
1408
+ Story: Story
1409
+ });
1410
+
1411
+ const BLOCK_ELEMENT_TAGS = [
1412
+ 'ADDRESS',
1413
+ 'ARTICLE',
1414
+ 'ASIDE',
1415
+ 'BLOCKQUOTE',
1416
+ 'DETAILS',
1417
+ 'DIV',
1418
+ 'DL',
1419
+ 'FIELDSET',
1420
+ 'FIGCAPTION',
1421
+ 'FIGURE',
1422
+ 'FOOTER',
1423
+ 'FORM',
1424
+ 'H1',
1425
+ 'H2',
1426
+ 'H3',
1427
+ 'H4',
1428
+ 'H5',
1429
+ 'H6',
1430
+ 'HEADER',
1431
+ 'HR',
1432
+ 'LINE',
1433
+ 'MAIN',
1434
+ 'MENU',
1435
+ 'NAV',
1436
+ 'OL',
1437
+ 'P',
1438
+ 'PARAGRAPH',
1439
+ 'PRE',
1440
+ 'SECTION',
1441
+ 'TABLE',
1442
+ 'UL',
1443
+ 'LI',
1444
+ 'BODY',
1445
+ 'HTML',
1446
+ ];
1447
+
1448
+ var html_constants = /*#__PURE__*/Object.freeze({
1449
+ __proto__: null,
1450
+ BLOCK_ELEMENT_TAGS: BLOCK_ELEMENT_TAGS
1451
+ });
1452
+
1453
+ const isTextNode = (node) => {
1454
+ return node instanceof TextNode;
1455
+ };
1456
+ const isHTMLElement = (node) => {
1457
+ return node instanceof HTMLElement;
1458
+ };
1459
+ const isCommentNode = (node) => {
1460
+ return node instanceof CommentNode;
1461
+ };
1462
+ const nodeTagIs = (node, name) => {
1463
+ return isHTMLElement(node) && node.tagName?.toLowerCase() === name.toLowerCase();
1464
+ };
1465
+ const nodeTagIn = (node, names) => {
1466
+ return isHTMLElement(node) && names.includes(node.tagName?.toLowerCase());
1467
+ };
1468
+ const isTextCE = (ce) => {
1469
+ return ce?.type === 'text';
1470
+ };
1471
+ const decodeHTMLEntities = (str) => decode(str);
1472
+ const htmlToText = (html, parseOptions) => {
1473
+ if (!html)
1474
+ return '';
1475
+ const doc = parse(html, parseOptions);
1476
+ return decodeHTMLEntities(doc.innerText);
1477
+ };
1478
+ const getHTMLElementAttribute = (e, key) => {
1479
+ const value = e.getAttribute(key);
1480
+ if (value)
1481
+ return value;
1482
+ return new URLSearchParams(e.rawAttrs.replaceAll(' ', '&')).get(key);
1483
+ };
1484
+
1485
+ var html_utils = /*#__PURE__*/Object.freeze({
1486
+ __proto__: null,
1487
+ decodeHTMLEntities: decodeHTMLEntities,
1488
+ getHTMLElementAttribute: getHTMLElementAttribute,
1489
+ htmlToText: htmlToText,
1490
+ isCommentNode: isCommentNode,
1491
+ isHTMLElement: isHTMLElement,
1492
+ isTextCE: isTextCE,
1493
+ isTextNode: isTextNode,
1494
+ nodeTagIn: nodeTagIn,
1495
+ nodeTagIs: nodeTagIs
1496
+ });
1497
+
1498
+ /**
1499
+ * HTMLProcessor is responsible for parsing HTML content into structured content elements.
1500
+ * It provides a flexible way to handle different HTML nodes and wrap text content.
1501
+ *
1502
+ * The processor can be extended with custom handlers for specific node types and
1503
+ * wrappers for text content.
1504
+ *
1505
+ * @example
1506
+ * ```ts
1507
+ * // Create and initialize processor
1508
+ * const processor = new HTMLProcessor();
1509
+ * processor.init();
1510
+ *
1511
+ * // Parse HTML content
1512
+ * const html = '<div><p>Some text</p><img src="image.jpg"></div>';
1513
+ * const elements = await processor.parse(html);
1514
+ * ```
1515
+ *
1516
+ * The processor comes with built-in handlers for common HTML elements like links,
1517
+ * text formatting (i, u, strong), and block elements. Custom handlers can be added
1518
+ * using the `handle()` and `wrap()` methods.
1519
+ */
1520
+ class HTMLProcessor {
1521
+ constructor() {
1522
+ this.parallelProcessing = true;
1523
+ this.handlers = {
1524
+ node: new Map(),
1525
+ wrap: new Map(),
1526
+ };
1527
+ }
1528
+ init() {
1529
+ // wrappers are used to wrap the content of nested text nodes
1530
+ // in a specific way
1531
+ this.wrap('link', (node, text) => {
1532
+ if (nodeTagIn(node, ['a'])) {
1533
+ const attributes = ['href', 'target', 'rel']
1534
+ .map((attr) => [attr, getHTMLElementAttribute(node, attr)])
1535
+ .filter(([_, value]) => value)
1536
+ .map(([key, value]) => `${key}="${value}"`)
1537
+ .join(' ');
1538
+ return {
1539
+ ...text,
1540
+ content: `<a ${attributes}>${text.content}</a>`,
1541
+ };
1542
+ }
1543
+ });
1544
+ this.wrap('i', (node, text) => {
1545
+ if (nodeTagIn(node, ['i'])) {
1546
+ return {
1547
+ ...text,
1548
+ content: `<i>${text.content}</i>`,
1549
+ };
1550
+ }
1551
+ });
1552
+ this.wrap('u', (node, text) => {
1553
+ if (nodeTagIn(node, ['u'])) {
1554
+ return {
1555
+ ...text,
1556
+ content: `<u>${text.content}</u>`,
1557
+ };
1558
+ }
1559
+ });
1560
+ this.wrap('sup/sub', (node, text) => {
1561
+ if (nodeTagIn(node, ['sup', 'sub'])) {
1562
+ return {
1563
+ ...text,
1564
+ content: `<mark class="${node.tagName.toLowerCase()}">${text.content}</mark>`,
1565
+ };
1566
+ }
1567
+ });
1568
+ this.wrap('strong', (node, text) => {
1569
+ if (nodeTagIn(node, ['strong', 'b'])) {
1570
+ return {
1571
+ ...text,
1572
+ content: `<b>${text.content}</b>`,
1573
+ };
1574
+ }
1575
+ });
1576
+ this.wrap('center', (node, text) => {
1577
+ if (nodeTagIn(node, ['center'])) {
1578
+ return {
1579
+ ...text,
1580
+ alignment: 'center',
1581
+ };
1582
+ }
1583
+ });
1584
+ this.wrap('aligned-paragraph', (node, text) => {
1585
+ if (nodeTagIn(node, ['p'])) {
1586
+ const styleAttribute = getHTMLElementAttribute(node, 'style') || '';
1587
+ if (!styleAttribute)
1588
+ return text;
1589
+ if (styleAttribute.includes('text-align: right;')) {
1590
+ return {
1591
+ ...text,
1592
+ alignment: 'right',
1593
+ };
1594
+ }
1595
+ if (styleAttribute.includes('text-align: left;')) {
1596
+ return {
1597
+ ...text,
1598
+ alignment: 'left',
1599
+ };
1600
+ }
1601
+ if (styleAttribute.includes('text-align: center;')) {
1602
+ return {
1603
+ ...text,
1604
+ alignment: 'center',
1605
+ };
1606
+ }
1607
+ return text;
1608
+ }
1609
+ });
1610
+ // handlers are used to handle specific nodes
1611
+ // and return a list of content elements
1612
+ this.handle('default', (node) => {
1613
+ const noTag = isHTMLElement(node) && !node.tagName;
1614
+ if (noTag ||
1615
+ nodeTagIn(node, [
1616
+ 'p',
1617
+ 'a',
1618
+ 'b',
1619
+ 'sup',
1620
+ 'sub',
1621
+ 'span',
1622
+ 'strong',
1623
+ 'em',
1624
+ 'i',
1625
+ 'u',
1626
+ 'section',
1627
+ 'main',
1628
+ 'div',
1629
+ 'li',
1630
+ 'center',
1631
+ ])) {
1632
+ return this.handleNested(node);
1633
+ }
1634
+ });
1635
+ this.handle('headers', (node) => {
1636
+ if (nodeTagIn(node, ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'])) {
1637
+ return this.createHeader(node);
1638
+ }
1639
+ });
1640
+ this.handle('text', (node) => {
1641
+ if (isTextNode(node)) {
1642
+ return this.createText(node);
1643
+ }
1644
+ });
1645
+ this.handle('comment', (node) => {
1646
+ if (isCommentNode(node)) {
1647
+ return this.handleComment(node);
1648
+ }
1649
+ });
1650
+ this.handle('list', async (node) => {
1651
+ if (nodeTagIn(node, ['ul', 'ol'])) {
1652
+ const listType = node.tagName === 'UL' ? 'unordered' : 'ordered';
1653
+ return this.createList(node, listType);
1654
+ }
1655
+ });
1656
+ this.handle('table', (node) => {
1657
+ if (nodeTagIs(node, 'table')) {
1658
+ return this.handleTable(node);
1659
+ }
1660
+ });
1661
+ this.handle('iframe', (node) => {
1662
+ if (nodeTagIs(node, 'iframe')) {
1663
+ return this.handleIframe(node);
1664
+ }
1665
+ });
1666
+ this.handle('img', (node) => {
1667
+ if (nodeTagIs(node, 'img')) {
1668
+ return this.handleImage(node);
1669
+ }
1670
+ });
1671
+ this.handle('br', (node) => {
1672
+ if (nodeTagIs(node, 'br')) {
1673
+ return this.handleBreak(node);
1674
+ }
1675
+ });
1676
+ }
1677
+ handle(name, handler) {
1678
+ if (this.handlers.node.has(name)) {
1679
+ this.warn({ name }, `${name} node handler already set`);
1680
+ }
1681
+ this.handlers.node.set(name, handler);
1682
+ }
1683
+ wrap(name, handler) {
1684
+ if (this.handlers.wrap.has(name)) {
1685
+ this.warn({ name }, `${name} wrap handler already set`);
1686
+ }
1687
+ this.handlers.wrap.set(name, handler);
1688
+ }
1689
+ async parse(html) {
1690
+ const doc = parse(html, { comment: true });
1691
+ doc.removeWhitespace();
1692
+ const elements = await this.process(doc);
1693
+ const filtered = elements?.filter((e) => e.type !== 'divider');
1694
+ return filtered || [];
1695
+ }
1696
+ addTextAdditionalProperties(c, parent) {
1697
+ const additionalProperties = c.additional_properties || {};
1698
+ const parentNodeIsBlockElement = this.isBlockElement(parent);
1699
+ c.additional_properties = {
1700
+ ...c.additional_properties,
1701
+ isBlockElement: additionalProperties.isBlockElement || parentNodeIsBlockElement,
1702
+ };
1703
+ return c;
1704
+ }
1705
+ /**
1706
+ * Wraps text content elements with additional properties and handlers.
1707
+ * This method iterates through an array of content elements and applies
1708
+ * wrappers to text elements.
1709
+ *
1710
+ * @param node - The HTML node containing the text elements
1711
+ **/
1712
+ wrapChildrenTextNodes(node, elements) {
1713
+ const wrapped = [];
1714
+ const wrappers = [...this.handlers.wrap.values()];
1715
+ for (const c of elements) {
1716
+ if (!isTextCE(c)) {
1717
+ wrapped.push(c);
1718
+ continue;
1719
+ }
1720
+ this.addTextAdditionalProperties(c, node);
1721
+ const handled = wrappers.map((wrapper) => wrapper(node, c)).find(Boolean);
1722
+ wrapped.push(handled || c);
1723
+ }
1724
+ return wrapped;
1725
+ }
1726
+ /**
1727
+ * Handles nested nodes by processing their children and merging text elements.
1728
+ * This method recursively processes the children of a given HTML node and
1729
+ * returns a list of content elements.
1730
+ *
1731
+ * @param node - The HTML node to process
1732
+ **/
1733
+ async handleNested(node) {
1734
+ const children = await this.processChildNodes(node);
1735
+ const filtered = children.filter(Boolean).flat();
1736
+ const merged = this.mergeParagraphs(filtered);
1737
+ const wrapped = this.wrapChildrenTextNodes(node, merged);
1738
+ return wrapped;
1739
+ }
1740
+ async processChildNodes(node) {
1741
+ if (this.parallelProcessing) {
1742
+ return await Promise.all(node.childNodes.map((child) => this.process(child)));
1743
+ }
1744
+ const children = [];
1745
+ for (const child of node.childNodes) {
1746
+ children.push(await this.process(child));
1747
+ }
1748
+ return children;
1749
+ }
1750
+ /**
1751
+ * Processes a single HTML node and converts it into content elements.
1752
+ * This method iterates through registered node handlers and attempts to process the node.
1753
+ * If a handler successfully processes the node, it returns an array of content elements.
1754
+ *
1755
+ * @param node - The HTML node to process
1756
+ * @returns Promise resolving to an array of content elements, or undefined if node cannot be processed
1757
+ */
1758
+ async process(node) {
1759
+ let isKnownNode = false;
1760
+ const elements = [];
1761
+ for (const [name, handler] of this.handlers.node.entries()) {
1762
+ try {
1763
+ const result = await handler(node);
1764
+ if (result) {
1765
+ // if handler returns an array of elements, it means that the node was handled properly, even if there is no elements inside
1766
+ isKnownNode = true;
1767
+ elements.push(...result);
1768
+ break;
1769
+ }
1770
+ }
1771
+ catch (error) {
1772
+ this.warn({ node: node.toString(), error: error.toString(), name }, 'HandlerError');
1773
+ }
1774
+ }
1775
+ if (isKnownNode)
1776
+ return elements;
1777
+ this.warn({ node: node.toString() }, 'UnknownNodeError');
1778
+ }
1779
+ /**
1780
+ * Merges adjacent text content elements into a single paragraph.
1781
+ * This method iterates through an array of content elements and combines
1782
+ * adjacent text elements into a single paragraph.
1783
+ *
1784
+ * @param items - The array of content elements to merge
1785
+ **/
1786
+ mergeParagraphs(items) {
1787
+ const merged = [];
1788
+ let toMerge = [];
1789
+ const merge = () => {
1790
+ if (!toMerge.length)
1791
+ return;
1792
+ const paragraph = toMerge.reduce((acc, p) => {
1793
+ return {
1794
+ ...p,
1795
+ content: acc.content + p.content,
1796
+ };
1797
+ }, { type: 'text', content: '' });
1798
+ merged.push(paragraph);
1799
+ toMerge = [];
1800
+ };
1801
+ for (let i = 0; i < items.length; i++) {
1802
+ const item = items[i];
1803
+ const isBlockElement = item.additional_properties?.isBlockElement;
1804
+ if (isTextCE(item) && !isBlockElement) {
1805
+ toMerge.push(item);
1806
+ }
1807
+ else {
1808
+ merge();
1809
+ merged.push(item);
1810
+ }
1811
+ }
1812
+ merge();
1813
+ return merged;
1814
+ }
1815
+ handleComment(_) {
1816
+ return [];
1817
+ }
1818
+ async handleTable(node) {
1819
+ return [ContentElement.raw_html(node.toString())];
1820
+ }
1821
+ async handleIframe(node) {
1822
+ return [ContentElement.raw_html(node.toString())];
1823
+ }
1824
+ async handleImage(node) {
1825
+ return [ContentElement.raw_html(node.toString())];
1826
+ }
1827
+ async handleBreak(_) {
1828
+ return [ContentElement.divider()];
1829
+ }
1830
+ async createQuote(node) {
1831
+ const items = await this.handleNested(node);
1832
+ return [ContentElement.quote(items)];
1833
+ }
1834
+ async createText(node) {
1835
+ const text = ContentElement.text(node.text);
1836
+ return [text];
1837
+ }
1838
+ filterListItems(items) {
1839
+ return items.filter((i) => ['text', 'list'].includes(i.type));
1840
+ }
1841
+ async createList(node, type) {
1842
+ const items = await this.handleNested(node);
1843
+ return [ContentElement.list(type, this.filterListItems(items))];
1844
+ }
1845
+ async createHeader(node) {
1846
+ const level = +node.tagName.split('H')[1] || 3;
1847
+ return [ContentElement.header(node.innerText, level)];
1848
+ }
1849
+ isBlockElement(node) {
1850
+ if (!isHTMLElement(node))
1851
+ return false;
1852
+ const defaultBlockElements = new Set(BLOCK_ELEMENT_TAGS);
1853
+ return defaultBlockElements.has(node.tagName);
1854
+ }
1855
+ warn(metadata, message) {
1856
+ console.warn(metadata, message);
1857
+ }
1858
+ }
1859
+
1860
+ var index$1 = /*#__PURE__*/Object.freeze({
1861
+ __proto__: null,
1862
+ Constants: html_constants,
1863
+ HTMLProcessor: HTMLProcessor,
1864
+ Utils: html_utils
1865
+ });
1866
+
1867
+ var index = /*#__PURE__*/Object.freeze({
1868
+ __proto__: null,
1869
+ ContentElement: ContentElement,
1870
+ HTML: index$1
1871
+ });
1872
+
1873
+ export { index$2 as AnsMapper, ArcAPI, ArcError, index$3 as ArcTypes, ArcUtils, index as ContentElements, WsClient, ArcAPI as default };
1874
+ //# sourceMappingURL=index.js.map