cnpmcore 4.25.0 → 4.26.0
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,6 +1,26 @@
|
|
|
1
1
|
import { type FetchResult } from './AbstractBinary.ts';
|
|
2
2
|
import { BucketBinary } from './BucketBinary.ts';
|
|
3
|
+
/**
|
|
4
|
+
* NW.js binary adapter.
|
|
5
|
+
*
|
|
6
|
+
* Root directory: scraped from https://dl.nwjs.io/ (HTML index)
|
|
7
|
+
* Sub directories: listed via Cloudflare R2 S3-compatible API (ListObjectsV2)
|
|
8
|
+
*
|
|
9
|
+
* The R2 bucket credentials are publicly available in the nwjs frontend page.
|
|
10
|
+
* @see https://github.com/cnpm/cnpmcore/issues/891
|
|
11
|
+
*/
|
|
3
12
|
export declare class NwjsBinary extends BucketBinary {
|
|
4
|
-
private
|
|
13
|
+
private r2Endpoint;
|
|
14
|
+
private r2BucketName;
|
|
15
|
+
private r2AccessKeyId;
|
|
16
|
+
private r2SecretAccessKey;
|
|
17
|
+
private r2Region;
|
|
5
18
|
fetch(dir: string): Promise<FetchResult | undefined>;
|
|
19
|
+
private fetchRootDir;
|
|
20
|
+
private fetchSubDir;
|
|
21
|
+
/**
|
|
22
|
+
* Request R2 S3 ListObjectsV2 API with AWS Signature V4 authentication.
|
|
23
|
+
*/
|
|
24
|
+
private requestR2Xml;
|
|
25
|
+
private getSignatureKey;
|
|
6
26
|
}
|
|
@@ -4,56 +4,143 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
+
import crypto from 'node:crypto';
|
|
7
8
|
import { SingletonProto } from 'egg';
|
|
8
9
|
import binaries from "../../../../config/binaries.js";
|
|
9
10
|
import { BinaryType } from "../../enum/Binary.js";
|
|
10
11
|
import { BinaryAdapter } from "./AbstractBinary.js";
|
|
11
12
|
import { BucketBinary } from "./BucketBinary.js";
|
|
13
|
+
/**
|
|
14
|
+
* NW.js binary adapter.
|
|
15
|
+
*
|
|
16
|
+
* Root directory: scraped from https://dl.nwjs.io/ (HTML index)
|
|
17
|
+
* Sub directories: listed via Cloudflare R2 S3-compatible API (ListObjectsV2)
|
|
18
|
+
*
|
|
19
|
+
* The R2 bucket credentials are publicly available in the nwjs frontend page.
|
|
20
|
+
* @see https://github.com/cnpm/cnpmcore/issues/891
|
|
21
|
+
*/
|
|
12
22
|
let NwjsBinary = class NwjsBinary extends BucketBinary {
|
|
13
23
|
constructor() {
|
|
14
24
|
super(...arguments);
|
|
15
|
-
|
|
25
|
+
// Cloudflare R2 S3-compatible endpoint for nwjs bucket
|
|
26
|
+
this.r2Endpoint = 'https://6883a4a09c48918c64df1ec7ddb744ba.r2.cloudflarestorage.com';
|
|
27
|
+
this.r2BucketName = 'nwjs';
|
|
28
|
+
this.r2AccessKeyId = '90fdca5d031b05eed0ef896a56a9521a';
|
|
29
|
+
this.r2SecretAccessKey = '34eeb665b34bfb9b773a8ff763a15e76621f541fdbbadeca6ed23e6d99c878ad';
|
|
30
|
+
this.r2Region = 'auto';
|
|
16
31
|
}
|
|
17
32
|
async fetch(dir) {
|
|
18
33
|
const binaryConfig = binaries.nwjs;
|
|
19
34
|
const isRootDir = dir === '/';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
35
|
+
if (isRootDir) {
|
|
36
|
+
return this.fetchRootDir(binaryConfig.distUrl);
|
|
37
|
+
}
|
|
38
|
+
return this.fetchSubDir(dir, binaryConfig);
|
|
39
|
+
}
|
|
40
|
+
async fetchRootDir(distUrl) {
|
|
41
|
+
const xml = await this.requestXml(distUrl);
|
|
24
42
|
if (!xml)
|
|
25
43
|
return;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
name,
|
|
43
|
-
isDir: true,
|
|
44
|
-
url: '',
|
|
45
|
-
size: '-',
|
|
46
|
-
date,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return { items, nextParams: null };
|
|
44
|
+
const items = [];
|
|
45
|
+
const re = /<td><a [^>]+?>([^<]+?\/)<\/a><\/td><td [^>]+?>([^>]+?)<\/td>/gi;
|
|
46
|
+
const matchs = xml.matchAll(re);
|
|
47
|
+
for (const m of matchs) {
|
|
48
|
+
const name = m[1].trim();
|
|
49
|
+
// ignore live-build/ name
|
|
50
|
+
if (name === 'live-build/')
|
|
51
|
+
continue;
|
|
52
|
+
const date = m[2].trim();
|
|
53
|
+
items.push({
|
|
54
|
+
name,
|
|
55
|
+
isDir: true,
|
|
56
|
+
url: '',
|
|
57
|
+
size: '-',
|
|
58
|
+
date,
|
|
59
|
+
});
|
|
50
60
|
}
|
|
61
|
+
return { items, nextParams: null };
|
|
62
|
+
}
|
|
63
|
+
async fetchSubDir(dir, binaryConfig) {
|
|
64
|
+
// /foo/ => foo/
|
|
65
|
+
const prefix = dir.slice(1);
|
|
66
|
+
const xml = await this.requestR2Xml(prefix);
|
|
67
|
+
if (!xml)
|
|
68
|
+
return;
|
|
51
69
|
return { items: this.parseItems(xml, dir, binaryConfig), nextParams: null };
|
|
52
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Request R2 S3 ListObjectsV2 API with AWS Signature V4 authentication.
|
|
73
|
+
*/
|
|
74
|
+
async requestR2Xml(prefix) {
|
|
75
|
+
const host = new URL(this.r2Endpoint).host;
|
|
76
|
+
const now = new Date();
|
|
77
|
+
const amzDate = now
|
|
78
|
+
.toISOString()
|
|
79
|
+
.replace(/[-:]/g, '')
|
|
80
|
+
.replace(/\.\d{3}/, '');
|
|
81
|
+
const dateStamp = amzDate.slice(0, 8);
|
|
82
|
+
const method = 'GET';
|
|
83
|
+
const canonicalUri = `/${this.r2BucketName}`;
|
|
84
|
+
// Build sorted query string
|
|
85
|
+
const queryParams = new URLSearchParams({
|
|
86
|
+
delimiter: '/',
|
|
87
|
+
'list-type': '2',
|
|
88
|
+
prefix: prefix,
|
|
89
|
+
});
|
|
90
|
+
queryParams.sort();
|
|
91
|
+
const canonicalQueryString = queryParams.toString();
|
|
92
|
+
// Build canonical request
|
|
93
|
+
const payloadHash = crypto.createHash('sha256').update('').digest('hex');
|
|
94
|
+
const canonicalHeaders = `host:${host}\nx-amz-content-sha256:${payloadHash}\nx-amz-date:${amzDate}\n`;
|
|
95
|
+
const signedHeaders = 'host;x-amz-content-sha256;x-amz-date';
|
|
96
|
+
const canonicalRequest = [
|
|
97
|
+
method,
|
|
98
|
+
canonicalUri,
|
|
99
|
+
canonicalQueryString,
|
|
100
|
+
canonicalHeaders,
|
|
101
|
+
signedHeaders,
|
|
102
|
+
payloadHash,
|
|
103
|
+
].join('\n');
|
|
104
|
+
// Build string to sign
|
|
105
|
+
const credentialScope = `${dateStamp}/${this.r2Region}/s3/aws4_request`;
|
|
106
|
+
const stringToSign = [
|
|
107
|
+
'AWS4-HMAC-SHA256',
|
|
108
|
+
amzDate,
|
|
109
|
+
credentialScope,
|
|
110
|
+
crypto.createHash('sha256').update(canonicalRequest).digest('hex'),
|
|
111
|
+
].join('\n');
|
|
112
|
+
// Calculate signature
|
|
113
|
+
const signingKey = this.getSignatureKey(this.r2SecretAccessKey, dateStamp, this.r2Region, 's3');
|
|
114
|
+
const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');
|
|
115
|
+
const authorization = `AWS4-HMAC-SHA256 Credential=${this.r2AccessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
|
|
116
|
+
const url = `${this.r2Endpoint}/${this.r2BucketName}?${canonicalQueryString}`;
|
|
117
|
+
const { status, data, headers } = await this.httpclient.request(url, {
|
|
118
|
+
timeout: 30_000,
|
|
119
|
+
followRedirect: true,
|
|
120
|
+
gzip: true,
|
|
121
|
+
headers: {
|
|
122
|
+
Authorization: authorization,
|
|
123
|
+
'X-Amz-Content-Sha256': payloadHash,
|
|
124
|
+
'X-Amz-Date': amzDate,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
const xml = data.toString();
|
|
128
|
+
if (status !== 200) {
|
|
129
|
+
this.logger.warn('[NwjsBinary.requestR2Xml:non-200-status] url: %s, status: %s, headers: %j, xml: %j', url, status, headers, xml);
|
|
130
|
+
return '';
|
|
131
|
+
}
|
|
132
|
+
return xml;
|
|
133
|
+
}
|
|
134
|
+
getSignatureKey(key, dateStamp, region, service) {
|
|
135
|
+
const kDate = crypto.createHmac('sha256', `AWS4${key}`).update(dateStamp).digest();
|
|
136
|
+
const kRegion = crypto.createHmac('sha256', kDate).update(region).digest();
|
|
137
|
+
const kService = crypto.createHmac('sha256', kRegion).update(service).digest();
|
|
138
|
+
return crypto.createHmac('sha256', kService).update('aws4_request').digest();
|
|
139
|
+
}
|
|
53
140
|
};
|
|
54
141
|
NwjsBinary = __decorate([
|
|
55
142
|
SingletonProto(),
|
|
56
143
|
BinaryAdapter(BinaryType.Nwjs)
|
|
57
144
|
], NwjsBinary);
|
|
58
145
|
export { NwjsBinary };
|
|
59
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
146
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTndqc0JpbmFyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2FwcC9jb21tb24vYWRhcHRlci9iaW5hcnkvTndqc0JpbmFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFFakMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUVyQyxPQUFPLFFBQVEsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN0RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGFBQWEsRUFBcUMsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFakQ7Ozs7Ozs7O0dBUUc7QUFHSSxJQUFNLFVBQVUsR0FBaEIsTUFBTSxVQUFXLFNBQVEsWUFBWTtJQUFyQzs7UUFDTCx1REFBdUQ7UUFDL0MsZUFBVSxHQUFHLG1FQUFtRSxDQUFDO1FBQ2pGLGlCQUFZLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLGtCQUFhLEdBQUcsa0NBQWtDLENBQUM7UUFDbkQsc0JBQWlCLEdBQUcsa0VBQWtFLENBQUM7UUFDdkYsYUFBUSxHQUFHLE1BQU0sQ0FBQztJQWtJNUIsQ0FBQztJQWhJQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQVc7UUFDckIsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUNuQyxNQUFNLFNBQVMsR0FBRyxHQUFHLEtBQUssR0FBRyxDQUFDO1FBRTlCLElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFTyxLQUFLLENBQUMs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
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { AbstractController } from './AbstractController.ts';
|
|
2
2
|
export declare class DownloadController extends AbstractController {
|
|
3
3
|
private packageVersionDownloadRepository;
|
|
4
|
+
showPackageDownloadPoint(fullname: string, range: string): Promise<{
|
|
5
|
+
downloads: number;
|
|
6
|
+
start: string;
|
|
7
|
+
end: string;
|
|
8
|
+
package: string;
|
|
9
|
+
}>;
|
|
10
|
+
showTotalDownloadPoint(range: string): Promise<{
|
|
11
|
+
downloads: number;
|
|
12
|
+
start: string;
|
|
13
|
+
end: string;
|
|
14
|
+
}>;
|
|
4
15
|
showPackageDownloads(fullname: string, range: string): Promise<{
|
|
5
16
|
downloads: {
|
|
6
17
|
day: string;
|
|
7
18
|
downloads: number;
|
|
8
19
|
}[];
|
|
20
|
+
start: string;
|
|
21
|
+
end: string;
|
|
22
|
+
package: string;
|
|
9
23
|
versions: Record<string, {
|
|
10
24
|
day: string;
|
|
11
25
|
downloads: number;
|
|
@@ -16,6 +30,10 @@ export declare class DownloadController extends AbstractController {
|
|
|
16
30
|
day: string;
|
|
17
31
|
downloads: number;
|
|
18
32
|
}[];
|
|
33
|
+
start: string;
|
|
34
|
+
end: string;
|
|
19
35
|
}>;
|
|
36
|
+
private getDayRange;
|
|
37
|
+
private sumDownloads;
|
|
20
38
|
private checkAndGetRange;
|
|
21
39
|
}
|
|
@@ -11,25 +11,50 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
13
|
import { HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam, Inject } from 'egg';
|
|
14
|
-
import {
|
|
14
|
+
import { UnprocessableEntityError } from 'egg/errors';
|
|
15
15
|
import dayjs from "../../common/dayjs.js";
|
|
16
|
-
import { FULLNAME_REG_STRING
|
|
16
|
+
import { FULLNAME_REG_STRING } from "../../common/PackageUtil.js";
|
|
17
17
|
import { AbstractController } from "./AbstractController.js";
|
|
18
18
|
const DATE_FORMAT = 'YYYY-MM-DD';
|
|
19
19
|
let DownloadController = class DownloadController extends AbstractController {
|
|
20
|
+
// npm compatible: /downloads/point/{period}/{package}
|
|
21
|
+
// @see https://github.com/npm/registry/blob/master/docs/download-counts.md
|
|
22
|
+
async showPackageDownloadPoint(fullname, range) {
|
|
23
|
+
const [startDate, endDate] = this.checkAndGetRange(range);
|
|
24
|
+
const pkg = await this.getPackageEntityByFullname(fullname);
|
|
25
|
+
const entities = await this.packageVersionDownloadRepository.query(pkg.packageId, startDate.toDate(), endDate.toDate());
|
|
26
|
+
const total = this.sumDownloads(entities, startDate, endDate);
|
|
27
|
+
return {
|
|
28
|
+
downloads: total,
|
|
29
|
+
start: startDate.format(DATE_FORMAT),
|
|
30
|
+
end: endDate.format(DATE_FORMAT),
|
|
31
|
+
package: fullname,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// /downloads/total/point/{period} (all packages, total count)
|
|
35
|
+
async showTotalDownloadPoint(range) {
|
|
36
|
+
const [startDate, endDate] = this.checkAndGetRange(range);
|
|
37
|
+
const entities = await this.packageVersionDownloadRepository.query('total', startDate.toDate(), endDate.toDate());
|
|
38
|
+
const total = this.sumDownloads(entities, startDate, endDate);
|
|
39
|
+
return {
|
|
40
|
+
downloads: total,
|
|
41
|
+
start: startDate.format(DATE_FORMAT),
|
|
42
|
+
end: endDate.format(DATE_FORMAT),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
20
45
|
async showPackageDownloads(fullname, range) {
|
|
21
46
|
const [startDate, endDate] = this.checkAndGetRange(range);
|
|
22
|
-
const
|
|
23
|
-
const pkg = await this.packageRepository.findPackage(scope, name);
|
|
24
|
-
if (!pkg)
|
|
25
|
-
throw new NotFoundError(`${fullname} not found`);
|
|
47
|
+
const pkg = await this.getPackageEntityByFullname(fullname);
|
|
26
48
|
const entities = await this.packageVersionDownloadRepository.query(pkg.packageId, startDate.toDate(), endDate.toDate());
|
|
27
49
|
const days = {};
|
|
28
50
|
const versions = {};
|
|
29
51
|
for (const entity of entities) {
|
|
30
|
-
const yearMonth =
|
|
31
|
-
const
|
|
32
|
-
|
|
52
|
+
const yearMonth = entity.yearMonth;
|
|
53
|
+
const yearStr = String(yearMonth).slice(0, 4);
|
|
54
|
+
const monthStr = String(yearMonth).slice(4, 6);
|
|
55
|
+
const prefix = `${yearStr}-${monthStr}`;
|
|
56
|
+
const [fromDay, toDay] = this.getDayRange(yearMonth, startDate, endDate);
|
|
57
|
+
for (let i = fromDay; i <= toDay; i++) {
|
|
33
58
|
const day = String(i).padStart(2, '0');
|
|
34
59
|
const field = `d${day}`;
|
|
35
60
|
const counter = entity[field];
|
|
@@ -52,6 +77,9 @@ let DownloadController = class DownloadController extends AbstractController {
|
|
|
52
77
|
}
|
|
53
78
|
return {
|
|
54
79
|
downloads,
|
|
80
|
+
start: startDate.format(DATE_FORMAT),
|
|
81
|
+
end: endDate.format(DATE_FORMAT),
|
|
82
|
+
package: fullname,
|
|
55
83
|
versions,
|
|
56
84
|
};
|
|
57
85
|
}
|
|
@@ -60,9 +88,12 @@ let DownloadController = class DownloadController extends AbstractController {
|
|
|
60
88
|
const entities = await this.packageVersionDownloadRepository.query(scope, startDate.toDate(), endDate.toDate());
|
|
61
89
|
const days = {};
|
|
62
90
|
for (const entity of entities) {
|
|
63
|
-
const yearMonth =
|
|
64
|
-
const
|
|
65
|
-
|
|
91
|
+
const yearMonth = entity.yearMonth;
|
|
92
|
+
const yearStr = String(yearMonth).slice(0, 4);
|
|
93
|
+
const monthStr = String(yearMonth).slice(4, 6);
|
|
94
|
+
const prefix = `${yearStr}-${monthStr}`;
|
|
95
|
+
const [fromDay, toDay] = this.getDayRange(yearMonth, startDate, endDate);
|
|
96
|
+
for (let i = fromDay; i <= toDay; i++) {
|
|
66
97
|
const day = String(i).padStart(2, '0');
|
|
67
98
|
const field = `d${day}`;
|
|
68
99
|
const counter = entity[field];
|
|
@@ -78,19 +109,79 @@ let DownloadController = class DownloadController extends AbstractController {
|
|
|
78
109
|
}
|
|
79
110
|
return {
|
|
80
111
|
downloads,
|
|
112
|
+
start: startDate.format(DATE_FORMAT),
|
|
113
|
+
end: endDate.format(DATE_FORMAT),
|
|
81
114
|
};
|
|
82
115
|
}
|
|
116
|
+
// Get the valid day range [startDay, endDay] for a given entity's yearMonth
|
|
117
|
+
// considering the requested date range boundaries
|
|
118
|
+
getDayRange(yearMonth, startDate, endDate) {
|
|
119
|
+
const year = Math.floor(yearMonth / 100);
|
|
120
|
+
const month = yearMonth % 100;
|
|
121
|
+
const startYM = startDate.year() * 100 + startDate.month() + 1;
|
|
122
|
+
const endYM = endDate.year() * 100 + endDate.month() + 1;
|
|
123
|
+
const entityYM = year * 100 + month;
|
|
124
|
+
// Days in this month
|
|
125
|
+
const daysInMonth = dayjs(`${year}-${String(month).padStart(2, '0')}-01`).daysInMonth();
|
|
126
|
+
let fromDay = 1;
|
|
127
|
+
let toDay = daysInMonth;
|
|
128
|
+
if (entityYM === startYM) {
|
|
129
|
+
fromDay = startDate.date();
|
|
130
|
+
}
|
|
131
|
+
if (entityYM === endYM) {
|
|
132
|
+
toDay = endDate.date();
|
|
133
|
+
}
|
|
134
|
+
return [fromDay, toDay];
|
|
135
|
+
}
|
|
136
|
+
sumDownloads(entities, startDate, endDate) {
|
|
137
|
+
let total = 0;
|
|
138
|
+
for (const entity of entities) {
|
|
139
|
+
const [fromDay, toDay] = this.getDayRange(entity.yearMonth, startDate, endDate);
|
|
140
|
+
for (let i = fromDay; i <= toDay; i++) {
|
|
141
|
+
const field = `d${String(i).padStart(2, '0')}`;
|
|
142
|
+
const counter = entity[field];
|
|
143
|
+
if (counter)
|
|
144
|
+
total += counter;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return total;
|
|
148
|
+
}
|
|
83
149
|
checkAndGetRange(range) {
|
|
150
|
+
// Support npm-compatible period aliases
|
|
151
|
+
// @see https://github.com/npm/registry/blob/master/docs/download-counts.md
|
|
152
|
+
const today = dayjs();
|
|
153
|
+
switch (range) {
|
|
154
|
+
case 'last-day':
|
|
155
|
+
return [today.subtract(1, 'day'), today.subtract(1, 'day')];
|
|
156
|
+
case 'last-week':
|
|
157
|
+
return [today.subtract(7, 'day'), today.subtract(1, 'day')];
|
|
158
|
+
case 'last-month':
|
|
159
|
+
return [today.subtract(30, 'day'), today.subtract(1, 'day')];
|
|
160
|
+
case 'last-year':
|
|
161
|
+
return [today.subtract(365, 'day'), today.subtract(1, 'day')];
|
|
162
|
+
default:
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
// Support single date: YYYY-MM-DD
|
|
166
|
+
const singleDateMatch = /^(\d{4}-\d{2}-\d{2})$/.exec(range);
|
|
167
|
+
if (singleDateMatch) {
|
|
168
|
+
const date = dayjs(singleDateMatch[1], DATE_FORMAT, true);
|
|
169
|
+
if (!date.isValid()) {
|
|
170
|
+
throw new UnprocessableEntityError(`range(${range}) format invalid, must be "last-day", "last-week", "last-month", "last-year", "${DATE_FORMAT}" or "${DATE_FORMAT}:${DATE_FORMAT}" style`);
|
|
171
|
+
}
|
|
172
|
+
return [date, date];
|
|
173
|
+
}
|
|
174
|
+
// Support date range: YYYY-MM-DD:YYYY-MM-DD
|
|
84
175
|
const matchs = /^(\d{4}-\d{2}-\d{2}):(\d{4}-\d{2}-\d{2})$/.exec(range);
|
|
85
176
|
if (!matchs) {
|
|
86
|
-
throw new UnprocessableEntityError(`range(${range}) format invalid, must be "${DATE_FORMAT}:${DATE_FORMAT}" style`);
|
|
177
|
+
throw new UnprocessableEntityError(`range(${range}) format invalid, must be "last-day", "last-week", "last-month", "last-year", "${DATE_FORMAT}" or "${DATE_FORMAT}:${DATE_FORMAT}" style`);
|
|
87
178
|
}
|
|
88
179
|
const start = matchs[1];
|
|
89
180
|
const end = matchs[2];
|
|
90
181
|
let startDate = dayjs(start, DATE_FORMAT, true);
|
|
91
182
|
let endDate = dayjs(end, DATE_FORMAT, true);
|
|
92
183
|
if (!startDate.isValid() || !endDate.isValid()) {
|
|
93
|
-
throw new UnprocessableEntityError(`range(${range}) format invalid, must be "${DATE_FORMAT}:${DATE_FORMAT}" style`);
|
|
184
|
+
throw new UnprocessableEntityError(`range(${range}) format invalid, must be "last-day", "last-week", "last-month", "last-year", "${DATE_FORMAT}" or "${DATE_FORMAT}:${DATE_FORMAT}" style`);
|
|
94
185
|
}
|
|
95
186
|
if (endDate.isBefore(startDate)) {
|
|
96
187
|
const tmp = startDate;
|
|
@@ -109,6 +200,27 @@ __decorate([
|
|
|
109
200
|
Inject(),
|
|
110
201
|
__metadata("design:type", Function)
|
|
111
202
|
], DownloadController.prototype, "packageVersionDownloadRepository", void 0);
|
|
203
|
+
__decorate([
|
|
204
|
+
HTTPMethod({
|
|
205
|
+
path: `/downloads/point/:range/:fullname(${FULLNAME_REG_STRING})`,
|
|
206
|
+
method: HTTPMethodEnum.GET,
|
|
207
|
+
}),
|
|
208
|
+
__param(0, HTTPParam()),
|
|
209
|
+
__param(1, HTTPParam()),
|
|
210
|
+
__metadata("design:type", Function),
|
|
211
|
+
__metadata("design:paramtypes", [String, String]),
|
|
212
|
+
__metadata("design:returntype", Promise)
|
|
213
|
+
], DownloadController.prototype, "showPackageDownloadPoint", null);
|
|
214
|
+
__decorate([
|
|
215
|
+
HTTPMethod({
|
|
216
|
+
path: '/downloads/total/point/:range',
|
|
217
|
+
method: HTTPMethodEnum.GET,
|
|
218
|
+
}),
|
|
219
|
+
__param(0, HTTPParam()),
|
|
220
|
+
__metadata("design:type", Function),
|
|
221
|
+
__metadata("design:paramtypes", [String]),
|
|
222
|
+
__metadata("design:returntype", Promise)
|
|
223
|
+
], DownloadController.prototype, "showTotalDownloadPoint", null);
|
|
112
224
|
__decorate([
|
|
113
225
|
HTTPMethod({
|
|
114
226
|
path: `/downloads/range/:range/:fullname(${FULLNAME_REG_STRING})`,
|
|
@@ -135,4 +247,4 @@ DownloadController = __decorate([
|
|
|
135
247
|
HTTPController()
|
|
136
248
|
], DownloadController);
|
|
137
249
|
export { DownloadController };
|
|
138
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRG93bmxvYWRDb250cm9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vYXBwL3BvcnQvY29udHJvbGxlci9Eb3dubG9hZENvbnRyb2xsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEYsT0FBTyxFQUFFLGFBQWEsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVyRSxPQUFPLEtBQUssTUFBTSx1QkFBdUIsQ0FBQztBQUMxQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFbkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFN0QsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDO0FBRzFCLElBQU0sa0JBQWtCLEdBQXhCLE1BQU0sa0JBQW1CLFNBQVEsa0JBQWtCO0lBUWxELEFBQU4sS0FBSyxDQUFDLG9CQUFvQixDQUFjLFFBQWdCLEVBQWUsS0FBYTtRQUNsRixNQUFNLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxRCxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxHQUFHO1lBQUUsTUFBTSxJQUFJLGFBQWEsQ0FBQyxHQUFHLFFBQVEsWUFBWSxDQUFDLENBQUM7UUFDM0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0NBQWdDLENB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
|
|
250
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRG93bmxvYWRDb250cm9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vYXBwL3BvcnQvY29udHJvbGxlci9Eb3dubG9hZENvbnRyb2xsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXRELE9BQU8sS0FBSyxNQUFNLHVCQUF1QixDQUFDO0FBQzFDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR2xFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRTdELE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQztBQUcxQixJQUFNLGtCQUFrQixHQUF4QixNQUFNLGtCQUFtQixTQUFRLGtCQUFrQjtJQUl4RCxzREFBc0Q7SUFDdEQsMkVBQTJFO0lBS3JFLEFBQU4sS0FBSyxDQUFDLHdCQUF3QixDQUFjLFFBQWdCLEVBQWUsS0FBYTtRQUN0RixNQUFNLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxRCxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1RCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxLQUFLLENBQ2hFLEdBQUcsQ0FBQyxTQUFTLEVBQ2IsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUNsQixPQUFPLENBQUMsTUFBTSxFQUFFLENBQ2pCLENBQUM7UUFDRixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUs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
|