@w5s/configurator-core 1.0.0-alpha.7 → 1.0.0-alpha.9
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/dist/index.cjs +199 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -91
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +114 -91
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +175 -147
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/src/FileMode.ts +14 -14
- package/src/__exists.ts +1 -1
- package/src/__toMode.ts +8 -8
- package/src/block.ts +51 -51
- package/src/directory.ts +14 -12
- package/src/exec.ts +23 -23
- package/src/file.ts +17 -15
- package/src/ignoreFile.ts +18 -18
- package/src/index.ts +2 -1
- package/src/json.ts +18 -18
- package/src/meta.ts +2 -2
- package/src/testing/getTempPath.ts +1 -0
- package/src/testing/getTestPath.ts +2 -1
- package/src/yaml.ts +45 -0
- package/src/yarnConfig.ts +13 -13
- package/src/yarnVersion.ts +10 -10
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { accessSync, chmodSync, constants, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { access, chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import YAML from "yaml";
|
|
3
4
|
import { spawn, spawnSync } from "node:child_process";
|
|
4
5
|
//#region src/__exists.ts
|
|
5
6
|
async function __exists(path) {
|
|
@@ -11,14 +12,6 @@ async function __exists(path) {
|
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
//#endregion
|
|
14
|
-
//#region src/__toMode.ts
|
|
15
|
-
function toModeFlag(permissionSet, read, write, execute) {
|
|
16
|
-
return (permissionSet?.read === true ? read : 0) | (permissionSet?.write === true ? write : 0) | (permissionSet?.execute === true ? execute : 0);
|
|
17
|
-
}
|
|
18
|
-
function __toMode(mode) {
|
|
19
|
-
return mode == null ? mode : toModeFlag(mode.owner, 256, 128, 64) | toModeFlag(mode.group, 32, 16, 8) | toModeFlag(mode.other, 4, 2, 1);
|
|
20
|
-
}
|
|
21
|
-
//#endregion
|
|
22
15
|
//#region src/__existsSync.ts
|
|
23
16
|
function __existsSync(path) {
|
|
24
17
|
try {
|
|
@@ -29,66 +22,12 @@ function __existsSync(path) {
|
|
|
29
22
|
}
|
|
30
23
|
}
|
|
31
24
|
//#endregion
|
|
32
|
-
//#region src/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* await directory({
|
|
39
|
-
* path: 'foo/bar',
|
|
40
|
-
* state: 'present',
|
|
41
|
-
* mode: {
|
|
42
|
-
* owner: { read: true, write: true, execute: true },
|
|
43
|
-
* group: { read: true, write: true, execute: true },
|
|
44
|
-
* other: { read: true, write: true, execute: true },
|
|
45
|
-
* },
|
|
46
|
-
* })
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
* @param options
|
|
50
|
-
*/
|
|
51
|
-
async function directory(options) {
|
|
52
|
-
const { path, state, mode } = options;
|
|
53
|
-
const isPresent = await __exists(path);
|
|
54
|
-
if (state === "present") {
|
|
55
|
-
const newMode = __toMode(mode);
|
|
56
|
-
if (!isPresent) await mkdir(path, {
|
|
57
|
-
recursive: true,
|
|
58
|
-
mode: newMode
|
|
59
|
-
});
|
|
60
|
-
if (newMode != null && isPresent) await chmod(path, newMode);
|
|
61
|
-
} else if (isPresent) await rm(path, { recursive: true });
|
|
25
|
+
//#region src/__toMode.ts
|
|
26
|
+
function __toMode(mode) {
|
|
27
|
+
return mode == null ? mode : toModeFlag(mode.owner, 256, 128, 64) | toModeFlag(mode.group, 32, 16, 8) | toModeFlag(mode.other, 4, 2, 1);
|
|
62
28
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```ts
|
|
68
|
-
* directorySync({
|
|
69
|
-
* path: 'foo/bar',
|
|
70
|
-
* state: 'present',
|
|
71
|
-
* mode: {
|
|
72
|
-
* owner: { read: true, write: true, execute: true },
|
|
73
|
-
* group: { read: true, write: true, execute: true },
|
|
74
|
-
* other: { read: true, write: true, execute: true },
|
|
75
|
-
* },
|
|
76
|
-
* })
|
|
77
|
-
* ```
|
|
78
|
-
*
|
|
79
|
-
* @param options
|
|
80
|
-
*/
|
|
81
|
-
function directorySync(options) {
|
|
82
|
-
const { path, state, mode } = options;
|
|
83
|
-
const isPresent = __existsSync(path);
|
|
84
|
-
if (state === "present") {
|
|
85
|
-
const newMode = __toMode(mode);
|
|
86
|
-
if (!isPresent) mkdirSync(path, {
|
|
87
|
-
recursive: true,
|
|
88
|
-
mode: newMode
|
|
89
|
-
});
|
|
90
|
-
if (newMode != null && isPresent) chmodSync(path, newMode);
|
|
91
|
-
} else if (isPresent) rmSync(path, { recursive: true });
|
|
29
|
+
function toModeFlag(permissionSet, read, write, execute) {
|
|
30
|
+
return (permissionSet?.read === true ? read : 0) | (permissionSet?.write === true ? write : 0) | (permissionSet?.execute === true ? execute : 0);
|
|
92
31
|
}
|
|
93
32
|
//#endregion
|
|
94
33
|
//#region src/file.ts
|
|
@@ -112,7 +51,7 @@ function directorySync(options) {
|
|
|
112
51
|
* @param options
|
|
113
52
|
*/
|
|
114
53
|
async function file(options) {
|
|
115
|
-
const {
|
|
54
|
+
const { encoding = "utf8", mode, path, state, update } = options;
|
|
116
55
|
if (state === "present") {
|
|
117
56
|
const isPresent = await __exists(path);
|
|
118
57
|
const previousContent = isPresent ? await readFile(path, encoding) : "";
|
|
@@ -145,7 +84,7 @@ async function file(options) {
|
|
|
145
84
|
* @param options
|
|
146
85
|
*/
|
|
147
86
|
function fileSync(options) {
|
|
148
|
-
const {
|
|
87
|
+
const { encoding = "utf8", mode, path, state, update } = options;
|
|
149
88
|
if (state === "present") {
|
|
150
89
|
const isPresent = __existsSync(path);
|
|
151
90
|
const previousContent = isPresent ? readFileSync(path, encoding) : "";
|
|
@@ -179,8 +118,32 @@ const matchLast = (string, regexp) => {
|
|
|
179
118
|
lastIndex
|
|
180
119
|
};
|
|
181
120
|
};
|
|
121
|
+
/**
|
|
122
|
+
* Replace asynchronously a block in file that follows pattern :
|
|
123
|
+
*
|
|
124
|
+
* marker(markerBegin)
|
|
125
|
+
* ...
|
|
126
|
+
* marker(markerEnd)
|
|
127
|
+
*
|
|
128
|
+
* @param options
|
|
129
|
+
*/
|
|
130
|
+
function block(options) {
|
|
131
|
+
return file(toFileOptions(options));
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Replace synchronously a block in file that follows pattern :
|
|
135
|
+
*
|
|
136
|
+
* marker(markerBegin)
|
|
137
|
+
* ...
|
|
138
|
+
* marker(markerEnd)
|
|
139
|
+
*
|
|
140
|
+
* @param options
|
|
141
|
+
*/
|
|
142
|
+
function blockSync(options) {
|
|
143
|
+
return fileSync(toFileOptions(options));
|
|
144
|
+
}
|
|
182
145
|
function toFileOptions(options) {
|
|
183
|
-
const { marker = (mark) => `# ${mark.toUpperCase()} MANAGED BLOCK`, path,
|
|
146
|
+
const { block: blockName, insertPosition = ["after", EOF], marker = (mark) => `# ${mark.toUpperCase()} MANAGED BLOCK`, path, state = "present" } = options;
|
|
184
147
|
const EOL = "\n";
|
|
185
148
|
const beginBlock = marker("Begin");
|
|
186
149
|
const endBlock = marker("End");
|
|
@@ -204,18 +167,18 @@ function toFileOptions(options) {
|
|
|
204
167
|
if (found.exists) return fullContent.slice(0, found.startIndex) + replaceBlock + fullContent.slice(found.endIndex);
|
|
205
168
|
if (remove) return fullContent;
|
|
206
169
|
switch (positionDirection) {
|
|
207
|
-
case "before":
|
|
208
|
-
if (positionAnchor !== BOF) {
|
|
209
|
-
const { firstIndex } = matchLast(fullContent, positionAnchor);
|
|
210
|
-
if (firstIndex >= 0) return insertAt(fullContent, firstIndex, replaceBlock + EOL);
|
|
211
|
-
}
|
|
212
|
-
return replaceBlock + EOL + fullContent;
|
|
213
170
|
case "after":
|
|
214
171
|
if (positionAnchor !== EOF) {
|
|
215
172
|
const { lastIndex } = matchLast(fullContent, positionAnchor);
|
|
216
173
|
if (lastIndex >= 0) return insertAt(fullContent, lastIndex, EOL + replaceBlock);
|
|
217
174
|
}
|
|
218
175
|
return fullContent + EOL + replaceBlock;
|
|
176
|
+
case "before":
|
|
177
|
+
if (positionAnchor !== BOF) {
|
|
178
|
+
const { firstIndex } = matchLast(fullContent, positionAnchor);
|
|
179
|
+
if (firstIndex >= 0) return insertAt(fullContent, firstIndex, replaceBlock + EOL);
|
|
180
|
+
}
|
|
181
|
+
return replaceBlock + EOL + fullContent;
|
|
219
182
|
default: throw new Error(`Unsupported position ${String(positionDirection)}`);
|
|
220
183
|
}
|
|
221
184
|
}
|
|
@@ -225,42 +188,70 @@ function toFileOptions(options) {
|
|
|
225
188
|
update: (sourceContent) => apply(sourceContent, blockName)
|
|
226
189
|
};
|
|
227
190
|
}
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/directory.ts
|
|
228
193
|
/**
|
|
229
|
-
*
|
|
194
|
+
* Ensure directory is present/absent
|
|
230
195
|
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* await directory({
|
|
199
|
+
* path: 'foo/bar',
|
|
200
|
+
* state: 'present',
|
|
201
|
+
* mode: {
|
|
202
|
+
* owner: { read: true, write: true, execute: true },
|
|
203
|
+
* group: { read: true, write: true, execute: true },
|
|
204
|
+
* other: { read: true, write: true, execute: true },
|
|
205
|
+
* },
|
|
206
|
+
* })
|
|
207
|
+
* ```
|
|
234
208
|
*
|
|
235
209
|
* @param options
|
|
236
210
|
*/
|
|
237
|
-
function
|
|
238
|
-
|
|
211
|
+
async function directory(options) {
|
|
212
|
+
const { mode, path, state } = options;
|
|
213
|
+
const isPresent = await __exists(path);
|
|
214
|
+
if (state === "present") {
|
|
215
|
+
const newMode = __toMode(mode);
|
|
216
|
+
if (!isPresent) await mkdir(path, {
|
|
217
|
+
mode: newMode,
|
|
218
|
+
recursive: true
|
|
219
|
+
});
|
|
220
|
+
if (newMode != null && isPresent) await chmod(path, newMode);
|
|
221
|
+
} else if (isPresent) await rm(path, { recursive: true });
|
|
239
222
|
}
|
|
240
223
|
/**
|
|
241
|
-
*
|
|
224
|
+
* Ensure directory is present/absent
|
|
242
225
|
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* directorySync({
|
|
229
|
+
* path: 'foo/bar',
|
|
230
|
+
* state: 'present',
|
|
231
|
+
* mode: {
|
|
232
|
+
* owner: { read: true, write: true, execute: true },
|
|
233
|
+
* group: { read: true, write: true, execute: true },
|
|
234
|
+
* other: { read: true, write: true, execute: true },
|
|
235
|
+
* },
|
|
236
|
+
* })
|
|
237
|
+
* ```
|
|
246
238
|
*
|
|
247
239
|
* @param options
|
|
248
240
|
*/
|
|
249
|
-
function
|
|
250
|
-
|
|
241
|
+
function directorySync(options) {
|
|
242
|
+
const { mode, path, state } = options;
|
|
243
|
+
const isPresent = __existsSync(path);
|
|
244
|
+
if (state === "present") {
|
|
245
|
+
const newMode = __toMode(mode);
|
|
246
|
+
if (!isPresent) mkdirSync(path, {
|
|
247
|
+
mode: newMode,
|
|
248
|
+
recursive: true
|
|
249
|
+
});
|
|
250
|
+
if (newMode != null && isPresent) chmodSync(path, newMode);
|
|
251
|
+
} else if (isPresent) rmSync(path, { recursive: true });
|
|
251
252
|
}
|
|
252
253
|
//#endregion
|
|
253
254
|
//#region src/ignoreFile.ts
|
|
254
|
-
function toFileOption$1({ update, ...otherOptions }) {
|
|
255
|
-
return {
|
|
256
|
-
...otherOptions,
|
|
257
|
-
update: update == null ? update : (content) => {
|
|
258
|
-
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
259
|
-
const updatedLines = update(content === "" ? void 0 : content.split(eol));
|
|
260
|
-
return updatedLines == null ? void 0 : updatedLines.join(eol);
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
255
|
/**
|
|
265
256
|
* Ensure file is present/absent asynchronously with content initialized or modified by line.
|
|
266
257
|
*
|
|
@@ -274,7 +265,7 @@ function toFileOption$1({ update, ...otherOptions }) {
|
|
|
274
265
|
* @param options File target options.
|
|
275
266
|
*/
|
|
276
267
|
async function ignoreFile(options) {
|
|
277
|
-
return file(toFileOption$
|
|
268
|
+
return file(toFileOption$2(options));
|
|
278
269
|
}
|
|
279
270
|
/**
|
|
280
271
|
* Ensure file is present/absent synchronously with content initialized or modified by line.
|
|
@@ -289,26 +280,27 @@ async function ignoreFile(options) {
|
|
|
289
280
|
* @param options File target options.
|
|
290
281
|
*/
|
|
291
282
|
function ignoreFileSync(options) {
|
|
292
|
-
return fileSync(toFileOption$
|
|
283
|
+
return fileSync(toFileOption$2(options));
|
|
293
284
|
}
|
|
294
|
-
|
|
295
|
-
//#region src/json.ts
|
|
296
|
-
function toFileOption({ update, ...otherOptions }) {
|
|
285
|
+
function toFileOption$2({ update, ...otherOptions }) {
|
|
297
286
|
return {
|
|
298
287
|
...otherOptions,
|
|
299
288
|
update: update == null ? update : (content) => {
|
|
300
|
-
const
|
|
301
|
-
|
|
289
|
+
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
290
|
+
const updatedLines = update(content === "" ? void 0 : content.split(eol));
|
|
291
|
+
return updatedLines == null ? void 0 : updatedLines.join(eol);
|
|
302
292
|
}
|
|
303
293
|
};
|
|
304
294
|
}
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/json.ts
|
|
305
297
|
/**
|
|
306
298
|
* Ensure file is present/absent asynchronously with content value initialized or modified with `update`
|
|
307
299
|
*
|
|
308
300
|
* @param options
|
|
309
301
|
*/
|
|
310
302
|
async function json(options) {
|
|
311
|
-
return file(toFileOption(options));
|
|
303
|
+
return file(toFileOption$1(options));
|
|
312
304
|
}
|
|
313
305
|
/**
|
|
314
306
|
* Ensure file is present/absent synchronously with content value initialized or modified with `update`
|
|
@@ -316,34 +308,53 @@ async function json(options) {
|
|
|
316
308
|
* @param options
|
|
317
309
|
*/
|
|
318
310
|
function jsonSync(options) {
|
|
319
|
-
return fileSync(toFileOption(options));
|
|
311
|
+
return fileSync(toFileOption$1(options));
|
|
312
|
+
}
|
|
313
|
+
function toFileOption$1({ update, ...otherOptions }) {
|
|
314
|
+
return {
|
|
315
|
+
...otherOptions,
|
|
316
|
+
update: update == null ? update : (content) => {
|
|
317
|
+
const jsonValue = content === "" ? void 0 : JSON.parse(content);
|
|
318
|
+
return JSON.stringify(update(jsonValue));
|
|
319
|
+
}
|
|
320
|
+
};
|
|
320
321
|
}
|
|
321
322
|
//#endregion
|
|
322
323
|
//#region src/meta.ts
|
|
323
324
|
const meta = Object.freeze({
|
|
325
|
+
buildNumber: 1,
|
|
324
326
|
name: "@w5s/configurator-core",
|
|
325
|
-
version: "1.0.0-alpha.
|
|
326
|
-
buildNumber: 1
|
|
327
|
+
version: "1.0.0-alpha.9"
|
|
327
328
|
});
|
|
328
329
|
//#endregion
|
|
329
|
-
//#region src/
|
|
330
|
+
//#region src/yaml.ts
|
|
330
331
|
/**
|
|
331
|
-
*
|
|
332
|
-
* containing the stdout and stderr strings.
|
|
332
|
+
* Ensure file is present/absent asynchronously with content value initialized or modified with `update`
|
|
333
333
|
*
|
|
334
|
-
* @param command The command to run
|
|
335
|
-
* @param args The arguments to pass to the command
|
|
336
334
|
* @param options
|
|
337
|
-
* @returns A promise that resolves with an object like `{ stdout: string, stderr: string }`
|
|
338
335
|
*/
|
|
339
|
-
function
|
|
340
|
-
|
|
341
|
-
|
|
336
|
+
async function yaml(options) {
|
|
337
|
+
return file(toFileOption(options));
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Ensure file is present/absent synchronously with content value initialized or modified with `update`
|
|
341
|
+
*
|
|
342
|
+
* @param options
|
|
343
|
+
*/
|
|
344
|
+
function yamlSync(options) {
|
|
345
|
+
return fileSync(toFileOption(options));
|
|
346
|
+
}
|
|
347
|
+
function toFileOption({ update, ...otherOptions }) {
|
|
342
348
|
return {
|
|
343
|
-
|
|
344
|
-
|
|
349
|
+
...otherOptions,
|
|
350
|
+
update: update == null ? update : (content) => {
|
|
351
|
+
const yamlValue = content === "" ? void 0 : YAML.parse(content);
|
|
352
|
+
return YAML.stringify(update(yamlValue));
|
|
353
|
+
}
|
|
345
354
|
};
|
|
346
355
|
}
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/exec.ts
|
|
347
358
|
/**
|
|
348
359
|
* Runs a command in a shell and returns a promise that resolves with an object
|
|
349
360
|
* containing the stdout and stderr strings.
|
|
@@ -366,110 +377,127 @@ async function exec(command, args, options) {
|
|
|
366
377
|
});
|
|
367
378
|
child.on("close", (_code) => {
|
|
368
379
|
resolve({
|
|
369
|
-
|
|
370
|
-
|
|
380
|
+
stderr,
|
|
381
|
+
stdout
|
|
371
382
|
});
|
|
372
383
|
});
|
|
373
384
|
child.on("error", reject);
|
|
374
385
|
});
|
|
375
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Runs a command in a shell and returns a promise that resolves with an object
|
|
389
|
+
* containing the stdout and stderr strings.
|
|
390
|
+
*
|
|
391
|
+
* @param command The command to run
|
|
392
|
+
* @param args The arguments to pass to the command
|
|
393
|
+
* @param options
|
|
394
|
+
* @returns A promise that resolves with an object like `{ stdout: string, stderr: string }`
|
|
395
|
+
*/
|
|
396
|
+
function execSync(command, args, options) {
|
|
397
|
+
const result = spawnSync(command, args, { ...options });
|
|
398
|
+
const encoding = "utf8";
|
|
399
|
+
return {
|
|
400
|
+
stderr: result.stderr.toString(encoding),
|
|
401
|
+
stdout: result.stdout.toString(encoding)
|
|
402
|
+
};
|
|
403
|
+
}
|
|
376
404
|
//#endregion
|
|
377
405
|
//#region src/yarnConfig.ts
|
|
378
406
|
/**
|
|
379
|
-
*
|
|
407
|
+
* Set/Unset yarn configuration value
|
|
380
408
|
*
|
|
381
409
|
* @param options
|
|
382
410
|
* @example
|
|
383
|
-
*
|
|
411
|
+
* await yarnConfig({
|
|
384
412
|
* key: 'nodeLinker',
|
|
385
413
|
* state: 'present',
|
|
386
414
|
* update: (content) => content.replace('node-modules', 'hoisted'),
|
|
387
415
|
* })
|
|
388
416
|
*/
|
|
389
|
-
function
|
|
417
|
+
async function yarnConfig(options) {
|
|
390
418
|
const { key, state, update } = options;
|
|
391
419
|
if (state === "present") {
|
|
392
|
-
const { stdout } =
|
|
420
|
+
const { stdout } = await exec("yarn", [
|
|
393
421
|
"config",
|
|
394
422
|
"get",
|
|
395
423
|
String(key)
|
|
396
424
|
]);
|
|
397
|
-
|
|
425
|
+
await exec("yarn", [
|
|
398
426
|
"config",
|
|
399
427
|
"set",
|
|
400
428
|
String(key),
|
|
401
|
-
|
|
429
|
+
String(update == null ? "" : update(stdout))
|
|
402
430
|
]);
|
|
403
|
-
} else
|
|
431
|
+
} else await exec("yarn", ["config", "unset"]);
|
|
404
432
|
}
|
|
405
433
|
/**
|
|
406
|
-
*
|
|
434
|
+
* Synchronous version of {@link yarnConfig}
|
|
407
435
|
*
|
|
408
436
|
* @param options
|
|
409
437
|
* @example
|
|
410
|
-
*
|
|
438
|
+
* yarnConfigSync({
|
|
411
439
|
* key: 'nodeLinker',
|
|
412
440
|
* state: 'present',
|
|
413
441
|
* update: (content) => content.replace('node-modules', 'hoisted'),
|
|
414
442
|
* })
|
|
415
443
|
*/
|
|
416
|
-
|
|
444
|
+
function yarnConfigSync(options) {
|
|
417
445
|
const { key, state, update } = options;
|
|
418
446
|
if (state === "present") {
|
|
419
|
-
const { stdout } =
|
|
447
|
+
const { stdout } = execSync("yarn", [
|
|
420
448
|
"config",
|
|
421
449
|
"get",
|
|
422
450
|
String(key)
|
|
423
451
|
]);
|
|
424
|
-
|
|
452
|
+
execSync("yarn", [
|
|
425
453
|
"config",
|
|
426
454
|
"set",
|
|
427
455
|
String(key),
|
|
428
|
-
|
|
456
|
+
String(update == null ? "" : update(stdout))
|
|
429
457
|
]);
|
|
430
|
-
} else
|
|
458
|
+
} else execSync("yarn", ["config", "unset"]);
|
|
431
459
|
}
|
|
432
460
|
//#endregion
|
|
433
461
|
//#region src/yarnVersion.ts
|
|
434
462
|
/**
|
|
435
|
-
*
|
|
463
|
+
* Set/Unset yarn configuration value
|
|
436
464
|
*
|
|
437
465
|
* @param options
|
|
438
466
|
* @example
|
|
439
|
-
*
|
|
467
|
+
* await yarnVersion({
|
|
440
468
|
* state: 'present',
|
|
441
469
|
* update: () => 'berry', // or 'classic'
|
|
442
470
|
* })
|
|
443
471
|
*/
|
|
444
|
-
function
|
|
472
|
+
async function yarnVersion(options) {
|
|
445
473
|
const { state, update } = options;
|
|
446
|
-
if (state === "present")
|
|
474
|
+
if (state === "present") await exec("yarn", [
|
|
447
475
|
"set",
|
|
448
476
|
"version",
|
|
449
|
-
|
|
477
|
+
String(update == null ? "berry" : update())
|
|
450
478
|
]);
|
|
451
479
|
else throw new Error("Not implemented");
|
|
452
480
|
}
|
|
453
481
|
/**
|
|
454
|
-
*
|
|
482
|
+
* Synchronous version of {@link yarnVersion}
|
|
455
483
|
*
|
|
456
484
|
* @param options
|
|
457
485
|
* @example
|
|
458
|
-
*
|
|
486
|
+
* yarnVersionSync({
|
|
459
487
|
* state: 'present',
|
|
460
488
|
* update: () => 'berry', // or 'classic'
|
|
461
489
|
* })
|
|
462
490
|
*/
|
|
463
|
-
|
|
491
|
+
function yarnVersionSync(options) {
|
|
464
492
|
const { state, update } = options;
|
|
465
|
-
if (state === "present")
|
|
493
|
+
if (state === "present") execSync("yarn", [
|
|
466
494
|
"set",
|
|
467
495
|
"version",
|
|
468
|
-
|
|
496
|
+
String(update == null ? "berry" : update())
|
|
469
497
|
]);
|
|
470
498
|
else throw new Error("Not implemented");
|
|
471
499
|
}
|
|
472
500
|
//#endregion
|
|
473
|
-
export { block, blockSync, directory, directorySync, file, fileSync, ignoreFile, ignoreFileSync, json, jsonSync, meta, yarnConfig, yarnConfigSync, yarnVersion, yarnVersionSync };
|
|
501
|
+
export { block, blockSync, directory, directorySync, file, fileSync, ignoreFile, ignoreFileSync, json, jsonSync, meta, yaml, yamlSync, yarnConfig, yarnConfigSync, yarnVersion, yarnVersionSync };
|
|
474
502
|
|
|
475
503
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["toFileOption"],"sources":["../src/__exists.ts","../src/__toMode.ts","../src/__existsSync.ts","../src/directory.ts","../src/file.ts","../src/block.ts","../src/ignoreFile.ts","../src/json.ts","../src/meta.ts","../src/exec.ts","../src/yarnConfig.ts","../src/yarnVersion.ts"],"sourcesContent":["import { access } from 'node:fs/promises';\nimport { constants } from 'node:fs';\n\nexport async function __exists(path: string) {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import type { FileMode, FilePermissionSet } from './FileMode.js';\n\nfunction toModeFlag(permissionSet: FilePermissionSet | undefined, read: number, write: number, execute: number): number {\n return (\n (permissionSet?.read === true ? read : 0)\n | (permissionSet?.write === true ? write : 0)\n | (permissionSet?.execute === true ? execute : 0)\n );\n}\n\nexport function __toMode(mode: FileMode | undefined): number | undefined {\n return mode == null\n ? mode\n : (\n toModeFlag(mode.owner, 0o400, 0o200, 0o100)\n | toModeFlag(mode.group, 0o040, 0o020, 0o010)\n | toModeFlag(mode.other, 0o004, 0o002, 0o001)\n );\n}\n","import { accessSync, constants } from 'node:fs';\n\nexport function __existsSync(path: string) {\n try {\n accessSync(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import { chmodSync, mkdirSync, rmSync } from 'node:fs';\nimport { chmod, mkdir, rm } from 'node:fs/promises';\nimport { __exists } from './__exists.js';\nimport type { FileMode } from './FileMode.js';\nimport { __toMode } from './__toMode.js';\nimport { __existsSync } from './__existsSync.js';\n\nexport interface DirectoryOptions {\n /**\n * Directory path\n */\n readonly path: string;\n\n /**\n * Directory target state\n */\n readonly state: 'present' | 'absent';\n\n /**\n * File permissions\n */\n readonly mode?: FileMode;\n}\n\n/**\n * Ensure directory is present/absent\n *\n * @example\n * ```ts\n * await directory({\n * path: 'foo/bar',\n * state: 'present',\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport async function directory(options: DirectoryOptions): Promise<void> {\n const { path, state, mode } = options;\n const isPresent = await __exists(path);\n if (state === 'present') {\n const newMode = __toMode(mode);\n if (!isPresent) {\n await mkdir(path, { recursive: true, mode: newMode });\n }\n if (newMode != null && isPresent) {\n await chmod(path, newMode);\n }\n } else if (isPresent) {\n await rm(path, { recursive: true });\n }\n}\n\n/**\n * Ensure directory is present/absent\n *\n * @example\n * ```ts\n * directorySync({\n * path: 'foo/bar',\n * state: 'present',\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport function directorySync(options: DirectoryOptions): void {\n const { path, state, mode } = options;\n const isPresent = __existsSync(path);\n if (state === 'present') {\n const newMode = __toMode(mode);\n if (!isPresent) {\n mkdirSync(path, { recursive: true, mode: newMode });\n }\n if (newMode != null && isPresent) {\n chmodSync(path, newMode);\n }\n } else if (isPresent) {\n rmSync(path, { recursive: true });\n }\n}\n","import { chmod, readFile, rm, writeFile } from 'node:fs/promises';\nimport { chmodSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { __exists } from './__exists.js';\nimport { __existsSync } from './__existsSync.js';\nimport type { FileMode } from './FileMode.js';\nimport { __toMode } from './__toMode.js';\n\nexport interface FileOptions {\n /**\n * File path\n */\n readonly path: string;\n\n /**\n * File target state\n */\n readonly state: 'present' | 'absent';\n\n /**\n * File content mapping function\n *\n */\n readonly update?: ((content: string) => string | undefined) | undefined;\n\n /**\n * File encoding\n */\n readonly encoding?: BufferEncoding;\n\n /**\n * File permissions\n */\n readonly mode?: FileMode;\n}\n\n/**\n * Ensure file is present/absent with content initialized or modified with `update\n *\n * @example\n * ```ts\n * await file({\n * path: 'foo/bar',\n * state: 'present',\n * update: (content) => content + '_test', // This will append '_test' after current content\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport async function file(options: FileOptions): Promise<void> {\n const { path, state, update, encoding = 'utf8', mode } = options;\n if (state === 'present') {\n const isPresent = await __exists(path);\n const previousContent = isPresent ? await readFile(path, encoding) : '';\n const newContent = update == null ? (isPresent ? undefined : '') : update(previousContent);\n const newMode = __toMode(mode);\n if (newContent != null) {\n await writeFile(path, newContent, { encoding, mode: newMode });\n }\n if (newMode != null && (isPresent || newContent != null)) {\n await chmod(path, newMode);\n }\n } else {\n await rm(path, { force: true });\n }\n}\n\n/**\n * Ensure file is present/absent with content initialized or modified with `update\n *\n * @example\n * ```ts\n * fileSync({\n * path: 'foo/bar',\n * state: 'present',\n * update: (content) => content + '_test', // This will append '_test' after current content\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport function fileSync(options: FileOptions): void {\n const { path, state, update, encoding = 'utf8', mode } = options;\n if (state === 'present') {\n const isPresent = __existsSync(path);\n const previousContent = isPresent ? readFileSync(path, encoding) : '';\n const newContent = update == null ? (isPresent ? undefined : '') : update(previousContent);\n const newMode = __toMode(mode);\n if (newContent != null) {\n writeFileSync(path, newContent, { encoding, mode: newMode });\n }\n if (newMode != null && (isPresent || newContent != null)) {\n chmodSync(path, newMode);\n }\n } else {\n rmSync(path, { force: true });\n }\n}\n","import { type FileOptions, file, fileSync } from './file.js';\n\nexport interface BlockOptions {\n /**\n * The marker builder function that will take either `markerBegin` or `markerEnd`\n *\n * @default '# ${mark} MANAGED BLOCK'\n */\n marker?: (mark: 'Begin' | 'End') => string;\n\n /**\n * File path\n */\n path: string;\n\n /**\n * Block content to insert\n */\n block: string;\n\n /**\n * Insert position\n */\n insertPosition?: ['before', 'BeginningOfFile' | RegExp] | ['after', 'EndOfFile' | RegExp];\n\n /**\n * Block target state\n */\n state?: 'present' | 'absent';\n}\n\nconst EOF = 'EndOfFile';\nconst BOF = 'BeginningOfFile';\nconst insertAt = (str: string, index: number, toInsert: string) => str.slice(0, index) + toInsert + str.slice(index);\nconst matchLast = (string: string, regexp: RegExp) => {\n const matcher = new RegExp(regexp.source, `${regexp.flags}g`);\n let firstIndex = -1;\n let lastIndex = -1;\n let matches;\n\n while (true) {\n matches = matcher.exec(string);\n if (matches == null) {\n break;\n }\n firstIndex = matches.index;\n lastIndex = matcher.lastIndex;\n }\n return { firstIndex, lastIndex };\n};\n\nfunction toFileOptions(options: BlockOptions): FileOptions {\n const {\n marker = (mark) => `# ${mark.toUpperCase()} MANAGED BLOCK`,\n path,\n block: blockName,\n insertPosition = ['after', EOF],\n state = 'present',\n } = options;\n\n const EOL = '\\n';\n const beginBlock = marker('Begin');\n const endBlock = marker('End');\n\n /**\n * @param content\n */\n function findBlock(content: string) {\n const startIndex = content.indexOf(beginBlock);\n const endIndex = content.indexOf(endBlock) + endBlock.length;\n\n return {\n endIndex,\n exists: startIndex !== -1 && endIndex >= 0,\n startIndex,\n };\n }\n\n function apply(fullContent: string, blockContent: string) {\n const found = findBlock(fullContent);\n const remove = state === 'absent';\n const replaceBlock = remove ? '' : beginBlock + EOL + blockContent + EOL + endBlock;\n const [positionDirection, positionAnchor] = insertPosition;\n\n if (found.exists) {\n return fullContent.slice(0, found.startIndex) + replaceBlock + fullContent.slice(found.endIndex);\n }\n if (remove) {\n return fullContent;\n }\n switch (positionDirection) {\n case 'before': {\n if (positionAnchor !== BOF) {\n const { firstIndex } = matchLast(fullContent, positionAnchor);\n if (firstIndex >= 0) {\n return insertAt(fullContent, firstIndex, replaceBlock + EOL);\n }\n }\n\n // Beginning of file\n return replaceBlock + EOL + fullContent;\n }\n case 'after': {\n // insert\n if (positionAnchor !== EOF) {\n const { lastIndex } = matchLast(fullContent, positionAnchor);\n if (lastIndex >= 0) {\n return insertAt(fullContent, lastIndex, EOL + replaceBlock);\n }\n }\n\n // end of file\n return fullContent + EOL + replaceBlock;\n }\n\n default: {\n throw new Error(`Unsupported position ${String(positionDirection)}`);\n }\n }\n }\n\n return {\n path,\n state: 'present',\n update: (sourceContent) => apply(sourceContent, blockName),\n };\n}\n\n/**\n * Replace asynchronously a block in file that follows pattern :\n *\n * marker(markerBegin)\n * ...\n * marker(markerEnd)\n *\n * @param options\n */\nexport function block(options: BlockOptions) {\n return file(toFileOptions(options));\n}\n\n/**\n * Replace synchronously a block in file that follows pattern :\n *\n * marker(markerBegin)\n * ...\n * marker(markerEnd)\n *\n * @param options\n */\nexport function blockSync(options: BlockOptions) {\n return fileSync(toFileOptions(options));\n}\n","import { type FileOptions, file, fileSync } from './file.js';\n\nexport interface IgnoreFileOptions extends Omit<FileOptions, 'update'> {\n /**\n * File content mapping function where content is represented as lines.\n * When the file does not yet exist, the callback receives `undefined`.\n */\n readonly update?: ((content: string[] | undefined) => string[] | undefined) | undefined;\n}\n\nfunction toFileOption({ update, ...otherOptions }: IgnoreFileOptions): FileOptions {\n return {\n ...otherOptions,\n\n update:\n update == null\n ? update\n : (content) => {\n const eol = content.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const lines = content === '' ? undefined : content.split(eol);\n const updatedLines = update(lines);\n\n return updatedLines == null ? undefined : updatedLines.join(eol);\n },\n };\n}\n\n/**\n * Ensure file is present/absent asynchronously with content initialized or modified by line.\n *\n * @example\n * ```ts\n * await ignoreFile({\n * path: '.gitignore',\n * update: (lines) => [...(lines ?? []), 'dist'],\n * });\n * ```\n * @param options File target options.\n */\nexport async function ignoreFile(options: IgnoreFileOptions): Promise<void> {\n return file(toFileOption(options));\n}\n\n/**\n * Ensure file is present/absent synchronously with content initialized or modified by line.\n *\n * @example\n * ```ts\n * ignoreFileSync({\n * path: '.gitignore',\n * update: (lines) => [...(lines ?? []), 'dist'],\n * });\n * ```\n * @param options File target options.\n */\nexport function ignoreFileSync(options: IgnoreFileOptions): void {\n return fileSync(toFileOption(options));\n}\n","import { type FileOptions, file, fileSync } from './file.js';\n\nexport type JSONValue = null | number | string | boolean | JSONValue[] | { [key: string]: JSONValue };\n\nexport interface JSONOption<V = JSONValue> extends Omit<FileOptions, 'update'> {\n /**\n * File content mapping function\n */\n readonly update?: ((content: V | undefined) => V | undefined) | undefined;\n}\n\nfunction toFileOption<Value>({ update, ...otherOptions }: JSONOption<Value>): FileOptions {\n return {\n ...otherOptions,\n\n update:\n update == null\n ? update\n : (content) => {\n const jsonValue = content === '' ? undefined : (JSON.parse(content) as Value);\n\n return JSON.stringify(update(jsonValue));\n },\n };\n}\n\n/**\n * Ensure file is present/absent asynchronously with content value initialized or modified with `update`\n *\n * @param options\n */\nexport async function json<Value>(options: JSONOption<Value>): Promise<void> {\n return file(toFileOption(options));\n}\n\n/**\n * Ensure file is present/absent synchronously with content value initialized or modified with `update`\n *\n * @param options\n */\nexport function jsonSync<Value>(options: JSONOption<Value>): void {\n return fileSync(toFileOption(options));\n}\n","export const meta = Object.freeze({\n // @ts-ignore - these variables are injected at build time\n name: (typeof __PACKAGE_NAME__ === 'undefined' ? '' : __PACKAGE_NAME__) as string,\n // @ts-ignore - these variables are injected at build time\n version: (typeof __PACKAGE_VERSION__ === 'undefined' ? '' : __PACKAGE_VERSION__) as string,\n // @ts-ignore - these variables are injected at build time\n buildNumber: 1 as number, // (typeof __PACKAGE_BUILD_NUMBER__ === 'undefined' ? 0 : __PACKAGE_BUILD_NUMBER__) as number,\n});\n","import { spawn, spawnSync } from 'node:child_process';\n\nexport interface ExecOptions {\n /**\n * Current working directory\n */\n cwd?: string;\n\n /**\n * Stdio options\n */\n stdio?: 'inherit' | 'pipe' | 'ignore';\n}\n\n/**\n * Runs a command in a shell and returns a promise that resolves with an object\n * containing the stdout and stderr strings.\n *\n * @param command The command to run\n * @param args The arguments to pass to the command\n * @param options\n * @returns A promise that resolves with an object like `{ stdout: string, stderr: string }`\n */\nexport function execSync(\n command: string,\n args: ReadonlyArray<string>,\n options?: ExecOptions,\n): { stdout: string; stderr: string } {\n const result = spawnSync(command, args, { ...options });\n const encoding = 'utf8';\n\n return { stdout: result.stdout.toString(encoding), stderr: result.stderr.toString(encoding) };\n}\n\n/**\n * Runs a command in a shell and returns a promise that resolves with an object\n * containing the stdout and stderr strings.\n *\n * @param command The command to run\n * @param args The arguments to pass to the command\n * @param options\n */\nexport async function exec(\n command: string,\n args: ReadonlyArray<string>,\n options?: ExecOptions,\n): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const encoding = 'utf8';\n const child = spawn(command, args, { ...options });\n let stdout = '';\n let stderr = '';\n\n // Capture the stdout and stderr streams\n if (child.stdout != null) {\n child.stdout.on('data', (data) => {\n stdout += data.toString(encoding);\n });\n }\n if (child.stderr != null) {\n child.stderr.on('data', (data) => {\n stderr += data.toString(encoding);\n });\n }\n // Handle process exit\n child.on('close', (_code) => {\n resolve({ stdout, stderr });\n });\n\n // Handle errors\n child.on('error', reject);\n });\n}\n","import { exec, execSync } from './exec.js';\n\nexport interface YarnConfigOptions {\n /**\n * Configuration key\n */\n readonly key: string;\n\n /**\n * Option target state\n */\n readonly state: 'present' | 'absent';\n\n /**\n * File content mapping function\n *\n */\n readonly update?: ((content: string) => string | undefined) | undefined;\n}\n\n/**\n * Synchronous version of {@link yarnConfig}\n *\n * @param options\n * @example\n * yarnConfigSync({\n * key: 'nodeLinker',\n * state: 'present',\n * update: (content) => content.replace('node-modules', 'hoisted'),\n * })\n */\nexport function yarnConfigSync(options: YarnConfigOptions) {\n const { key, state, update } = options;\n if (state === 'present') {\n const { stdout } = execSync('yarn', ['config', 'get', String(key)]);\n execSync('yarn', ['config', 'set', String(key), `${update == null ? '' : update(stdout)}`]);\n } else {\n execSync('yarn', ['config', 'unset']);\n }\n}\n\n/**\n * Set/Unset yarn configuration value\n *\n * @param options\n * @example\n * await yarnConfig({\n * key: 'nodeLinker',\n * state: 'present',\n * update: (content) => content.replace('node-modules', 'hoisted'),\n * })\n */\nexport async function yarnConfig(options: YarnConfigOptions): Promise<void> {\n const { key, state, update } = options;\n if (state === 'present') {\n const { stdout } = await exec('yarn', ['config', 'get', String(key)]);\n await exec('yarn', ['config', 'set', String(key), `${update == null ? '' : update(stdout)}`]);\n } else {\n await exec('yarn', ['config', 'unset']);\n }\n}\n","import { exec, execSync } from './exec.js';\n\nexport type YarnVersionKind = 'berry' | 'classic';\n\nexport interface YarnVersionOptions {\n /**\n * Option target state\n */\n readonly state: 'present' | 'absent';\n\n /**\n * Version mapping function\n *\n */\n readonly update?: (() => YarnVersionKind | undefined) | undefined;\n}\n\n/**\n * Synchronous version of {@link yarnVersion}\n *\n * @param options\n * @example\n * yarnVersionSync({\n * state: 'present',\n * update: () => 'berry', // or 'classic'\n * })\n */\nexport function yarnVersionSync(options: YarnVersionOptions) {\n const { state, update } = options;\n if (state === 'present') {\n execSync('yarn', ['set', 'version', `${update == null ? 'berry' : update()}`]);\n } else {\n // TODO: remove yarn.lock\n throw new Error('Not implemented');\n }\n}\n\n/**\n * Set/Unset yarn configuration value\n *\n * @param options\n * @example\n * await yarnVersion({\n * state: 'present',\n * update: () => 'berry', // or 'classic'\n * })\n */\nexport async function yarnVersion(options: YarnVersionOptions): Promise<void> {\n const { state, update } = options;\n if (state === 'present') {\n await exec('yarn', ['set', 'version', `${update == null ? 'berry' : update()}`]);\n } else {\n // TODO: remove yarn.lock\n throw new Error('Not implemented');\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["toFileOption","toFileOption"],"sources":["../src/__exists.ts","../src/__existsSync.ts","../src/__toMode.ts","../src/file.ts","../src/block.ts","../src/directory.ts","../src/ignoreFile.ts","../src/json.ts","../src/meta.ts","../src/yaml.ts","../src/exec.ts","../src/yarnConfig.ts","../src/yarnVersion.ts"],"sourcesContent":["import { constants } from 'node:fs';\nimport { access } from 'node:fs/promises';\n\nexport async function __exists(path: string) {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import { accessSync, constants } from 'node:fs';\n\nexport function __existsSync(path: string) {\n try {\n accessSync(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import type { FileMode, FilePermissionSet } from './FileMode.js';\n\nexport function __toMode(mode: FileMode | undefined): number | undefined {\n return mode == null\n ? mode\n : (\n toModeFlag(mode.owner, 0o400, 0o200, 0o100)\n | toModeFlag(mode.group, 0o040, 0o020, 0o010)\n | toModeFlag(mode.other, 0o004, 0o002, 0o001)\n );\n}\n\nfunction toModeFlag(permissionSet: FilePermissionSet | undefined, read: number, write: number, execute: number): number {\n return (\n (permissionSet?.read === true ? read : 0)\n | (permissionSet?.write === true ? write : 0)\n | (permissionSet?.execute === true ? execute : 0)\n );\n}\n","import { chmodSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { chmod, readFile, rm, writeFile } from 'node:fs/promises';\n\nimport type { FileMode } from './FileMode.js';\n\nimport { __exists } from './__exists.js';\nimport { __existsSync } from './__existsSync.js';\nimport { __toMode } from './__toMode.js';\n\nexport interface FileOptions {\n /**\n * File encoding\n */\n readonly encoding?: BufferEncoding;\n\n /**\n * File permissions\n */\n readonly mode?: FileMode;\n\n /**\n * File path\n */\n readonly path: string;\n\n /**\n * File target state\n */\n readonly state: 'absent' | 'present';\n\n /**\n * File content mapping function\n *\n */\n readonly update?: ((content: string) => string | undefined) | undefined;\n}\n\n/**\n * Ensure file is present/absent with content initialized or modified with `update\n *\n * @example\n * ```ts\n * await file({\n * path: 'foo/bar',\n * state: 'present',\n * update: (content) => content + '_test', // This will append '_test' after current content\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport async function file(options: FileOptions): Promise<void> {\n const { encoding = 'utf8', mode, path, state, update } = options;\n if (state === 'present') {\n const isPresent = await __exists(path);\n const previousContent = isPresent ? await readFile(path, encoding) : '';\n const newContent = update == null ? (isPresent ? undefined : '') : update(previousContent);\n const newMode = __toMode(mode);\n if (newContent != null) {\n await writeFile(path, newContent, { encoding, mode: newMode });\n }\n if (newMode != null && (isPresent || newContent != null)) {\n await chmod(path, newMode);\n }\n } else {\n await rm(path, { force: true });\n }\n}\n\n/**\n * Ensure file is present/absent with content initialized or modified with `update\n *\n * @example\n * ```ts\n * fileSync({\n * path: 'foo/bar',\n * state: 'present',\n * update: (content) => content + '_test', // This will append '_test' after current content\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport function fileSync(options: FileOptions): void {\n const { encoding = 'utf8', mode, path, state, update } = options;\n if (state === 'present') {\n const isPresent = __existsSync(path);\n const previousContent = isPresent ? readFileSync(path, encoding) : '';\n const newContent = update == null ? (isPresent ? undefined : '') : update(previousContent);\n const newMode = __toMode(mode);\n if (newContent != null) {\n writeFileSync(path, newContent, { encoding, mode: newMode });\n }\n if (newMode != null && (isPresent || newContent != null)) {\n chmodSync(path, newMode);\n }\n } else {\n rmSync(path, { force: true });\n }\n}\n","import { file, type FileOptions, fileSync } from './file.js';\n\nexport interface BlockOptions {\n /**\n * Block content to insert\n */\n block: string;\n\n /**\n * Insert position\n */\n insertPosition?: ['after', 'EndOfFile' | RegExp] | ['before', 'BeginningOfFile' | RegExp];\n\n /**\n * The marker builder function that will take either `markerBegin` or `markerEnd`\n *\n * @default '# ${mark} MANAGED BLOCK'\n */\n marker?: (mark: 'Begin' | 'End') => string;\n\n /**\n * File path\n */\n path: string;\n\n /**\n * Block target state\n */\n state?: 'absent' | 'present';\n}\n\nconst EOF = 'EndOfFile';\nconst BOF = 'BeginningOfFile';\nconst insertAt = (str: string, index: number, toInsert: string) => str.slice(0, index) + toInsert + str.slice(index);\nconst matchLast = (string: string, regexp: RegExp) => {\n const matcher = new RegExp(regexp.source, `${regexp.flags}g`);\n let firstIndex = -1;\n let lastIndex = -1;\n let matches;\n\n while (true) {\n matches = matcher.exec(string);\n if (matches == null) {\n break;\n }\n firstIndex = matches.index;\n lastIndex = matcher.lastIndex;\n }\n return { firstIndex, lastIndex };\n};\n\n/**\n * Replace asynchronously a block in file that follows pattern :\n *\n * marker(markerBegin)\n * ...\n * marker(markerEnd)\n *\n * @param options\n */\nexport function block(options: BlockOptions) {\n return file(toFileOptions(options));\n}\n\n/**\n * Replace synchronously a block in file that follows pattern :\n *\n * marker(markerBegin)\n * ...\n * marker(markerEnd)\n *\n * @param options\n */\nexport function blockSync(options: BlockOptions) {\n return fileSync(toFileOptions(options));\n}\n\nfunction toFileOptions(options: BlockOptions): FileOptions {\n const {\n block: blockName,\n insertPosition = ['after', EOF],\n marker = (mark) => `# ${mark.toUpperCase()} MANAGED BLOCK`,\n path,\n state = 'present',\n } = options;\n\n const EOL = '\\n';\n const beginBlock = marker('Begin');\n const endBlock = marker('End');\n\n /**\n * @param content\n */\n function findBlock(content: string) {\n const startIndex = content.indexOf(beginBlock);\n const endIndex = content.indexOf(endBlock) + endBlock.length;\n\n return {\n endIndex,\n exists: startIndex !== -1 && endIndex >= 0,\n startIndex,\n };\n }\n\n function apply(fullContent: string, blockContent: string) {\n const found = findBlock(fullContent);\n const remove = state === 'absent';\n const replaceBlock = remove ? '' : beginBlock + EOL + blockContent + EOL + endBlock;\n const [positionDirection, positionAnchor] = insertPosition;\n\n if (found.exists) {\n return fullContent.slice(0, found.startIndex) + replaceBlock + fullContent.slice(found.endIndex);\n }\n if (remove) {\n return fullContent;\n }\n switch (positionDirection) {\n case 'after': {\n // insert\n if (positionAnchor !== EOF) {\n const { lastIndex } = matchLast(fullContent, positionAnchor);\n if (lastIndex >= 0) {\n return insertAt(fullContent, lastIndex, EOL + replaceBlock);\n }\n }\n\n // end of file\n return fullContent + EOL + replaceBlock;\n }\n case 'before': {\n if (positionAnchor !== BOF) {\n const { firstIndex } = matchLast(fullContent, positionAnchor);\n if (firstIndex >= 0) {\n return insertAt(fullContent, firstIndex, replaceBlock + EOL);\n }\n }\n\n // Beginning of file\n return replaceBlock + EOL + fullContent;\n }\n\n default: {\n throw new Error(`Unsupported position ${String(positionDirection)}`);\n }\n }\n }\n\n return {\n path,\n state: 'present',\n update: (sourceContent) => apply(sourceContent, blockName),\n };\n}\n","import { chmodSync, mkdirSync, rmSync } from 'node:fs';\nimport { chmod, mkdir, rm } from 'node:fs/promises';\n\nimport type { FileMode } from './FileMode.js';\n\nimport { __exists } from './__exists.js';\nimport { __existsSync } from './__existsSync.js';\nimport { __toMode } from './__toMode.js';\n\nexport interface DirectoryOptions {\n /**\n * File permissions\n */\n readonly mode?: FileMode;\n\n /**\n * Directory path\n */\n readonly path: string;\n\n /**\n * Directory target state\n */\n readonly state: 'absent' | 'present';\n}\n\n/**\n * Ensure directory is present/absent\n *\n * @example\n * ```ts\n * await directory({\n * path: 'foo/bar',\n * state: 'present',\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport async function directory(options: DirectoryOptions): Promise<void> {\n const { mode, path, state } = options;\n const isPresent = await __exists(path);\n if (state === 'present') {\n const newMode = __toMode(mode);\n if (!isPresent) {\n await mkdir(path, { mode: newMode, recursive: true });\n }\n if (newMode != null && isPresent) {\n await chmod(path, newMode);\n }\n } else if (isPresent) {\n await rm(path, { recursive: true });\n }\n}\n\n/**\n * Ensure directory is present/absent\n *\n * @example\n * ```ts\n * directorySync({\n * path: 'foo/bar',\n * state: 'present',\n * mode: {\n * owner: { read: true, write: true, execute: true },\n * group: { read: true, write: true, execute: true },\n * other: { read: true, write: true, execute: true },\n * },\n * })\n * ```\n *\n * @param options\n */\nexport function directorySync(options: DirectoryOptions): void {\n const { mode, path, state } = options;\n const isPresent = __existsSync(path);\n if (state === 'present') {\n const newMode = __toMode(mode);\n if (!isPresent) {\n mkdirSync(path, { mode: newMode, recursive: true });\n }\n if (newMode != null && isPresent) {\n chmodSync(path, newMode);\n }\n } else if (isPresent) {\n rmSync(path, { recursive: true });\n }\n}\n","import { file, type FileOptions, fileSync } from './file.js';\n\nexport interface IgnoreFileOptions extends Omit<FileOptions, 'update'> {\n /**\n * File content mapping function where content is represented as lines.\n * When the file does not yet exist, the callback receives `undefined`.\n */\n readonly update?: ((content: string[] | undefined) => string[] | undefined) | undefined;\n}\n\n/**\n * Ensure file is present/absent asynchronously with content initialized or modified by line.\n *\n * @example\n * ```ts\n * await ignoreFile({\n * path: '.gitignore',\n * update: (lines) => [...(lines ?? []), 'dist'],\n * });\n * ```\n * @param options File target options.\n */\nexport async function ignoreFile(options: IgnoreFileOptions): Promise<void> {\n return file(toFileOption(options));\n}\n\n/**\n * Ensure file is present/absent synchronously with content initialized or modified by line.\n *\n * @example\n * ```ts\n * ignoreFileSync({\n * path: '.gitignore',\n * update: (lines) => [...(lines ?? []), 'dist'],\n * });\n * ```\n * @param options File target options.\n */\nexport function ignoreFileSync(options: IgnoreFileOptions): void {\n return fileSync(toFileOption(options));\n}\n\nfunction toFileOption({ update, ...otherOptions }: IgnoreFileOptions): FileOptions {\n return {\n ...otherOptions,\n\n update:\n update == null\n ? update\n : (content) => {\n const eol = content.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const lines = content === '' ? undefined : content.split(eol);\n const updatedLines = update(lines);\n\n return updatedLines == null ? undefined : updatedLines.join(eol);\n },\n };\n}\n","import { file, type FileOptions, fileSync } from './file.js';\n\nexport interface JSONOption<V = JSONValue> extends Omit<FileOptions, 'update'> {\n /**\n * File content mapping function\n */\n readonly update?: ((content: undefined | V) => undefined | V) | undefined;\n}\n\nexport type JSONValue = boolean | JSONValue[] | null | number | string | { [key: string]: JSONValue };\n\n/**\n * Ensure file is present/absent asynchronously with content value initialized or modified with `update`\n *\n * @param options\n */\nexport async function json<Value>(options: JSONOption<Value>): Promise<void> {\n return file(toFileOption(options));\n}\n\n/**\n * Ensure file is present/absent synchronously with content value initialized or modified with `update`\n *\n * @param options\n */\nexport function jsonSync<Value>(options: JSONOption<Value>): void {\n return fileSync(toFileOption(options));\n}\n\nfunction toFileOption<Value>({ update, ...otherOptions }: JSONOption<Value>): FileOptions {\n return {\n ...otherOptions,\n\n update:\n update == null\n ? update\n : (content) => {\n const jsonValue = content === '' ? undefined : (JSON.parse(content) as Value);\n\n return JSON.stringify(update(jsonValue));\n },\n };\n}\n","export const meta = Object.freeze({\n // @ts-ignore - these variables are injected at build time\n buildNumber: 1 as number, // (typeof __PACKAGE_BUILD_NUMBER__ === 'undefined' ? 0 : __PACKAGE_BUILD_NUMBER__) as number,\n // @ts-ignore - these variables are injected at build time\n name: (typeof __PACKAGE_NAME__ === 'undefined' ? '' : __PACKAGE_NAME__) as string,\n // @ts-ignore - these variables are injected at build time\n version: (typeof __PACKAGE_VERSION__ === 'undefined' ? '' : __PACKAGE_VERSION__) as string,\n});\n","import YAML from 'yaml';\n\nimport { file, type FileOptions, fileSync } from './file.js';\n\nexport interface YAMLOption<V = YAMLValue> extends Omit<FileOptions, 'update'> {\n /**\n * File content mapping function\n */\n readonly update?: ((content: undefined | V) => undefined | V) | undefined;\n}\n\nexport type YAMLValue = boolean | null | number | string | YAMLValue[] | { [key: string]: YAMLValue };\n\n/**\n * Ensure file is present/absent asynchronously with content value initialized or modified with `update`\n *\n * @param options\n */\nexport async function yaml<Value>(options: YAMLOption<Value>): Promise<void> {\n return file(toFileOption(options));\n}\n\n/**\n * Ensure file is present/absent synchronously with content value initialized or modified with `update`\n *\n * @param options\n */\nexport function yamlSync<Value>(options: YAMLOption<Value>): void {\n return fileSync(toFileOption(options));\n}\n\nfunction toFileOption<Value>({ update, ...otherOptions }: YAMLOption<Value>): FileOptions {\n return {\n ...otherOptions,\n\n update:\n update == null\n ? update\n : (content) => {\n const yamlValue = content === '' ? undefined : (YAML.parse(content) as Value);\n\n return YAML.stringify(update(yamlValue));\n },\n };\n}\n","import { spawn, spawnSync } from 'node:child_process';\n\nexport interface ExecOptions {\n /**\n * Current working directory\n */\n cwd?: string;\n\n /**\n * Stdio options\n */\n stdio?: 'ignore' | 'inherit' | 'pipe';\n}\n\n/**\n * Runs a command in a shell and returns a promise that resolves with an object\n * containing the stdout and stderr strings.\n *\n * @param command The command to run\n * @param args The arguments to pass to the command\n * @param options\n */\nexport async function exec(\n command: string,\n args: ReadonlyArray<string>,\n options?: ExecOptions,\n): Promise<{ stderr: string; stdout: string }> {\n return new Promise((resolve, reject) => {\n const encoding = 'utf8';\n const child = spawn(command, args, { ...options });\n let stdout = '';\n let stderr = '';\n\n // Capture the stdout and stderr streams\n if (child.stdout != null) {\n child.stdout.on('data', (data) => {\n stdout += data.toString(encoding);\n });\n }\n if (child.stderr != null) {\n child.stderr.on('data', (data) => {\n stderr += data.toString(encoding);\n });\n }\n // Handle process exit\n child.on('close', (_code) => {\n resolve({ stderr, stdout });\n });\n\n // Handle errors\n child.on('error', reject);\n });\n}\n\n/**\n * Runs a command in a shell and returns a promise that resolves with an object\n * containing the stdout and stderr strings.\n *\n * @param command The command to run\n * @param args The arguments to pass to the command\n * @param options\n * @returns A promise that resolves with an object like `{ stdout: string, stderr: string }`\n */\nexport function execSync(\n command: string,\n args: ReadonlyArray<string>,\n options?: ExecOptions,\n): { stderr: string; stdout: string } {\n const result = spawnSync(command, args, { ...options });\n const encoding = 'utf8';\n\n return { stderr: result.stderr.toString(encoding), stdout: result.stdout.toString(encoding) };\n}\n","import { exec, execSync } from './exec.js';\n\nexport interface YarnConfigOptions {\n /**\n * Configuration key\n */\n readonly key: string;\n\n /**\n * Option target state\n */\n readonly state: 'absent' | 'present';\n\n /**\n * File content mapping function\n *\n */\n readonly update?: ((content: string) => string | undefined) | undefined;\n}\n\n/**\n * Set/Unset yarn configuration value\n *\n * @param options\n * @example\n * await yarnConfig({\n * key: 'nodeLinker',\n * state: 'present',\n * update: (content) => content.replace('node-modules', 'hoisted'),\n * })\n */\nexport async function yarnConfig(options: YarnConfigOptions): Promise<void> {\n const { key, state, update } = options;\n if (state === 'present') {\n const { stdout } = await exec('yarn', ['config', 'get', String(key)]);\n await exec('yarn', ['config', 'set', String(key), String(update == null ? '' : update(stdout))]);\n } else {\n await exec('yarn', ['config', 'unset']);\n }\n}\n\n/**\n * Synchronous version of {@link yarnConfig}\n *\n * @param options\n * @example\n * yarnConfigSync({\n * key: 'nodeLinker',\n * state: 'present',\n * update: (content) => content.replace('node-modules', 'hoisted'),\n * })\n */\nexport function yarnConfigSync(options: YarnConfigOptions) {\n const { key, state, update } = options;\n if (state === 'present') {\n const { stdout } = execSync('yarn', ['config', 'get', String(key)]);\n execSync('yarn', ['config', 'set', String(key), String(update == null ? '' : update(stdout))]);\n } else {\n execSync('yarn', ['config', 'unset']);\n }\n}\n","import { exec, execSync } from './exec.js';\n\nexport type YarnVersionKind = 'berry' | 'classic';\n\nexport interface YarnVersionOptions {\n /**\n * Option target state\n */\n readonly state: 'absent' | 'present';\n\n /**\n * Version mapping function\n *\n */\n readonly update?: (() => undefined | YarnVersionKind) | undefined;\n}\n\n/**\n * Set/Unset yarn configuration value\n *\n * @param options\n * @example\n * await yarnVersion({\n * state: 'present',\n * update: () => 'berry', // or 'classic'\n * })\n */\nexport async function yarnVersion(options: YarnVersionOptions): Promise<void> {\n const { state, update } = options;\n if (state === 'present') {\n await exec('yarn', ['set', 'version', String(update == null ? 'berry' : update())]);\n } else {\n // TODO: remove yarn.lock\n throw new Error('Not implemented');\n }\n}\n\n/**\n * Synchronous version of {@link yarnVersion}\n *\n * @param options\n * @example\n * yarnVersionSync({\n * state: 'present',\n * update: () => 'berry', // or 'classic'\n * })\n */\nexport function yarnVersionSync(options: YarnVersionOptions) {\n const { state, update } = options;\n if (state === 'present') {\n execSync('yarn', ['set', 'version', String(update == null ? 'berry' : update())]);\n } else {\n // TODO: remove yarn.lock\n throw new Error('Not implemented');\n }\n}\n"],"mappings":"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"}
|