build-strap 4.0.0-dev.46 → 4.0.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.
- package/README.md +3 -34
- package/dist/src/ant.d.ts +19 -0
- package/dist/src/ant.js +18 -0
- package/dist/src/cert.d.ts +12 -0
- package/dist/src/cert.js +91 -0
- package/dist/src/clean.d.ts +4 -0
- package/dist/src/clean.js +11 -0
- package/dist/src/copy.d.ts +7 -0
- package/dist/src/copy.js +53 -0
- package/dist/src/cp.d.ts +17 -0
- package/dist/src/cp.js +88 -0
- package/dist/src/docker.container.d.ts +73 -0
- package/dist/src/docker.container.js +247 -0
- package/dist/src/docker.d.ts +68 -0
- package/dist/src/docker.js +188 -0
- package/dist/src/docker.network.d.ts +42 -0
- package/dist/src/docker.network.js +85 -0
- package/dist/src/docker.volume.d.ts +26 -0
- package/dist/src/docker.volume.js +62 -0
- package/dist/src/dockerCleanup.d.ts +38 -0
- package/dist/src/dockerCleanup.js +77 -0
- package/dist/src/dockerCompose.d.ts +154 -0
- package/dist/src/dockerCompose.js +439 -0
- package/dist/src/fs.d.ts +5 -0
- package/dist/src/fs.js +38 -0
- package/dist/src/git.d.ts +9 -0
- package/dist/src/git.js +24 -0
- package/dist/src/index.d.ts +20 -0
- package/dist/src/index.js +20 -0
- package/dist/src/maps.d.ts +33 -0
- package/dist/src/maps.js +41 -0
- package/dist/src/npm.d.ts +35 -0
- package/dist/src/npm.js +104 -0
- package/dist/src/pkg.d.ts +33 -0
- package/dist/src/pkg.js +33 -0
- package/dist/src/publish.d.ts +27 -0
- package/dist/src/publish.js +57 -0
- package/dist/src/run.d.ts +13 -0
- package/dist/src/run.js +44 -0
- package/dist/src/tgz.d.ts +13 -0
- package/dist/src/tgz.js +67 -0
- package/dist/src/version.d.ts +34 -0
- package/dist/src/version.js +101 -0
- package/dist/src/yarn.d.ts +26 -0
- package/dist/src/yarn.js +75 -0
- package/package.json +74 -20
- package/ant.js +0 -43
- package/ant.js.flow +0 -42
- package/artifactory.js +0 -617
- package/artifactory.js.flow +0 -616
- package/cert.conf +0 -20
- package/cert.js +0 -153
- package/cert.js.flow +0 -152
- package/clean.js +0 -20
- package/clean.js.flow +0 -19
- package/copy.js +0 -80
- package/copy.js.flow +0 -79
- package/cp.js +0 -173
- package/cp.js.flow +0 -172
- package/docker.container.js +0 -390
- package/docker.container.js.flow +0 -389
- package/docker.js +0 -365
- package/docker.js.flow +0 -364
- package/docker.network.js +0 -160
- package/docker.network.js.flow +0 -159
- package/docker.volume.js +0 -136
- package/docker.volume.js.flow +0 -136
- package/dockerCleanup.js +0 -152
- package/dockerCleanup.js.flow +0 -151
- package/dockerCompose.js +0 -766
- package/dockerCompose.js.flow +0 -765
- package/flow.js +0 -21
- package/flow.js.flow +0 -20
- package/fs.js +0 -95
- package/fs.js.flow +0 -96
- package/git.js +0 -35
- package/git.js.flow +0 -34
- package/hg.js +0 -35
- package/hg.js.flow +0 -34
- package/index.js +0 -27
- package/index.js.flow +0 -26
- package/inline-resources.js +0 -158
- package/inline-resources.js.flow +0 -157
- package/maps.js +0 -112
- package/maps.js.flow +0 -111
- package/npm.js +0 -145
- package/npm.js.flow +0 -144
- package/pkg.js +0 -81
- package/pkg.js.flow +0 -80
- package/publish.js +0 -145
- package/publish.js.flow +0 -144
- package/run.js +0 -90
- package/run.js.flow +0 -89
- package/src/ant.js +0 -42
- package/src/artifactory.js +0 -616
- package/src/cert.conf +0 -20
- package/src/cert.js +0 -152
- package/src/clean.js +0 -19
- package/src/copy.js +0 -79
- package/src/cp.js +0 -172
- package/src/docker.container.js +0 -389
- package/src/docker.js +0 -364
- package/src/docker.network.js +0 -159
- package/src/docker.volume.js +0 -136
- package/src/dockerCleanup.js +0 -151
- package/src/dockerCompose.js +0 -765
- package/src/flow.js +0 -20
- package/src/fs.js +0 -96
- package/src/git.js +0 -34
- package/src/hg.js +0 -34
- package/src/index.js +0 -26
- package/src/inline-resources.js +0 -157
- package/src/maps.js +0 -111
- package/src/npm.js +0 -144
- package/src/pkg.js +0 -80
- package/src/publish.js +0 -144
- package/src/run.js +0 -89
- package/src/test.js +0 -55
- package/src/tgz.js +0 -101
- package/src/version.js +0 -142
- package/src/yarn.js +0 -123
- package/test.js +0 -56
- package/test.js.flow +0 -55
- package/tgz.js +0 -102
- package/tgz.js.flow +0 -101
- package/version.js +0 -143
- package/version.js.flow +0 -142
- package/yarn.js +0 -124
- package/yarn.js.flow +0 -123
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _DockerComposeService_name, _DockerComposeService_svcDef, _DockerComposeService_dockerCompose, _DockerComposeService_tracker, _DockerComposeService_parsedPorts, _DockerComposeService_parsedNetworks, _DockerComposeService_parsedVolumes, _DockerComposeService_baseRunArgs;
|
|
13
|
+
import fs from 'fs-extra';
|
|
14
|
+
import getPort from 'get-port';
|
|
15
|
+
import yaml from 'js-yaml';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import { dockerContainerFind, dockerContainerRunDaemon, } from './docker.container.js';
|
|
18
|
+
import { dockerPull } from './docker.js';
|
|
19
|
+
import { dockerNetworkCreate, dockerNetworkDelete, } from './docker.network.js';
|
|
20
|
+
import { dockerVolumeCreate, dockerVolumeRm, } from './docker.volume.js';
|
|
21
|
+
import { mapValuesAsync } from './maps.js';
|
|
22
|
+
import { buildLog } from './run.js';
|
|
23
|
+
export const dockerComposeCreateResourceTracker = () => ({
|
|
24
|
+
cleaning: null,
|
|
25
|
+
containers: new Map(),
|
|
26
|
+
networks: new Map(),
|
|
27
|
+
services: new Map(),
|
|
28
|
+
volumes: new Map(),
|
|
29
|
+
});
|
|
30
|
+
const defaultTracker = dockerComposeCreateResourceTracker();
|
|
31
|
+
/**
|
|
32
|
+
* Parse a docker-compose.yml file into a pojo representation
|
|
33
|
+
* @param {string} filePath Path to the docker-compose.yml file
|
|
34
|
+
*/
|
|
35
|
+
export const dockerComposeParse = async (filePath = './docker-compose.yml') => yaml.load(await fs.readFile(filePath, 'utf8'));
|
|
36
|
+
let dc = null;
|
|
37
|
+
/**
|
|
38
|
+
* Get the main docker-compose.yml from the root of the repo
|
|
39
|
+
* @param {boolean} force Force reload from file
|
|
40
|
+
*/
|
|
41
|
+
export const dockerComposeGetMain = async (force = false) => {
|
|
42
|
+
if (force || !dc) {
|
|
43
|
+
dc = await dockerComposeParse();
|
|
44
|
+
}
|
|
45
|
+
return dc;
|
|
46
|
+
};
|
|
47
|
+
// Function that handles passed dockerCompose as either a file path or `DockerCompose` object.
|
|
48
|
+
// If not passed, defaults to the main docker-compose.yml from the root of the repo
|
|
49
|
+
const dockerComposeResolve = async (dockerCompose, force) => typeof dockerCompose === 'string'
|
|
50
|
+
? dockerComposeParse(dockerCompose)
|
|
51
|
+
: dockerCompose || dockerComposeGetMain(force);
|
|
52
|
+
// Determines an unnamed resource's name from the dirname combined with the key
|
|
53
|
+
const prefixName = (name) => `${path.basename(__dirname)}_${name}`;
|
|
54
|
+
const getServiceDef = async (name, force, dockerCompose) => (await dockerComposeResolve(dockerCompose, force)).services?.[name] || null;
|
|
55
|
+
const parsePorts = async (portsCfg = [], avoidConflicts = true, mapLocal = true, host = '0.0.0.0') => {
|
|
56
|
+
const ports = [];
|
|
57
|
+
const runArgs = await portsCfg.reduce(async (args, portStr) => {
|
|
58
|
+
const [lp, dp] = portStr.split(':');
|
|
59
|
+
const localDefault = parseInt(lp, 10);
|
|
60
|
+
const docker = parseInt(dp, 10);
|
|
61
|
+
const local = mapLocal
|
|
62
|
+
? avoidConflicts
|
|
63
|
+
? await getPort({ host, port: localDefault })
|
|
64
|
+
: localDefault
|
|
65
|
+
: null;
|
|
66
|
+
ports.push({ docker, local, localDefault });
|
|
67
|
+
return local ? [...(await args), '-p', `${local}:${docker}`] : args;
|
|
68
|
+
}, Promise.resolve([]));
|
|
69
|
+
return { ports, runArgs };
|
|
70
|
+
};
|
|
71
|
+
const parseEnv = (env = []) => Array.isArray(env)
|
|
72
|
+
? env.flatMap((e) => ['-e', e])
|
|
73
|
+
: Object.entries(env).flatMap(([k, v]) => ['-e', `${k}=${v}`]);
|
|
74
|
+
const parseULimits = (ul = {}) => Object.entries(ul).flatMap(([k, v]) => [
|
|
75
|
+
'--ulimit',
|
|
76
|
+
`${k}=${typeof v === 'number' ? v : `${v.soft}${v.hard ? `:${v.hard}` : ''}`}`,
|
|
77
|
+
]);
|
|
78
|
+
const parseVolumes = async (volCfg = [], nameSuffix = '', dockerCompose = null) => {
|
|
79
|
+
const { volumes: volMap } = await dockerComposeResolve(dockerCompose);
|
|
80
|
+
const volumes = [];
|
|
81
|
+
const runArgs = volCfg
|
|
82
|
+
.map((v) => {
|
|
83
|
+
const [src, ...rest] = v.split(':');
|
|
84
|
+
const name = volMap?.[src]
|
|
85
|
+
? `${volMap[src].name || prefixName(src)}${nameSuffix}`
|
|
86
|
+
: null;
|
|
87
|
+
if (name) {
|
|
88
|
+
volumes.push(name);
|
|
89
|
+
}
|
|
90
|
+
const realSrc = name || path.resolve(src);
|
|
91
|
+
return [realSrc, ...rest].join(':');
|
|
92
|
+
})
|
|
93
|
+
.flatMap((v) => ['-v', v]);
|
|
94
|
+
return { runArgs, volumes };
|
|
95
|
+
};
|
|
96
|
+
const parseNetworks = async (netCfg = [], dockerCompose = null) => {
|
|
97
|
+
const { networks: netMap } = await dockerComposeResolve(dockerCompose);
|
|
98
|
+
const networks = netCfg.map((n) => netMap?.[n].name || prefixName(n));
|
|
99
|
+
return {
|
|
100
|
+
networks,
|
|
101
|
+
runArgs: networks.flatMap((n) => ['--network', n]),
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
export const dockerComposeCreateNetworks = async (names, dockerCompose, tracker = defaultTracker) => {
|
|
105
|
+
const { networks = {} } = await dockerComposeResolve(dockerCompose);
|
|
106
|
+
await Promise.all(Object.entries(networks).map(async ([key, val]) => {
|
|
107
|
+
const name = val?.name || prefixName(key);
|
|
108
|
+
if (names?.includes(name)) {
|
|
109
|
+
const network = await dockerNetworkCreate(name, val);
|
|
110
|
+
if (network) {
|
|
111
|
+
tracker.networks.set(name, network);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}));
|
|
115
|
+
};
|
|
116
|
+
export const dockerComposeCreateVolumes = async (names, dockerCompose, tracker = defaultTracker) => {
|
|
117
|
+
const { volumes = {} } = await dockerComposeResolve(dockerCompose);
|
|
118
|
+
await Promise.all(Object.entries(volumes).map(async ([key, val]) => {
|
|
119
|
+
const name = val?.name || prefixName(key);
|
|
120
|
+
if (!names || names.includes(name)) {
|
|
121
|
+
const volume = await dockerVolumeCreate(name, val);
|
|
122
|
+
if (volume) {
|
|
123
|
+
tracker.volumes.set(name, volume);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
127
|
+
};
|
|
128
|
+
export class DockerComposeService {
|
|
129
|
+
constructor(name, serviceDef, dockerCompose) {
|
|
130
|
+
_DockerComposeService_name.set(this, void 0);
|
|
131
|
+
_DockerComposeService_svcDef.set(this, void 0);
|
|
132
|
+
_DockerComposeService_dockerCompose.set(this, void 0);
|
|
133
|
+
_DockerComposeService_tracker.set(this, dockerComposeCreateResourceTracker());
|
|
134
|
+
// lazily computed
|
|
135
|
+
_DockerComposeService_parsedPorts.set(this, null);
|
|
136
|
+
_DockerComposeService_parsedNetworks.set(this, null);
|
|
137
|
+
_DockerComposeService_parsedVolumes.set(this, null);
|
|
138
|
+
_DockerComposeService_baseRunArgs.set(this, null);
|
|
139
|
+
__classPrivateFieldSet(this, _DockerComposeService_name, name, "f");
|
|
140
|
+
__classPrivateFieldSet(this, _DockerComposeService_svcDef, serviceDef, "f");
|
|
141
|
+
__classPrivateFieldSet(this, _DockerComposeService_dockerCompose, dockerCompose || null, "f");
|
|
142
|
+
}
|
|
143
|
+
get name() {
|
|
144
|
+
return __classPrivateFieldGet(this, _DockerComposeService_name, "f");
|
|
145
|
+
}
|
|
146
|
+
get serviceDef() {
|
|
147
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f");
|
|
148
|
+
}
|
|
149
|
+
get image() {
|
|
150
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").image || null;
|
|
151
|
+
}
|
|
152
|
+
get defaultContainerName() {
|
|
153
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").container_name || __classPrivateFieldGet(this, _DockerComposeService_name, "f");
|
|
154
|
+
}
|
|
155
|
+
get cmd() {
|
|
156
|
+
return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").command || [];
|
|
157
|
+
}
|
|
158
|
+
get envArgs() {
|
|
159
|
+
return parseEnv(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").environment);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Find (available) container name and alias(es)
|
|
163
|
+
* @param {boolean} avoidConflicts if `true`, find a container name that is unused
|
|
164
|
+
* @param {number} max maximum number of names to try
|
|
165
|
+
*/
|
|
166
|
+
async getNames(avoidConflicts = false, max = 100) {
|
|
167
|
+
/* eslint-disable no-await-in-loop */
|
|
168
|
+
for (let i = 0; i < max; i += 1) {
|
|
169
|
+
const suffix = i ? `-${i}` : '';
|
|
170
|
+
const testName = `${this.defaultContainerName}${suffix}`;
|
|
171
|
+
const container = await dockerContainerFind(testName, { all: true });
|
|
172
|
+
if (!avoidConflicts || !container) {
|
|
173
|
+
return {
|
|
174
|
+
aliases: [`${this.name}${suffix}`],
|
|
175
|
+
name: testName,
|
|
176
|
+
suffix,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/* eslint-enable no-await-in-loop */
|
|
181
|
+
throw new Error(`Failed to find available container name for ${this.defaultContainerName}`);
|
|
182
|
+
}
|
|
183
|
+
// Get (available) port mappings
|
|
184
|
+
async getPorts(avoidConflicts = false, mapLocal = true) {
|
|
185
|
+
return parsePorts(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").ports, avoidConflicts, mapLocal);
|
|
186
|
+
}
|
|
187
|
+
async getDefaultPortInfo() {
|
|
188
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_parsedPorts, "f")) {
|
|
189
|
+
__classPrivateFieldSet(this, _DockerComposeService_parsedPorts, await this.getPorts(), "f");
|
|
190
|
+
}
|
|
191
|
+
return __classPrivateFieldGet(this, _DockerComposeService_parsedPorts, "f");
|
|
192
|
+
}
|
|
193
|
+
async getDefaultPorts() {
|
|
194
|
+
const { ports } = await this.getDefaultPortInfo();
|
|
195
|
+
return ports;
|
|
196
|
+
}
|
|
197
|
+
async getDefaultPortArgs() {
|
|
198
|
+
const { runArgs } = await this.getDefaultPortInfo();
|
|
199
|
+
return runArgs;
|
|
200
|
+
}
|
|
201
|
+
async getDefaultUrls() {
|
|
202
|
+
return DockerComposeService.getUrls(await this.getDefaultPorts(), this.defaultContainerName);
|
|
203
|
+
}
|
|
204
|
+
async getDefaultNetworkInfo() {
|
|
205
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_parsedNetworks, "f")) {
|
|
206
|
+
__classPrivateFieldSet(this, _DockerComposeService_parsedNetworks, await parseNetworks(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").networks), "f");
|
|
207
|
+
}
|
|
208
|
+
return __classPrivateFieldGet(this, _DockerComposeService_parsedNetworks, "f");
|
|
209
|
+
}
|
|
210
|
+
async getDefaultNetworks() {
|
|
211
|
+
const { networks } = await this.getDefaultNetworkInfo();
|
|
212
|
+
return networks;
|
|
213
|
+
}
|
|
214
|
+
async getDefaultNetworkArgs() {
|
|
215
|
+
const { runArgs } = await this.getDefaultNetworkInfo();
|
|
216
|
+
return runArgs;
|
|
217
|
+
}
|
|
218
|
+
async getDefaultVolumeInfo() {
|
|
219
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_parsedVolumes, "f")) {
|
|
220
|
+
__classPrivateFieldSet(this, _DockerComposeService_parsedVolumes, await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").networks), "f");
|
|
221
|
+
}
|
|
222
|
+
return __classPrivateFieldGet(this, _DockerComposeService_parsedVolumes, "f");
|
|
223
|
+
}
|
|
224
|
+
async getDefaultVolumes() {
|
|
225
|
+
const { volumes } = await this.getDefaultVolumeInfo();
|
|
226
|
+
return volumes;
|
|
227
|
+
}
|
|
228
|
+
async getDefaultVolumeArgs() {
|
|
229
|
+
const { runArgs } = await this.getDefaultVolumeInfo();
|
|
230
|
+
return runArgs;
|
|
231
|
+
}
|
|
232
|
+
async pull() {
|
|
233
|
+
if (!this.image) {
|
|
234
|
+
throw new Error(`Cannot pull '${this.name}', no image configured.`);
|
|
235
|
+
}
|
|
236
|
+
await dockerPull({ image: this.image });
|
|
237
|
+
}
|
|
238
|
+
async getBaseRunArgs() {
|
|
239
|
+
if (!__classPrivateFieldGet(this, _DockerComposeService_baseRunArgs, "f")) {
|
|
240
|
+
const envArgs = parseEnv(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").environment);
|
|
241
|
+
const ulArgs = parseULimits(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").ulimits);
|
|
242
|
+
const netArgs = await this.getDefaultNetworkArgs();
|
|
243
|
+
__classPrivateFieldSet(this, _DockerComposeService_baseRunArgs, ['--rm', ...envArgs, ...netArgs, ...ulArgs], "f");
|
|
244
|
+
}
|
|
245
|
+
return __classPrivateFieldGet(this, _DockerComposeService_baseRunArgs, "f");
|
|
246
|
+
}
|
|
247
|
+
async assembleRunArgs(containerName = this.defaultContainerName, aliases = [this.name], additionalArgs = null) {
|
|
248
|
+
const additional = additionalArgs || [
|
|
249
|
+
...(await this.getDefaultPortArgs()),
|
|
250
|
+
...(await this.getDefaultVolumeArgs()),
|
|
251
|
+
];
|
|
252
|
+
return [
|
|
253
|
+
...(await this.getBaseRunArgs()),
|
|
254
|
+
...(containerName ? ['--name', containerName] : []),
|
|
255
|
+
...aliases.flatMap((a) => (a ? ['--network-alias', a] : [])),
|
|
256
|
+
...additional,
|
|
257
|
+
];
|
|
258
|
+
}
|
|
259
|
+
async getRunArgs(avoidConflicts = false, mapLocalPorts = true) {
|
|
260
|
+
const { aliases, name: cName, suffix, } = await this.getNames(avoidConflicts);
|
|
261
|
+
const { runArgs: pArgs } = await this.getPorts(avoidConflicts, mapLocalPorts);
|
|
262
|
+
const { runArgs: vArgs } = await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").volumes, suffix);
|
|
263
|
+
return this.assembleRunArgs(cName, aliases, [...pArgs, ...vArgs]);
|
|
264
|
+
}
|
|
265
|
+
async up({ healthCheck, avoidConflicts = false, mapVolumes = true, mapPorts = true, cmd = this.cmd, tracker = defaultTracker, } = {}) {
|
|
266
|
+
const { image } = this;
|
|
267
|
+
if (!image) {
|
|
268
|
+
throw new Error(`Cannot bring up service '${this.name}', no image defined.`);
|
|
269
|
+
}
|
|
270
|
+
if (__classPrivateFieldGet(this, _DockerComposeService_tracker, "f").containers.size) {
|
|
271
|
+
buildLog(`Warning: up called on service '${this.name}' with already running container`);
|
|
272
|
+
}
|
|
273
|
+
const { aliases, name: containerName, suffix, } = await this.getNames(avoidConflicts);
|
|
274
|
+
const { ports, runArgs: pArgs } = await this.getPorts(avoidConflicts, mapPorts);
|
|
275
|
+
const { runArgs: vArgs, volumes } = mapVolumes
|
|
276
|
+
? await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").volumes, suffix)
|
|
277
|
+
: { runArgs: [], volumes: [] };
|
|
278
|
+
let container = await dockerContainerFind(containerName, { all: true });
|
|
279
|
+
if (container && !(await container.isRunning())) {
|
|
280
|
+
await container.start();
|
|
281
|
+
}
|
|
282
|
+
if (!container) {
|
|
283
|
+
await this.pull();
|
|
284
|
+
await dockerComposeCreateNetworks(await this.getDefaultNetworks(), __classPrivateFieldGet(this, _DockerComposeService_dockerCompose, "f"), __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"));
|
|
285
|
+
await dockerComposeCreateVolumes(volumes, __classPrivateFieldGet(this, _DockerComposeService_dockerCompose, "f"), __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"));
|
|
286
|
+
const runArgs = await this.assembleRunArgs(containerName, aliases, [
|
|
287
|
+
...pArgs,
|
|
288
|
+
...vArgs,
|
|
289
|
+
]);
|
|
290
|
+
container = await dockerContainerRunDaemon({
|
|
291
|
+
cmd,
|
|
292
|
+
image,
|
|
293
|
+
runArgs,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
buildLog(`Reusing existing container for '${this.name}' service.`);
|
|
298
|
+
}
|
|
299
|
+
// This service tracks the things it created
|
|
300
|
+
__classPrivateFieldGet(this, _DockerComposeService_tracker, "f").containers.set(containerName, container);
|
|
301
|
+
// The passed tracker needs to track this service
|
|
302
|
+
tracker.services.set(this.name, this);
|
|
303
|
+
const idAlias = container.id.slice(0, 12);
|
|
304
|
+
aliases.push(idAlias);
|
|
305
|
+
const urls = DockerComposeService.getUrls(ports, idAlias);
|
|
306
|
+
const info = {
|
|
307
|
+
aliases,
|
|
308
|
+
container,
|
|
309
|
+
containerName,
|
|
310
|
+
ports,
|
|
311
|
+
service: this,
|
|
312
|
+
urls,
|
|
313
|
+
volumes,
|
|
314
|
+
};
|
|
315
|
+
await healthCheck?.(info);
|
|
316
|
+
return info;
|
|
317
|
+
}
|
|
318
|
+
async down({ includeDefaults = false, includeNetworks = false, includeVolumes = false, } = {}) {
|
|
319
|
+
buildLog(`Bringing down <${this.name}> service...`);
|
|
320
|
+
await dockerComposeTeardown({
|
|
321
|
+
includeNetworks,
|
|
322
|
+
includeVolumes,
|
|
323
|
+
tracker: __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"),
|
|
324
|
+
});
|
|
325
|
+
if (includeDefaults) {
|
|
326
|
+
const container = await dockerContainerFind(this.defaultContainerName);
|
|
327
|
+
if (container) {
|
|
328
|
+
await container.teardown(true);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
static async parse(name, force = true, dockerCompose = null) {
|
|
333
|
+
const svcDef = await getServiceDef(name, force, dockerCompose);
|
|
334
|
+
return svcDef ? new this(name, svcDef, dockerCompose) : null;
|
|
335
|
+
}
|
|
336
|
+
static getUrls(ports, alias) {
|
|
337
|
+
return ports.map(({ docker, local }) => ({
|
|
338
|
+
docker: docker ? `http://${alias}:${docker}` : null,
|
|
339
|
+
local: local ? `http://localhost:${local}` : null,
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
_DockerComposeService_name = new WeakMap(), _DockerComposeService_svcDef = new WeakMap(), _DockerComposeService_dockerCompose = new WeakMap(), _DockerComposeService_tracker = new WeakMap(), _DockerComposeService_parsedPorts = new WeakMap(), _DockerComposeService_parsedNetworks = new WeakMap(), _DockerComposeService_parsedVolumes = new WeakMap(), _DockerComposeService_baseRunArgs = new WeakMap();
|
|
344
|
+
export async function dockerComposeGetAllServices(dockerCompose) {
|
|
345
|
+
const { services } = await dockerComposeResolve(dockerCompose);
|
|
346
|
+
return mapValuesAsync(services, (s, name) => DockerComposeService.parse(name));
|
|
347
|
+
}
|
|
348
|
+
export async function dockerComposeTeardown({ includeDefaults = false, includeVolumes = false, includeNetworks = false, dockerCompose, tracker = defaultTracker, } = {}) {
|
|
349
|
+
if (!tracker.cleaning) {
|
|
350
|
+
// eslint-disable-next-line no-param-reassign
|
|
351
|
+
tracker.cleaning = (async () => {
|
|
352
|
+
if (tracker.services.size) {
|
|
353
|
+
buildLog('Bringing down started docker services...');
|
|
354
|
+
const promises = Promise.all(Array.from(tracker.services.values()).map(async (s) => s.down({ includeNetworks, includeVolumes })));
|
|
355
|
+
tracker.services.clear();
|
|
356
|
+
await promises;
|
|
357
|
+
}
|
|
358
|
+
if (includeDefaults) {
|
|
359
|
+
const { services } = await dockerComposeResolve(dockerCompose);
|
|
360
|
+
const svcNames = Object.keys(services ?? {});
|
|
361
|
+
if (svcNames.length) {
|
|
362
|
+
buildLog('Bringing down default docker services...');
|
|
363
|
+
await Promise.all(svcNames.map(async (s) => (await DockerComposeService.parse(s))?.down({
|
|
364
|
+
includeDefaults,
|
|
365
|
+
includeNetworks,
|
|
366
|
+
includeVolumes,
|
|
367
|
+
})));
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (tracker.containers.size) {
|
|
371
|
+
buildLog('Stopping created docker containers...');
|
|
372
|
+
const promises = Promise.all(Array.from(tracker.containers.values()).map(async (c) => c.teardown(true)));
|
|
373
|
+
tracker.containers.clear();
|
|
374
|
+
await promises;
|
|
375
|
+
}
|
|
376
|
+
if (includeVolumes) {
|
|
377
|
+
if (tracker.volumes.size) {
|
|
378
|
+
buildLog('Removing created docker volumes...');
|
|
379
|
+
const promises = Promise.all(Array.from(tracker.volumes.values()).map(async (v) => v.rm()));
|
|
380
|
+
tracker.volumes.clear();
|
|
381
|
+
await promises;
|
|
382
|
+
}
|
|
383
|
+
if (includeDefaults) {
|
|
384
|
+
buildLog('Removing default docker volumes...');
|
|
385
|
+
const { volumes } = await dockerComposeResolve(dockerCompose);
|
|
386
|
+
await Promise.all(Object.entries(volumes ?? {}).map(async ([key, val]) => {
|
|
387
|
+
const name = val?.name || prefixName(key);
|
|
388
|
+
await dockerVolumeRm(name, true);
|
|
389
|
+
}));
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (includeNetworks) {
|
|
393
|
+
if (tracker.networks.size) {
|
|
394
|
+
buildLog('Removing created docker networks...');
|
|
395
|
+
const promises = Promise.all(Array.from(tracker.networks.values()).map(async (n) => n.rm()));
|
|
396
|
+
tracker.networks.clear();
|
|
397
|
+
await promises;
|
|
398
|
+
}
|
|
399
|
+
if (includeDefaults) {
|
|
400
|
+
buildLog('Removing default docker networks...');
|
|
401
|
+
const { networks } = await dockerComposeResolve(dockerCompose);
|
|
402
|
+
await Promise.all(Object.entries(networks ?? {}).map(async ([key, val]) => {
|
|
403
|
+
const name = val?.name || prefixName(key);
|
|
404
|
+
try {
|
|
405
|
+
await dockerNetworkDelete(name);
|
|
406
|
+
}
|
|
407
|
+
catch (err) {
|
|
408
|
+
buildLog(`Error deleting network '${name}': ${err.message}`);
|
|
409
|
+
}
|
|
410
|
+
}));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// eslint-disable-next-line no-param-reassign
|
|
414
|
+
tracker.cleaning = null;
|
|
415
|
+
})();
|
|
416
|
+
}
|
|
417
|
+
return tracker.cleaning;
|
|
418
|
+
}
|
|
419
|
+
export async function dockerComposeRunService(key, upOptions = {}, dockerCompose = null) {
|
|
420
|
+
const service = await DockerComposeService.parse(key, false, dockerCompose);
|
|
421
|
+
if (!service) {
|
|
422
|
+
throw new Error(`Failed to find service '${key}'`);
|
|
423
|
+
}
|
|
424
|
+
buildLog(`Starting <${service.name}> service...`);
|
|
425
|
+
const upResult = await service.up(upOptions);
|
|
426
|
+
const { container, urls, urls: [{ docker: dockerUrl, local: url }], ports: [{ docker: dockerPort, local: port }], } = upResult;
|
|
427
|
+
const { id, image, name } = container;
|
|
428
|
+
urls.forEach(({ local }) => local && buildLog(`<${service.name}> accessible at ${local}`));
|
|
429
|
+
return {
|
|
430
|
+
...upResult,
|
|
431
|
+
dockerPort,
|
|
432
|
+
dockerUrl,
|
|
433
|
+
id,
|
|
434
|
+
image,
|
|
435
|
+
name,
|
|
436
|
+
port,
|
|
437
|
+
url,
|
|
438
|
+
};
|
|
439
|
+
}
|
package/dist/src/fs.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import glob from 'glob';
|
|
2
|
+
export declare const readDir: (pattern: string, options?: glob.IOptions | undefined) => Promise<string[]>;
|
|
3
|
+
export declare const moveDir: (source: string, target: string) => Promise<void>;
|
|
4
|
+
export declare const copyDir: (source: string, target: string, fileGlob?: string, globOptions?: null | glob.IOptions, renameFn?: (name: string) => string) => Promise<void>;
|
|
5
|
+
export declare const cleanDir: (pattern: string, globOptions?: false | glob.IOptions | undefined) => Promise<void>;
|
package/dist/src/fs.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import glob from 'glob';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import rimraf from 'rimraf';
|
|
5
|
+
export const readDir = async (pattern, options) => new Promise((resolve, reject) => {
|
|
6
|
+
glob(pattern, options || {}, (err, result) => err ? reject(err) : resolve(result));
|
|
7
|
+
});
|
|
8
|
+
export const moveDir = async (source, target) => {
|
|
9
|
+
const dirs = await readDir('**/*.*', {
|
|
10
|
+
cwd: source,
|
|
11
|
+
dot: true,
|
|
12
|
+
nosort: true,
|
|
13
|
+
});
|
|
14
|
+
await Promise.all(dirs.map(async (dir) => {
|
|
15
|
+
const from = path.resolve(source, dir);
|
|
16
|
+
const to = path.resolve(target, dir);
|
|
17
|
+
await fs.ensureDir(path.dirname(to));
|
|
18
|
+
await fs.rename(from, to);
|
|
19
|
+
}));
|
|
20
|
+
};
|
|
21
|
+
export const copyDir = async (source, target, fileGlob = '**/*.*', globOptions = null, renameFn = (n) => n) => {
|
|
22
|
+
const paths = await readDir(fileGlob, {
|
|
23
|
+
cwd: source,
|
|
24
|
+
dot: true,
|
|
25
|
+
nodir: true,
|
|
26
|
+
nosort: true,
|
|
27
|
+
...globOptions,
|
|
28
|
+
});
|
|
29
|
+
await Promise.all(paths.map(async (p) => {
|
|
30
|
+
const from = path.resolve(source, p);
|
|
31
|
+
const to = path.resolve(target, renameFn(p));
|
|
32
|
+
await fs.ensureDir(path.dirname(to));
|
|
33
|
+
await fs.copyFile(from, to);
|
|
34
|
+
}));
|
|
35
|
+
};
|
|
36
|
+
export const cleanDir = async (pattern, globOptions) => new Promise((resolve, reject) => {
|
|
37
|
+
rimraf(pattern, { glob: globOptions }, (err) => err ? reject(err) : resolve());
|
|
38
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function git(args: string[]): Promise<string>;
|
|
2
|
+
export declare function gitBranch(): Promise<string>;
|
|
3
|
+
export declare function gitRevId(): Promise<string>;
|
|
4
|
+
declare type GitInfo = {
|
|
5
|
+
branch: string;
|
|
6
|
+
revision: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function gitInfo(noCache?: boolean): Promise<GitInfo>;
|
|
9
|
+
export {};
|
package/dist/src/git.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { exec } from './cp.js';
|
|
2
|
+
export async function git(args) {
|
|
3
|
+
return (await exec(`git ${args.join(' ')}`)).stdout.toString();
|
|
4
|
+
}
|
|
5
|
+
export async function gitBranch() {
|
|
6
|
+
return (await git(['symbolic-ref', '--short', 'HEAD']))
|
|
7
|
+
.replace(/[_+/]/g, '-')
|
|
8
|
+
.trim();
|
|
9
|
+
}
|
|
10
|
+
export async function gitRevId() {
|
|
11
|
+
return (await git(['rev-parse', '--short=12', 'HEAD']))
|
|
12
|
+
.replace(/[+]/g, '')
|
|
13
|
+
.trim();
|
|
14
|
+
}
|
|
15
|
+
let info = null;
|
|
16
|
+
export async function gitInfo(noCache = false) {
|
|
17
|
+
if (!info || noCache) {
|
|
18
|
+
info = {
|
|
19
|
+
branch: await gitBranch(),
|
|
20
|
+
revision: await gitRevId(),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return info;
|
|
24
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from './ant.js';
|
|
2
|
+
export * from './cert.js';
|
|
3
|
+
export * from './clean.js';
|
|
4
|
+
export * from './copy.js';
|
|
5
|
+
export * from './cp.js';
|
|
6
|
+
export * from './docker.js';
|
|
7
|
+
export * from './docker.container.js';
|
|
8
|
+
export * from './docker.network.js';
|
|
9
|
+
export * from './docker.volume.js';
|
|
10
|
+
export * from './dockerCleanup.js';
|
|
11
|
+
export * from './dockerCompose.js';
|
|
12
|
+
export * from './fs.js';
|
|
13
|
+
export * from './git.js';
|
|
14
|
+
export * from './npm.js';
|
|
15
|
+
export * from './pkg.js';
|
|
16
|
+
export * from './publish.js';
|
|
17
|
+
export * from './run.js';
|
|
18
|
+
export * from './tgz.js';
|
|
19
|
+
export * from './version.js';
|
|
20
|
+
export * from './yarn.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from './ant.js';
|
|
2
|
+
export * from './cert.js';
|
|
3
|
+
export * from './clean.js';
|
|
4
|
+
export * from './copy.js';
|
|
5
|
+
export * from './cp.js';
|
|
6
|
+
export * from './docker.js';
|
|
7
|
+
export * from './docker.container.js';
|
|
8
|
+
export * from './docker.network.js';
|
|
9
|
+
export * from './docker.volume.js';
|
|
10
|
+
export * from './dockerCleanup.js';
|
|
11
|
+
export * from './dockerCompose.js';
|
|
12
|
+
export * from './fs.js';
|
|
13
|
+
export * from './git.js';
|
|
14
|
+
export * from './npm.js';
|
|
15
|
+
export * from './pkg.js';
|
|
16
|
+
export * from './publish.js';
|
|
17
|
+
export * from './run.js';
|
|
18
|
+
export * from './tgz.js';
|
|
19
|
+
export * from './version.js';
|
|
20
|
+
export * from './yarn.js';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given a `ObjMap`, iterate over each entry and run it through the given `map` function.
|
|
3
|
+
* @param {ObjMap} obj the input object
|
|
4
|
+
* @param {Function} map the mapping operation
|
|
5
|
+
* @returns {ObjMap} a new object
|
|
6
|
+
*/
|
|
7
|
+
export declare const mapValues: <K extends string, V, R>(obj: Record<K, V> | null | undefined, map: (value: V, key: K, map: Record<K, V>) => R) => Record<K, R>;
|
|
8
|
+
/**
|
|
9
|
+
* Given a `ObjMap`, iterate over each entry and run it through the given async `map` function.
|
|
10
|
+
* The promise returned by the `map` is awaited, such that the resulting `ObjMap` values are
|
|
11
|
+
* the result of the resolved promise.
|
|
12
|
+
* @param {ObjMap} obj the input object
|
|
13
|
+
* @param {Function} map the async mapping operation
|
|
14
|
+
* @returns {Promise} a promise for a new object
|
|
15
|
+
*/
|
|
16
|
+
export declare const mapValuesAsync: <K extends string, V, R>(obj: Record<K, V> | null | undefined, map: (value: V, key: K, objMap: Record<K, V>) => Promise<R>) => Promise<Record<K, R>>;
|
|
17
|
+
/**
|
|
18
|
+
* Given a `ObjMap`, iterate over each entry and run it through the given `filter` function.
|
|
19
|
+
* Any entry for which the `filter` returns `false` is removed from the resulting `ObjMap`.
|
|
20
|
+
* All other entries are left as-is. The resulting output is a subset of the input.
|
|
21
|
+
* If no `filter` is specified, default to filtering out nullish values.
|
|
22
|
+
* @param {ObjMap} obj the input object
|
|
23
|
+
* @param {Function} filter the filter operation
|
|
24
|
+
* @returns {ObjMap} a new object, a subset of the input
|
|
25
|
+
*/
|
|
26
|
+
export declare const filterKeys: <V, K extends string = string>(obj: Record<K, V> | null | undefined, filter?: (value: V, key: K, objMap: Record<K, V>) => boolean) => Partial<Record<K, V>>;
|
|
27
|
+
/**
|
|
28
|
+
* Given an object, removes any top level keys with a nullish value.
|
|
29
|
+
* The type system should preserve the incoming object type, with all such keys typed as `empty`.
|
|
30
|
+
* @param {Object} obj the input object
|
|
31
|
+
* @returns {Object} a new object, a subset of the input
|
|
32
|
+
*/
|
|
33
|
+
export declare const filterNullish: <T>(obj: Record<string, T>) => Record<string, Exclude<T, null | undefined>>;
|
package/dist/src/maps.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given a `ObjMap`, iterate over each entry and run it through the given `map` function.
|
|
3
|
+
* @param {ObjMap} obj the input object
|
|
4
|
+
* @param {Function} map the mapping operation
|
|
5
|
+
* @returns {ObjMap} a new object
|
|
6
|
+
*/
|
|
7
|
+
export const mapValues = (obj, map) => Object.entries(obj ?? {}).reduce((acc, [k, v]) => Object.assign(acc, {
|
|
8
|
+
[k]: map(v, k, (obj ?? {})),
|
|
9
|
+
}), {});
|
|
10
|
+
/**
|
|
11
|
+
* Given a `ObjMap`, iterate over each entry and run it through the given async `map` function.
|
|
12
|
+
* The promise returned by the `map` is awaited, such that the resulting `ObjMap` values are
|
|
13
|
+
* the result of the resolved promise.
|
|
14
|
+
* @param {ObjMap} obj the input object
|
|
15
|
+
* @param {Function} map the async mapping operation
|
|
16
|
+
* @returns {Promise} a promise for a new object
|
|
17
|
+
*/
|
|
18
|
+
export const mapValuesAsync = async (obj, map) => Object.entries(obj ?? {}).reduce(async (acc, [k, v]) => Object.assign(await acc, {
|
|
19
|
+
[k]: await map(v, k, (obj ?? {})),
|
|
20
|
+
}), Promise.resolve({}));
|
|
21
|
+
/**
|
|
22
|
+
* Given a `ObjMap`, iterate over each entry and run it through the given `filter` function.
|
|
23
|
+
* Any entry for which the `filter` returns `false` is removed from the resulting `ObjMap`.
|
|
24
|
+
* All other entries are left as-is. The resulting output is a subset of the input.
|
|
25
|
+
* If no `filter` is specified, default to filtering out nullish values.
|
|
26
|
+
* @param {ObjMap} obj the input object
|
|
27
|
+
* @param {Function} filter the filter operation
|
|
28
|
+
* @returns {ObjMap} a new object, a subset of the input
|
|
29
|
+
*/
|
|
30
|
+
export const filterKeys = (obj, filter = (v) => v != null) => Object.entries(obj ?? {}).reduce((acc, [k, v]) => filter(v, k, (obj ?? {}))
|
|
31
|
+
? Object.assign(acc, {
|
|
32
|
+
[k]: v,
|
|
33
|
+
})
|
|
34
|
+
: acc, {});
|
|
35
|
+
/**
|
|
36
|
+
* Given an object, removes any top level keys with a nullish value.
|
|
37
|
+
* The type system should preserve the incoming object type, with all such keys typed as `empty`.
|
|
38
|
+
* @param {Object} obj the input object
|
|
39
|
+
* @returns {Object} a new object, a subset of the input
|
|
40
|
+
*/
|
|
41
|
+
export const filterNullish = (obj) => filterKeys(obj);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare type NpmCreds = {
|
|
2
|
+
email?: string;
|
|
3
|
+
password?: string;
|
|
4
|
+
username?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare type NpmConfig = {
|
|
7
|
+
access?: 'public' | 'restricted';
|
|
8
|
+
dryRun?: boolean;
|
|
9
|
+
name?: string;
|
|
10
|
+
publish?: boolean;
|
|
11
|
+
registry?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function getNpmConfig(): NpmConfig;
|
|
14
|
+
export declare function npmExec(args: string[], npmPath?: string): Promise<string>;
|
|
15
|
+
export declare function npmGetVersions(packageName: string, npmPath?: string): Promise<string[]>;
|
|
16
|
+
export interface NpmPublishOptions {
|
|
17
|
+
npmAuthToken?: string;
|
|
18
|
+
npmConfig?: NpmConfig;
|
|
19
|
+
npmCreds?: NpmCreds;
|
|
20
|
+
npmPath?: string;
|
|
21
|
+
publishPath?: string;
|
|
22
|
+
skipExisting?: boolean;
|
|
23
|
+
tag?: string;
|
|
24
|
+
workDir?: string;
|
|
25
|
+
writeNpmrc?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function npmPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath, skipExisting, tag, workDir: passedWorkDir, writeNpmrc, }?: NpmPublishOptions): Promise<boolean>;
|
|
28
|
+
interface NpmPackOptions {
|
|
29
|
+
destination?: string;
|
|
30
|
+
npmConfig?: NpmConfig;
|
|
31
|
+
npmPath?: string;
|
|
32
|
+
workDir?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function npmPack({ destination, npmConfig, npmPath, workDir, }: NpmPackOptions): Promise<string>;
|
|
35
|
+
export {};
|