UNPKG

7.56 kBPlain TextView Raw
1import * as fs from 'fs';
2import * as request from 'request';
3import * as retry from 'retry';
4
5import { MagnoliaSourceOptions } from './magnolia-source-options.interface';
6
7export function fetchSitemap(options: MagnoliaSourceOptions): Promise<string[]> {
8 const operation = retry.operation({ forever: true });
9
10 return new Promise((resolve, reject) => {
11 operation.attempt(() => {
12 request.get(
13 options.magnolia.url + options.magnolia.sitemapEndpoint,
14 {
15 json: true,
16 headers: {
17 Authorization: options.magnolia.auth.header,
18 'User-Agent': 'Paperboy'
19 }
20 },
21 (err, res, body: string[]) => {
22 if (operation.retry(err)) {
23 console.error('Attempt to get the sitemap failed, will retry in some time...');
24 console.error(err);
25 return;
26 }
27
28 if (res && res.statusCode === 200) {
29 resolve(body);
30 } else {
31 reject(res ? res.statusCode : '');
32 }
33 }
34 );
35 });
36 });
37}
38
39export function fetchWorkspace(workspace: string, options: MagnoliaSourceOptions): Promise<any> {
40 const operation = retry.operation();
41
42 return new Promise((resolve, reject) => {
43 operation.attempt(() => {
44 request.get(
45 options.magnolia.url + '/.rest/delivery/' + workspace + '/v1',
46 {
47 json: true,
48 headers: {
49 Authorization: options.magnolia.auth.header,
50 'User-Agent': 'Paperboy'
51 }
52 },
53 (err, res, body) => {
54 if (operation.retry(err)) {
55 console.error('Attempt to get pages failed, will retry in some time...');
56 return;
57 }
58
59 if (res && res.statusCode === 200) {
60 resolve(body.results);
61 } else {
62 reject(res ? res.statusCode : '');
63 }
64 }
65 );
66 });
67 });
68}
69
70export function fetchPages(options: MagnoliaSourceOptions): Promise<any> {
71 const operation = retry.operation();
72
73 return new Promise((resolve, reject) => {
74 operation.attempt(() => {
75 request.get(
76 options.magnolia.url + options.magnolia.pagesEndpoint,
77 {
78 json: true,
79 headers: {
80 Authorization: options.magnolia.auth.header,
81 'User-Agent': 'Paperboy'
82 }
83 },
84 (err, res, body) => {
85 if (operation.retry(err)) {
86 console.error('Attempt to get pages failed, will retry in some time...');
87 return;
88 }
89
90 if (res && res.statusCode === 200) {
91 resolve(body.results);
92 } else {
93 reject(res ? res.statusCode : '');
94 }
95 }
96 );
97 });
98 });
99}
100
101export function writePagesFile(pages: any[], options?: MagnoliaSourceOptions): Promise<void> {
102 return new Promise((resolve, reject) => {
103 if (!fs.existsSync(options.output.json)) {
104 fs.mkdirSync(options.output.json);
105 }
106
107 fs.writeFile(options.output.json + '/pages.json', JSON.stringify(pages), err => {
108 if (err) {
109 reject(err);
110 }
111
112 resolve();
113 });
114 });
115}
116
117export function writeWorkspaceFile(
118 workspace: string,
119 workspaceData: any,
120 options?: MagnoliaSourceOptions
121): Promise<void> {
122 return new Promise((resolve, reject) => {
123 if (!fs.existsSync(options.output.json)) {
124 fs.mkdirSync(options.output.json);
125 }
126
127 fs.writeFile(
128 options.output.json + '/' + workspace + '.json',
129 JSON.stringify(workspaceData),
130 err => {
131 if (err) {
132 reject(err);
133 }
134
135 resolve();
136 }
137 );
138 });
139}
140
141export function sanitizeJson(
142 json: any,
143 damAssets: any[],
144 pages: any,
145 sourceOptions: MagnoliaSourceOptions,
146 workspaces: { [workspace: string]: any } = {}
147): any {
148 const sanitized: any = {};
149
150 if (json) {
151 Object.keys(json).forEach(key => {
152 const isKeyExcluded =
153 sourceOptions &&
154 sourceOptions.output.excludedProperties &&
155 sourceOptions.output.excludedProperties.findIndex(prop => prop === key) > -1;
156
157 if (!isKeyExcluded && key === '@nodes') {
158 const contentOrder: string[] = json[key];
159
160 if (contentOrder.length > 0) {
161 sanitized[key.substr(1)] = contentOrder.map(contentKeyIndex =>
162 sanitizeJson(json[contentKeyIndex], damAssets, pages, sourceOptions, workspaces)
163 );
164 }
165 } else if (!isKeyExcluded && key !== 'content' && !key.match(/^\d+$/)) {
166 const originalKey = key;
167 const sanitizedKey = key
168 .replace(/^@/, '')
169 .replace(/^mgnl:/, '')
170 .replace(/^jcr:uuid/, 'id');
171
172 if (!sanitizedKey.match(/^jcr:/)) {
173 if (typeof json[key] === 'object' && !Array.isArray(json[key])) {
174 sanitized[sanitizedKey] = sanitizeJson(
175 json[key],
176 damAssets,
177 pages,
178 sourceOptions,
179 workspaces
180 );
181 } else {
182 let items = Array.isArray(json[key]) ? json[key] : [json[key]];
183
184 items = items.map((item: any) => {
185 if (
186 item.match(
187 /^jcr:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
188 )
189 ) {
190 const uuid = item.replace('jcr:', '');
191 return damAssets.find(damAsset => damAsset && damAsset.id === uuid);
192 } else if (
193 !originalKey.match(/^@/) &&
194 !originalKey.match(/^jcr:uuid/) &&
195 item.match(
196 /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
197 )
198 ) {
199 const node = getPopulatedNode(item, pages);
200 let value: any;
201
202 if (node) {
203 value = Object.assign(node || {}, {
204 workspace: 'website'
205 });
206 } else {
207 const asset = getPopulatedNode(item, damAssets);
208
209 if (asset) {
210 value = Object.assign(asset || {}, {
211 workspace: 'dam'
212 });
213 } else {
214 const workspaceNode = Object.keys(workspaces)
215 .map(key => workspaces[key])
216 .map(workspace =>
217 Object.assign({}, getPopulatedNode(item, workspace), { workspace: key })
218 )
219 .shift();
220
221 value = Object.assign(workspaceNode || {}, {
222 workspace: workspaceNode ? workspaceNode.workspace : null
223 });
224 }
225 }
226
227 return value;
228 } else {
229 return item;
230 }
231 });
232
233 sanitized[sanitizedKey] = Array.isArray(json[key]) ? items : items[0];
234 }
235 }
236 }
237 });
238 }
239
240 return sanitized;
241}
242
243export function getPopulatedNode(id: string, source: any, populatedNode?: any): any {
244 if (populatedNode || !source) {
245 return populatedNode;
246 } else {
247 if (source['jcr:uuid'] === id || source.id === id) {
248 populatedNode = {
249 id,
250 path: source['@path'] || source.path
251 };
252 } else {
253 Object.keys(source).forEach(key => {
254 if (source[key] && typeof source[key] === 'object') {
255 populatedNode = getPopulatedNode(id, source[key], populatedNode);
256 }
257 });
258 }
259
260 return populatedNode;
261 }
262}