depflow 3.0.0-dev.10 → 3.0.0-dev.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +513 -117
- package/dist/builder/Builder.d.ts +279 -0
- package/dist/builder/Builder.js +391 -0
- package/dist/builder/Builder.js.map +1 -0
- package/dist/cli/Actions.d.ts +187 -0
- package/dist/cli/Actions.js +793 -0
- package/dist/cli/Actions.js.map +1 -0
- package/dist/cli/CLI.d.ts +170 -0
- package/dist/cli/CLI.js +231 -0
- package/dist/cli/CLI.js.map +1 -0
- package/dist/cli/DepflowCLI.d.ts +62 -0
- package/dist/cli/DepflowCLI.js +229 -0
- package/dist/cli/DepflowCLI.js.map +1 -0
- package/dist/cli/Flags.d.ts +106 -0
- package/dist/cli/Flags.js +125 -0
- package/dist/cli/Flags.js.map +1 -0
- package/dist/cli/bin.js +63 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/config/Config.d.ts +690 -0
- package/dist/config/Config.js +45 -0
- package/dist/config/Config.js.map +1 -0
- package/dist/config/ImportMap.d.ts +60 -0
- package/dist/config/ImportMap.js +66 -0
- package/dist/config/ImportMap.js.map +1 -0
- package/dist/config/JsonSchema.d.ts +12 -0
- package/dist/config/JsonSchema.js +26 -0
- package/dist/config/JsonSchema.js.map +1 -0
- package/dist/config/Settings.d.ts +201 -0
- package/dist/config/Settings.js +191 -0
- package/dist/config/Settings.js.map +1 -0
- package/dist/config/TSConfig.d.ts +73 -0
- package/dist/config/TSConfig.js +73 -0
- package/dist/config/TSConfig.js.map +1 -0
- package/dist/config/codecs/JsonCodec.d.ts +30 -0
- package/dist/config/codecs/JsonCodec.js +31 -0
- package/dist/config/codecs/JsonCodec.js.map +1 -0
- package/dist/config/codecs/YamlCodec.d.ts +62 -0
- package/dist/config/codecs/YamlCodec.js +89 -0
- package/dist/config/codecs/YamlCodec.js.map +1 -0
- package/dist/dependency/DepUtils.d.ts +78 -0
- package/dist/dependency/DepUtils.js +122 -0
- package/dist/dependency/DepUtils.js.map +1 -0
- package/dist/dependency/Dependency.d.ts +81 -0
- package/dist/dependency/Dependency.js +71 -0
- package/dist/dependency/Dependency.js.map +1 -0
- package/dist/dependency/Git.d.ts +75 -0
- package/dist/dependency/Git.js +97 -0
- package/dist/dependency/Git.js.map +1 -0
- package/dist/dependency/GitDependency.d.ts +30 -0
- package/dist/dependency/GitDependency.js +79 -0
- package/dist/dependency/GitDependency.js.map +1 -0
- package/dist/dependency/NpmDependency.d.ts +27 -0
- package/dist/dependency/NpmDependency.js +91 -0
- package/dist/dependency/NpmDependency.js.map +1 -0
- package/{build/support/PathResolver → dist/resolve}/AliasCompiler.d.ts +18 -5
- package/{build/support/PathResolver → dist/resolve}/AliasCompiler.js +31 -9
- package/dist/resolve/AliasCompiler.js.map +1 -0
- package/{build/support/PathResolver → dist/resolve}/PathResolver.d.ts +25 -8
- package/dist/resolve/PathResolver.js +133 -0
- package/dist/resolve/PathResolver.js.map +1 -0
- package/dist/resolve/PathRewriter.d.ts +24 -0
- package/{build/support/PathResolver → dist/resolve}/PathRewriter.js +21 -11
- package/dist/resolve/PathRewriter.js.map +1 -0
- package/{build → dist}/schema/Config/Builder.d.ts +114 -49
- package/dist/schema/Config/Builder.js +78 -0
- package/dist/schema/Config/Builder.js.map +1 -0
- package/{build → dist}/schema/Config/Config.d.ts +169 -78
- package/dist/schema/Config/Config.js +62 -0
- package/dist/schema/Config/Config.js.map +1 -0
- package/{build → dist}/schema/Config/Dependency.d.ts +219 -89
- package/dist/schema/Config/Dependency.js +80 -0
- package/dist/schema/Config/Dependency.js.map +1 -0
- package/{build → dist}/schema/Config/Extractor.d.ts +41 -17
- package/dist/schema/Config/Extractor.js +43 -0
- package/dist/schema/Config/Extractor.js.map +1 -0
- package/{build → dist}/schema/Config/Resolver.d.ts +25 -8
- package/dist/schema/Config/Resolver.js +43 -0
- package/dist/schema/Config/Resolver.js.map +1 -0
- package/{build → dist}/schema/Config/Transform.d.ts +22 -5
- package/dist/schema/Config/Transform.js +51 -0
- package/dist/schema/Config/Transform.js.map +1 -0
- package/dist/schema/Defaults.d.ts +20 -0
- package/dist/schema/Defaults.js +24 -0
- package/dist/schema/Defaults.js.map +1 -0
- package/dist/schema/ImportMap.d.ts +30 -0
- package/dist/schema/ImportMap.js +28 -0
- package/dist/schema/ImportMap.js.map +1 -0
- package/{build → dist}/schema/TSConfig.d.ts +23 -9
- package/dist/schema/TSConfig.js +39 -0
- package/dist/schema/TSConfig.js.map +1 -0
- package/{build → dist}/schema/schema.d.ts +11 -2
- package/{build → dist}/schema/schema.js +11 -2
- package/dist/schema/schema.js.map +1 -0
- package/dist/task/Command.d.ts +287 -0
- package/dist/task/Command.js +404 -0
- package/dist/task/Command.js.map +1 -0
- package/dist/task/Group.d.ts +15 -0
- package/dist/task/Group.js +29 -0
- package/dist/task/Group.js.map +1 -0
- package/dist/task/OutputPolicy.d.ts +262 -0
- package/dist/task/OutputPolicy.js +364 -0
- package/dist/task/OutputPolicy.js.map +1 -0
- package/dist/task/Task.d.ts +210 -0
- package/dist/task/Task.js +312 -0
- package/dist/task/Task.js.map +1 -0
- package/package.json +14 -10
- package/.gitignore +0 -7
- package/build/cli/DepFLowCLI.d.ts +0 -16
- package/build/cli/DepFLowCLI.js +0 -254
- package/build/cli/DepFLowCLI.js.map +0 -1
- package/build/cli/bin.js +0 -38
- package/build/cli/bin.js.map +0 -1
- package/build/config/Config.d.ts +0 -28
- package/build/config/Config.js +0 -46
- package/build/config/Config.js.map +0 -1
- package/build/config/ImportMap.d.ts +0 -51
- package/build/config/ImportMap.js +0 -97
- package/build/config/ImportMap.js.map +0 -1
- package/build/config/TSConfig.d.ts +0 -54
- package/build/config/TSConfig.js +0 -104
- package/build/config/TSConfig.js.map +0 -1
- package/build/schema/Config/Builder.js +0 -48
- package/build/schema/Config/Builder.js.map +0 -1
- package/build/schema/Config/Config.js +0 -20
- package/build/schema/Config/Config.js.map +0 -1
- package/build/schema/Config/Dependency.js +0 -25
- package/build/schema/Config/Dependency.js.map +0 -1
- package/build/schema/Config/Extractor.js +0 -25
- package/build/schema/Config/Extractor.js.map +0 -1
- package/build/schema/Config/Resolver.js +0 -25
- package/build/schema/Config/Resolver.js.map +0 -1
- package/build/schema/Config/Transform.js +0 -27
- package/build/schema/Config/Transform.js.map +0 -1
- package/build/schema/ImportMap.d.ts +0 -22
- package/build/schema/ImportMap.js +0 -12
- package/build/schema/ImportMap.js.map +0 -1
- package/build/schema/TSConfig.js +0 -19
- package/build/schema/TSConfig.js.map +0 -1
- package/build/schema/schema.js.map +0 -1
- package/build/support/Builder/Builder.d.ts +0 -46
- package/build/support/Builder/Builder.js +0 -116
- package/build/support/Builder/Builder.js.map +0 -1
- package/build/support/Dependency/Dependency.d.ts +0 -38
- package/build/support/Dependency/Dependency.js +0 -14
- package/build/support/Dependency/Dependency.js.map +0 -1
- package/build/support/Dependency/GitDependency.d.ts +0 -20
- package/build/support/Dependency/GitDependency.js +0 -67
- package/build/support/Dependency/GitDependency.js.map +0 -1
- package/build/support/Dependency/NpmDependency.d.ts +0 -18
- package/build/support/Dependency/NpmDependency.js +0 -65
- package/build/support/Dependency/NpmDependency.js.map +0 -1
- package/build/support/Git.d.ts +0 -53
- package/build/support/Git.js +0 -86
- package/build/support/Git.js.map +0 -1
- package/build/support/PathResolver/AliasCompiler.js.map +0 -1
- package/build/support/PathResolver/PathResolver.js +0 -105
- package/build/support/PathResolver/PathResolver.js.map +0 -1
- package/build/support/PathResolver/PathRewriter.d.ts +0 -18
- package/build/support/PathResolver/PathRewriter.js.map +0 -1
- package/build/support/PathResolver/Utils.d.ts +0 -36
- package/build/support/PathResolver/Utils.js +0 -45
- package/build/support/PathResolver/Utils.js.map +0 -1
- package/build/support/Task/Command.d.ts +0 -49
- package/build/support/Task/Command.js +0 -100
- package/build/support/Task/Command.js.map +0 -1
- package/build/support/Task/Task.d.ts +0 -84
- package/build/support/Task/Task.js +0 -145
- package/build/support/Task/Task.js.map +0 -1
- package/build/support/Utils.d.ts +0 -40
- package/build/support/Utils.js +0 -138
- package/build/support/Utils.js.map +0 -1
- package/build/support/Validator.d.ts +0 -22
- package/build/support/Validator.js +0 -28
- package/build/support/Validator.js.map +0 -1
- /package/{build → dist}/cli/bin.d.ts +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Updates and persists TypeScript path mappings from compiled path aliases.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Logger } from '@netfeez/vterm';
|
|
7
|
+
import schema from '../schema/schema.js';
|
|
8
|
+
import Settings from './Settings.js';
|
|
9
|
+
import type AliasCompiler from '../resolve/AliasCompiler.js';
|
|
10
|
+
export declare class TSConfig extends Settings<typeof schema.TSConfig> {
|
|
11
|
+
protected static schema: import("@netfeez/schema").Schema<{
|
|
12
|
+
readonly type: "object";
|
|
13
|
+
readonly additional: true;
|
|
14
|
+
readonly keys: {
|
|
15
|
+
readonly compilerOptions: {
|
|
16
|
+
readonly type: "object";
|
|
17
|
+
readonly additional: true;
|
|
18
|
+
readonly keys: {
|
|
19
|
+
readonly rootDir: {
|
|
20
|
+
readonly type: "string";
|
|
21
|
+
readonly description: "Root directory of the TypeScript source files.";
|
|
22
|
+
};
|
|
23
|
+
readonly outDir: {
|
|
24
|
+
readonly type: "string";
|
|
25
|
+
readonly description: "Output directory for the compiled files.";
|
|
26
|
+
};
|
|
27
|
+
readonly paths: {
|
|
28
|
+
readonly type: "object";
|
|
29
|
+
readonly additional: {
|
|
30
|
+
readonly type: "array";
|
|
31
|
+
readonly items: {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
readonly description: "Path mapping aliases used by TypeScript to resolve modules.";
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
readonly description: "The compiler options object of the tsconfig file.";
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
readonly description: "Structure of a tsconfig.json file.";
|
|
42
|
+
}>;
|
|
43
|
+
protected logger: Logger;
|
|
44
|
+
constructor(data: TSConfig.Data, options?: TSConfig.Options);
|
|
45
|
+
/**
|
|
46
|
+
* The formats of the tsconfig file: JSON only, so it never reaches a YAML parser.
|
|
47
|
+
* @returns The JSON codec of the file.
|
|
48
|
+
*/
|
|
49
|
+
protected static get codecs(): readonly Settings.AnyCodec[];
|
|
50
|
+
/**
|
|
51
|
+
* Updates the paths in the tsconfig data based on the provided compiled aliases.
|
|
52
|
+
* It ensures that the compilerOptions and paths properties exist in the tsconfig data, and then iterates through the compiled aliases to construct the appropriate path mappings.
|
|
53
|
+
* For each alias, it calculates the relative path from the project root to the local target and normalizes it. If the alias is a wildcard, it appends '/*' to the target path.
|
|
54
|
+
* Finally, it updates the paths in the tsconfig data with the new mappings, allowing TypeScript to resolve module paths according to the defined aliases.
|
|
55
|
+
* @param aliases - An array of compiled aliases containing alias names, target paths, and wildcard information.
|
|
56
|
+
*/
|
|
57
|
+
updatePaths(aliases: AliasCompiler.CompiledAlias[]): void;
|
|
58
|
+
/**
|
|
59
|
+
* Saves the current tsconfig data to a file.
|
|
60
|
+
* It constructs the path to the tsconfig file using the project root and filename, converts the data to a JSON string with proper formatting, and writes it to the file system using the File.write method.
|
|
61
|
+
* The method also includes error handling to log any issues that occur during the save process, ensuring that users are informed of any problems when attempting to save the tsconfig configuration.
|
|
62
|
+
* @param path - The path to the tsconfig file where the data should be saved.
|
|
63
|
+
* @returns A promise that resolves when the save operation is complete, or rejects if an error occurs during the process.
|
|
64
|
+
*/
|
|
65
|
+
save(path?: string): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
export declare namespace TSConfig {
|
|
68
|
+
type Data = schema.TSConfig.Root;
|
|
69
|
+
interface Options extends Settings.Options {
|
|
70
|
+
logger?: Logger;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export default TSConfig;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Updates and persists TypeScript path mappings from compiled path aliases.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Logger } from '@netfeez/vterm';
|
|
7
|
+
import { Path } from '@netfeez/common-node';
|
|
8
|
+
import schema from '../schema/schema.js';
|
|
9
|
+
import Settings from './Settings.js';
|
|
10
|
+
import JsonCodec from './codecs/JsonCodec.js';
|
|
11
|
+
export class TSConfig extends Settings {
|
|
12
|
+
static schema = schema.TSConfig;
|
|
13
|
+
logger;
|
|
14
|
+
constructor(data, options = {}) {
|
|
15
|
+
super(data, options);
|
|
16
|
+
this.logger = options.logger || new Logger({ name: 'TS-CFG' });
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The formats of the tsconfig file: JSON only, so it never reaches a YAML parser.
|
|
20
|
+
* @returns The JSON codec of the file.
|
|
21
|
+
*/
|
|
22
|
+
static get codecs() { return [new JsonCodec()]; }
|
|
23
|
+
/**
|
|
24
|
+
* Updates the paths in the tsconfig data based on the provided compiled aliases.
|
|
25
|
+
* It ensures that the compilerOptions and paths properties exist in the tsconfig data, and then iterates through the compiled aliases to construct the appropriate path mappings.
|
|
26
|
+
* For each alias, it calculates the relative path from the project root to the local target and normalizes it. If the alias is a wildcard, it appends '/*' to the target path.
|
|
27
|
+
* Finally, it updates the paths in the tsconfig data with the new mappings, allowing TypeScript to resolve module paths according to the defined aliases.
|
|
28
|
+
* @param aliases - An array of compiled aliases containing alias names, target paths, and wildcard information.
|
|
29
|
+
*/
|
|
30
|
+
updatePaths(aliases) {
|
|
31
|
+
if (!this.data.compilerOptions)
|
|
32
|
+
this.data.compilerOptions = {};
|
|
33
|
+
if (!this.data.compilerOptions.paths)
|
|
34
|
+
this.data.compilerOptions.paths = {};
|
|
35
|
+
const projectRoot = Path.dirname(this.path);
|
|
36
|
+
for (const alias of aliases) {
|
|
37
|
+
const key = alias.isWildcard ? `${alias.alias}/*` : alias.alias;
|
|
38
|
+
let target = Path.diff(projectRoot, alias.targets.local);
|
|
39
|
+
target = target.startsWith('.') ? target : `./${target}`;
|
|
40
|
+
target = Path.normalize(target);
|
|
41
|
+
let typeTarget;
|
|
42
|
+
if (alias.targets.type) {
|
|
43
|
+
typeTarget = Path.diff(projectRoot, alias.targets.type);
|
|
44
|
+
typeTarget = typeTarget.startsWith('.') ? typeTarget : `./${typeTarget}`;
|
|
45
|
+
typeTarget = Path.normalize(typeTarget);
|
|
46
|
+
}
|
|
47
|
+
if (alias.isWildcard) {
|
|
48
|
+
const suffix = target.endsWith('/') ? '*' : '/*';
|
|
49
|
+
target = `${target}${suffix}`;
|
|
50
|
+
if (typeTarget) {
|
|
51
|
+
typeTarget = `${typeTarget}${suffix}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
this.data.compilerOptions.paths[key] = typeTarget ? [typeTarget, target] : [target];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Saves the current tsconfig data to a file.
|
|
59
|
+
* It constructs the path to the tsconfig file using the project root and filename, converts the data to a JSON string with proper formatting, and writes it to the file system using the File.write method.
|
|
60
|
+
* The method also includes error handling to log any issues that occur during the save process, ensuring that users are informed of any problems when attempting to save the tsconfig configuration.
|
|
61
|
+
* @param path - The path to the tsconfig file where the data should be saved.
|
|
62
|
+
* @returns A promise that resolves when the save operation is complete, or rejects if an error occurs during the process.
|
|
63
|
+
*/
|
|
64
|
+
async save(path = this.path) {
|
|
65
|
+
await super.save(path);
|
|
66
|
+
if (path !== this.path)
|
|
67
|
+
this.path = path;
|
|
68
|
+
const filename = Path.fileName(path);
|
|
69
|
+
this.logger.log(`&C2Saved file &C4${filename}&C2 successfully.`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export default TSConfig;
|
|
73
|
+
//# sourceMappingURL=TSConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TSConfig.js","sourceRoot":"","sources":["../../src/config/TSConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Reads and writes a config file as plain JSON.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { JsonValue } from '@netfeez/yaml';
|
|
7
|
+
import type Settings from '../Settings.js';
|
|
8
|
+
/**
|
|
9
|
+
* Reads and writes a config file as plain JSON.
|
|
10
|
+
*
|
|
11
|
+
* JSON preserves nothing around the values, so it has no document of its own: the data is the
|
|
12
|
+
* document, and every save regenerates the file from it.
|
|
13
|
+
*/
|
|
14
|
+
export declare class JsonCodec implements Settings.Codec<null, JsonValue> {
|
|
15
|
+
/** The file extensions this codec is selected by. */
|
|
16
|
+
readonly extensions: readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* Parses the JSON text into the data it holds.
|
|
19
|
+
* @param text - The JSON text of the file.
|
|
20
|
+
* @returns The data and the document of the file, or `null` when the text holds no document.
|
|
21
|
+
* @throws { SyntaxError } When the text is not valid JSON.
|
|
22
|
+
*/
|
|
23
|
+
decode(text: string): Settings.Decoded<null> | null;
|
|
24
|
+
/** JSON has no document to create: the data is the document. **/
|
|
25
|
+
create(): null;
|
|
26
|
+
/** Renders the data as indented JSON. **/
|
|
27
|
+
encode(data: JsonValue, document: null): string;
|
|
28
|
+
}
|
|
29
|
+
export declare namespace JsonCodec { }
|
|
30
|
+
export default JsonCodec;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Reads and writes a config file as plain JSON.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Reads and writes a config file as plain JSON.
|
|
8
|
+
*
|
|
9
|
+
* JSON preserves nothing around the values, so it has no document of its own: the data is the
|
|
10
|
+
* document, and every save regenerates the file from it.
|
|
11
|
+
*/
|
|
12
|
+
export class JsonCodec {
|
|
13
|
+
/** The file extensions this codec is selected by. */
|
|
14
|
+
extensions = ['.json'];
|
|
15
|
+
/**
|
|
16
|
+
* Parses the JSON text into the data it holds.
|
|
17
|
+
* @param text - The JSON text of the file.
|
|
18
|
+
* @returns The data and the document of the file, or `null` when the text holds no document.
|
|
19
|
+
* @throws { SyntaxError } When the text is not valid JSON.
|
|
20
|
+
*/
|
|
21
|
+
decode(text) {
|
|
22
|
+
const data = JSON.parse(text);
|
|
23
|
+
return data === null ? null : { data, document: null };
|
|
24
|
+
}
|
|
25
|
+
/** JSON has no document to create: the data is the document. **/
|
|
26
|
+
create() { return null; }
|
|
27
|
+
/** Renders the data as indented JSON. **/
|
|
28
|
+
encode(data, document) { return JSON.stringify(data, null, 4); }
|
|
29
|
+
}
|
|
30
|
+
export default JsonCodec;
|
|
31
|
+
//# sourceMappingURL=JsonCodec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonCodec.js","sourceRoot":"","sources":["../../../src/config/codecs/JsonCodec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;GAKG;AACH,MAAM,OAAO,SAAS;IAClB,qDAAqD;IACrC,UAAU,GAAsB,CAAE,OAAO,CAAE,CAAC;IAE5D;;;;;OAKG;IACI,MAAM,CAAC,IAAY;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC3D,CAAC;IAED,iEAAiE;IAC1D,MAAM,KAAW,OAAO,IAAI,CAAC,CAAC,CAAC;IAEtC,0CAA0C;IACnC,MAAM,CAAC,IAAe,EAAE,QAAc,IAAY,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;CACnG;AAID,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Reads and writes a config file as YAML, preserving the formatting of the file it was read from.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import Schema, { Definition } from '@netfeez/schema';
|
|
7
|
+
import { type Document, type JsonValue } from '@netfeez/yaml';
|
|
8
|
+
import type Settings from '../Settings.js';
|
|
9
|
+
/**
|
|
10
|
+
* Reads and writes a config file as YAML, preserving the formatting of the file it was read from.
|
|
11
|
+
*
|
|
12
|
+
* The document is the YAML tree: the values it holds, plus everything YAML keeps around them (key
|
|
13
|
+
* order, indentation, comments). A document created from scratch is decorated with the file header
|
|
14
|
+
* and with the description the schema declares for each key, so a generated config documents itself.
|
|
15
|
+
*/
|
|
16
|
+
export declare class YamlCodec implements Settings.Codec<Document, JsonValue> {
|
|
17
|
+
/** The file extensions this codec is selected by. */
|
|
18
|
+
readonly extensions: readonly string[];
|
|
19
|
+
protected schema: Schema<Definition.Definition>;
|
|
20
|
+
protected header: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Creates the codec.
|
|
23
|
+
* @param schema - The schema whose key descriptions document a generated file.
|
|
24
|
+
* @param options - Options for the codec.
|
|
25
|
+
*/
|
|
26
|
+
constructor(schema: Schema<Definition.Definition>, options?: YamlCodec.Options);
|
|
27
|
+
/**
|
|
28
|
+
* Parses the YAML text into the document it describes.
|
|
29
|
+
* @param text - The YAML text of the file.
|
|
30
|
+
* @returns The data and the document of the file, or `null` when the text holds no document.
|
|
31
|
+
* @throws { YamlError } When the text is not valid YAML.
|
|
32
|
+
*
|
|
33
|
+
* @remarks A file holding only comments, or nothing at all, parses into an empty tree: it has
|
|
34
|
+
* no data, so there is nothing to load and the defaults of the schema take over.
|
|
35
|
+
*/
|
|
36
|
+
decode(text: string): Settings.Decoded<Document> | null;
|
|
37
|
+
/**
|
|
38
|
+
* Creates a document holding the data, with the file header and the schema descriptions.
|
|
39
|
+
* @param data - The data to hold in the new document.
|
|
40
|
+
* @returns The new document.
|
|
41
|
+
*/
|
|
42
|
+
create(data: JsonValue): Document;
|
|
43
|
+
/**
|
|
44
|
+
* Synchronizes the data into the document and renders it, leaving everything the data does not
|
|
45
|
+
* touch (key order, indentation, and the comments of the keys it leaves alone) as it was.
|
|
46
|
+
* @param data - The data to render.
|
|
47
|
+
* @param document - The document the data is rendered through.
|
|
48
|
+
* @returns The YAML text of the document.
|
|
49
|
+
*/
|
|
50
|
+
encode(data: JsonValue, document: Document): string;
|
|
51
|
+
/** Writes the file header and the schema description of every key the document has. **/
|
|
52
|
+
private decorate;
|
|
53
|
+
/** The description of every declared top-level key, as the comment lines of a generated file. **/
|
|
54
|
+
private descriptions;
|
|
55
|
+
}
|
|
56
|
+
export declare namespace YamlCodec {
|
|
57
|
+
interface Options {
|
|
58
|
+
/** The raw lines written at the top of a generated file, pushed verbatim. */
|
|
59
|
+
header?: string[];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export default YamlCodec;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Reads and writes a config file as YAML, preserving the formatting of the file it was read from.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import Yaml from '@netfeez/yaml';
|
|
7
|
+
/**
|
|
8
|
+
* Reads and writes a config file as YAML, preserving the formatting of the file it was read from.
|
|
9
|
+
*
|
|
10
|
+
* The document is the YAML tree: the values it holds, plus everything YAML keeps around them (key
|
|
11
|
+
* order, indentation, comments). A document created from scratch is decorated with the file header
|
|
12
|
+
* and with the description the schema declares for each key, so a generated config documents itself.
|
|
13
|
+
*/
|
|
14
|
+
export class YamlCodec {
|
|
15
|
+
/** The file extensions this codec is selected by. */
|
|
16
|
+
extensions = ['.yaml', '.yml'];
|
|
17
|
+
schema;
|
|
18
|
+
header;
|
|
19
|
+
/**
|
|
20
|
+
* Creates the codec.
|
|
21
|
+
* @param schema - The schema whose key descriptions document a generated file.
|
|
22
|
+
* @param options - Options for the codec.
|
|
23
|
+
*/
|
|
24
|
+
constructor(schema, options = {}) {
|
|
25
|
+
this.schema = schema;
|
|
26
|
+
this.header = options.header ?? [];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parses the YAML text into the document it describes.
|
|
30
|
+
* @param text - The YAML text of the file.
|
|
31
|
+
* @returns The data and the document of the file, or `null` when the text holds no document.
|
|
32
|
+
* @throws { YamlError } When the text is not valid YAML.
|
|
33
|
+
*
|
|
34
|
+
* @remarks A file holding only comments, or nothing at all, parses into an empty tree: it has
|
|
35
|
+
* no data, so there is nothing to load and the defaults of the schema take over.
|
|
36
|
+
*/
|
|
37
|
+
decode(text) {
|
|
38
|
+
const document = Yaml.parse(text);
|
|
39
|
+
const data = document.toJS();
|
|
40
|
+
return data === null ? null : { data, document };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates a document holding the data, with the file header and the schema descriptions.
|
|
44
|
+
* @param data - The data to hold in the new document.
|
|
45
|
+
* @returns The new document.
|
|
46
|
+
*/
|
|
47
|
+
create(data) {
|
|
48
|
+
const document = Yaml.create(data);
|
|
49
|
+
this.decorate(document);
|
|
50
|
+
return document;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Synchronizes the data into the document and renders it, leaving everything the data does not
|
|
54
|
+
* touch (key order, indentation, and the comments of the keys it leaves alone) as it was.
|
|
55
|
+
* @param data - The data to render.
|
|
56
|
+
* @param document - The document the data is rendered through.
|
|
57
|
+
* @returns The YAML text of the document.
|
|
58
|
+
*/
|
|
59
|
+
encode(data, document) {
|
|
60
|
+
document.sync(data);
|
|
61
|
+
return document.dump();
|
|
62
|
+
}
|
|
63
|
+
/** Writes the file header and the schema description of every key the document has. **/
|
|
64
|
+
decorate(document) {
|
|
65
|
+
if (this.header.length)
|
|
66
|
+
document.header.push(...this.header);
|
|
67
|
+
for (const [key, description] of Object.entries(this.descriptions())) {
|
|
68
|
+
const node = document.get(key);
|
|
69
|
+
if (!node)
|
|
70
|
+
continue;
|
|
71
|
+
node.meta.lead = description.map(line => line.startsWith('#') ? line : `# ${line}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** The description of every declared top-level key, as the comment lines of a generated file. **/
|
|
75
|
+
descriptions() {
|
|
76
|
+
const definition = this.schema.definition;
|
|
77
|
+
if (definition.type !== 'object' || !definition.keys)
|
|
78
|
+
return {};
|
|
79
|
+
const descriptions = {};
|
|
80
|
+
for (const [key, value] of Object.entries(definition.keys)) {
|
|
81
|
+
if (!value.description)
|
|
82
|
+
continue;
|
|
83
|
+
descriptions[key] = value.description.split('\n').map(line => line.trim());
|
|
84
|
+
}
|
|
85
|
+
return descriptions;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export default YamlCodec;
|
|
89
|
+
//# sourceMappingURL=YamlCodec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YamlCodec.js","sourceRoot":"","sources":["../../../src/config/codecs/YamlCodec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,IAAuC,MAAM,eAAe,CAAC;AAKpE;;;;;;GAMG;AACH,MAAM,OAAO,SAAS;IAClB,qDAAqD;IACrC,UAAU,GAAsB,CAAE,OAAO,EAAE,MAAM,CAAE,CAAC;IAE1D,MAAM,CAAgC;IACtC,MAAM,CAAW;IAE3B;;;;OAIG;IACH,YAAmB,MAAqC,EAAE,OAAO,GAAsB,EAAE;QACrF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IACvC,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,IAAY;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,IAAe;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,IAAe,EAAE,QAAkB;QAC7C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,wFAAwF;IAChF,QAAQ,CAAC,QAAkB;QAC/B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7D,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;IAED,kGAAkG;IAC1F,YAAY;QAChB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;QAC1C,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QAChE,MAAM,YAAY,GAA6B,EAAE,CAAC;QAClD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,KAAK,CAAC,WAAW;gBAAE,SAAS;YACjC,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,YAAY,CAAC;IACxB,CAAC;CACJ;AASD,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Dependency source utilities: git repository validation and identity derivation.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export declare namespace DepUtils {
|
|
7
|
+
/**
|
|
8
|
+
* A repository in the canonical form `git clone` accepts: a remote over one of the transports it
|
|
9
|
+
* speaks, or a local path of a repository, always ending in `.git`. The name of a dependency is
|
|
10
|
+
* never derived from it, only the repo itself is.
|
|
11
|
+
*
|
|
12
|
+
* @remarks Every transport is spelled out so the accepted shapes are readable, but the `.git`
|
|
13
|
+
* suffix is what all of them share and what {@link DepUtils.repo} enforces, so the last member is
|
|
14
|
+
* the one that decides.
|
|
15
|
+
*/
|
|
16
|
+
type Repo = `https://${string}.git` | `http://${string}.git` | `ssh://${string}.git` | `git://${string}.git` | `file://${string}.git` | `git@${string}.git` | `${string}.git`;
|
|
17
|
+
/**
|
|
18
|
+
* What a repository reference resolves to: the URL `git clone` is given and the name GitHub
|
|
19
|
+
* derives from it.
|
|
20
|
+
*/
|
|
21
|
+
interface Reference {
|
|
22
|
+
/** The repository, canonical: a value {@link DepUtils.Repo} accepts whatever form it came in. */
|
|
23
|
+
repo: Repo;
|
|
24
|
+
/** The `<user>/<name>` GitHub derives, or `null` when the reference is not a GitHub one. **/
|
|
25
|
+
name: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parses a repository reference into the repository git clones from and the name GitHub derives.
|
|
29
|
+
*
|
|
30
|
+
* A GitHub repository may be written as the bare `user/repo` shorthand, as an HTTP(S) URL or as an
|
|
31
|
+
* SCP like ssh address, with or without the `.git` suffix; every one of them is canonicalized to
|
|
32
|
+
* the same repository. Any other repository is accepted as it stands when it is a value
|
|
33
|
+
* {@link DepUtils.Repo} accepts, and carries no derivable name.
|
|
34
|
+
* @param reference - The repository reference as a user writes it.
|
|
35
|
+
* @returns The canonical repository and the derived name, `null` when there is none.
|
|
36
|
+
* @throws { Error } When the reference is not a clonable repository.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* DepUtils.parse('netfeez/omega');
|
|
41
|
+
* // { repo: 'https://github.com/netfeez/omega.git', name: 'netfeez/omega' }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
function parse(reference: string): Reference;
|
|
45
|
+
/**
|
|
46
|
+
* Validates that the provided value is a repository `git clone` accepts, and says what it is not when
|
|
47
|
+
* it does not: a URL with its scheme, an SCP like address or a local path of a repository.
|
|
48
|
+
* @param repo - The repository value to validate.
|
|
49
|
+
* @throws Will throw an error if the value is not a clonable repository.
|
|
50
|
+
*
|
|
51
|
+
* @remarks A repository always carries the `.git` suffix, whichever transport it comes in: it is what
|
|
52
|
+
* tells a repository apart from a page, a package or a folder, and the name of the dependency is
|
|
53
|
+
* derived from the same suffix, so both read one repository.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* DepUtils.repo('https://github.com/NetFeez/omega.git');
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
function repo(repo: unknown): asserts repo is Repo;
|
|
61
|
+
/**
|
|
62
|
+
* Extracts the name a dependency is known by from its repository reference.
|
|
63
|
+
*
|
|
64
|
+
* Only a GitHub repository has a name that can be derived without asking, and the name it derives
|
|
65
|
+
* is the one the alias of the dependency takes everywhere else, so it is derived here and nowhere
|
|
66
|
+
* else.
|
|
67
|
+
* @param repo - The repository reference, in any of the forms {@link DepUtils.parse} accepts.
|
|
68
|
+
* @returns The repository name, as `<user>/<name>`.
|
|
69
|
+
* @throws { Error } When the repository is not a GitHub one, saying the name has to be given.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* DepUtils.getRepoName('https://github.com/NetFeez/omega.git'); // 'NetFeez/omega'
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
function getRepoName(repo: string): string;
|
|
77
|
+
}
|
|
78
|
+
export default DepUtils;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Dependency source utilities: git repository validation and identity derivation.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export var DepUtils;
|
|
7
|
+
(function (DepUtils) {
|
|
8
|
+
/**
|
|
9
|
+
* Matches what `git clone` accepts, in the transports it speaks: a URL with its scheme, an SCP
|
|
10
|
+
* like address, or a local path of a repository.
|
|
11
|
+
*/
|
|
12
|
+
const CLONEABLE_REGEX = /^(?:(?:https?|ssh|git|file):\/\/|git@)\S+$|\S*\.git$/;
|
|
13
|
+
/**
|
|
14
|
+
* Matches a GitHub repository over HTTP, with or without the `.git` suffix, and captures its user
|
|
15
|
+
* and name.
|
|
16
|
+
*/
|
|
17
|
+
const GITHUB_HTTP_REGEX = /^(https?):\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/;
|
|
18
|
+
/**
|
|
19
|
+
* Matches a GitHub repository over SSH in the SCP like form, with or without the `.git` suffix and
|
|
20
|
+
* tolerating the stray slash some clients write after the colon (`git@github.com:/user/repo`).
|
|
21
|
+
*/
|
|
22
|
+
const GITHUB_SSH_REGEX = /^git@github\.com:?\/?([^/]+)\/([^/]+?)(?:\.git)?$/;
|
|
23
|
+
/**
|
|
24
|
+
* Matches the bare `user/repo` shorthand GitHub itself accepts, without a scheme and with or
|
|
25
|
+
* without the `.git` suffix.
|
|
26
|
+
*/
|
|
27
|
+
const GITHUB_SHORT_REGEX = /^([A-Za-z0-9][A-Za-z0-9._-]*)\/([A-Za-z0-9][A-Za-z0-9._-]*?)(?:\.git)?$/;
|
|
28
|
+
/**
|
|
29
|
+
* The suffix that tells a repository from anything else, checked on the value as a whole instead of
|
|
30
|
+
* anchoring it, so a local path of a repository keeps validating wherever it lives.
|
|
31
|
+
*/
|
|
32
|
+
const GIT_SUFFIX_REGEX = /\.git$/;
|
|
33
|
+
/**
|
|
34
|
+
* The failure every rejected reference is reported with, so a caller sees what was expected of it.
|
|
35
|
+
* @param reference - The value that was refused.
|
|
36
|
+
* @returns The error describing what a repository reference may be.
|
|
37
|
+
**/
|
|
38
|
+
function notClonable(reference) {
|
|
39
|
+
return new Error(`Not a clonable git repository: "${reference}". Pass a user/repo pair, a repository ending in .git, a URL git can clone, an ssh address or a local path of a repository.`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parses a repository reference into the repository git clones from and the name GitHub derives.
|
|
43
|
+
*
|
|
44
|
+
* A GitHub repository may be written as the bare `user/repo` shorthand, as an HTTP(S) URL or as an
|
|
45
|
+
* SCP like ssh address, with or without the `.git` suffix; every one of them is canonicalized to
|
|
46
|
+
* the same repository. Any other repository is accepted as it stands when it is a value
|
|
47
|
+
* {@link DepUtils.Repo} accepts, and carries no derivable name.
|
|
48
|
+
* @param reference - The repository reference as a user writes it.
|
|
49
|
+
* @returns The canonical repository and the derived name, `null` when there is none.
|
|
50
|
+
* @throws { Error } When the reference is not a clonable repository.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* DepUtils.parse('netfeez/omega');
|
|
55
|
+
* // { repo: 'https://github.com/netfeez/omega.git', name: 'netfeez/omega' }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
function parse(reference) {
|
|
59
|
+
if (typeof reference !== 'string' || !reference.trim())
|
|
60
|
+
throw notClonable(reference);
|
|
61
|
+
const value = reference.trim();
|
|
62
|
+
const http = value.match(GITHUB_HTTP_REGEX);
|
|
63
|
+
if (http)
|
|
64
|
+
return { repo: `${http[1]}://github.com/${http[2]}/${http[3]}.git`, name: `${http[2]}/${http[3]}` };
|
|
65
|
+
const ssh = value.match(GITHUB_SSH_REGEX);
|
|
66
|
+
if (ssh)
|
|
67
|
+
return { repo: `git@github.com:${ssh[1]}/${ssh[2]}.git`, name: `${ssh[1]}/${ssh[2]}` };
|
|
68
|
+
const short = value.match(GITHUB_SHORT_REGEX);
|
|
69
|
+
if (short)
|
|
70
|
+
return { repo: `https://github.com/${short[1]}/${short[2]}.git`, name: `${short[1]}/${short[2]}` };
|
|
71
|
+
if (!CLONEABLE_REGEX.test(value) || !GIT_SUFFIX_REGEX.test(value))
|
|
72
|
+
throw notClonable(value);
|
|
73
|
+
return { repo: value, name: null };
|
|
74
|
+
}
|
|
75
|
+
DepUtils.parse = parse;
|
|
76
|
+
/**
|
|
77
|
+
* Validates that the provided value is a repository `git clone` accepts, and says what it is not when
|
|
78
|
+
* it does not: a URL with its scheme, an SCP like address or a local path of a repository.
|
|
79
|
+
* @param repo - The repository value to validate.
|
|
80
|
+
* @throws Will throw an error if the value is not a clonable repository.
|
|
81
|
+
*
|
|
82
|
+
* @remarks A repository always carries the `.git` suffix, whichever transport it comes in: it is what
|
|
83
|
+
* tells a repository apart from a page, a package or a folder, and the name of the dependency is
|
|
84
|
+
* derived from the same suffix, so both read one repository.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* DepUtils.repo('https://github.com/NetFeez/omega.git');
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
function repo(repo) {
|
|
92
|
+
if (typeof repo !== 'string' || !repo.trim())
|
|
93
|
+
throw new Error(`Not a clonable git repository: "${repo}".`);
|
|
94
|
+
if (!CLONEABLE_REGEX.test(repo) || !GIT_SUFFIX_REGEX.test(repo.trim()))
|
|
95
|
+
throw new Error(`Not a clonable git repository: "${repo}". Pass a repository ending in .git, a URL git can clone, an ssh address or a local path of a repository.`);
|
|
96
|
+
}
|
|
97
|
+
DepUtils.repo = repo;
|
|
98
|
+
/**
|
|
99
|
+
* Extracts the name a dependency is known by from its repository reference.
|
|
100
|
+
*
|
|
101
|
+
* Only a GitHub repository has a name that can be derived without asking, and the name it derives
|
|
102
|
+
* is the one the alias of the dependency takes everywhere else, so it is derived here and nowhere
|
|
103
|
+
* else.
|
|
104
|
+
* @param repo - The repository reference, in any of the forms {@link DepUtils.parse} accepts.
|
|
105
|
+
* @returns The repository name, as `<user>/<name>`.
|
|
106
|
+
* @throws { Error } When the repository is not a GitHub one, saying the name has to be given.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* DepUtils.getRepoName('https://github.com/NetFeez/omega.git'); // 'NetFeez/omega'
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
function getRepoName(repo) {
|
|
114
|
+
const { name } = parse(repo);
|
|
115
|
+
if (!name)
|
|
116
|
+
throw new Error(`Cannot derive a name from "${repo}": only GitHub repositories are named automatically, pass the name yourself.`);
|
|
117
|
+
return name;
|
|
118
|
+
}
|
|
119
|
+
DepUtils.getRepoName = getRepoName;
|
|
120
|
+
})(DepUtils || (DepUtils = {}));
|
|
121
|
+
export default DepUtils;
|
|
122
|
+
//# sourceMappingURL=DepUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DepUtils.js","sourceRoot":"","sources":["../../src/dependency/DepUtils.ts"],"names":[],"mappings":"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"}
|