@shuvi/reporters 1.0.30

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.
@@ -0,0 +1,25 @@
1
+ /// <reference types="node" />
2
+ declare type PackageManager = {
3
+ packageManager: 'npm' | 'pnpm' | 'yarn';
4
+ packageManagerVersion: string | undefined;
5
+ };
6
+ declare type AnonymousMeta = {
7
+ systemPlatform: NodeJS.Platform;
8
+ systemRelease: string;
9
+ systemArchitecture: string;
10
+ cpuCount: number;
11
+ cpuModel: string | null;
12
+ cpuSpeed: number | null;
13
+ memoryInMb: number;
14
+ isDocker: boolean;
15
+ isWsl: boolean;
16
+ isCI: boolean;
17
+ ciName: string | null;
18
+ packageManager: string;
19
+ packageManagerVersion: string | undefined;
20
+ nodeVersion: string;
21
+ shuviVersion?: string;
22
+ };
23
+ export declare function getAnonymousMeta(): AnonymousMeta;
24
+ export declare function getPkgManager(): PackageManager;
25
+ export {};
@@ -0,0 +1,99 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.getPkgManager = exports.getAnonymousMeta = void 0;
30
+ const is_docker_1 = __importDefault(require("is-docker"));
31
+ const is_wsl_1 = __importDefault(require("is-wsl"));
32
+ const os_1 = __importDefault(require("os"));
33
+ const child_process_1 = require("child_process");
34
+ const ciEnvironment = __importStar(require("ci-info"));
35
+ let traits;
36
+ function getAnonymousMeta() {
37
+ if (traits) {
38
+ return traits;
39
+ }
40
+ const cpus = os_1.default.cpus() || [];
41
+ const { packageManager, packageManagerVersion } = getPkgManager();
42
+ traits = {
43
+ // Software information
44
+ systemPlatform: os_1.default.platform(),
45
+ systemRelease: os_1.default.release(),
46
+ systemArchitecture: os_1.default.arch(),
47
+ // Machine information
48
+ cpuCount: cpus.length,
49
+ cpuModel: cpus.length ? cpus[0].model : null,
50
+ cpuSpeed: cpus.length ? cpus[0].speed : null,
51
+ memoryInMb: Math.trunc(os_1.default.totalmem() / Math.pow(1024, 2)),
52
+ // Environment information
53
+ isDocker: (0, is_docker_1.default)(),
54
+ isWsl: is_wsl_1.default,
55
+ isCI: ciEnvironment.isCI,
56
+ ciName: (ciEnvironment.isCI && ciEnvironment.name) || null,
57
+ packageManager,
58
+ packageManagerVersion,
59
+ nodeVersion: process.version
60
+ };
61
+ return traits;
62
+ }
63
+ exports.getAnonymousMeta = getAnonymousMeta;
64
+ function getPkgManager() {
65
+ try {
66
+ const userAgent = process.env.npm_config_user_agent;
67
+ if (userAgent) {
68
+ const packageManagerVersion = userAgent.split(' ')[0].split('/')[1];
69
+ if (userAgent.startsWith('yarn')) {
70
+ return { packageManager: 'yarn', packageManagerVersion };
71
+ }
72
+ else if (userAgent.startsWith('pnpm')) {
73
+ return { packageManager: 'pnpm', packageManagerVersion };
74
+ }
75
+ }
76
+ try {
77
+ const packageManagerVersion = (0, child_process_1.execSync)(`yarn --version`)
78
+ .toString()
79
+ .trim();
80
+ return { packageManager: 'yarn', packageManagerVersion };
81
+ }
82
+ catch (_a) {
83
+ const packageManagerVersion = (0, child_process_1.execSync)(`pnpm --version`)
84
+ .toString()
85
+ .trim();
86
+ return { packageManager: 'pnpm', packageManagerVersion };
87
+ }
88
+ }
89
+ catch (_b) {
90
+ try {
91
+ const packageManagerVersion = (0, child_process_1.execSync)(`npm --version`).toString().trim();
92
+ return { packageManager: 'npm', packageManagerVersion };
93
+ }
94
+ catch (_c) {
95
+ return { packageManager: 'npm', packageManagerVersion: undefined };
96
+ }
97
+ }
98
+ }
99
+ exports.getPkgManager = getPkgManager;
@@ -0,0 +1 @@
1
+ export declare function _postPayload(endpoint: string, body: object): Promise<void>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports._postPayload = void 0;
7
+ const async_retry_1 = __importDefault(require("async-retry"));
8
+ const node_fetch_1 = __importDefault(require("node-fetch"));
9
+ function _postPayload(endpoint, body) {
10
+ return ((0, async_retry_1.default)(() => (0, node_fetch_1.default)(endpoint, {
11
+ method: 'POST',
12
+ body: JSON.stringify(body),
13
+ headers: { 'content-type': 'application/json' },
14
+ timeout: 5000
15
+ }).then(res => {
16
+ if (!res.ok) {
17
+ const err = new Error(res.statusText);
18
+ err.response = res;
19
+ throw err;
20
+ }
21
+ }), { minTimeout: 500, retries: 1, factor: 1 })
22
+ .catch(() => {
23
+ // We swallow errors when telemetry cannot be sent
24
+ })
25
+ // Ensure promise is voided
26
+ .then(() => { }, () => { }));
27
+ }
28
+ exports._postPayload = _postPayload;
@@ -0,0 +1 @@
1
+ export declare function getRawProjectId(): string;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRawProjectId = void 0;
4
+ const child_process_1 = require("child_process");
5
+ function _getProjectIdByGit() {
6
+ try {
7
+ const originBuffer = (0, child_process_1.execSync)(`git config --local --get remote.origin.url`, {
8
+ timeout: 1000,
9
+ stdio: `pipe`
10
+ });
11
+ return String(originBuffer).trim();
12
+ }
13
+ catch (_) {
14
+ return null;
15
+ }
16
+ }
17
+ function getRawProjectId() {
18
+ return _getProjectIdByGit() || process.env.REPOSITORY_URL || process.cwd();
19
+ }
20
+ exports.getRawProjectId = getRawProjectId;
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './telemetry';
2
+ export * from './to-json';
package/lib/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ // This package 'telemetry' is a modified version of the Next.js that can be found here:
3
+ // https://github.com/vercel/next.js/tree/canary/packages/next/telemetry
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ __exportStar(require("./telemetry"), exports);
20
+ __exportStar(require("./to-json"), exports);
@@ -0,0 +1,49 @@
1
+ import type { Reporter } from '@shuvi/shared/reporter';
2
+ export declare type TelemetryEvent = {
3
+ eventName: string;
4
+ payload: object;
5
+ };
6
+ export declare type EventContext = {
7
+ anonymousId?: string;
8
+ projectId?: string;
9
+ sessionId?: string;
10
+ [key: string]: unknown;
11
+ };
12
+ export declare type EventMeta = {
13
+ [key: string]: unknown;
14
+ };
15
+ export declare type EventBatchShape = {
16
+ eventName: string;
17
+ fields: object;
18
+ };
19
+ export declare type RecordObject = {
20
+ isFulfilled: boolean;
21
+ isRejected: boolean;
22
+ value?: any;
23
+ reason?: any;
24
+ };
25
+ export declare class Telemetry {
26
+ private name;
27
+ private conf;
28
+ private sessionId;
29
+ private rawProjectId;
30
+ private projectId;
31
+ private meta;
32
+ private context;
33
+ private postEndpoint;
34
+ private queue;
35
+ constructor({ name, meta, context, postEndpoint }: {
36
+ name: string;
37
+ meta?: EventMeta;
38
+ context?: EventContext;
39
+ postEndpoint?: string;
40
+ });
41
+ get anonymousId(): string;
42
+ get salt(): string;
43
+ report: Reporter;
44
+ record(_events: TelemetryEvent | TelemetryEvent[]): Promise<RecordObject>;
45
+ flush(): Promise<void>;
46
+ private _notify;
47
+ private _oneWayHash;
48
+ private _submitRecord;
49
+ }
@@ -0,0 +1,171 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.Telemetry = void 0;
16
+ const chalk_1 = __importDefault(require("@shuvi/utils/chalk"));
17
+ const conf_1 = __importDefault(require("conf"));
18
+ const crypto_1 = require("crypto");
19
+ const anonymous_meta_1 = require("./helper/anonymous-meta");
20
+ const post_payload_1 = require("./helper/post-payload");
21
+ const project_id_1 = require("./helper/project-id");
22
+ // This is the key that specifies when the user was informed about anonymous
23
+ // telemetry collection.
24
+ const TELEMETRY_KEY_NOTIFY_DATE = 'telemetry.notifiedAt';
25
+ // This is a quasi-persistent identifier used to dedupe recurring events. It's
26
+ // generated from random data and completely anonymous.
27
+ const TELEMETRY_KEY_ID = `telemetry.anonymousId`;
28
+ // This is the cryptographic salt that is included within every hashed value.
29
+ // This salt value is never sent to us, ensuring privacy and the one-way nature
30
+ // of the hash (prevents dictionary lookups of pre-computed hashes).
31
+ // See the `oneWayHash` function.
32
+ const TELEMETRY_KEY_SALT = `telemetry.salt`;
33
+ class Telemetry {
34
+ constructor({ name, meta, context, postEndpoint }) {
35
+ this.report = ({ timestamp, name, duration, startTime, id, parentId, attrs }) => {
36
+ this.record({
37
+ eventName: name,
38
+ payload: {
39
+ parentId,
40
+ name,
41
+ id,
42
+ startTime,
43
+ duration,
44
+ timestamp,
45
+ tags: attrs
46
+ }
47
+ });
48
+ };
49
+ try {
50
+ // `conf` incorrectly throws a permission error during initialization
51
+ // instead of waiting for first use. We need to handle it, otherwise the
52
+ // process may crash.
53
+ this.conf = new conf_1.default({ projectName: 'shuvijs' });
54
+ }
55
+ catch (_) {
56
+ this.conf = null;
57
+ }
58
+ this.name = name;
59
+ this.sessionId = (0, crypto_1.randomBytes)(32).toString('hex');
60
+ this.rawProjectId = (0, project_id_1.getRawProjectId)();
61
+ this.projectId = this._oneWayHash(this.rawProjectId);
62
+ this.postEndpoint = postEndpoint;
63
+ this.queue = new Set();
64
+ this._notify();
65
+ this.meta = Object.assign(Object.assign({}, (0, anonymous_meta_1.getAnonymousMeta)()), meta);
66
+ this.context = Object.assign({ anonymousId: this.anonymousId, projectId: this.projectId, sessionId: this.sessionId }, context);
67
+ Object.freeze(this.meta);
68
+ Object.freeze(this.context);
69
+ }
70
+ get anonymousId() {
71
+ const val = this.conf && this.conf.get(TELEMETRY_KEY_ID);
72
+ if (val) {
73
+ return val;
74
+ }
75
+ const generated = (0, crypto_1.randomBytes)(32).toString('hex');
76
+ this.conf && this.conf.set(TELEMETRY_KEY_ID, generated);
77
+ return generated;
78
+ }
79
+ get salt() {
80
+ const val = this.conf && this.conf.get(TELEMETRY_KEY_SALT);
81
+ if (val) {
82
+ return val;
83
+ }
84
+ const generated = (0, crypto_1.randomBytes)(16).toString('hex');
85
+ this.conf && this.conf.set(TELEMETRY_KEY_SALT, generated);
86
+ return generated;
87
+ }
88
+ record(_events) {
89
+ const _this = this;
90
+ // pseudo try-catch
91
+ function wrapper() {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ return yield _this._submitRecord(_events);
94
+ });
95
+ }
96
+ const prom = wrapper()
97
+ .then(value => ({
98
+ isFulfilled: true,
99
+ isRejected: false,
100
+ value
101
+ }))
102
+ .catch(reason => ({
103
+ isFulfilled: false,
104
+ isRejected: true,
105
+ reason
106
+ }))
107
+ // Acts as `Promise#finally` because `catch` transforms the error
108
+ .then(res => {
109
+ // Clean up the event to prevent unbounded `Set` growth
110
+ this.queue.delete(prom);
111
+ return res;
112
+ });
113
+ // Track this `Promise` so we can flush pending events
114
+ this.queue.add(prom);
115
+ return prom;
116
+ }
117
+ flush() {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ yield Promise.all(this.queue).catch(() => null);
120
+ });
121
+ }
122
+ _notify() {
123
+ if (!this.conf) {
124
+ return;
125
+ }
126
+ // The end-user has already been notified about our telemetry integration. We
127
+ // don't need to constantly annoy them about it.
128
+ // We will re-inform users about the telemetry if significant changes are
129
+ // ever made.
130
+ if (this.conf.get(TELEMETRY_KEY_NOTIFY_DATE, '')) {
131
+ return;
132
+ }
133
+ this.conf.set(TELEMETRY_KEY_NOTIFY_DATE, Date.now().toString());
134
+ console.log(`${chalk_1.default.magenta.bold('Attention')}: ${this.name} now collects completely anonymous telemetry regarding usage.`);
135
+ console.log();
136
+ }
137
+ _oneWayHash(payload) {
138
+ const hash = (0, crypto_1.createHash)('sha256');
139
+ // Always prepend the payload value with salt. This ensures the hash is truly
140
+ // one-way.
141
+ hash.update(this.salt);
142
+ // Update is an append operation, not a replacement. The salt from the prior
143
+ // update is still present!
144
+ hash.update(payload);
145
+ return hash.digest('hex');
146
+ }
147
+ _submitRecord(_events) {
148
+ let events;
149
+ if (Array.isArray(_events)) {
150
+ events = _events;
151
+ }
152
+ else {
153
+ events = [_events];
154
+ }
155
+ if (events.length < 1) {
156
+ return Promise.resolve();
157
+ }
158
+ if (!this.postEndpoint) {
159
+ return Promise.resolve();
160
+ }
161
+ return (0, post_payload_1._postPayload)(this.postEndpoint, {
162
+ context: this.context,
163
+ meta: this.meta,
164
+ events: events.map(({ eventName, payload }) => ({
165
+ eventName,
166
+ fields: payload
167
+ }))
168
+ });
169
+ }
170
+ }
171
+ exports.Telemetry = Telemetry;
@@ -0,0 +1,11 @@
1
+ import type { Reporter } from '@shuvi/shared/reporter';
2
+ export declare class ToJson {
3
+ private phase;
4
+ private buildDir;
5
+ private traceId;
6
+ private writeStream;
7
+ private batch;
8
+ constructor(phase: string, buildDir: string, traceId: string);
9
+ flushAll: () => void;
10
+ report: Reporter;
11
+ }
package/lib/to-json.js ADDED
@@ -0,0 +1,150 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ToJson = void 0;
16
+ const crypto_1 = require("crypto");
17
+ const fs_1 = __importDefault(require("fs"));
18
+ const path_1 = __importDefault(require("path"));
19
+ // Batch events as zipkin allows for multiple events to be sent in one go
20
+ function batcher(reportEvents) {
21
+ const events = [];
22
+ // Promise queue to ensure events are always sent on flushAll
23
+ const queue = new Set();
24
+ return {
25
+ flushAll: () => __awaiter(this, void 0, void 0, function* () {
26
+ yield Promise.all(queue);
27
+ if (events.length > 0) {
28
+ yield reportEvents(events);
29
+ events.length = 0;
30
+ }
31
+ }),
32
+ report: (event) => {
33
+ events.push(event);
34
+ if (events.length > 100) {
35
+ const evts = events.slice();
36
+ events.length = 0;
37
+ const report = reportEvents(evts);
38
+ queue.add(report);
39
+ report.then(() => queue.delete(report));
40
+ }
41
+ }
42
+ };
43
+ }
44
+ const writeStreamOptions = {
45
+ flags: 'a',
46
+ encoding: 'utf8'
47
+ };
48
+ class RotatingWriteStream {
49
+ constructor(file, sizeLimit) {
50
+ this.file = file;
51
+ this.size = 0;
52
+ this.sizeLimit = sizeLimit;
53
+ this.createWriteStream();
54
+ }
55
+ createWriteStream() {
56
+ this.writeStream = fs_1.default.createWriteStream(this.file, writeStreamOptions);
57
+ }
58
+ // Recreate the file
59
+ rotate() {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ yield this.end();
62
+ try {
63
+ fs_1.default.unlinkSync(this.file);
64
+ }
65
+ catch (err) {
66
+ // It's fine if the file does not exist yet
67
+ if (err.code !== 'ENOENT') {
68
+ throw err;
69
+ }
70
+ }
71
+ this.size = 0;
72
+ this.createWriteStream();
73
+ this.rotatePromise = undefined;
74
+ });
75
+ }
76
+ write(data) {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ if (this.rotatePromise)
79
+ yield this.rotatePromise;
80
+ this.size += data.length;
81
+ if (this.size > this.sizeLimit) {
82
+ yield (this.rotatePromise = this.rotate());
83
+ }
84
+ if (!this.writeStream.write(data, 'utf8')) {
85
+ if (this.drainPromise === undefined) {
86
+ this.drainPromise = new Promise((resolve, _reject) => {
87
+ this.writeStream.once('drain', () => {
88
+ this.drainPromise = undefined;
89
+ resolve();
90
+ });
91
+ });
92
+ }
93
+ yield this.drainPromise;
94
+ }
95
+ });
96
+ }
97
+ end() {
98
+ return new Promise(resolve => {
99
+ this.writeStream.end(resolve);
100
+ });
101
+ }
102
+ }
103
+ class ToJson {
104
+ constructor(phase, buildDir, traceId) {
105
+ this.flushAll = () => {
106
+ this.batch.flushAll().then(() => {
107
+ var _a;
108
+ // Only end writeStream when manually flushing in production
109
+ if (this.phase !== 'PHASE_DEVELOPMENT_SERVER') {
110
+ (_a = this.writeStream) === null || _a === void 0 ? void 0 : _a.end();
111
+ }
112
+ });
113
+ };
114
+ this.report = ({ timestamp, name, duration, startTime, id, parentId, attrs }) => {
115
+ if (!this.buildDir || !this.phase) {
116
+ return;
117
+ }
118
+ this.batch.report({
119
+ traceId: this.traceId,
120
+ parentId,
121
+ name,
122
+ id,
123
+ startTime,
124
+ duration,
125
+ timestamp,
126
+ tags: attrs
127
+ });
128
+ };
129
+ this.phase = phase;
130
+ this.buildDir = buildDir;
131
+ this.traceId = traceId || (0, crypto_1.randomBytes)(8).toString('hex');
132
+ this.batch = batcher((events) => __awaiter(this, void 0, void 0, function* () {
133
+ if (!this.writeStream) {
134
+ yield fs_1.default.promises.mkdir(this.buildDir, { recursive: true });
135
+ const file = path_1.default.join(this.buildDir, 'trace');
136
+ this.writeStream = new RotatingWriteStream(file,
137
+ // Development is limited to 50MB, production is unlimited
138
+ this.phase === 'PHASE_DEVELOPMENT_SERVER' ? 52428800 : Infinity);
139
+ }
140
+ const eventsJson = JSON.stringify(events);
141
+ try {
142
+ yield this.writeStream.write(eventsJson + '\n');
143
+ }
144
+ catch (err) {
145
+ console.log(err);
146
+ }
147
+ }));
148
+ }
149
+ }
150
+ exports.ToJson = ToJson;
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@shuvi/reporters",
3
+ "version": "1.0.30",
4
+ "author": "liximomo",
5
+ "license": "MIT",
6
+ "main": "lib/index.js",
7
+ "files": [
8
+ "lib"
9
+ ],
10
+ "scripts": {
11
+ "dev": "tsc -p tsconfig.build.json -m commonjs -w",
12
+ "prebuild": "rimraf lib",
13
+ "build": "tsc -p tsconfig.build.json -m commonjs"
14
+ },
15
+ "dependencies": {
16
+ "@shuvi/shared": "1.0.30",
17
+ "@shuvi/utils": "1.0.30",
18
+ "conf": "5.0.0",
19
+ "is-docker": "2.0.0",
20
+ "is-wsl": "2.2.0",
21
+ "ci-info": "3.6.2",
22
+ "async-retry": "1.3.3",
23
+ "node-fetch": "2.6.7"
24
+ },
25
+ "devDependencies": {
26
+ "@types/async-retry": "1.3.0",
27
+ "@types/node-fetch": "2.6.1"
28
+ },
29
+ "engines": {
30
+ "node": ">=12.0.0"
31
+ }
32
+ }