presetter 4.5.0 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/content.d.ts +77 -0
- package/lib/content.d.ts.map +1 -1
- package/lib/content.js +126 -1
- package/lib/directive.d.ts +23 -0
- package/lib/directive.d.ts.map +1 -1
- package/lib/directive.js +85 -1
- package/lib/error.d.ts +6 -0
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +21 -1
- package/lib/executable/entry.d.ts +5 -0
- package/lib/executable/entry.d.ts.map +1 -1
- package/lib/executable/entry.js +24 -1
- package/lib/executable/error.d.ts +4 -0
- package/lib/executable/error.d.ts.map +1 -1
- package/lib/executable/error.js +23 -1
- package/lib/executable/index.js +16 -1
- package/lib/index.js +16 -1
- package/lib/io.d.ts +39 -0
- package/lib/io.d.ts.map +1 -1
- package/lib/io.js +96 -11
- package/lib/package.d.ts +22 -0
- package/lib/package.d.ts.map +1 -1
- package/lib/package.js +53 -3
- package/lib/preset/content.d.ts +7 -0
- package/lib/preset/content.d.ts.map +1 -1
- package/lib/preset/content.js +20 -1
- package/lib/preset/context.d.ts +4 -0
- package/lib/preset/context.d.ts.map +1 -1
- package/lib/preset/context.js +19 -1
- package/lib/preset/graph.d.ts +17 -0
- package/lib/preset/graph.d.ts.map +1 -1
- package/lib/preset/graph.js +34 -1
- package/lib/preset/index.js +25 -1
- package/lib/preset/mapping.d.ts +6 -0
- package/lib/preset/mapping.d.ts.map +1 -1
- package/lib/preset/mapping.js +25 -2
- package/lib/preset/presetterRC.d.ts +19 -0
- package/lib/preset/presetterRC.d.ts.map +1 -1
- package/lib/preset/presetterRC.js +37 -1
- package/lib/preset/scripts.d.ts +4 -0
- package/lib/preset/scripts.d.ts.map +1 -1
- package/lib/preset/scripts.js +19 -1
- package/lib/preset/setup.d.ts +10 -0
- package/lib/preset/setup.d.ts.map +1 -1
- package/lib/preset/setup.js +38 -1
- package/lib/preset/unset.d.ts +3 -0
- package/lib/preset/unset.d.ts.map +1 -1
- package/lib/preset/unset.js +18 -1
- package/lib/resolution.d.ts +17 -0
- package/lib/resolution.d.ts.map +1 -1
- package/lib/resolution.js +33 -1
- package/lib/run.d.ts +7 -0
- package/lib/run.d.ts.map +1 -1
- package/lib/run.js +77 -1
- package/lib/scripts.d.ts +12 -0
- package/lib/scripts.d.ts.map +1 -1
- package/lib/scripts.js +50 -1
- package/lib/task.d.ts +18 -0
- package/lib/task.d.ts.map +1 -1
- package/lib/task.js +40 -2
- package/lib/template.d.ts +47 -0
- package/lib/template.d.ts.map +1 -1
- package/lib/template.js +96 -2
- package/lib/utilities/index.js +16 -1
- package/lib/utilities/mapValues.d.ts +6 -0
- package/lib/utilities/mapValues.d.ts.map +1 -1
- package/lib/utilities/mapValues.js +21 -1
- package/package.json +3 -3
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../source/executable/entry.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../source/executable/entry.ts"],"names":[],"mappings":"AA+HA;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBzD"}
|
package/lib/executable/entry.js
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
/*
|
2
|
+
* *** MIT LICENSE ***
|
3
|
+
* -------------------------------------------------------------------------
|
4
|
+
* This code may be modified and distributed under the MIT license.
|
5
|
+
* See the LICENSE file for details.
|
6
|
+
* -------------------------------------------------------------------------
|
7
|
+
*
|
8
|
+
* @summary Entry point for the command line interface (CLI)
|
9
|
+
*
|
10
|
+
* @author Alvis HT Tang <alvis@hilbert.space>
|
11
|
+
* @license MIT
|
12
|
+
* @copyright Copyright (c) 2019 - All Rights Reserved.
|
13
|
+
* -------------------------------------------------------------------------
|
14
|
+
*/
|
1
15
|
import { existsSync } from 'node:fs';
|
2
16
|
import yargs from 'yargs';
|
3
17
|
import { bootstrapPreset, setupPreset, unsetPreset } from '../preset/index.js';
|
@@ -31,6 +45,7 @@ const bootstrapCommand = {
|
|
31
45
|
.help(),
|
32
46
|
handler: async (argv) => {
|
33
47
|
const { force, only } = argv;
|
48
|
+
// only proceed if the specified file exists
|
34
49
|
if (!only || existsSync(only)) {
|
35
50
|
await bootstrapPreset({ force });
|
36
51
|
}
|
@@ -48,6 +63,7 @@ const runCommand = {
|
|
48
63
|
.usage('run <task>')
|
49
64
|
.demandCommand(),
|
50
65
|
handler: async (argv) => {
|
66
|
+
// get the options
|
51
67
|
const [, selector] = argv._.map((arg) => arg.toString());
|
52
68
|
const args = parseGlobalArgs(argv);
|
53
69
|
await run([{ selector, args }], { templateOnly: argv.template });
|
@@ -80,9 +96,16 @@ const unsetCommand = {
|
|
80
96
|
describe: 'remove all artifacts created by the preset',
|
81
97
|
handler: async () => unsetPreset(),
|
82
98
|
};
|
99
|
+
/**
|
100
|
+
* provide a command line interface
|
101
|
+
* @param args command line arguments
|
102
|
+
* @returns the command entered together with its options
|
103
|
+
*/
|
83
104
|
export async function entry(args) {
|
84
105
|
await yargs()
|
85
106
|
.parserConfiguration({
|
107
|
+
// make sure flags after end-of-options flag `--` are stored under `--`, not `_`
|
108
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
86
109
|
'populate--': true,
|
87
110
|
})
|
88
111
|
.usage('⚙ presetter: your preset configurator')
|
@@ -96,4 +119,4 @@ export async function entry(args) {
|
|
96
119
|
.demandCommand()
|
97
120
|
.parse(args);
|
98
121
|
}
|
99
|
-
//# sourceMappingURL=data:application/json;base64,
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zb3VyY2UvZXhlY3V0YWJsZS9lbnRyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVyQyxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFFMUIsT0FBTyxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDN0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFJekQsTUFBTSxVQUFVLEdBQStEO0lBQzdFLE9BQU8sRUFBRSxnQkFBZ0I7SUFDekIsUUFBUSxFQUFFLDJDQUEyQztJQUNyRCxPQUFPLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNqQixLQUFLO1NBQ0YsVUFBVSxDQUFDLFFBQVEsRUFBRTtRQUNwQixRQUFRLEVBQUUsSUFBYTtRQUN2QixJQUFJLEVBQUUsUUFBUTtRQUNkLFdBQVcsRUFBRSxtQ0FBbUM7S0FDakQsQ0FBQztTQUNELElBQUksRUFBRTtJQUNYLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxXQUFXLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0NBQ3JELENBQUM7QUFFRixNQUFNLGdCQUFnQixHQUdsQjtJQUNGLE9BQU8sRUFBRSxXQUFXO0lBQ3BCLFFBQVEsRUFBRSxxREFBcUQ7SUFDL0QsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDakIsS0FBSztTQUNGLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDZixJQUFJLEVBQUUsU0FBUztRQUNmLE9BQU8sRUFBRSxLQUFLO1FBQ2QsV0FBVyxFQUFFLDBCQUEwQjtLQUN4QyxDQUFDO1NBQ0Qs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
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../source/executable/error.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../source/executable/error.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB7D"}
|
package/lib/executable/error.js
CHANGED
@@ -1,14 +1,36 @@
|
|
1
|
+
/*
|
2
|
+
* *** MIT LICENSE ***
|
3
|
+
* -------------------------------------------------------------------------
|
4
|
+
* This code may be modified and distributed under the MIT license.
|
5
|
+
* See the LICENSE file for details.
|
6
|
+
* -------------------------------------------------------------------------
|
7
|
+
*
|
8
|
+
* @summary Helpers for handling error
|
9
|
+
*
|
10
|
+
* @author Alvis HT Tang <alvis@hilbert.space>
|
11
|
+
* @license MIT
|
12
|
+
* @copyright Copyright (c) 2019 - All Rights Reserved.
|
13
|
+
* -------------------------------------------------------------------------
|
14
|
+
*/
|
15
|
+
/* istanbul ignore file */
|
1
16
|
import { warn } from 'node:console';
|
2
17
|
import createCallsiteRecord from 'callsite-record';
|
3
18
|
import chalk from 'chalk';
|
19
|
+
/**
|
20
|
+
* print error nicely on console
|
21
|
+
* @param error the error to be reported
|
22
|
+
*/
|
4
23
|
export async function handleError(error) {
|
5
24
|
if (!process.stdout.isTTY) {
|
25
|
+
// don't print formatted error message if the process is not run on TTY
|
6
26
|
warn(error);
|
7
27
|
}
|
8
28
|
else {
|
29
|
+
// print the error message
|
9
30
|
const type = chalk.red.bold(`[${error.name}]`);
|
10
31
|
const message = chalk.white.bold(error.message.trim());
|
11
32
|
warn(`${type} ${message}`);
|
33
|
+
// print the callsite record
|
12
34
|
const record = createCallsiteRecord({
|
13
35
|
forError: error,
|
14
36
|
});
|
@@ -18,4 +40,4 @@ export async function handleError(error) {
|
|
18
40
|
}
|
19
41
|
}
|
20
42
|
}
|
21
|
-
//# sourceMappingURL=data:application/json;base64,
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zb3VyY2UvZXhlY3V0YWJsZS9lcnJvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsMEJBQTBCO0FBRTFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFcEMsT0FBTyxvQkFBb0IsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFFMUI7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBWTtJQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDekIsdUVBQXVFO1FBQ3ZFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNiO1NBQU07UUFDTCwwQkFBMEI7UUFDMUIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUMvQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLEdBQUcsSUFBSSxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFM0IsNEJBQTRCO1FBQzVCLE1BQU0sTUFBTSxHQUFHLG9CQUFvQixDQUFDO1lBQ2xDLFFBQVEsRUFBRSxLQUFLO1NBQ2hCLENBQUMsQ0FBQztRQUVILElBQUksTUFBTSxFQUFFO1lBQ1YsSUFBSSxFQUFFLENBQUM7WUFDUCxJQUFJLENBQUMsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDL0I7S0FDRjtBQUNILENBQUMifQ==
|
package/lib/executable/index.js
CHANGED
@@ -1,5 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
* *** MIT LICENSE ***
|
3
|
+
* -------------------------------------------------------------------------
|
4
|
+
* This code may be modified and distributed under the MIT license.
|
5
|
+
* See the LICENSE file for details.
|
6
|
+
* -------------------------------------------------------------------------
|
7
|
+
*
|
8
|
+
* @summary A command line interface for presetter
|
9
|
+
*
|
10
|
+
* @author Alvis HT Tang <alvis@hilbert.space>
|
11
|
+
* @license MIT
|
12
|
+
* @copyright Copyright (c) 2019 - All Rights Reserved.
|
13
|
+
* -------------------------------------------------------------------------
|
14
|
+
*/
|
15
|
+
/* istanbul ignore file */
|
1
16
|
import { entry } from './entry.js';
|
2
17
|
import { handleError } from './error.js';
|
3
18
|
const [, , ...args] = process.argv;
|
4
19
|
entry(args).catch(handleError);
|
5
|
-
//# sourceMappingURL=data:application/json;base64,
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zb3VyY2UvZXhlY3V0YWJsZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsMEJBQTBCO0FBRTFCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDaEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUV0QyxNQUFNLENBQUMsRUFBRSxBQUFELEVBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO0FBRW5DLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMifQ==
|
package/lib/index.js
CHANGED
@@ -1,7 +1,22 @@
|
|
1
|
+
/*
|
2
|
+
* *** MIT LICENSE ***
|
3
|
+
* -------------------------------------------------------------------------
|
4
|
+
* This code may be modified and distributed under the MIT license.
|
5
|
+
* See the LICENSE file for details.
|
6
|
+
* -------------------------------------------------------------------------
|
7
|
+
*
|
8
|
+
* @summary Collection of public types
|
9
|
+
*
|
10
|
+
* @author Alvis HT Tang <alvis@hilbert.space>
|
11
|
+
* @license MIT
|
12
|
+
* @copyright Copyright (c) 2020 - All Rights Reserved.
|
13
|
+
* -------------------------------------------------------------------------
|
14
|
+
*/
|
15
|
+
/* istanbul ignore file */
|
1
16
|
export * from 'presetter-types';
|
2
17
|
export * from './content.js';
|
3
18
|
export * from './directive.js';
|
4
19
|
export * from './io.js';
|
5
20
|
export * from './resolution.js';
|
6
21
|
export * from './template.js';
|
7
|
-
//# sourceMappingURL=data:application/json;base64,
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2UvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUVILDBCQUEwQjtBQUUxQixjQUFjLGlCQUFpQixDQUFDO0FBRWhDLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsTUFBTSxDQUFDO0FBQ3JCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsWUFBWSxDQUFDIn0=
|
package/lib/io.d.ts
CHANGED
@@ -1,11 +1,50 @@
|
|
1
1
|
import type { Template } from 'presetter-types';
|
2
|
+
/** collection of options for file ios */
|
2
3
|
export interface IOOptions {
|
4
|
+
/** whether to overwrite existing files */
|
3
5
|
force?: boolean;
|
4
6
|
}
|
7
|
+
/**
|
8
|
+
* check if a path is either a link or a file with multiple hard links
|
9
|
+
* @param path path to be checked
|
10
|
+
* @returns true if the path is a link or a file with multiple hard links
|
11
|
+
*/
|
12
|
+
export declare function islink(path: string): boolean;
|
13
|
+
/**
|
14
|
+
* load the content of a file
|
15
|
+
* @param path file path to be loaded
|
16
|
+
* @param defaultFormat default format of the file
|
17
|
+
* @returns content of the file
|
18
|
+
*/
|
5
19
|
export declare function loadFile(path: string, defaultFormat?: 'json' | 'yaml'): Record<string, unknown>;
|
6
20
|
export declare function loadFile(path: string, defaultFormat?: 'text'): string;
|
21
|
+
/**
|
22
|
+
* serialize a configuration content to the right format according to its destination
|
23
|
+
* @param destination the path to which the content will be written
|
24
|
+
* @param content configuration content
|
25
|
+
* @returns serialized content
|
26
|
+
*/
|
7
27
|
export declare function serializeContent(destination: string, content: Template): string;
|
28
|
+
/**
|
29
|
+
* write all generated configuration to their destination
|
30
|
+
* @param root path to the target project root
|
31
|
+
* @param config a map of configuration content and its path to be written
|
32
|
+
* @param pathMap a map of keys in the config map and their destination path
|
33
|
+
* @param options collection of options
|
34
|
+
*/
|
8
35
|
export declare function writeFiles(root: string, config: Record<string, Template>, pathMap: Record<string, string>, options?: IOOptions): void;
|
36
|
+
/**
|
37
|
+
* link generated files to the project root
|
38
|
+
* @param root path to the target project root
|
39
|
+
* @param configurationLink map of symlinks to its real path
|
40
|
+
* @param options collection of options
|
41
|
+
*/
|
9
42
|
export declare function linkFiles(root: string, configurationLink: Record<string, string>, options?: IOOptions): void;
|
43
|
+
/**
|
44
|
+
* unlink generated files from the project root
|
45
|
+
* @param root path to the target project root
|
46
|
+
* @param configurationLink map of symlinks to its real path
|
47
|
+
* @param options collection of options
|
48
|
+
*/
|
10
49
|
export declare function unlinkFiles(root: string, configurationLink: Record<string, string>, options?: IOOptions): void;
|
11
50
|
//# sourceMappingURL=io.d.ts.map
|
package/lib/io.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../source/io.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../source/io.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACxB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAKD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ5C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3B,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;AAmBvE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,QAAQ,GAChB,MAAM,CAaR;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,CAAC,EAAE,SAAS,GAClB,IAAI,CAsBN;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,OAAO,CAAC,EAAE,SAAS,GAClB,IAAI,CAoBN;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,OAAO,CAAC,EAAE,SAAS,GAClB,IAAI,CAeN"}
|
package/lib/io.js
CHANGED
@@ -1,10 +1,37 @@
|
|
1
|
+
/*
|
2
|
+
* *** MIT LICENSE ***
|
3
|
+
* -------------------------------------------------------------------------
|
4
|
+
* This code may be modified and distributed under the MIT license.
|
5
|
+
* See the LICENSE file for details.
|
6
|
+
* -------------------------------------------------------------------------
|
7
|
+
*
|
8
|
+
* @summary Collection of io helpers
|
9
|
+
*
|
10
|
+
* @author Alvis HT Tang <alvis@hilbert.space>
|
11
|
+
* @license MIT
|
12
|
+
* @copyright Copyright (c) 2020 - All Rights Reserved.
|
13
|
+
* -------------------------------------------------------------------------
|
14
|
+
*/
|
1
15
|
import { info } from 'node:console';
|
2
|
-
import { lstatSync, mkdirSync, readFileSync, readlinkSync, symlinkSync, unlinkSync, writeFileSync, } from 'node:fs';
|
16
|
+
import { linkSync, lstatSync, mkdirSync, readFileSync, readlinkSync, statSync, symlinkSync, unlinkSync, writeFileSync, } from 'node:fs';
|
3
17
|
import { basename, dirname, extname, relative, resolve } from 'node:path';
|
4
18
|
import { dump, load } from 'js-yaml';
|
19
|
+
// JSON format
|
5
20
|
const INDENT = 2;
|
21
|
+
/**
|
22
|
+
* check if a path is either a link or a file with multiple hard links
|
23
|
+
* @param path path to be checked
|
24
|
+
* @returns true if the path is a link or a file with multiple hard links
|
25
|
+
*/
|
26
|
+
export function islink(path) {
|
27
|
+
const pathLinkStat = lstatSync(path, { throwIfNoEntry: false });
|
28
|
+
const pathStat = statSync(path, { throwIfNoEntry: false });
|
29
|
+
return (!!pathLinkStat?.isSymbolicLink() ||
|
30
|
+
(!!pathStat?.nlink && pathStat.nlink > 1));
|
31
|
+
}
|
6
32
|
export function loadFile(path, defaultFormat = 'text') {
|
7
33
|
const content = readFileSync(path).toString();
|
34
|
+
// parse the content depending on the extension
|
8
35
|
switch (extname(path) || `.${defaultFormat}`) {
|
9
36
|
case '.json':
|
10
37
|
return JSON.parse(content);
|
@@ -15,6 +42,12 @@ export function loadFile(path, defaultFormat = 'text') {
|
|
15
42
|
return content;
|
16
43
|
}
|
17
44
|
}
|
45
|
+
/**
|
46
|
+
* serialize a configuration content to the right format according to its destination
|
47
|
+
* @param destination the path to which the content will be written
|
48
|
+
* @param content configuration content
|
49
|
+
* @returns serialized content
|
50
|
+
*/
|
18
51
|
export function serializeContent(destination, content) {
|
19
52
|
if (typeof content === 'string') {
|
20
53
|
return content;
|
@@ -28,12 +61,24 @@ export function serializeContent(destination, content) {
|
|
28
61
|
return JSON.stringify(content, null, INDENT);
|
29
62
|
}
|
30
63
|
}
|
64
|
+
/**
|
65
|
+
* write all generated configuration to their destination
|
66
|
+
* @param root path to the target project root
|
67
|
+
* @param config a map of configuration content and its path to be written
|
68
|
+
* @param pathMap a map of keys in the config map and their destination path
|
69
|
+
* @param options collection of options
|
70
|
+
*/
|
31
71
|
export function writeFiles(root, config, pathMap, options) {
|
32
72
|
const { force = false } = { ...options };
|
33
73
|
for (const [key, content] of Object.entries(config)) {
|
34
74
|
const destination = pathMap[key];
|
35
|
-
|
75
|
+
// write content to the destination path
|
76
|
+
if (
|
77
|
+
// force overwrite
|
78
|
+
force ||
|
79
|
+
// file don't exist
|
36
80
|
!lstatSync(destination, { throwIfNoEntry: false }) ||
|
81
|
+
// content to be written under the configurations folder
|
37
82
|
destination !== resolve(root, key)) {
|
38
83
|
info(`Generating ${key}`);
|
39
84
|
ensureFile(destination, serializeContent(destination, content));
|
@@ -43,23 +88,39 @@ export function writeFiles(root, config, pathMap, options) {
|
|
43
88
|
}
|
44
89
|
}
|
45
90
|
}
|
91
|
+
/**
|
92
|
+
* link generated files to the project root
|
93
|
+
* @param root path to the target project root
|
94
|
+
* @param configurationLink map of symlinks to its real path
|
95
|
+
* @param options collection of options
|
96
|
+
*/
|
46
97
|
export function linkFiles(root, configurationLink, options) {
|
47
98
|
const { force = false } = { ...options };
|
48
99
|
for (const [file, destination] of Object.entries(configurationLink)) {
|
49
100
|
const path = resolve(root, file);
|
50
101
|
const to = relative(dirname(path), destination);
|
51
102
|
const pathStat = lstatSync(path, { throwIfNoEntry: false });
|
52
|
-
|
53
|
-
|
103
|
+
const linkDoesNotExist = !pathStat;
|
104
|
+
if (
|
105
|
+
// for files that mean to be created directly on the target project root, not via symlink
|
106
|
+
to !== basename(to) &&
|
107
|
+
// do not replace any user created files unless overwrite is set
|
108
|
+
(linkDoesNotExist || islink(path) || force)) {
|
54
109
|
info(`Linking ${relative(root, path)} => ${to}`);
|
55
110
|
ensureLink(path, to);
|
56
111
|
}
|
57
112
|
}
|
58
113
|
}
|
114
|
+
/**
|
115
|
+
* unlink generated files from the project root
|
116
|
+
* @param root path to the target project root
|
117
|
+
* @param configurationLink map of symlinks to its real path
|
118
|
+
* @param options collection of options
|
119
|
+
*/
|
59
120
|
export function unlinkFiles(root, configurationLink, options) {
|
60
121
|
const { force = false } = { ...options };
|
61
122
|
for (const [name, destination] of Object.entries(configurationLink)) {
|
62
|
-
const link =
|
123
|
+
const link = readLink(resolve(root, name));
|
63
124
|
const to = relative(root, destination);
|
64
125
|
if (link === to || force) {
|
65
126
|
info(`Removing ${name}`);
|
@@ -69,22 +130,46 @@ export function unlinkFiles(root, configurationLink, options) {
|
|
69
130
|
info(`Skipping ${name}`);
|
70
131
|
}
|
71
132
|
}
|
72
|
-
|
133
|
+
/**
|
134
|
+
* resolve a path and follow any symlink
|
135
|
+
* @param path path to be resolved
|
136
|
+
* @returns the target of the symlink or a resolved path if the path is not a symlink
|
137
|
+
*/
|
138
|
+
function readLink(path) {
|
73
139
|
const pathStat = lstatSync(path, { throwIfNoEntry: false });
|
74
140
|
return pathStat?.isSymbolicLink() ? readlinkSync(path) : null;
|
75
141
|
}
|
142
|
+
/**
|
143
|
+
* ensure that there is a symlink at the given path pointing to the target
|
144
|
+
* @param path path where the symlink should be created
|
145
|
+
* @param to target of the symlink
|
146
|
+
*/
|
76
147
|
function ensureLink(path, to) {
|
148
|
+
// create the parent directory if it doesn't exist
|
77
149
|
mkdirSync(dirname(path), { recursive: true });
|
150
|
+
// remove any existing files or symlinks
|
78
151
|
if (lstatSync(path, { throwIfNoEntry: false })) {
|
79
152
|
unlinkSync(path);
|
80
153
|
}
|
81
|
-
|
154
|
+
// create a new link pointing to the target
|
155
|
+
try {
|
156
|
+
// try to create a hardlink
|
157
|
+
linkSync(to, path);
|
158
|
+
}
|
159
|
+
catch {
|
160
|
+
// if hard link creation failed (e.g. linking across disc boundary) create a symlink instead
|
161
|
+
symlinkSync(to, path);
|
162
|
+
}
|
82
163
|
}
|
164
|
+
/**
|
165
|
+
* ensure that there is a file at the given path with the given content
|
166
|
+
* @param path path where the file should be created
|
167
|
+
* @param content content of the file
|
168
|
+
*/
|
83
169
|
function ensureFile(path, content) {
|
170
|
+
// ensure that all parent folders exist to avoid errors from writeFile
|
84
171
|
mkdirSync(dirname(path), { recursive: true });
|
85
|
-
|
86
|
-
unlinkSync(path);
|
87
|
-
}
|
172
|
+
// write content to the destination path
|
88
173
|
writeFileSync(path, content);
|
89
174
|
}
|
90
|
-
//# sourceMappingURL=data:application/json;base64,
|
175
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2UvaW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUVILE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxFQUNMLFFBQVEsRUFDUixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osUUFBUSxFQUNSLFdBQVcsRUFDWCxVQUFVLEVBQ1YsYUFBYSxHQUNkLE1BQU0sU0FBUyxDQUFDO0FBQ2pCLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRTFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBVXJDLGNBQWM7QUFDZCxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFFakI7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxNQUFNLENBQUMsSUFBWTtJQUNqQyxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDaEUsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBRTNELE9BQU8sQ0FDTCxDQUFDLENBQUMsWUFBWSxFQUFFLGNBQWMsRUFBRTtRQUNoQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxJQUFJLFFBQVEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQzFDLENBQUM7QUFDSixDQUFDO0FBYUQsTUFBTSxVQUFVLFFBQVEsQ0FDdEIsSUFBWSxFQUNaLGdCQUEwQyxNQUFNO0lBRWhELE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUU5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
|
package/lib/package.d.ts
CHANGED
@@ -1,10 +1,32 @@
|
|
1
1
|
import type { PackageJson } from 'type-fest';
|
2
|
+
/** package detail */
|
2
3
|
export type Package = {
|
4
|
+
/** path to the package.json */
|
3
5
|
path: string;
|
6
|
+
/** content of package.json */
|
4
7
|
json: PackageJson;
|
5
8
|
};
|
9
|
+
/**
|
10
|
+
* indicate whether peer packages would be installed automatically
|
11
|
+
* @returns true for npm v7+
|
12
|
+
*/
|
6
13
|
export declare function arePeerPackagesAutoInstalled(): boolean;
|
14
|
+
/**
|
15
|
+
* get scripts from the targeted project's package.json
|
16
|
+
* @param root path to the project's root folder
|
17
|
+
* @returns package detail
|
18
|
+
*/
|
7
19
|
export declare function getPackage(root?: string): Promise<Package>;
|
20
|
+
/**
|
21
|
+
* reify packages for the target project
|
22
|
+
* @param args list of packages and other options
|
23
|
+
* @param args.root directory of the project package.json
|
24
|
+
* @param args.add list of packages to be added
|
25
|
+
* @param args.remove list of packages to be removed
|
26
|
+
* @param args.saveAs type of dependency
|
27
|
+
* @param args.lockFile indicate whether package-lock.json should be produced
|
28
|
+
* @returns list of installed packages
|
29
|
+
*/
|
8
30
|
export declare function reifyDependencies(args: {
|
9
31
|
root: string;
|
10
32
|
add?: string[];
|
package/lib/package.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../source/package.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
1
|
+
{"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../source/package.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,qBAAqB;AACrB,MAAM,MAAM,OAAO,GAAG;IACpB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAuBtD;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAahE;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA2BjD"}
|
package/lib/package.js
CHANGED
@@ -1,22 +1,53 @@
|
|
1
|
+
/*
|
2
|
+
* *** MIT LICENSE ***
|
3
|
+
* -------------------------------------------------------------------------
|
4
|
+
* This code may be modified and distributed under the MIT license.
|
5
|
+
* See the LICENSE file for details.
|
6
|
+
* -------------------------------------------------------------------------
|
7
|
+
*
|
8
|
+
* @summary Helpers for handling a package
|
9
|
+
*
|
10
|
+
* @author Alvis HT Tang <alvis@hilbert.space>
|
11
|
+
* @license MIT
|
12
|
+
* @copyright Copyright (c) 2019 - All Rights Reserved.
|
13
|
+
* -------------------------------------------------------------------------
|
14
|
+
*/
|
1
15
|
import { homedir } from 'node:os';
|
2
16
|
import { resolve } from 'node:path';
|
3
17
|
import { Arborist } from '@npmcli/arborist';
|
4
18
|
import Config from '@npmcli/config';
|
5
19
|
import { readPackageUp } from 'read-pkg-up';
|
6
20
|
const NPM_VERSION_FOR_PEER_INSTALLATION = 7;
|
21
|
+
/**
|
22
|
+
* indicate whether peer packages would be installed automatically
|
23
|
+
* @returns true for npm v7+
|
24
|
+
*/
|
7
25
|
export function arePeerPackagesAutoInstalled() {
|
26
|
+
// NOTE npm_config_user_agent should be in the form of 'npm/7.3.0 node/v15.5.0 darwin x64'
|
27
|
+
/* istanbul ignore next */
|
8
28
|
const [clientID] = process.env['npm_config_user_agent']?.split(' ') ?? [];
|
29
|
+
/* istanbul ignore next */
|
9
30
|
const [name, version] = clientID?.split('/') ?? [];
|
31
|
+
/* istanbul ignore next */
|
10
32
|
const [major] = version?.split('.') ?? [];
|
11
33
|
const isNPM = name === 'npm';
|
12
34
|
const isNonNPM = name !== 'npm';
|
13
|
-
return (
|
35
|
+
return (
|
36
|
+
// assume peer packages would be installed automatically if the client is not npm
|
37
|
+
isNonNPM ||
|
14
38
|
(isNPM &&
|
15
39
|
major !== undefined &&
|
16
40
|
parseInt(major) >= NPM_VERSION_FOR_PEER_INSTALLATION));
|
17
41
|
}
|
42
|
+
/**
|
43
|
+
* get scripts from the targeted project's package.json
|
44
|
+
* @param root path to the project's root folder
|
45
|
+
* @returns package detail
|
46
|
+
*/
|
18
47
|
export async function getPackage(root) {
|
48
|
+
// try to find the target project's package.json
|
19
49
|
const detail = await readPackageUp({ cwd: root, normalize: true });
|
50
|
+
// throw an error if there's no package.json found
|
20
51
|
if (!detail) {
|
21
52
|
throw new Error("failed to find target's package.json");
|
22
53
|
}
|
@@ -24,11 +55,23 @@ export async function getPackage(root) {
|
|
24
55
|
const json = detail.packageJson;
|
25
56
|
return { path, json };
|
26
57
|
}
|
58
|
+
/**
|
59
|
+
* reify packages for the target project
|
60
|
+
* @param args list of packages and other options
|
61
|
+
* @param args.root directory of the project package.json
|
62
|
+
* @param args.add list of packages to be added
|
63
|
+
* @param args.remove list of packages to be removed
|
64
|
+
* @param args.saveAs type of dependency
|
65
|
+
* @param args.lockFile indicate whether package-lock.json should be produced
|
66
|
+
* @returns list of installed packages
|
67
|
+
*/
|
27
68
|
export async function reifyDependencies(args) {
|
28
69
|
const { root, add = [], remove = [], saveAs = 'prod', lockFile = false, } = { ...args };
|
70
|
+
// use arborist to install peer dependencies
|
29
71
|
const config = await getNPMConfig();
|
30
|
-
const workspacesEnabled = arePeerPackagesAutoInstalled();
|
72
|
+
const workspacesEnabled = arePeerPackagesAutoInstalled(); // no workspace before npm 7
|
31
73
|
const arborist = new Arborist({ path: root, workspacesEnabled, ...config });
|
74
|
+
// don't write to the lockfile
|
32
75
|
const actualTree = await arborist.reify({
|
33
76
|
add,
|
34
77
|
rm: remove,
|
@@ -41,7 +84,12 @@ export async function reifyDependencies(args) {
|
|
41
84
|
spec: edge.spec,
|
42
85
|
}));
|
43
86
|
}
|
87
|
+
/**
|
88
|
+
* get the url of the package registry of the target project
|
89
|
+
* @returns url of the registry
|
90
|
+
*/
|
44
91
|
async function getNPMConfig() {
|
92
|
+
// get npm config
|
45
93
|
const config = new Config({
|
46
94
|
definitions: {
|
47
95
|
userconfig: { default: resolve(homedir(), '.npmrc'), type: String },
|
@@ -49,10 +97,12 @@ async function getNPMConfig() {
|
|
49
97
|
},
|
50
98
|
npmPath: '.',
|
51
99
|
flatten: (config, flattenedConfig) => {
|
100
|
+
// NOTE: this function is called multiple time for flattening the configs at multiple levels, user, project, cli etc.
|
101
|
+
// ensure that higher level configs are always in priority
|
52
102
|
Object.assign(flattenedConfig, config);
|
53
103
|
},
|
54
104
|
});
|
55
105
|
await config.load();
|
56
106
|
return config.flat;
|
57
107
|
}
|
58
|
-
//# sourceMappingURL=data:application/json;base64,
|
108
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9wYWNrYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFcEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sTUFBTSxNQUFNLGdCQUFnQixDQUFDO0FBRXBDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFJNUMsTUFBTSxpQ0FBaUMsR0FBRyxDQUFDLENBQUM7QUFVNUM7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLDRCQUE0QjtJQUMxQywwRkFBMEY7SUFFMUYsMEJBQTBCO0lBQzFCLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FDZCxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixDQUFDLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFLLEVBQWtCLENBQUM7SUFFMUUsMEJBQTBCO0lBQzFCLE1BQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEdBQUcsUUFBUSxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSyxFQUFrQixDQUFDO0lBRXBFLDBCQUEwQjtJQUMxQixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSyxFQUFrQixDQUFDO0lBRTNELE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxLQUFLLENBQUM7SUFDN0IsTUFBTSxRQUFRLEdBQUcsSUFBSSxLQUFLLEtBQUssQ0FBQztJQUVoQyxPQUFPO0lBQ0wsaUZBQWlGO0lBQ2pGLFFBQVE7UUFDUixDQUFDLEtBQUs7WUFDSixLQUFLLEtBQUssU0FBUztZQUNuQixRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksaUNB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
|
package/lib/preset/content.d.ts
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
import type { PresetContext } from 'presetter-types';
|
2
|
+
/** collection of options for bootstrapping */
|
2
3
|
interface BootstrapOptions {
|
4
|
+
/** whether to skip all checks */
|
3
5
|
force?: boolean;
|
4
6
|
}
|
7
|
+
/**
|
8
|
+
* generate files from templates and link them to the target project root
|
9
|
+
* @param context context about the target project and any customization in .presetterrc
|
10
|
+
* @param options collection of options
|
11
|
+
*/
|
5
12
|
export declare function bootstrapContent(context: PresetContext, options?: BootstrapOptions): Promise<void>;
|
6
13
|
export {};
|
7
14
|
//# sourceMappingURL=content.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../source/preset/content.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../source/preset/content.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,8CAA8C;AAC9C,UAAU,gBAAgB;IACxB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,IAAI,CAAC,CAUf"}
|