@bjmhe/automd 0.0.0 → 0.0.4
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 +4 -5
- package/dist/_parse-KesGTpQx.d.ts +49 -0
- package/dist/_parse.d.ts +4 -0
- package/dist/_parse.js +67 -0
- package/dist/_parse.js.map +1 -0
- package/dist/_utils.d.ts +18 -0
- package/dist/_utils.js +36 -0
- package/dist/_utils.js.map +1 -0
- package/dist/automd-C2wjw_SG.d.ts +131 -0
- package/dist/automd.d.ts +4 -0
- package/dist/automd.js +88 -0
- package/dist/automd.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +107 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +41 -0
- package/dist/config.js.map +1 -0
- package/dist/generator.d.ts +4 -0
- package/dist/generator.js +11 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.d.ts +2 -195
- package/dist/index.js +5 -806
- package/dist/transform-BOfYBrHa.js +599 -0
- package/dist/transform-BOfYBrHa.js.map +1 -0
- package/dist/transform.d.ts +4 -0
- package/dist/transform.js +6 -0
- package/package.json +24 -19
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- automd:badges bundlephobia license engine provider=npmx -->
|
|
4
4
|
|
|
5
|
-
[](https://npmx.dev/api/registry/badge/engines/@bjmhe/automd)
|
|
5
|
+
[](https://npmjs.com/package/@bjmhe/automd)
|
|
6
|
+
[](https://npm.chart.dev/@bjmhe/automd)
|
|
7
|
+
[](https://bundlephobia.com/package/@bjmhe/automd)
|
|
8
|
+
[](https://github.com/bjmhe/automd/blob/main/LICENSE)
|
|
10
9
|
|
|
11
10
|
<!-- /automd -->
|
|
12
11
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
//#region src/_parse.d.ts
|
|
3
|
+
interface Block {
|
|
4
|
+
/** The name of the generator to use for updates. */
|
|
5
|
+
generator: string;
|
|
6
|
+
/** The arguments that are passed to the generator. */
|
|
7
|
+
rawArgs: string;
|
|
8
|
+
/** The current content of the block. */
|
|
9
|
+
contents: string;
|
|
10
|
+
/** The location of the content in the original document. */
|
|
11
|
+
loc: {
|
|
12
|
+
start: number;
|
|
13
|
+
end: number;
|
|
14
|
+
};
|
|
15
|
+
/** The location including the automd comments. */
|
|
16
|
+
_loc: {
|
|
17
|
+
start: number;
|
|
18
|
+
end: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Searches a markdown document for special sections that `automd` can update.
|
|
23
|
+
*
|
|
24
|
+
* @param md - The markdown document as a string.
|
|
25
|
+
* @returns An array of blocks that can be updated automatically. {@link Block}
|
|
26
|
+
*/
|
|
27
|
+
declare function findBlocks(md: string): Block[];
|
|
28
|
+
/**
|
|
29
|
+
* Checks if a markdown document contains sections that can be automatically updated.
|
|
30
|
+
*
|
|
31
|
+
* @param md - The markdown document as a string.
|
|
32
|
+
* @returns True if there are `automd` sections, false otherwise.
|
|
33
|
+
*/
|
|
34
|
+
declare function containsAutomd(md: string): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Converts a string of raw arguments to an object. Each argument is separated by spaces. Arguments
|
|
37
|
+
* can be key-value pairs separated by '='. If an argument starts with "no-", the key is set to
|
|
38
|
+
* false. Otherwise it sets the key to true. Keys are converted to camelCase. Values are processed
|
|
39
|
+
* to determine their actual type (e.g. string, boolean).
|
|
40
|
+
*
|
|
41
|
+
* @param {string} rawArgs - The string of arguments to parse.
|
|
42
|
+
* @returns {Object} - An object with keys derived from the arguments. Keys are in camelCase. Values
|
|
43
|
+
* are true, false, or strings.
|
|
44
|
+
*/
|
|
45
|
+
declare function parseRawArgs(rawArgs: string): any;
|
|
46
|
+
//#endregion
|
|
47
|
+
export { parseRawArgs as i, containsAutomd as n, findBlocks as r, Block as t };
|
|
48
|
+
/*! Built with love & coffee ☕ */
|
|
49
|
+
//# sourceMappingURL=_parse-KesGTpQx.d.ts.map
|
package/dist/_parse.d.ts
ADDED
package/dist/_parse.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
import { destr } from "destr";
|
|
3
|
+
import { camelCase } from "scule";
|
|
4
|
+
//#region src/_parse.ts
|
|
5
|
+
/**
|
|
6
|
+
* Searches a markdown document for special sections that `automd` can update.
|
|
7
|
+
*
|
|
8
|
+
* @param md - The markdown document as a string.
|
|
9
|
+
* @returns An array of blocks that can be updated automatically. {@link Block}
|
|
10
|
+
*/
|
|
11
|
+
function findBlocks(md) {
|
|
12
|
+
const blocks = [];
|
|
13
|
+
for (const match of md.matchAll(/^(?<open><!--\s*automd:(?<generator>.+?)\s+(?<args>.*?)\s*-->)(?<contents>.+?)(?<close>^<!--\s*\/automd\s*-->)/gimsu)) {
|
|
14
|
+
if (match.index === void 0 || !match.groups) continue;
|
|
15
|
+
const start = match.index + match.groups.open.length || 0;
|
|
16
|
+
const end = start + match.groups.contents.length;
|
|
17
|
+
blocks.push({
|
|
18
|
+
generator: match.groups.generator,
|
|
19
|
+
rawArgs: match.groups.args,
|
|
20
|
+
contents: match.groups.contents,
|
|
21
|
+
loc: {
|
|
22
|
+
start,
|
|
23
|
+
end
|
|
24
|
+
},
|
|
25
|
+
_loc: {
|
|
26
|
+
start: match.index,
|
|
27
|
+
end: match.index + match[0].length
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return blocks;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Checks if a markdown document contains sections that can be automatically updated.
|
|
35
|
+
*
|
|
36
|
+
* @param md - The markdown document as a string.
|
|
37
|
+
* @returns True if there are `automd` sections, false otherwise.
|
|
38
|
+
*/
|
|
39
|
+
function containsAutomd(md) {
|
|
40
|
+
return /^<!--\s*automd:/gimsu.test(md);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Converts a string of raw arguments to an object. Each argument is separated by spaces. Arguments
|
|
44
|
+
* can be key-value pairs separated by '='. If an argument starts with "no-", the key is set to
|
|
45
|
+
* false. Otherwise it sets the key to true. Keys are converted to camelCase. Values are processed
|
|
46
|
+
* to determine their actual type (e.g. string, boolean).
|
|
47
|
+
*
|
|
48
|
+
* @param {string} rawArgs - The string of arguments to parse.
|
|
49
|
+
* @returns {Object} - An object with keys derived from the arguments. Keys are in camelCase. Values
|
|
50
|
+
* are true, false, or strings.
|
|
51
|
+
*/
|
|
52
|
+
function parseRawArgs(rawArgs) {
|
|
53
|
+
const args = Object.create(null);
|
|
54
|
+
for (const part of rawArgs.split(/\s+/)) {
|
|
55
|
+
const [_key, value] = part.split("=");
|
|
56
|
+
const key = _key && camelCase(_key);
|
|
57
|
+
if (key && value) args[key] = destr(value);
|
|
58
|
+
else if (part.startsWith("no-")) args[part.slice(3)] = false;
|
|
59
|
+
else args[part] = true;
|
|
60
|
+
}
|
|
61
|
+
return args;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { containsAutomd, findBlocks, parseRawArgs };
|
|
65
|
+
|
|
66
|
+
/*! Built with love & coffee ☕ */
|
|
67
|
+
//# sourceMappingURL=_parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_parse.js","names":[],"sources":["../src/_parse.ts"],"sourcesContent":["import { destr } from \"destr\";\nimport { camelCase } from \"scule\";\n\nexport interface Block {\n /** The name of the generator to use for updates. */\n generator: string;\n\n /** The arguments that are passed to the generator. */\n rawArgs: string;\n\n /** The current content of the block. */\n contents: string;\n\n /** The location of the content in the original document. */\n loc: { start: number; end: number };\n\n /** The location including the automd comments. */\n _loc: { start: number; end: number };\n}\n\n/**\n * Searches a markdown document for special sections that `automd` can update.\n *\n * @param md - The markdown document as a string.\n * @returns An array of blocks that can be updated automatically. {@link Block}\n */\nexport function findBlocks(md: string): Block[] {\n const blocks: Block[] = [];\n\n // Regex is stateful, so we need to reset it\n const AUTOMD_RE =\n /^(?<open><!--\\s*automd:(?<generator>.+?)\\s+(?<args>.*?)\\s*-->)(?<contents>.+?)(?<close>^<!--\\s*\\/automd\\s*-->)/gimsu;\n\n for (const match of md.matchAll(AUTOMD_RE)) {\n if (match.index === undefined || !match.groups) {\n continue;\n }\n\n const start = match.index + match.groups.open!.length || 0;\n const end = start + match.groups.contents!.length;\n\n blocks.push({\n generator: match.groups.generator!,\n rawArgs: match.groups.args!,\n contents: match.groups.contents!,\n loc: { start, end },\n _loc: { start: match.index, end: match.index + match[0].length },\n });\n }\n\n return blocks;\n}\n\n/**\n * Checks if a markdown document contains sections that can be automatically updated.\n *\n * @param md - The markdown document as a string.\n * @returns True if there are `automd` sections, false otherwise.\n */\nexport function containsAutomd(md: string) {\n return /^<!--\\s*automd:/gimsu.test(md);\n}\n\n/**\n * Converts a string of raw arguments to an object. Each argument is separated by spaces. Arguments\n * can be key-value pairs separated by '='. If an argument starts with \"no-\", the key is set to\n * false. Otherwise it sets the key to true. Keys are converted to camelCase. Values are processed\n * to determine their actual type (e.g. string, boolean).\n *\n * @param {string} rawArgs - The string of arguments to parse.\n * @returns {Object} - An object with keys derived from the arguments. Keys are in camelCase. Values\n * are true, false, or strings.\n */\nexport function parseRawArgs(rawArgs: string) {\n const args = Object.create(null);\n\n for (const part of rawArgs.split(/\\s+/)) {\n const [_key, value] = part.split(\"=\");\n const key = _key && camelCase(_key);\n if (key && value) {\n args[key] = destr(value);\n } else if (part.startsWith(\"no-\")) {\n args[part.slice(3)] = false;\n } else {\n args[part] = true;\n }\n }\n\n return args;\n}\n"],"mappings":";;;;;;;;;;AA0BA,SAAgB,WAAW,IAAqB;CAC9C,MAAM,SAAkB,CAAC;CAMzB,KAAK,MAAM,SAAS,GAAG,SAAS,qHAAS,GAAG;EAC1C,IAAI,MAAM,UAAU,KAAA,KAAa,CAAC,MAAM,QACtC;EAGF,MAAM,QAAQ,MAAM,QAAQ,MAAM,OAAO,KAAM,UAAU;EACzD,MAAM,MAAM,QAAQ,MAAM,OAAO,SAAU;EAE3C,OAAO,KAAK;GACV,WAAW,MAAM,OAAO;GACxB,SAAS,MAAM,OAAO;GACtB,UAAU,MAAM,OAAO;GACvB,KAAK;IAAE;IAAO;GAAI;GAClB,MAAM;IAAE,OAAO,MAAM;IAAO,KAAK,MAAM,QAAQ,MAAM,GAAG;GAAO;EACjE,CAAC;CACH;CAEA,OAAO;AACT;;;;;;;AAQA,SAAgB,eAAe,IAAY;CACzC,OAAO,uBAAuB,KAAK,EAAE;AACvC;;;;;;;;;;;AAYA,SAAgB,aAAa,SAAiB;CAC5C,MAAM,OAAO,OAAO,OAAO,IAAI;CAE/B,KAAK,MAAM,QAAQ,QAAQ,MAAM,KAAK,GAAG;EACvC,MAAM,CAAC,MAAM,SAAS,KAAK,MAAM,GAAG;EACpC,MAAM,MAAM,QAAQ,UAAU,IAAI;EAClC,IAAI,OAAO,OACT,KAAK,OAAO,MAAM,KAAK;OAClB,IAAI,KAAK,WAAW,KAAK,GAC9B,KAAK,KAAK,MAAM,CAAC,KAAK;OAEtB,KAAK,QAAQ;CAEjB;CAEA,OAAO;AACT"}
|
package/dist/_utils.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
//#region src/_utils.d.ts
|
|
3
|
+
declare function resolvePath(path: string, {
|
|
4
|
+
url,
|
|
5
|
+
dir
|
|
6
|
+
}: {
|
|
7
|
+
url?: string;
|
|
8
|
+
dir: string;
|
|
9
|
+
}): string;
|
|
10
|
+
declare function getPkg(dir: string, input?: Record<string, string>): Promise<{
|
|
11
|
+
name: string;
|
|
12
|
+
version: string | undefined;
|
|
13
|
+
github: string;
|
|
14
|
+
}>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { getPkg, resolvePath };
|
|
17
|
+
/*! Built with love & coffee ☕ */
|
|
18
|
+
//# sourceMappingURL=_utils.d.ts.map
|
package/dist/_utils.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
import { defu } from "defu";
|
|
3
|
+
import { fileURLToPath } from "mlly";
|
|
4
|
+
import { join, resolve } from "pathe";
|
|
5
|
+
import { readPackageJSON } from "pkg-types";
|
|
6
|
+
//#region src/_utils.ts
|
|
7
|
+
function resolvePath(path, { url, dir }) {
|
|
8
|
+
if (path.startsWith("/")) return join(dir, path);
|
|
9
|
+
return url ? fileURLToPath(new URL(path, url)) : resolve(dir, path);
|
|
10
|
+
}
|
|
11
|
+
async function getPkg(dir, input = {}) {
|
|
12
|
+
const pkg = await readPackageJSON(dir).catch(() => void 0);
|
|
13
|
+
return defu({
|
|
14
|
+
name: input.name,
|
|
15
|
+
version: typeof input.version === "string" ? input.version : void 0,
|
|
16
|
+
github: input.github || input.gh
|
|
17
|
+
}, {
|
|
18
|
+
name: pkg?.name,
|
|
19
|
+
version: pkg?.version,
|
|
20
|
+
github: _getGitRepo(pkg?.repository)
|
|
21
|
+
}, {
|
|
22
|
+
name: process.env.npm_package_name,
|
|
23
|
+
version: process.env.npm_package_version
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function _getGitRepo(repo) {
|
|
27
|
+
const url = typeof repo === "string" ? repo : repo?.url;
|
|
28
|
+
if (!url || typeof url !== "string") return;
|
|
29
|
+
const match = /(?:https:\/\/github\.com\/|gh:|github:|)([\w-]+)\/([\w-]+)/.exec(url);
|
|
30
|
+
if (match && match[1] && match[2]) return `${match[1]}/${match[2]}`;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { getPkg, resolvePath };
|
|
34
|
+
|
|
35
|
+
/*! Built with love & coffee ☕ */
|
|
36
|
+
//# sourceMappingURL=_utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_utils.js","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { defu } from \"defu\";\nimport { fileURLToPath } from \"mlly\";\nimport { resolve, join } from \"pathe\";\nimport type { PackageJson } from \"pkg-types\";\nimport { readPackageJSON } from \"pkg-types\";\n\nexport function resolvePath(path: string, { url, dir }: { url?: string; dir: string }) {\n if (path.startsWith(\"/\")) {\n return join(dir, path);\n }\n return url ? fileURLToPath(new URL(path, url)) : resolve(dir, path);\n}\n\nexport async function getPkg(dir: string, input: Record<string, string> = {}) {\n const pkg = await readPackageJSON(dir).catch(() => undefined);\n return defu(\n {\n name: input.name,\n version: typeof input.version === \"string\" ? input.version : undefined,\n github: input.github || input.gh,\n },\n {\n name: pkg?.name,\n version: pkg?.version,\n github: _getGitRepo(pkg?.repository),\n },\n {\n name: process.env.npm_package_name,\n version: process.env.npm_package_version,\n },\n );\n}\n\nfunction _getGitRepo(repo: PackageJson[\"repository\"]) {\n const url = typeof repo === \"string\" ? repo : repo?.url;\n if (!url || typeof url !== \"string\") {\n return;\n }\n const match = /(?:https:\\/\\/github\\.com\\/|gh:|github:|)([\\w-]+)\\/([\\w-]+)/.exec(url);\n if (match && match[1] && match[2]) {\n return `${match[1]}/${match[2]}`;\n }\n}\n"],"mappings":";;;;;;AAMA,SAAgB,YAAY,MAAc,EAAE,KAAK,OAAsC;CACrF,IAAI,KAAK,WAAW,GAAG,GACrB,OAAO,KAAK,KAAK,IAAI;CAEvB,OAAO,MAAM,cAAc,IAAI,IAAI,MAAM,GAAG,CAAC,IAAI,QAAQ,KAAK,IAAI;AACpE;AAEA,eAAsB,OAAO,KAAa,QAAgC,CAAC,GAAG;CAC5E,MAAM,MAAM,MAAM,gBAAgB,GAAG,EAAE,YAAY,KAAA,CAAS;CAC5D,OAAO,KACL;EACE,MAAM,MAAM;EACZ,SAAS,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU,KAAA;EAC7D,QAAQ,MAAM,UAAU,MAAM;CAChC,GACA;EACE,MAAM,KAAK;EACX,SAAS,KAAK;EACd,QAAQ,YAAY,KAAK,UAAU;CACrC,GACA;EACE,MAAM,QAAQ,IAAI;EAClB,SAAS,QAAQ,IAAI;CACvB,CACF;AACF;AAEA,SAAS,YAAY,MAAiC;CACpD,MAAM,MAAM,OAAO,SAAS,WAAW,OAAO,MAAM;CACpD,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB;CAEF,MAAM,QAAQ,6DAA6D,KAAK,GAAG;CACnF,IAAI,SAAS,MAAM,MAAM,MAAM,IAC7B,OAAO,GAAG,MAAM,GAAG,GAAG,MAAM;AAEhC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
import { t as Block } from "./_parse-KesGTpQx.js";
|
|
3
|
+
|
|
4
|
+
//#region src/transform.d.ts
|
|
5
|
+
interface TransformResult {
|
|
6
|
+
/** Wether if the document has been modified at all. */
|
|
7
|
+
hasChanged: boolean;
|
|
8
|
+
/** Whether if there were any problems found in the document. */
|
|
9
|
+
hasIssues: boolean;
|
|
10
|
+
/** The text of the document after it was transformed. */
|
|
11
|
+
contents: string;
|
|
12
|
+
/** A list of specific parts that have been transformed in the document. */
|
|
13
|
+
updates: {
|
|
14
|
+
/** The specific part of the document that has been transformed. */block: Block; /** What the transform has done to this part of the document. */
|
|
15
|
+
result: GenerateResult;
|
|
16
|
+
}[];
|
|
17
|
+
/** How long the editing process took, measured in milliseconds. */
|
|
18
|
+
time: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Edits a markdown document based on certain rules and configurations.
|
|
22
|
+
*
|
|
23
|
+
* @param contents - The text of the markdown document you want to edit.
|
|
24
|
+
* @param _config - Optional. The settings that affect how the document will be edited. See
|
|
25
|
+
* {@link Config}.
|
|
26
|
+
* @param url - Optional. The URL associated with the document, if any.
|
|
27
|
+
* @returns - The result of the transformation, including any changes made and how long it took. See
|
|
28
|
+
* {@link TransformResult}.
|
|
29
|
+
*/
|
|
30
|
+
declare function transform(contents: string, _config?: Config, url?: string): Promise<TransformResult>;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/generator.d.ts
|
|
33
|
+
interface GenerateContext {
|
|
34
|
+
args: Record<string, any>;
|
|
35
|
+
config: ResolvedConfig;
|
|
36
|
+
block: Block;
|
|
37
|
+
url?: string;
|
|
38
|
+
transform: (contents: string) => Promise<TransformResult>;
|
|
39
|
+
}
|
|
40
|
+
/** The result of generating a component. */
|
|
41
|
+
interface GenerateResult {
|
|
42
|
+
/** The generated component */
|
|
43
|
+
contents: string;
|
|
44
|
+
/** A list of issues that occurred during generation. */
|
|
45
|
+
issues?: string[];
|
|
46
|
+
/** Whether to unwrap the component. */
|
|
47
|
+
unwrap?: boolean;
|
|
48
|
+
}
|
|
49
|
+
interface Generator {
|
|
50
|
+
name: string;
|
|
51
|
+
generate: (ctx: GenerateContext) => GenerateResult | Promise<GenerateResult>;
|
|
52
|
+
}
|
|
53
|
+
/** @internal */
|
|
54
|
+
declare function defineGenerator(generator: Generator): Generator;
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/config.d.ts
|
|
57
|
+
interface Config {
|
|
58
|
+
/**
|
|
59
|
+
* The working directory
|
|
60
|
+
*
|
|
61
|
+
* @default "." (current directory)
|
|
62
|
+
*/
|
|
63
|
+
dir?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Name or path to the input file or files with glob patterns.
|
|
66
|
+
*
|
|
67
|
+
* @default "README.md"
|
|
68
|
+
*/
|
|
69
|
+
input?: string | string[];
|
|
70
|
+
/**
|
|
71
|
+
* Name or path of the output files. If not provided, the input file will be overwritten.
|
|
72
|
+
*
|
|
73
|
+
* @default input
|
|
74
|
+
*/
|
|
75
|
+
output?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Ignore patterns if input is a glob pattern
|
|
78
|
+
*
|
|
79
|
+
* @default ["node_modules", "dist", "/.*"]
|
|
80
|
+
*/
|
|
81
|
+
ignore?: string[];
|
|
82
|
+
/** Watch for changes in input files and regenerate output */
|
|
83
|
+
watch?: boolean;
|
|
84
|
+
/** Watch callback */
|
|
85
|
+
onWatch?: (event: {
|
|
86
|
+
results: AutomdResult[];
|
|
87
|
+
time: number;
|
|
88
|
+
}) => void;
|
|
89
|
+
/** Custom generators */
|
|
90
|
+
generators?: Record<string, Generator>;
|
|
91
|
+
}
|
|
92
|
+
declare const RESOLVED_CONFIG_SYMBOL: unique symbol;
|
|
93
|
+
type ResolvedConfig = { [P in keyof Config]-?: Config[P] } & {
|
|
94
|
+
[RESOLVED_CONFIG_SYMBOL]: true;
|
|
95
|
+
input: string[];
|
|
96
|
+
output?: string;
|
|
97
|
+
};
|
|
98
|
+
declare function resolveConfig(config?: Config | ResolvedConfig): ResolvedConfig;
|
|
99
|
+
declare function loadConfig(dir: string | undefined, overrides: Config): Promise<ResolvedConfig>;
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/automd.d.ts
|
|
102
|
+
interface AutomdResult extends TransformResult {
|
|
103
|
+
input: string;
|
|
104
|
+
output: string;
|
|
105
|
+
}
|
|
106
|
+
/** Describes what you get back from the `automd` function. */
|
|
107
|
+
interface AutomdReturn {
|
|
108
|
+
/** A list of the changes made to the file(s) by `automd`. */
|
|
109
|
+
results: AutomdResult[];
|
|
110
|
+
/** How long it took to make the changes, in milliseconds. */
|
|
111
|
+
time: number;
|
|
112
|
+
/** The resolved configuration that were used for these changes. */
|
|
113
|
+
config: ResolvedConfig;
|
|
114
|
+
/** If you started watching the file(s) for changes, this function can be called to stop watching. */
|
|
115
|
+
unwatch?: () => void | Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Scans a markdown file looking for special comments. These comments tell the function to add or
|
|
119
|
+
* update certain parts of the file automatically. You can change how this works by giving it
|
|
120
|
+
* different settings in the `_config` option.
|
|
121
|
+
*
|
|
122
|
+
* @param _config - The settings to use for the update process. See {@link Config}.
|
|
123
|
+
* @returns - An object containing the results of the update, including any changes made and any
|
|
124
|
+
* problems found. See {@link AutomdReturn}.
|
|
125
|
+
* @see https://automd.unjs.io/guide
|
|
126
|
+
*/
|
|
127
|
+
declare function automd(_config?: Config): Promise<AutomdReturn>;
|
|
128
|
+
//#endregion
|
|
129
|
+
export { ResolvedConfig as a, GenerateContext as c, defineGenerator as d, TransformResult as f, Config as i, GenerateResult as l, AutomdReturn as n, loadConfig as o, transform as p, automd as r, resolveConfig as s, AutomdResult as t, Generator as u };
|
|
130
|
+
/*! Built with love & coffee ☕ */
|
|
131
|
+
//# sourceMappingURL=automd-C2wjw_SG.d.ts.map
|
package/dist/automd.d.ts
ADDED
package/dist/automd.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
import { loadConfig } from "./config.js";
|
|
3
|
+
import { t as transform } from "./transform-BOfYBrHa.js";
|
|
4
|
+
import { pathToFileURL } from "mlly";
|
|
5
|
+
import { dirname, relative, resolve } from "pathe";
|
|
6
|
+
import { existsSync, promises } from "node:fs";
|
|
7
|
+
import { debounce } from "perfect-debounce";
|
|
8
|
+
//#region src/automd.ts
|
|
9
|
+
/**
|
|
10
|
+
* Scans a markdown file looking for special comments. These comments tell the function to add or
|
|
11
|
+
* update certain parts of the file automatically. You can change how this works by giving it
|
|
12
|
+
* different settings in the `_config` option.
|
|
13
|
+
*
|
|
14
|
+
* @param _config - The settings to use for the update process. See {@link Config}.
|
|
15
|
+
* @returns - An object containing the results of the update, including any changes made and any
|
|
16
|
+
* problems found. See {@link AutomdReturn}.
|
|
17
|
+
* @see https://automd.unjs.io/guide
|
|
18
|
+
*/
|
|
19
|
+
async function automd(_config = {}) {
|
|
20
|
+
const start = performance.now();
|
|
21
|
+
const config = await loadConfig(_config.dir, _config);
|
|
22
|
+
let inputFiles = config.input;
|
|
23
|
+
if (inputFiles.some((i) => i.includes("*"))) {
|
|
24
|
+
const { glob } = await import("tinyglobby");
|
|
25
|
+
inputFiles = await glob(inputFiles, {
|
|
26
|
+
cwd: config.dir,
|
|
27
|
+
absolute: false,
|
|
28
|
+
onlyFiles: true,
|
|
29
|
+
ignore: config.ignore
|
|
30
|
+
});
|
|
31
|
+
} else inputFiles = inputFiles.map((i) => resolve(config.dir, i)).filter((i) => existsSync(i)).map((i) => relative(config.dir, i));
|
|
32
|
+
const multiFiles = inputFiles.length > 1;
|
|
33
|
+
const cache = /* @__PURE__ */ new Map();
|
|
34
|
+
const results = await Promise.all(inputFiles.map((i) => _automd(i, config, multiFiles, cache)));
|
|
35
|
+
let unwatch;
|
|
36
|
+
if (config.watch) unwatch = await _watch(inputFiles, config, multiFiles, cache);
|
|
37
|
+
return {
|
|
38
|
+
time: performance.now() - start,
|
|
39
|
+
results,
|
|
40
|
+
config,
|
|
41
|
+
unwatch
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function _automd(relativeInput, config, multiFiles, cache) {
|
|
45
|
+
const start = performance.now();
|
|
46
|
+
const input = resolve(config.dir, relativeInput);
|
|
47
|
+
const contents = await promises.readFile(input, "utf8");
|
|
48
|
+
const cachedResult = await cache.get(input);
|
|
49
|
+
if (cachedResult?.contents === contents) {
|
|
50
|
+
cachedResult.time = performance.now() - start;
|
|
51
|
+
return cachedResult;
|
|
52
|
+
}
|
|
53
|
+
const transformResult = await transform(contents, config, pathToFileURL(input));
|
|
54
|
+
const output = multiFiles ? resolve(config.dir, config.output || ".", relativeInput) : resolve(config.dir, config.output || relativeInput);
|
|
55
|
+
await promises.mkdir(dirname(output), { recursive: true });
|
|
56
|
+
await promises.writeFile(output, transformResult.contents, "utf8");
|
|
57
|
+
const result = {
|
|
58
|
+
input,
|
|
59
|
+
output,
|
|
60
|
+
...transformResult
|
|
61
|
+
};
|
|
62
|
+
cache.set(input, result);
|
|
63
|
+
result.time = performance.now() - start;
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
async function _watch(inputFiles, config, multiFiles, cache) {
|
|
67
|
+
const watcher = await import("@parcel/watcher");
|
|
68
|
+
const watchCb = debounce(async (_err, events) => {
|
|
69
|
+
const filesToUpdate = events.map((e) => relative(config.dir, e.path)).filter((p) => inputFiles.includes(p));
|
|
70
|
+
const start = performance.now();
|
|
71
|
+
const results = await Promise.all(filesToUpdate.map((f) => _automd(f, config, multiFiles, cache)));
|
|
72
|
+
const time = performance.now() - start;
|
|
73
|
+
if (config.onWatch) config.onWatch({
|
|
74
|
+
results,
|
|
75
|
+
time
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
const subscription = await watcher.subscribe(config.dir, watchCb, { ignore: config.ignore });
|
|
79
|
+
process.on("SIGINT", () => {
|
|
80
|
+
subscription.unsubscribe();
|
|
81
|
+
});
|
|
82
|
+
return subscription.unsubscribe;
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { automd };
|
|
86
|
+
|
|
87
|
+
/*! Built with love & coffee ☕ */
|
|
88
|
+
//# sourceMappingURL=automd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automd.js","names":["fsp"],"sources":["../src/automd.ts"],"sourcesContent":["import { existsSync, promises as fsp } from \"node:fs\";\n\nimport type { SubscribeCallback } from \"@parcel/watcher\";\nimport { pathToFileURL } from \"mlly\";\nimport { resolve, relative, dirname } from \"pathe\";\nimport { debounce } from \"perfect-debounce\";\n\nimport type { Config, ResolvedConfig } from \"./config.ts\";\nimport { loadConfig } from \"./config.ts\";\nimport { type TransformResult, transform } from \"./transform.ts\";\n\nexport interface AutomdResult extends TransformResult {\n input: string;\n output: string;\n}\n\n/** Describes what you get back from the `automd` function. */\nexport interface AutomdReturn {\n /** A list of the changes made to the file(s) by `automd`. */\n results: AutomdResult[];\n\n /** How long it took to make the changes, in milliseconds. */\n time: number;\n\n /** The resolved configuration that were used for these changes. */\n config: ResolvedConfig;\n\n /** If you started watching the file(s) for changes, this function can be called to stop watching. */\n unwatch?: () => void | Promise<void>;\n}\n\n/**\n * Scans a markdown file looking for special comments. These comments tell the function to add or\n * update certain parts of the file automatically. You can change how this works by giving it\n * different settings in the `_config` option.\n *\n * @param _config - The settings to use for the update process. See {@link Config}.\n * @returns - An object containing the results of the update, including any changes made and any\n * problems found. See {@link AutomdReturn}.\n * @see https://automd.unjs.io/guide\n */\nexport async function automd(_config: Config = {}): Promise<AutomdReturn> {\n const start = performance.now();\n const config = await loadConfig(_config.dir, _config);\n\n let inputFiles = config.input;\n if (inputFiles.some((i) => i.includes(\"*\"))) {\n const { glob } = await import(\"tinyglobby\");\n inputFiles = await glob(inputFiles, {\n cwd: config.dir,\n absolute: false,\n onlyFiles: true,\n ignore: config.ignore,\n });\n } else {\n inputFiles = inputFiles\n .map((i) => resolve(config.dir, i))\n .filter((i) => existsSync(i))\n .map((i) => relative(config.dir, i));\n }\n const multiFiles = inputFiles.length > 1;\n\n const cache: ResultCache = new Map();\n\n const results = await Promise.all(inputFiles.map((i) => _automd(i, config, multiFiles, cache)));\n\n let unwatch;\n if (config.watch) {\n unwatch = await _watch(inputFiles, config, multiFiles, cache);\n }\n\n const time = performance.now() - start;\n\n return {\n time,\n results,\n config,\n unwatch,\n };\n}\n\n// -- internal --\n\ntype ResultCache = Map<string, AutomdResult>;\n\nasync function _automd(\n relativeInput: string,\n config: ResolvedConfig,\n multiFiles: boolean,\n cache: ResultCache,\n): Promise<AutomdResult> {\n const start = performance.now();\n const input = resolve(config.dir, relativeInput);\n const contents = await fsp.readFile(input, \"utf8\");\n\n const cachedResult = await cache.get(input);\n if (cachedResult?.contents === contents) {\n cachedResult.time = performance.now() - start;\n return cachedResult;\n }\n\n const transformResult = await transform(contents, config, pathToFileURL(input));\n\n const output = multiFiles\n ? resolve(config.dir, config.output || \".\", relativeInput)\n : resolve(config.dir, config.output || relativeInput);\n\n await fsp.mkdir(dirname(output), { recursive: true });\n await fsp.writeFile(output, transformResult.contents, \"utf8\");\n\n const result: AutomdResult = {\n input,\n output,\n ...transformResult,\n };\n cache.set(input, result);\n result.time = performance.now() - start;\n return result;\n}\n\nasync function _watch(\n inputFiles: string[],\n config: ResolvedConfig,\n multiFiles: boolean,\n cache: ResultCache,\n) {\n const watcher = await import(\"@parcel/watcher\");\n\n const watchCb: SubscribeCallback = debounce(async (_err, events) => {\n const filesToUpdate = events\n .map((e) => relative(config.dir, e.path))\n .filter((p) => inputFiles.includes(p));\n const start = performance.now();\n const results = await Promise.all(\n filesToUpdate.map((f) => _automd(f, config, multiFiles, cache)),\n );\n const time = performance.now() - start;\n if (config.onWatch) {\n config.onWatch({ results, time });\n }\n });\n\n const subscription = await watcher.subscribe(config.dir, watchCb, {\n ignore: config.ignore,\n });\n\n process.on(\"SIGINT\", () => {\n subscription.unsubscribe();\n });\n\n return subscription.unsubscribe;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyCA,eAAsB,OAAO,UAAkB,CAAC,GAA0B;CACxE,MAAM,QAAQ,YAAY,IAAI;CAC9B,MAAM,SAAS,MAAM,WAAW,QAAQ,KAAK,OAAO;CAEpD,IAAI,aAAa,OAAO;CACxB,IAAI,WAAW,MAAM,MAAM,EAAE,SAAS,GAAG,CAAC,GAAG;EAC3C,MAAM,EAAE,SAAS,MAAM,OAAO;EAC9B,aAAa,MAAM,KAAK,YAAY;GAClC,KAAK,OAAO;GACZ,UAAU;GACV,WAAW;GACX,QAAQ,OAAO;EACjB,CAAC;CACH,OACE,aAAa,WACV,KAAK,MAAM,QAAQ,OAAO,KAAK,CAAC,CAAC,EACjC,QAAQ,MAAM,WAAW,CAAC,CAAC,EAC3B,KAAK,MAAM,SAAS,OAAO,KAAK,CAAC,CAAC;CAEvC,MAAM,aAAa,WAAW,SAAS;CAEvC,MAAM,wBAAqB,IAAI,IAAI;CAEnC,MAAM,UAAU,MAAM,QAAQ,IAAI,WAAW,KAAK,MAAM,QAAQ,GAAG,QAAQ,YAAY,KAAK,CAAC,CAAC;CAE9F,IAAI;CACJ,IAAI,OAAO,OACT,UAAU,MAAM,OAAO,YAAY,QAAQ,YAAY,KAAK;CAK9D,OAAO;EACL,MAHW,YAAY,IAAI,IAAI;EAI/B;EACA;EACA;CACF;AACF;AAMA,eAAe,QACb,eACA,QACA,YACA,OACuB;CACvB,MAAM,QAAQ,YAAY,IAAI;CAC9B,MAAM,QAAQ,QAAQ,OAAO,KAAK,aAAa;CAC/C,MAAM,WAAW,MAAMA,SAAI,SAAS,OAAO,MAAM;CAEjD,MAAM,eAAe,MAAM,MAAM,IAAI,KAAK;CAC1C,IAAI,cAAc,aAAa,UAAU;EACvC,aAAa,OAAO,YAAY,IAAI,IAAI;EACxC,OAAO;CACT;CAEA,MAAM,kBAAkB,MAAM,UAAU,UAAU,QAAQ,cAAc,KAAK,CAAC;CAE9E,MAAM,SAAS,aACX,QAAQ,OAAO,KAAK,OAAO,UAAU,KAAK,aAAa,IACvD,QAAQ,OAAO,KAAK,OAAO,UAAU,aAAa;CAEtD,MAAMA,SAAI,MAAM,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;CACpD,MAAMA,SAAI,UAAU,QAAQ,gBAAgB,UAAU,MAAM;CAE5D,MAAM,SAAuB;EAC3B;EACA;EACA,GAAG;CACL;CACA,MAAM,IAAI,OAAO,MAAM;CACvB,OAAO,OAAO,YAAY,IAAI,IAAI;CAClC,OAAO;AACT;AAEA,eAAe,OACb,YACA,QACA,YACA,OACA;CACA,MAAM,UAAU,MAAM,OAAO;CAE7B,MAAM,UAA6B,SAAS,OAAO,MAAM,WAAW;EAClE,MAAM,gBAAgB,OACnB,KAAK,MAAM,SAAS,OAAO,KAAK,EAAE,IAAI,CAAC,EACvC,QAAQ,MAAM,WAAW,SAAS,CAAC,CAAC;EACvC,MAAM,QAAQ,YAAY,IAAI;EAC9B,MAAM,UAAU,MAAM,QAAQ,IAC5B,cAAc,KAAK,MAAM,QAAQ,GAAG,QAAQ,YAAY,KAAK,CAAC,CAChE;EACA,MAAM,OAAO,YAAY,IAAI,IAAI;EACjC,IAAI,OAAO,SACT,OAAO,QAAQ;GAAE;GAAS;EAAK,CAAC;CAEpC,CAAC;CAED,MAAM,eAAe,MAAM,QAAQ,UAAU,OAAO,KAAK,SAAS,EAChE,QAAQ,OAAO,OACjB,CAAC;CAED,QAAQ,GAAG,gBAAgB;EACzB,aAAa,YAAY;CAC3B,CAAC;CAED,OAAO,aAAa;AACtB"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*! Keep it simple, keep it free */
|
|
3
|
+
import "./config.js";
|
|
4
|
+
import { automd } from "./automd.js";
|
|
5
|
+
import { relative } from "pathe";
|
|
6
|
+
import { defineCommand, runMain } from "citty";
|
|
7
|
+
import consola from "consola";
|
|
8
|
+
import { colorize } from "consola/utils";
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/cli.ts
|
|
11
|
+
runMain(defineCommand({
|
|
12
|
+
meta: {
|
|
13
|
+
name: "@bjmhe/automd",
|
|
14
|
+
description: "Your automated markdown maintainer!",
|
|
15
|
+
version: "0.0.4"
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
dir: {
|
|
19
|
+
description: "current working directory",
|
|
20
|
+
type: "string"
|
|
21
|
+
},
|
|
22
|
+
input: {
|
|
23
|
+
description: "name or path the markdown input to update",
|
|
24
|
+
type: "string",
|
|
25
|
+
default: "README.md"
|
|
26
|
+
},
|
|
27
|
+
output: {
|
|
28
|
+
description: "name or path the markdown output (defaults to input)",
|
|
29
|
+
type: "string"
|
|
30
|
+
},
|
|
31
|
+
watch: {
|
|
32
|
+
description: "watch for changes in input files and regenerate output",
|
|
33
|
+
type: "boolean"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
async setup({ args }) {
|
|
37
|
+
const { results, config, time } = await automd({
|
|
38
|
+
dir: args.dir,
|
|
39
|
+
input: args.input?.split(",").map((i) => i.trim()),
|
|
40
|
+
output: args.output,
|
|
41
|
+
watch: args.watch,
|
|
42
|
+
onWatch: (event) => {
|
|
43
|
+
console.clear();
|
|
44
|
+
_printResults(event.results, event.time, config);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
if (args.watch) {
|
|
48
|
+
console.clear();
|
|
49
|
+
consola.info(`Watching for changes in \`${args.input}\``);
|
|
50
|
+
}
|
|
51
|
+
if (results.length === 0) {
|
|
52
|
+
consola.warn(`No files processed!`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
_printResults(results, time, config);
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
const _types = {
|
|
59
|
+
updated: {
|
|
60
|
+
label: "updated",
|
|
61
|
+
color: "blue"
|
|
62
|
+
},
|
|
63
|
+
noChanges: {
|
|
64
|
+
label: "no changes",
|
|
65
|
+
color: "gray"
|
|
66
|
+
},
|
|
67
|
+
alreadyUpdate: {
|
|
68
|
+
label: "already up-to-date",
|
|
69
|
+
color: "green"
|
|
70
|
+
},
|
|
71
|
+
issues: {
|
|
72
|
+
label: "with issues",
|
|
73
|
+
color: "yellow"
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function _printResults(results, time, config) {
|
|
77
|
+
const rDir = relative(process.cwd(), config.dir);
|
|
78
|
+
consola.success(`Automd updated${rDir ? ` in \`${rDir}\` dir` : ""} ${_formatTime(time)}\n`);
|
|
79
|
+
for (const res of results) {
|
|
80
|
+
const type = _getChangeType(res);
|
|
81
|
+
const input = relative(config.dir, res.input);
|
|
82
|
+
const output = relative(config.dir, res.output);
|
|
83
|
+
const name = `${input === output ? ` ${input}` : ` ${input} ~> ${output}`}`;
|
|
84
|
+
consola.log(colorize(type.color, ` ─ ${name} ${type.label} ${_formatTime(res.time)}`));
|
|
85
|
+
}
|
|
86
|
+
const issues = results.filter((res) => res.hasIssues).map((res) => _formatIssues(res, config));
|
|
87
|
+
if (issues.length > 0) {
|
|
88
|
+
consola.warn(`Some issues happened during automd update:`);
|
|
89
|
+
for (const issue of issues) consola.log(issue);
|
|
90
|
+
}
|
|
91
|
+
consola.log("");
|
|
92
|
+
}
|
|
93
|
+
function _getChangeType(res) {
|
|
94
|
+
if (res.updates.length === 0) return _types.noChanges;
|
|
95
|
+
if (res.hasIssues) return _types.issues;
|
|
96
|
+
return res.hasChanged ? _types.updated : _types.alreadyUpdate;
|
|
97
|
+
}
|
|
98
|
+
function _formatIssues(res, config) {
|
|
99
|
+
return `${colorize(_types.issues.color, relative(config.dir, res.input))} \n\n ${res.updates.flatMap((u) => u.result.issues).join("\n")}`;
|
|
100
|
+
}
|
|
101
|
+
function _formatTime(time) {
|
|
102
|
+
return colorize("gray", `(${Math.round(time * 100) / 100 + "ms"})`);
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
|
|
106
|
+
/*! Built with love & coffee ☕ */
|
|
107
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","names":["pkg.name","pkg.description","pkg.version"],"sources":["../package.json","../src/cli.ts"],"sourcesContent":["","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\";\nimport consola from \"consola\";\nimport { colorize } from \"consola/utils\";\nimport { relative } from \"pathe\";\n\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport { type AutomdResult, automd } from \"./automd.ts\";\nimport { type ResolvedConfig } from \"./config.ts\";\n\nconst main = defineCommand({\n meta: {\n name: pkg.name,\n description: pkg.description,\n version: pkg.version,\n },\n args: {\n dir: {\n description: \"current working directory\",\n type: \"string\",\n },\n input: {\n description: \"name or path the markdown input to update\",\n type: \"string\",\n default: \"README.md\",\n },\n output: {\n description: \"name or path the markdown output (defaults to input)\",\n type: \"string\",\n },\n watch: {\n description: \"watch for changes in input files and regenerate output\",\n type: \"boolean\",\n },\n },\n async setup({ args }) {\n const { results, config, time } = await automd({\n dir: args.dir,\n input: args.input?.split(\",\").map((i) => i.trim()),\n output: args.output,\n watch: args.watch,\n onWatch: (event) => {\n console.clear();\n _printResults(event.results, event.time, config);\n },\n });\n if (args.watch) {\n console.clear();\n consola.info(`Watching for changes in \\`${args.input}\\``);\n }\n\n if (results.length === 0) {\n consola.warn(`No files processed!`);\n process.exit(1);\n }\n\n _printResults(results, time, config);\n },\n});\n\nrunMain(main);\n\n// -- internal --\n\nconst _types = {\n updated: { label: \"updated\", color: \"blue\" },\n noChanges: { label: \"no changes\", color: \"gray\" },\n alreadyUpdate: { label: \"already up-to-date\", color: \"green\" },\n issues: { label: \"with issues\", color: \"yellow\" },\n} as const;\n\nfunction _printResults(results: AutomdResult[], time: number, config: ResolvedConfig) {\n const rDir = relative(process.cwd(), config.dir);\n consola.success(`Automd updated${rDir ? ` in \\`${rDir}\\` dir` : \"\"} ${_formatTime(time)}\\n`);\n for (const res of results) {\n const type = _getChangeType(res);\n const input = relative(config.dir, res.input);\n const output = relative(config.dir, res.output);\n const name = `${input === output ? ` ${input}` : ` ${input} ~> ${output}`}`;\n consola.log(colorize(type.color, ` ─ ${name} ${type.label} ${_formatTime(res.time)}`));\n }\n const issues = results.filter((res) => res.hasIssues).map((res) => _formatIssues(res, config));\n if (issues.length > 0) {\n consola.warn(`Some issues happened during automd update:`);\n for (const issue of issues) {\n consola.log(issue);\n }\n }\n consola.log(\"\");\n}\n\nfunction _getChangeType(res: AutomdResult) {\n if (res.updates.length === 0) {\n return _types.noChanges;\n }\n if (res.hasIssues) {\n return _types.issues;\n }\n return res.hasChanged ? _types.updated : _types.alreadyUpdate;\n}\n\nfunction _formatIssues(res: AutomdResult, config: ResolvedConfig) {\n return `${colorize(_types.issues.color, relative(config.dir, res.input))} \\n\\n ${res.updates.flatMap((u) => u.result.issues).join(\"\\n\")}`;\n}\n\nfunction _formatTime(time: number) {\n return colorize(\"gray\", `(${Math.round(time * 100) / 100 + \"ms\"})`);\n}\n"],"mappings":";;;;;;;;;;AC6DA,QAlDa,cAAc;CACzB,MAAM;EACEA;EACOC;EACJC;CACX;CACA,MAAM;EACJ,KAAK;GACH,aAAa;GACb,MAAM;EACR;EACA,OAAO;GACL,aAAa;GACb,MAAM;GACN,SAAS;EACX;EACA,QAAQ;GACN,aAAa;GACb,MAAM;EACR;EACA,OAAO;GACL,aAAa;GACb,MAAM;EACR;CACF;CACA,MAAM,MAAM,EAAE,QAAQ;EACpB,MAAM,EAAE,SAAS,QAAQ,SAAS,MAAM,OAAO;GAC7C,KAAK,KAAK;GACV,OAAO,KAAK,OAAO,MAAM,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,CAAC;GACjD,QAAQ,KAAK;GACb,OAAO,KAAK;GACZ,UAAU,UAAU;IAClB,QAAQ,MAAM;IACd,cAAc,MAAM,SAAS,MAAM,MAAM,MAAM;GACjD;EACF,CAAC;EACD,IAAI,KAAK,OAAO;GACd,QAAQ,MAAM;GACd,QAAQ,KAAK,6BAA6B,KAAK,MAAM,GAAG;EAC1D;EAEA,IAAI,QAAQ,WAAW,GAAG;GACxB,QAAQ,KAAK,qBAAqB;GAClC,QAAQ,KAAK,CAAC;EAChB;EAEA,cAAc,SAAS,MAAM,MAAM;CACrC;AACF,CAEW,CAAC;AAIZ,MAAM,SAAS;CACb,SAAS;EAAE,OAAO;EAAW,OAAO;CAAO;CAC3C,WAAW;EAAE,OAAO;EAAc,OAAO;CAAO;CAChD,eAAe;EAAE,OAAO;EAAsB,OAAO;CAAQ;CAC7D,QAAQ;EAAE,OAAO;EAAe,OAAO;CAAS;AAClD;AAEA,SAAS,cAAc,SAAyB,MAAc,QAAwB;CACpF,MAAM,OAAO,SAAS,QAAQ,IAAI,GAAG,OAAO,GAAG;CAC/C,QAAQ,QAAQ,iBAAiB,OAAO,SAAS,KAAK,UAAU,GAAG,GAAG,YAAY,IAAI,EAAE,GAAG;CAC3F,KAAK,MAAM,OAAO,SAAS;EACzB,MAAM,OAAO,eAAe,GAAG;EAC/B,MAAM,QAAQ,SAAS,OAAO,KAAK,IAAI,KAAK;EAC5C,MAAM,SAAS,SAAS,OAAO,KAAK,IAAI,MAAM;EAC9C,MAAM,OAAO,GAAG,UAAU,SAAS,KAAK,UAAU,KAAK,MAAM,MAAM;EACnE,QAAQ,IAAI,SAAS,KAAK,OAAO,QAAQ,KAAK,GAAG,KAAK,MAAM,GAAG,YAAY,IAAI,IAAI,GAAG,CAAC;CACzF;CACA,MAAM,SAAS,QAAQ,QAAQ,QAAQ,IAAI,SAAS,EAAE,KAAK,QAAQ,cAAc,KAAK,MAAM,CAAC;CAC7F,IAAI,OAAO,SAAS,GAAG;EACrB,QAAQ,KAAK,4CAA4C;EACzD,KAAK,MAAM,SAAS,QAClB,QAAQ,IAAI,KAAK;CAErB;CACA,QAAQ,IAAI,EAAE;AAChB;AAEA,SAAS,eAAe,KAAmB;CACzC,IAAI,IAAI,QAAQ,WAAW,GACzB,OAAO,OAAO;CAEhB,IAAI,IAAI,WACN,OAAO,OAAO;CAEhB,OAAO,IAAI,aAAa,OAAO,UAAU,OAAO;AAClD;AAEA,SAAS,cAAc,KAAmB,QAAwB;CAChE,OAAO,GAAG,SAAS,OAAO,OAAO,OAAO,SAAS,OAAO,KAAK,IAAI,KAAK,CAAC,EAAE,QAAQ,IAAI,QAAQ,SAAS,MAAM,EAAE,OAAO,MAAM,EAAE,KAAK,IAAI;AACxI;AAEA,SAAS,YAAY,MAAc;CACjC,OAAO,SAAS,QAAQ,IAAI,KAAK,MAAM,OAAO,GAAG,IAAI,MAAM,KAAK,EAAE;AACpE"}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
import { resolve } from "pathe";
|
|
3
|
+
//#region src/config.ts
|
|
4
|
+
const RESOLVED_CONFIG_SYMBOL = Symbol("automdConfig");
|
|
5
|
+
function resolveConfig(config) {
|
|
6
|
+
if (config && RESOLVED_CONFIG_SYMBOL in config) return config;
|
|
7
|
+
const _config = {
|
|
8
|
+
dir: ".",
|
|
9
|
+
input: "README.md",
|
|
10
|
+
generators: {},
|
|
11
|
+
[RESOLVED_CONFIG_SYMBOL]: true,
|
|
12
|
+
...config
|
|
13
|
+
};
|
|
14
|
+
_config.dir = resolve(_config.dir);
|
|
15
|
+
_config.input = (Array.isArray(_config.input) ? _config.input : [_config.input]).filter(Boolean);
|
|
16
|
+
return _config;
|
|
17
|
+
}
|
|
18
|
+
async function loadConfig(dir = ".", overrides) {
|
|
19
|
+
const { loadConfig } = await import("c12");
|
|
20
|
+
dir = resolve(dir);
|
|
21
|
+
const { config } = await loadConfig({
|
|
22
|
+
cwd: dir,
|
|
23
|
+
name: "automd",
|
|
24
|
+
dotenv: true,
|
|
25
|
+
overrides,
|
|
26
|
+
defaults: {
|
|
27
|
+
ignore: [
|
|
28
|
+
"**/node_modules",
|
|
29
|
+
"**/dist",
|
|
30
|
+
"**/.*"
|
|
31
|
+
],
|
|
32
|
+
dir
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return resolveConfig(config);
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { loadConfig, resolveConfig };
|
|
39
|
+
|
|
40
|
+
/*! Built with love & coffee ☕ */
|
|
41
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { resolve } from \"pathe\";\n\nimport type { AutomdResult } from \"./automd.ts\";\nimport type { Generator } from \"./generator.ts\";\n\nexport interface Config {\n /**\n * The working directory\n *\n * @default \".\" (current directory)\n */\n dir?: string;\n\n /**\n * Name or path to the input file or files with glob patterns.\n *\n * @default \"README.md\"\n */\n input?: string | string[];\n\n /**\n * Name or path of the output files. If not provided, the input file will be overwritten.\n *\n * @default input\n */\n output?: string;\n\n /**\n * Ignore patterns if input is a glob pattern\n *\n * @default [\"node_modules\", \"dist\", \"/.*\"]\n */\n ignore?: string[];\n\n /** Watch for changes in input files and regenerate output */\n watch?: boolean;\n\n /** Watch callback */\n onWatch?: (event: { results: AutomdResult[]; time: number }) => void;\n\n /** Custom generators */\n generators?: Record<string, Generator>;\n}\n\nconst RESOLVED_CONFIG_SYMBOL = Symbol(\"automdConfig\");\n\nexport type ResolvedConfig = { [P in keyof Config]-?: Config[P] } & {\n [RESOLVED_CONFIG_SYMBOL]: true;\n input: string[];\n output?: string;\n};\n\nexport function resolveConfig(config?: Config | ResolvedConfig): ResolvedConfig {\n if (config && RESOLVED_CONFIG_SYMBOL in config) {\n return config as ResolvedConfig;\n }\n\n const _config = {\n dir: \".\",\n input: \"README.md\",\n generators: {},\n [RESOLVED_CONFIG_SYMBOL]: true,\n ...(config as Partial<ResolvedConfig>),\n } as ResolvedConfig;\n\n _config.dir = resolve(_config.dir);\n\n _config.input = (Array.isArray(_config.input) ? _config.input : [_config.input]).filter(Boolean);\n\n return _config;\n}\n\nexport async function loadConfig(dir = \".\", overrides: Config): Promise<ResolvedConfig> {\n const { loadConfig } = await import(\"c12\");\n\n dir = resolve(dir);\n\n const { config } = await loadConfig<Config>({\n cwd: dir,\n name: \"automd\",\n dotenv: true,\n overrides,\n defaults: {\n ignore: [\"**/node_modules\", \"**/dist\", \"**/.*\"],\n dir,\n },\n });\n\n return resolveConfig(config as Config);\n}\n"],"mappings":";;;AA4CA,MAAM,yBAAyB,OAAO,cAAc;AAQpD,SAAgB,cAAc,QAAkD;CAC9E,IAAI,UAAU,0BAA0B,QACtC,OAAO;CAGT,MAAM,UAAU;EACd,KAAK;EACL,OAAO;EACP,YAAY,CAAC;GACZ,yBAAyB;EAC1B,GAAI;CACN;CAEA,QAAQ,MAAM,QAAQ,QAAQ,GAAG;CAEjC,QAAQ,SAAS,MAAM,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC,QAAQ,KAAK,GAAG,OAAO,OAAO;CAE/F,OAAO;AACT;AAEA,eAAsB,WAAW,MAAM,KAAK,WAA4C;CACtF,MAAM,EAAE,eAAe,MAAM,OAAO;CAEpC,MAAM,QAAQ,GAAG;CAEjB,MAAM,EAAE,WAAW,MAAM,WAAmB;EAC1C,KAAK;EACL,MAAM;EACN,QAAQ;EACR;EACA,UAAU;GACR,QAAQ;IAAC;IAAmB;IAAW;GAAO;GAC9C;EACF;CACF,CAAC;CAED,OAAO,cAAc,MAAgB;AACvC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*! Keep it simple, keep it free */
|
|
2
|
+
//#region src/generator.ts
|
|
3
|
+
/** @internal */
|
|
4
|
+
function defineGenerator(generator) {
|
|
5
|
+
return generator;
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { defineGenerator };
|
|
9
|
+
|
|
10
|
+
/*! Built with love & coffee ☕ */
|
|
11
|
+
//# sourceMappingURL=generator.js.map
|