@ffflorian/xkcdjs 3.4.4 → 3.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -9
- package/dist/Interfaces.d.ts +0 -26
- package/dist/Interfaces.js +0 -2
- package/dist/XKCD.d.ts +0 -13
- package/dist/XKCD.js +0 -20
- package/dist/XKCDAPI.d.ts +0 -35
- package/dist/XKCDAPI.js +0 -68
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -135
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -18
package/package.json
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
"author": "Florian Imdahl <git@ffflorian.de>",
|
|
3
3
|
"bin": "dist/cli.js",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@ffflorian/api-client": "2.
|
|
6
|
-
"commander": "14.0.
|
|
5
|
+
"@ffflorian/api-client": "2.5.0",
|
|
6
|
+
"commander": "14.0.3"
|
|
7
7
|
},
|
|
8
8
|
"description": "An xkcd API client with a CLI.",
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/node": "~24",
|
|
11
11
|
"http-status-codes": "2.3.0",
|
|
12
|
-
"nock": "14.0.
|
|
13
|
-
"rimraf": "6.1.
|
|
12
|
+
"nock": "14.0.11",
|
|
13
|
+
"rimraf": "6.1.3",
|
|
14
14
|
"tsx": "4.21.0",
|
|
15
|
-
"typedoc": "0.28.
|
|
16
|
-
"typescript": "
|
|
17
|
-
"vitest": "4.0
|
|
15
|
+
"typedoc": "0.28.18",
|
|
16
|
+
"typescript": "6.0.2",
|
|
17
|
+
"vitest": "4.1.0"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">= 21"
|
|
@@ -41,6 +41,5 @@
|
|
|
41
41
|
"start": "tsx src/cli.ts",
|
|
42
42
|
"test": "vitest"
|
|
43
43
|
},
|
|
44
|
-
"version": "3.4.
|
|
45
|
-
"gitHead": "12bebfb90528bb894bccb99670373af33c6a5159"
|
|
44
|
+
"version": "3.4.6"
|
|
46
45
|
}
|
package/dist/Interfaces.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export interface ImageData {
|
|
2
|
-
data: Buffer;
|
|
3
|
-
mimeType?: string;
|
|
4
|
-
}
|
|
5
|
-
export interface RequestOptions {
|
|
6
|
-
withData?: boolean;
|
|
7
|
-
}
|
|
8
|
-
export interface ClientOptions {
|
|
9
|
-
apiUrl?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface XKCDResult {
|
|
12
|
-
alt: string;
|
|
13
|
-
day: string;
|
|
14
|
-
img: string;
|
|
15
|
-
link: string;
|
|
16
|
-
month: string;
|
|
17
|
-
news: string;
|
|
18
|
-
num: number;
|
|
19
|
-
safe_title: string;
|
|
20
|
-
title: string;
|
|
21
|
-
transcript: string;
|
|
22
|
-
year: string;
|
|
23
|
-
}
|
|
24
|
-
export interface XKCDResultWithData extends XKCDResult {
|
|
25
|
-
data: ImageData;
|
|
26
|
-
}
|
package/dist/Interfaces.js
DELETED
package/dist/XKCD.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ClientOptions } from './Interfaces';
|
|
2
|
-
import { XKCDAPI } from './XKCDAPI';
|
|
3
|
-
export declare class XKCD {
|
|
4
|
-
readonly api: XKCDAPI;
|
|
5
|
-
private readonly apiClient;
|
|
6
|
-
private readonly options;
|
|
7
|
-
constructor(options?: ClientOptions);
|
|
8
|
-
/**
|
|
9
|
-
* Set a new API URL.
|
|
10
|
-
* @param url The new API URL.
|
|
11
|
-
*/
|
|
12
|
-
setApiUrl(newURL: string): void;
|
|
13
|
-
}
|
package/dist/XKCD.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.XKCD = void 0;
|
|
4
|
-
const api_client_1 = require("@ffflorian/api-client");
|
|
5
|
-
const XKCDAPI_1 = require("./XKCDAPI");
|
|
6
|
-
class XKCD {
|
|
7
|
-
constructor(options) {
|
|
8
|
-
this.options = Object.assign({ apiUrl: 'https://xkcd.com' }, options);
|
|
9
|
-
this.apiClient = new api_client_1.APIClient(this.options.apiUrl);
|
|
10
|
-
this.api = new XKCDAPI_1.XKCDAPI(this.apiClient, this.options);
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Set a new API URL.
|
|
14
|
-
* @param url The new API URL.
|
|
15
|
-
*/
|
|
16
|
-
setApiUrl(newURL) {
|
|
17
|
-
this.apiClient.setBaseURL(newURL);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
exports.XKCD = XKCD;
|
package/dist/XKCDAPI.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { APIClient } from '@ffflorian/api-client';
|
|
2
|
-
import type { ClientOptions, RequestOptions, XKCDResultWithData } from './Interfaces';
|
|
3
|
-
export declare class XKCDAPI {
|
|
4
|
-
protected readonly apiClient: APIClient;
|
|
5
|
-
protected readonly options: ClientOptions;
|
|
6
|
-
private readonly JSON_INFO_FILE;
|
|
7
|
-
private readonly lowestIndex;
|
|
8
|
-
constructor(apiClient: APIClient, options: ClientOptions);
|
|
9
|
-
/**
|
|
10
|
-
* Get a comic by index.
|
|
11
|
-
* @param index Index number
|
|
12
|
-
* @param options Request options
|
|
13
|
-
*/
|
|
14
|
-
getByIndex(index: number, options: {
|
|
15
|
-
withData: true;
|
|
16
|
-
}): Promise<XKCDResultWithData>;
|
|
17
|
-
getByIndex(index: number, options?: RequestOptions): Promise<XKCDResultWithData>;
|
|
18
|
-
/**
|
|
19
|
-
* Get the latest comic.
|
|
20
|
-
* @param options Request options
|
|
21
|
-
*/
|
|
22
|
-
getLatest(options: {
|
|
23
|
-
withData: true;
|
|
24
|
-
}): Promise<XKCDResultWithData>;
|
|
25
|
-
getLatest(options?: RequestOptions): Promise<XKCDResultWithData>;
|
|
26
|
-
/**
|
|
27
|
-
* Get a random comic.
|
|
28
|
-
* @param options Request options
|
|
29
|
-
*/
|
|
30
|
-
getRandom(options: {
|
|
31
|
-
withData: true;
|
|
32
|
-
}): Promise<XKCDResultWithData>;
|
|
33
|
-
getRandom(options?: RequestOptions): Promise<XKCDResultWithData>;
|
|
34
|
-
private getImage;
|
|
35
|
-
}
|
package/dist/XKCDAPI.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.XKCDAPI = void 0;
|
|
13
|
-
class XKCDAPI {
|
|
14
|
-
constructor(apiClient, options) {
|
|
15
|
-
this.apiClient = apiClient;
|
|
16
|
-
this.options = options;
|
|
17
|
-
this.lowestIndex = 1;
|
|
18
|
-
this.JSON_INFO_FILE = 'info.0.json';
|
|
19
|
-
}
|
|
20
|
-
getByIndex(index_1) {
|
|
21
|
-
return __awaiter(this, arguments, void 0, function* (index, options = {}) {
|
|
22
|
-
if (index < this.lowestIndex) {
|
|
23
|
-
throw new Error(`Index is lower than the lowest index of ${this.lowestIndex}.`);
|
|
24
|
-
}
|
|
25
|
-
const { data: metaData } = yield this.apiClient.get(`/${index}/${this.JSON_INFO_FILE}`);
|
|
26
|
-
if (options.withData === true) {
|
|
27
|
-
const imageData = yield this.getImage(metaData.img);
|
|
28
|
-
return Object.assign(Object.assign({}, metaData), { data: imageData });
|
|
29
|
-
}
|
|
30
|
-
return metaData;
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
getLatest() {
|
|
34
|
-
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
35
|
-
const { data: metaData } = yield this.apiClient.get(`/${this.JSON_INFO_FILE}`);
|
|
36
|
-
if (options.withData) {
|
|
37
|
-
const imageData = yield this.getImage(metaData.img);
|
|
38
|
-
return Object.assign(Object.assign({}, metaData), { data: imageData });
|
|
39
|
-
}
|
|
40
|
-
return metaData;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
getRandom() {
|
|
44
|
-
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
45
|
-
const latest = yield this.getLatest();
|
|
46
|
-
const randomIndex = Math.floor(Math.random() * (latest.num - this.lowestIndex + 1)) + this.lowestIndex;
|
|
47
|
-
const metaData = yield this.getByIndex(randomIndex);
|
|
48
|
-
if (options.withData === true) {
|
|
49
|
-
const imageData = yield this.getImage(metaData.img);
|
|
50
|
-
return Object.assign(Object.assign({}, metaData), { data: imageData });
|
|
51
|
-
}
|
|
52
|
-
return metaData;
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
getImage(imageUrl) {
|
|
56
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
-
const { data, headers } = yield this.apiClient.get(imageUrl, {
|
|
58
|
-
responseType: 'arraybuffer',
|
|
59
|
-
});
|
|
60
|
-
const contentType = headers.get('content-type');
|
|
61
|
-
return {
|
|
62
|
-
data,
|
|
63
|
-
mimeType: contentType ? String(contentType) : undefined,
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
exports.XKCDAPI = XKCDAPI;
|
package/dist/cli.d.ts
DELETED
package/dist/cli.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
-
if (k2 === undefined) k2 = k;
|
|
5
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
-
}
|
|
9
|
-
Object.defineProperty(o, k2, desc);
|
|
10
|
-
}) : (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
o[k2] = m[k];
|
|
13
|
-
}));
|
|
14
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
-
}) : function(o, v) {
|
|
17
|
-
o["default"] = v;
|
|
18
|
-
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
-
var ownKeys = function(o) {
|
|
21
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
-
var ar = [];
|
|
23
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
-
return ar;
|
|
25
|
-
};
|
|
26
|
-
return ownKeys(o);
|
|
27
|
-
};
|
|
28
|
-
return function (mod) {
|
|
29
|
-
if (mod && mod.__esModule) return mod;
|
|
30
|
-
var result = {};
|
|
31
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
-
__setModuleDefault(result, mod);
|
|
33
|
-
return result;
|
|
34
|
-
};
|
|
35
|
-
})();
|
|
36
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
37
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
38
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
39
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
40
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
41
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
42
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
const commander_1 = require("commander");
|
|
47
|
-
const fs_1 = require("fs");
|
|
48
|
-
const path = __importStar(require("path"));
|
|
49
|
-
const _1 = require("./");
|
|
50
|
-
function init() {
|
|
51
|
-
return __awaiter(this, arguments, void 0, function* (dir = '.') {
|
|
52
|
-
const resolvedPath = path.resolve(dir);
|
|
53
|
-
try {
|
|
54
|
-
yield fs_1.promises.access(resolvedPath, fs_1.constants.F_OK | fs_1.constants.R_OK);
|
|
55
|
-
const xkcd = new _1.XKCD();
|
|
56
|
-
return [resolvedPath, xkcd];
|
|
57
|
-
}
|
|
58
|
-
catch (_a) {
|
|
59
|
-
throw new Error('The specified path does not exist or is not writable.');
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
function save(filePath, imageResult) {
|
|
64
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
-
const { data, num, safe_title } = imageResult;
|
|
66
|
-
const extension = data.mimeType ? data.mimeType.replace('image/', '') : 'png';
|
|
67
|
-
const resolvedFilePath = path.resolve(filePath, `xkcd #${num} - ${safe_title}.${extension}`);
|
|
68
|
-
yield fs_1.promises.writeFile(resolvedFilePath, data.data);
|
|
69
|
-
console.info(`Saved image to "${resolvedFilePath}".`);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
const { description, name, version } = require('../package.json');
|
|
73
|
-
commander_1.program.on('command:*', () => commander_1.program.help());
|
|
74
|
-
commander_1.program
|
|
75
|
-
.name(name.replace(/^@[^/]+\//, ''))
|
|
76
|
-
.version(version, '-v, --version')
|
|
77
|
-
.description(description)
|
|
78
|
-
.option('-o, --output <dir>', 'Specify the output directory', path.resolve('.'));
|
|
79
|
-
commander_1.program
|
|
80
|
-
.command('latest')
|
|
81
|
-
.description('Save the latest comic')
|
|
82
|
-
.action((command) => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
|
-
try {
|
|
84
|
-
const [resolvedPath, xkcd] = yield init(command.parent.output);
|
|
85
|
-
const imageData = yield xkcd.api.getLatest({ withData: true });
|
|
86
|
-
yield save(resolvedPath, imageData);
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
console.error(`Error: ${error.message}`);
|
|
90
|
-
commander_1.program.outputHelp();
|
|
91
|
-
process.exit(1);
|
|
92
|
-
}
|
|
93
|
-
}));
|
|
94
|
-
commander_1.program
|
|
95
|
-
.command('random')
|
|
96
|
-
.description('Save a random comic')
|
|
97
|
-
.action((command) => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
|
-
try {
|
|
99
|
-
const [resolvedPath, xkcd] = yield init(command.parent.output);
|
|
100
|
-
const imageData = yield xkcd.api.getRandom({ withData: true });
|
|
101
|
-
yield save(resolvedPath, imageData);
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
console.error(`Error: ${error.message}`);
|
|
105
|
-
commander_1.program.outputHelp();
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
}));
|
|
109
|
-
commander_1.program
|
|
110
|
-
.command('number <index>')
|
|
111
|
-
.description('Save comic by index number')
|
|
112
|
-
.action((index, command) => __awaiter(void 0, void 0, void 0, function* () {
|
|
113
|
-
let parsedIndex;
|
|
114
|
-
try {
|
|
115
|
-
parsedIndex = parseInt(index, 10);
|
|
116
|
-
}
|
|
117
|
-
catch (_a) {
|
|
118
|
-
throw new Error('Invalid number specified.');
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
const [resolvedPath, xkcd] = yield init(command.parent.output);
|
|
122
|
-
const imageData = yield xkcd.api.getByIndex(parsedIndex, { withData: true });
|
|
123
|
-
yield save(resolvedPath, imageData);
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
console.error(`Error: ${error.message}`);
|
|
127
|
-
commander_1.program.outputHelp();
|
|
128
|
-
process.exit(1);
|
|
129
|
-
}
|
|
130
|
-
}));
|
|
131
|
-
commander_1.program.parse(process.argv);
|
|
132
|
-
if (!process.argv.slice(2).length) {
|
|
133
|
-
commander_1.program.outputHelp();
|
|
134
|
-
process.exit(1);
|
|
135
|
-
}
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./XKCD"), exports);
|
|
18
|
-
__exportStar(require("./Interfaces"), exports);
|