@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.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/directory.ts
33
- /**
34
- * Ensure directory is present/absent
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
- * Ensure directory is present/absent
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 { path, state, update, encoding = "utf8", mode } = options;
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 { path, state, update, encoding = "utf8", mode } = options;
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, block: blockName, insertPosition = ["after", EOF], state = "present" } = options;
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
- * Replace asynchronously a block in file that follows pattern :
194
+ * Ensure directory is present/absent
230
195
  *
231
- * marker(markerBegin)
232
- * ...
233
- * marker(markerEnd)
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 block(options) {
238
- return file(toFileOptions(options));
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
- * Replace synchronously a block in file that follows pattern :
224
+ * Ensure directory is present/absent
242
225
  *
243
- * marker(markerBegin)
244
- * ...
245
- * marker(markerEnd)
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 blockSync(options) {
250
- return fileSync(toFileOptions(options));
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$1(options));
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$1(options));
283
+ return fileSync(toFileOption$2(options));
293
284
  }
294
- //#endregion
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 jsonValue = content === "" ? void 0 : JSON.parse(content);
301
- return JSON.stringify(update(jsonValue));
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.7",
326
- buildNumber: 1
327
+ version: "1.0.0-alpha.9"
327
328
  });
328
329
  //#endregion
329
- //#region src/exec.ts
330
+ //#region src/yaml.ts
330
331
  /**
331
- * Runs a command in a shell and returns a promise that resolves with an object
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 execSync(command, args, options) {
340
- const result = spawnSync(command, args, { ...options });
341
- const encoding = "utf8";
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
- stdout: result.stdout.toString(encoding),
344
- stderr: result.stderr.toString(encoding)
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
- stdout,
370
- stderr
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
- * Synchronous version of {@link yarnConfig}
407
+ * Set/Unset yarn configuration value
380
408
  *
381
409
  * @param options
382
410
  * @example
383
- * yarnConfigSync({
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 yarnConfigSync(options) {
417
+ async function yarnConfig(options) {
390
418
  const { key, state, update } = options;
391
419
  if (state === "present") {
392
- const { stdout } = execSync("yarn", [
420
+ const { stdout } = await exec("yarn", [
393
421
  "config",
394
422
  "get",
395
423
  String(key)
396
424
  ]);
397
- execSync("yarn", [
425
+ await exec("yarn", [
398
426
  "config",
399
427
  "set",
400
428
  String(key),
401
- `${update == null ? "" : update(stdout)}`
429
+ String(update == null ? "" : update(stdout))
402
430
  ]);
403
- } else execSync("yarn", ["config", "unset"]);
431
+ } else await exec("yarn", ["config", "unset"]);
404
432
  }
405
433
  /**
406
- * Set/Unset yarn configuration value
434
+ * Synchronous version of {@link yarnConfig}
407
435
  *
408
436
  * @param options
409
437
  * @example
410
- * await yarnConfig({
438
+ * yarnConfigSync({
411
439
  * key: 'nodeLinker',
412
440
  * state: 'present',
413
441
  * update: (content) => content.replace('node-modules', 'hoisted'),
414
442
  * })
415
443
  */
416
- async function yarnConfig(options) {
444
+ function yarnConfigSync(options) {
417
445
  const { key, state, update } = options;
418
446
  if (state === "present") {
419
- const { stdout } = await exec("yarn", [
447
+ const { stdout } = execSync("yarn", [
420
448
  "config",
421
449
  "get",
422
450
  String(key)
423
451
  ]);
424
- await exec("yarn", [
452
+ execSync("yarn", [
425
453
  "config",
426
454
  "set",
427
455
  String(key),
428
- `${update == null ? "" : update(stdout)}`
456
+ String(update == null ? "" : update(stdout))
429
457
  ]);
430
- } else await exec("yarn", ["config", "unset"]);
458
+ } else execSync("yarn", ["config", "unset"]);
431
459
  }
432
460
  //#endregion
433
461
  //#region src/yarnVersion.ts
434
462
  /**
435
- * Synchronous version of {@link yarnVersion}
463
+ * Set/Unset yarn configuration value
436
464
  *
437
465
  * @param options
438
466
  * @example
439
- * yarnVersionSync({
467
+ * await yarnVersion({
440
468
  * state: 'present',
441
469
  * update: () => 'berry', // or 'classic'
442
470
  * })
443
471
  */
444
- function yarnVersionSync(options) {
472
+ async function yarnVersion(options) {
445
473
  const { state, update } = options;
446
- if (state === "present") execSync("yarn", [
474
+ if (state === "present") await exec("yarn", [
447
475
  "set",
448
476
  "version",
449
- `${update == null ? "berry" : update()}`
477
+ String(update == null ? "berry" : update())
450
478
  ]);
451
479
  else throw new Error("Not implemented");
452
480
  }
453
481
  /**
454
- * Set/Unset yarn configuration value
482
+ * Synchronous version of {@link yarnVersion}
455
483
  *
456
484
  * @param options
457
485
  * @example
458
- * await yarnVersion({
486
+ * yarnVersionSync({
459
487
  * state: 'present',
460
488
  * update: () => 'berry', // or 'classic'
461
489
  * })
462
490
  */
463
- async function yarnVersion(options) {
491
+ function yarnVersionSync(options) {
464
492
  const { state, update } = options;
465
- if (state === "present") await exec("yarn", [
493
+ if (state === "present") execSync("yarn", [
466
494
  "set",
467
495
  "version",
468
- `${update == null ? "berry" : update()}`
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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"}