@quantcdn/quant-client 1.0.0 → 2.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.
@@ -1,696 +0,0 @@
1
- "use strict";
2
- /**
3
- * Quant API client.
4
- */
5
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
- return new (P || (P = Promise))(function (resolve, reject) {
8
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
12
- });
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.QuantClient = void 0;
16
- const request = require('request');
17
- const util = require('util');
18
- const fs = require('fs');
19
- const path = require('path');
20
- const mime = require('mime-types');
21
- const querystring = require('querystring');
22
- const quant_url_1 = require("./helper/quant-url");
23
- function QuantClient() {
24
- const req = util.promisify(request); // eslint-disable-line
25
- const get = util.promisify(request.get);
26
- const post = util.promisify(request.post);
27
- const patch = util.promisify(request.patch);
28
- const del = util.promisify(request.delete);
29
- let headers = {};
30
- let config;
31
- /**
32
- * Handle the response.
33
- *
34
- * @param {string} response
35
- * Response body from the Quant API.
36
- *
37
- * @return {object}
38
- * The API response.
39
- */
40
- const handleResponse = function (response) {
41
- const body = typeof response.body == 'string' ? JSON.parse(response.body) : response.body; // eslint-disable-line max-len
42
- if (typeof body.errors != 'undefined') {
43
- let msg = '';
44
- for (const i in body.errors) { // eslint-disable-line
45
- msg += body.errors[i].errorMsg + '\n';
46
- }
47
- throw new Error(msg);
48
- }
49
- if (response.statusCode == 400) {
50
- // @TODO: this is generally if the content is
51
- // streamed to the endpoint 4xx and 5xx are thrown
52
- // similarly, the API should respond with errors
53
- // otherwise.
54
- if (typeof body.errorMsg != 'undefined') {
55
- throw new Error(body.errorMsg);
56
- }
57
- throw new Error('Critical error...');
58
- }
59
- if (body.error || (typeof body.errorMsg != 'undefined' && body.errorMsg.length > 0)) { // eslint-disable-line max-len
60
- const msg = typeof body.errorMsg != 'undefined' ? body.errorMsg : body.msg;
61
- throw new Error(msg);
62
- }
63
- return body;
64
- };
65
- return {
66
- /**
67
- * Initialize the client
68
- */
69
- init: function () {
70
- this.config = {
71
- clientid: process.env.QUANT_CUSTOMER,
72
- project: process.env.QUANT_PROJECT,
73
- token: process.env.QUANT_TOKEN,
74
- endpoint: 'https://api.quantcdn.io/v1'
75
- };
76
- this.headers = {
77
- 'User-Agent': 'Quant (+http://api.quantcdn.io)',
78
- 'Quant-Token': this.config.token,
79
- 'Quant-Customer': this.config.clientid,
80
- 'Quant-Project': this.config.project,
81
- 'Content-Type': 'application/json',
82
- };
83
- },
84
- /**
85
- * Ping the quant API.
86
- *
87
- * @return {object}
88
- * The response object.
89
- *
90
- * @throws Error.
91
- */
92
- ping: function () {
93
- return __awaiter(this, void 0, void 0, function* () {
94
- try {
95
- this.init();
96
- const options = {
97
- url: `${this.config.endpoint}/ping`,
98
- json: true,
99
- headers,
100
- };
101
- const res = yield get(options);
102
- return handleResponse(res);
103
- }
104
- catch (err) {
105
- console.error(err);
106
- }
107
- });
108
- },
109
- /**
110
- * Access the global meta for the project.
111
- *
112
- * @param {bool} unfold
113
- * Unfold the record set.
114
- * @param {bool} exclude
115
- * Exclude delete objects from the meta result.
116
- * @param {object} extend
117
- * Additional query parameters to send.
118
- *
119
- * @return {object}
120
- * The global meta response object.
121
- *
122
- * @throws Error.
123
- *
124
- * @TODO
125
- * - Async iterator for memory 21k items ~ 40mb.
126
- */
127
- meta: function (unfold = false, exclude = true, extend = {}) {
128
- return __awaiter(this, void 0, void 0, function* () {
129
- try {
130
- this.init();
131
- const records = [];
132
- const query = Object.assign({
133
- page_size: 500,
134
- published: true,
135
- deleted: false,
136
- sort_field: 'last_modified',
137
- sort_direction: 'desc',
138
- }, extend);
139
- const url = `${this.config.endpoint}/global-meta?${querystring.stringify(query)}`;
140
- const doUnfold = function (i) {
141
- return __awaiter(this, void 0, void 0, function* () {
142
- const res = yield get({
143
- url: `${url}&page=${i}`,
144
- json: true,
145
- headers,
146
- });
147
- if (res.body.global_meta && res.body.global_meta.records) {
148
- res.body.global_meta.records.map((item) => records.push({ url: item.meta.url, md5: item.meta.md5 }));
149
- }
150
- });
151
- };
152
- let page = 1;
153
- const options = {
154
- url: `${url}&page=${page}`,
155
- json: true,
156
- headers,
157
- };
158
- // Seed the record set.
159
- const res = yield get(options);
160
- if (!res.body.global_meta) {
161
- // If no records have been published then global_meta is not
162
- // present in the response.
163
- return;
164
- }
165
- if (res.body.global_meta.records) {
166
- res.body.global_meta.records.map((item) => records.push({ url: item.meta.url, md5: item.meta.md5 }));
167
- }
168
- if (unfold) {
169
- page++;
170
- while (res.body.global_meta.total_pages >= page) {
171
- yield doUnfold(page);
172
- page++;
173
- }
174
- }
175
- return {
176
- total_pages: res.body.global_meta.total_pages,
177
- total_records: res.body.global_meta.total_records,
178
- records,
179
- };
180
- }
181
- catch (err) {
182
- console.error(err);
183
- }
184
- });
185
- },
186
- /**
187
- * Send a file to the server.
188
- *
189
- * @param {string} file
190
- * The path to the file.
191
- * @param {string} location
192
- * The path the location.
193
- * @param {bool} published
194
- * The status.
195
- * @param {bool} attachments
196
- * Should quant find attachments.
197
- * @param {bool} skipPurge
198
- * Skip CDN cache purge.
199
- * @param {bool} includeIndex
200
- * Include index.html suffix on HTML assets.
201
- * @param {object} extraHeaders
202
- * Additional HTTP headers.
203
- * @param {string} encoding
204
- * The encoding type.
205
- *
206
- * @return {object}
207
- * The API response.
208
- */
209
- send: function (file, location, published = true, attachments = false, skipPurge = false, includeIndex = false, extraHeaders = {}, encoding = 'utf-8') {
210
- return __awaiter(this, void 0, void 0, function* () {
211
- try {
212
- this.init();
213
- const mimeType = mime.lookup(file);
214
- if (mimeType == 'text/html') {
215
- if (!location) {
216
- const p = path.resolve(process.cwd(), this.config.dir);
217
- // If a location isn't given, calculate it.
218
- location = path.relative(p, file);
219
- }
220
- location = quant_url_1.QuantURL.prepare(location);
221
- if (!location.endsWith('.html') && includeIndex) {
222
- location = `${location}/index.html`;
223
- location = location.replace(/^\/\//, '/');
224
- }
225
- return yield this.markup(file, location, published, attachments, extraHeaders, encoding, skipPurge);
226
- }
227
- else {
228
- return yield this.file(file, location, false, extraHeaders, skipPurge);
229
- }
230
- }
231
- catch (err) {
232
- console.error(err);
233
- }
234
- });
235
- },
236
- /**
237
- * Upload markup.
238
- *
239
- * @param {string} file
240
- * Filepath on disk.
241
- * @param {string} location
242
- * The web accessible destination.
243
- * @param {bool} published
244
- * The status.
245
- * @param {bool} attachments
246
- * Quant looking for attachments.
247
- * @param {object} extraHeaders
248
- * Additional HTTP headers.
249
- * @param {string} encoding
250
- * The encoding type.
251
- * @param {bool} skipPurge
252
- * Skip CDN cache purge.
253
- *
254
- * @return {object}
255
- * The API response.
256
- */
257
- markup: function (file, location, published = true, attachments = false, extraHeaders = {}, encoding = 'utf-8', skipPurge = false) {
258
- return __awaiter(this, void 0, void 0, function* () {
259
- try {
260
- this.init();
261
- if (!Buffer.isBuffer(file)) {
262
- if (!location) {
263
- const p = path.resolve(process.cwd(), this.config.dir);
264
- // If a location isn't given, calculate it.
265
- location = path.relative(p, file);
266
- }
267
- file = fs.readFileSync(file, [encoding]);
268
- }
269
- const content = file.toString('utf8');
270
- location = location.startsWith('/') ? location : `/${location}`;
271
- if (skipPurge) {
272
- headers['Quant-Skip-Purge'] = 'true';
273
- }
274
- const options = {
275
- url: `${this.config.endpoint}`,
276
- json: true,
277
- body: {
278
- url: location,
279
- find_attachments: attachments,
280
- content,
281
- published,
282
- },
283
- headers: Object.assign({}, headers),
284
- };
285
- // if (Object.entries(extraHeaders).length > 0) {
286
- // options.body.headers = extraHeaders;
287
- // }
288
- const res = yield post(options);
289
- return handleResponse(res);
290
- }
291
- catch (err) {
292
- console.error(err);
293
- }
294
- });
295
- },
296
- /**
297
- * Send a file to the Quant API.
298
- *
299
- * @param {string} local
300
- * File path on disk.
301
- * @param {string} location
302
- * Accessible location.
303
- * @param {bool} absolute
304
- * If the location is an absolute path.
305
- * @param {object} extraHeaders
306
- * Additional HTTP headers.
307
- * @param {bool} skipPurge
308
- * Skip CDN cache purge.
309
- *
310
- * @return {object}
311
- * The successful payload.
312
- *
313
- * @throws Error
314
- */
315
- file: function (local, location, absolute = false, extraHeaders = {}, skipPurge = false) {
316
- return __awaiter(this, void 0, void 0, function* () {
317
- try {
318
- this.init();
319
- if (!Buffer.isBuffer(local)) {
320
- if (!location) {
321
- const p = path.resolve(process.cwd(), this.config.dir);
322
- // If a location isn't given, calculate it.
323
- location = path.relative(p, local);
324
- location.replace(path.basename(location), '');
325
- }
326
- if (!fs.existsSync(local)) {
327
- throw new Error('File is not accessible.');
328
- }
329
- local = fs.createReadStream(local);
330
- }
331
- const formData = {
332
- data: local,
333
- };
334
- location = location.startsWith('/') ? location : `/${location}`;
335
- if (skipPurge) {
336
- headers['Quant-Skip-Purge'] = 'true';
337
- }
338
- const options = {
339
- url: this.config.endpoint,
340
- json: true,
341
- headers: Object.assign(Object.assign({}, headers), { 'Content-Type': 'multipart/form-data', 'Quant-File-Url': location }),
342
- formData,
343
- };
344
- if (Object.entries(extraHeaders).length > 0) {
345
- options.headers['Quant-File-Headers'] = JSON.stringify(extraHeaders);
346
- }
347
- const res = yield post(options);
348
- return handleResponse(res);
349
- }
350
- catch (err) {
351
- console.error(err);
352
- }
353
- });
354
- },
355
- /**
356
- * Change the status of an asset.
357
- *
358
- * @param {string} location
359
- * The URL location of the content.
360
- * @param {string} revision
361
- * The revision to publish.
362
- *
363
- * @return {object}
364
- * API payload.
365
- *
366
- * @throws Error.
367
- */
368
- publish: function (location, revision) {
369
- return __awaiter(this, void 0, void 0, function* () {
370
- try {
371
- this.init();
372
- const url = quant_url_1.QuantURL.prepare(location);
373
- if (!revision) {
374
- throw Error('Invalid revision ID provided.');
375
- }
376
- const options = {
377
- url: `${this.config.endpoint}/publish/${revision}`,
378
- headers: Object.assign(Object.assign({}, headers), { 'Quant-Url': url }),
379
- json: true,
380
- };
381
- const res = yield patch(options);
382
- return handleResponse(res);
383
- }
384
- catch (err) {
385
- console.error(err);
386
- }
387
- });
388
- },
389
- /**
390
- * Unpublish a URL.
391
- *
392
- * @param {string} url
393
- * The URL to unpublish.
394
- *
395
- * @return {object}
396
- *
397
- * @throws Error.
398
- */
399
- unpublish: function (url) {
400
- return __awaiter(this, void 0, void 0, function* () {
401
- try {
402
- this.init();
403
- url = quant_url_1.QuantURL.prepare(url);
404
- const options = {
405
- url: `${this.config.endpoint}/unpublish`,
406
- headers: Object.assign(Object.assign({}, headers), { 'Quant-Url': url }),
407
- json: true,
408
- };
409
- const res = yield patch(options);
410
- return handleResponse(res);
411
- }
412
- catch (err) {
413
- console.error(err);
414
- }
415
- });
416
- },
417
- /**
418
- *
419
- * @param {string} from
420
- * The URL to redirect form.
421
- * @param {string} to
422
- * The URL to redirect to.
423
- * @param {string} author
424
- * (Optional) Author.
425
- * @param {int} status
426
- * HTTP status code.
427
- *
428
- * @return {object}
429
- * API payload.
430
- *
431
- * @throws Error.
432
- */
433
- redirect: function (from, to, author, status = 302) {
434
- return __awaiter(this, void 0, void 0, function* () {
435
- try {
436
- this.init();
437
- const options = {
438
- url: `${this.config.endpoint}/redirect`,
439
- headers: Object.assign({}, headers),
440
- json: true,
441
- body: {
442
- url: from,
443
- redirect_url: to,
444
- redirect_http_code: status,
445
- published: true,
446
- },
447
- };
448
- if (status < 300 || status > 400) {
449
- throw new Error('A valid redirect status code is required');
450
- }
451
- // if (author) {
452
- // options.body.info = {author_user: author};
453
- // }
454
- const res = yield post(options);
455
- return handleResponse(res);
456
- }
457
- catch (err) {
458
- console.error(err);
459
- }
460
- });
461
- },
462
- /**
463
- * Create a proxy with the Quant API.
464
- *
465
- * @param {string} url
466
- * The relative URL to proxy.
467
- * @param {string} destination
468
- * The absolute FQDN/path to proxy to.
469
- * @param {bool} published
470
- * If the proxy is published
471
- * @param {string} username
472
- * Basic auth user.
473
- * @param {string} password
474
- * Basic auth password.
475
- *
476
- * @return {object}
477
- * The response.
478
- *
479
- * @throws Error.
480
- */
481
- proxy: function (url, destination, published = true, username, password) {
482
- return __awaiter(this, void 0, void 0, function* () {
483
- try {
484
- this.init();
485
- const options = {
486
- url: `${this.config.endpoint}/proxy`,
487
- headers: Object.assign({}, headers),
488
- json: true,
489
- body: {
490
- url,
491
- destination,
492
- published,
493
- },
494
- };
495
- // if (username) {
496
- // options.body.basic_auth_user = username;
497
- // options.body.basic_auth_pass = password;
498
- // }
499
- const res = yield post(options);
500
- return handleResponse(res);
501
- }
502
- catch (err) {
503
- console.error(err);
504
- }
505
- });
506
- },
507
- /**
508
- * Delete a path from Quant.
509
- *
510
- * @param {string} path
511
- *
512
- * @return {object}
513
- * The response object.
514
- *
515
- * @throw Error.
516
- */
517
- delete: function (path) {
518
- return __awaiter(this, void 0, void 0, function* () {
519
- try {
520
- this.init();
521
- path = path.replace('index.html', '');
522
- const options = {
523
- url: `${this.config.endpoint}/delete/all`,
524
- headers: Object.assign(Object.assign({}, headers), { 'Quant-Url': path }),
525
- };
526
- const res = yield del(options);
527
- return handleResponse(res);
528
- }
529
- catch (err) {
530
- console.error(err);
531
- }
532
- });
533
- },
534
- /**
535
- * Get the revision history from Quant.
536
- *
537
- * @param {string} url
538
- * The URL path to get revisions for.
539
- * @param {string|bool} revision
540
- * Retrieve a specific revision.
541
- *
542
- * @return {object}
543
- * The response.
544
- *
545
- * @throws Error.
546
- */
547
- revisions: function (url, revision = false) {
548
- return __awaiter(this, void 0, void 0, function* () {
549
- try {
550
- this.init();
551
- const path = revision ? revision : 'published';
552
- url = url.indexOf('/') == 0 ? url : `/${url}`;
553
- url = url.toLowerCase();
554
- url = url.replace(/\/?index\.html/, '');
555
- const options = {
556
- url: `${this.config.endpoint}/revisions/${path}`,
557
- headers: Object.assign(Object.assign({}, headers), { 'Quant-Url': url }),
558
- json: true,
559
- };
560
- const res = yield get(options);
561
- return handleResponse(res);
562
- }
563
- catch (err) {
564
- console.error(err);
565
- }
566
- });
567
- },
568
- /**
569
- * Purge URL patterns from Quants Varnish.
570
- *
571
- * @param {string} urlPattern
572
- *
573
- * @throws Error
574
- */
575
- purge: function (urlPattern) {
576
- return __awaiter(this, void 0, void 0, function* () {
577
- try {
578
- this.init();
579
- const options = {
580
- url: `${this.config.endpoint}/purge`,
581
- headers: Object.assign(Object.assign({}, this.headers), { 'Quant-Url': urlPattern }),
582
- };
583
- const res = yield post(options);
584
- return handleResponse(res);
585
- }
586
- catch (err) {
587
- console.error(err);
588
- }
589
- });
590
- },
591
- /**
592
- * Add/update items in search index.
593
- *
594
- * @param {string} filePath
595
- *
596
- * @throws Error
597
- */
598
- searchIndex: function (filePath) {
599
- return __awaiter(this, void 0, void 0, function* () {
600
- try {
601
- this.init();
602
- let data = '';
603
- // filePath is a JSON file we send the raw content of.
604
- try {
605
- data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
606
- }
607
- catch (err) {
608
- console.error(err);
609
- return;
610
- }
611
- const options = {
612
- url: `${this.config.endpoint}/search`,
613
- headers: Object.assign({}, this.headers),
614
- json: true,
615
- body: data,
616
- };
617
- const res = yield post(options);
618
- return handleResponse(res);
619
- }
620
- catch (err) {
621
- console.error(err);
622
- }
623
- });
624
- },
625
- /**
626
- * Remove item from search index.
627
- *
628
- * @param {string} url
629
- *
630
- * @throws Error
631
- */
632
- searchRemove: function (url) {
633
- return __awaiter(this, void 0, void 0, function* () {
634
- try {
635
- this.init();
636
- const options = {
637
- url: `${this.config.endpoint}/search`,
638
- headers: Object.assign(Object.assign({}, this.headers), { 'Quant-Url': url }),
639
- json: true,
640
- };
641
- const res = yield del(options);
642
- return handleResponse(res);
643
- }
644
- catch (err) {
645
- console.error(err);
646
- }
647
- });
648
- },
649
- /**
650
- * Clear search index.
651
- *
652
- * @throws Error
653
- */
654
- searchClearIndex: function () {
655
- return __awaiter(this, void 0, void 0, function* () {
656
- try {
657
- this.init();
658
- const options = {
659
- url: `${this.config.endpoint}/search/all`,
660
- headers: Object.assign({}, this.headers),
661
- json: true,
662
- };
663
- const res = yield del(options);
664
- return handleResponse(res);
665
- }
666
- catch (err) {
667
- console.error(err);
668
- }
669
- });
670
- },
671
- /**
672
- * Retrieve search index status.
673
- *
674
- * @throws Error
675
- */
676
- searchStatus: function () {
677
- return __awaiter(this, void 0, void 0, function* () {
678
- try {
679
- this.init();
680
- const options = {
681
- url: `${this.config.endpoint}/search`,
682
- headers: Object.assign({}, this.headers),
683
- json: true,
684
- };
685
- const res = yield get(options);
686
- return handleResponse(res);
687
- }
688
- catch (err) {
689
- console.error(err);
690
- }
691
- });
692
- },
693
- };
694
- }
695
- exports.QuantClient = QuantClient;
696
- ;