@p-buddy/parkdown 0.0.1 → 0.0.3

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.
@@ -1,3 +0,0 @@
1
- Before... [](<url>) <!-- p▼ Begin -->
2
- ...Included Content...
3
- ...Included Content... <!-- p▼ End --> ...After
package/.assets/query.md DELETED
@@ -1,73 +0,0 @@
1
- # Query parameters
2
-
3
- You can pass query parameters to your inclusion links to control how their content is processed and included within your markdown.
4
-
5
- ## Processing Order
6
-
7
- [](../src/include.ts?&region=extract(query))
8
-
9
- ## `region`
10
-
11
- Either extract, remove, or replace content from the included file based on the provided specifier(s).
12
-
13
- Specifiers will be searched for within the file's comments, and are expected to come in pairs / bookend the desired region, like so:
14
-
15
- ```ts
16
- /** some-specifier */
17
- ... code to find ...
18
- /** some-specifier */
19
- ```
20
-
21
- ```md
22
- [](...?region=extract(some-specifier))
23
- ```
24
-
25
- Below is the currently supported API for the `region` query parameter, where each defined method signature can be _invoked_ as a value for the `region` parameter (e.g. `[](<url>?region=extract(some-specifier))`, `[](<url>?region=remove(some-specifier))`, `[](<url>?region=replace(some-specifier))`).
26
-
27
- [](./api-note.md?wrap=quote)
28
-
29
- [](../src/region.ts?region=extract(definition))
30
-
31
- ## `skip`
32
-
33
- Skip the default processing behavior for the given type of file.
34
-
35
- [](../src/include.ts?wrap=dropdown(See-default-processing-behavior.)&region=extract(Default-Behavior),replace(...))
36
-
37
- ```md
38
- [](<url>?skip)
39
- ```
40
-
41
- ## `heading`
42
-
43
- Modify the heading depth applied to included content. By default, the headings of the included content are adjusted to be one-level below their parent heading.
44
-
45
- In the following example, the headings within the included content of `<url>` will be adjusted to one-level below the parent heading (which is an `h2` / `##`), so any `#` headings will be converted to `###` headings, and `##` headings will be converted to `####` headings, and so on.
46
-
47
- ```md
48
- ## Heading
49
-
50
- [](<url>)
51
- ```
52
-
53
- The following would then ensure that the headings of the included content are at the same level as the parent heading.
54
-
55
- ```md
56
- ## Heading
57
-
58
- [](<url>?heading=-1)
59
- ```
60
-
61
- A value of `-2` would result in the headings of the included content being at their original level (since the content is being included underneath an `h2` / `##` heading).
62
-
63
- ## `inline` (Advanced)
64
-
65
- ## `wrap`
66
-
67
- Wrap the content of the included file in a specific kind of element.
68
-
69
- Below is the currently supported API for the `wrap` query parameter, where each defined method signature can be _invoked_ as a value for the `wrap` parameter (e.g. `[](<url>?wrap=code)`, `[](<url>?wrap=dropdown(hello-world))`).
70
-
71
- [](./api-note.md?wrap=quote)
72
-
73
- [](../src/wrap.ts?region=extract(definition))
File without changes
@@ -1,5 +0,0 @@
1
- Before...
2
-
3
- [](<url>)
4
-
5
- ...After
@@ -1,3 +0,0 @@
1
- Before...
2
- [](<url>)
3
- ...After
@@ -1 +0,0 @@
1
- Before... [](<url>) ...After
@@ -1,16 +0,0 @@
1
- # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.187.0/containers/typescript-node/.devcontainer/base.Dockerfile
2
-
3
- # [Choice] Node.js version: 16, 18, 20
4
- ARG VARIANT="20-buster"
5
- FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT}
6
-
7
- # [Optional] Uncomment this section to install additional OS packages.
8
- # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
9
- # && apt-get -y install --no-install-recommends <your-package-list-here>
10
-
11
- # [Optional] Uncomment if you want to install an additional version of node using nvm
12
- # ARG EXTRA_NODE_VERSION=10
13
- # RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
14
-
15
- # To install more global node packages
16
- RUN su node -c "npm install -g pnpm@10"
@@ -1,35 +0,0 @@
1
- {
2
- "name": "parkdown-dev",
3
- "dockerFile": "Dockerfile",
4
- "customizations": {
5
- "vscode": {
6
- "extensions": [
7
- "ms-vscode.vscode-typescript-next",
8
- "svelte.svelte-vscode",
9
- "ms-azuretools.vscode-docker",
10
- "bradlc.vscode-tailwindcss",
11
- "YoavBls.pretty-ts-errors"
12
- ]
13
- }
14
- },
15
- "postStartCommand": [
16
- "bash",
17
- "-c",
18
- "git config --global user.name \"${GIT_USER_NAME}\"",
19
- "bash",
20
- "-c",
21
- "git config --global user.email \"${GIT_USER_EMAIL}\"",
22
- "bash",
23
- "-c",
24
- "pnpm install"
25
- ],
26
- "mounts": [
27
- "source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,type=bind,readonly"
28
- ],
29
- "containerEnv": {
30
- "NPM_TOKEN": "${localEnv:PARKDOWN_NPM_TOKEN}",
31
- "HOST_WORKSPACE_PATH": "${localWorkspaceFolder}",
32
- "GIT_USER_NAME": "${localEnv:GIT_USER_NAME}",
33
- "GIT_USER_EMAIL": "${localEnv:GIT_USER_EMAIL}"
34
- }
35
- }
@@ -1,32 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import { MethodDefinition } from "./types";
3
- import { numberedParameters, createParser } from "./index";
4
-
5
- describe(numberedParameters.name, () => {
6
- test("simple", () => {
7
- const definitions = [
8
- "example(0: string, 1?: string)" satisfies MethodDefinition,
9
- ] as const;
10
-
11
- const result = createParser(definitions)("example(z,a)");
12
- expect(numberedParameters(result)).toEqual(["z", "a"]);
13
- });
14
-
15
- test("mixed types", () => {
16
- const definitions = [
17
- "example(0: string, 1?: string, 2: boolean)" satisfies MethodDefinition,
18
- ] as const;
19
-
20
- const result = createParser(definitions)("example(z,a,true)");
21
- expect(numberedParameters(result)).toEqual(["z", "a", true]);
22
- });
23
-
24
- test("mixed positions", () => {
25
- const definitions = [
26
- "example(0: string, hi: string, 1: boolean)" satisfies MethodDefinition,
27
- ] as const;
28
-
29
- const result = createParser(definitions)("example(z,hi,true)");
30
- expect(numberedParameters(result)).toEqual(["z", true]);
31
- });
32
- });
package/src/api/index.ts DELETED
@@ -1,8 +0,0 @@
1
- export type { MethodDefinition } from "./types";
2
- import type { Parser } from "./types";
3
- export { createParser } from "./utils";
4
-
5
- export const numberedParameters = (result: ReturnType<Parser<any>>) =>
6
- Object.entries(result)
7
- .filter(([key]) => key !== "name" && !isNaN(Number(key)))
8
- .map(([_, value]) => value);
package/src/api/types.ts DELETED
@@ -1,78 +0,0 @@
1
- export type TypeRecord = {
2
- "string": string,
3
- "number": number,
4
- "boolean": boolean,
5
- }
6
-
7
- type ExpandRecursively<T> =
8
- T extends (...args: infer A) => infer R
9
- /**/ ? (...args: ExpandRecursively<A>) => ExpandRecursively<R>
10
- /**/ : T extends object
11
- /**/ ? T extends infer O
12
- /**/ ? { [K in keyof O]: ExpandRecursively<O[K]> }
13
- /**/ : never
14
- /**/ : T;
15
-
16
- type WithoutLeadingWhitespace<T extends string> = T extends ` ${infer Without}` ? Without : T;
17
-
18
- type SplitOn<T extends string, Delimeter extends string> =
19
- T extends `${infer Left}${Delimeter}${infer Right}` ? [Left, ...SplitOn<Right, Delimeter>] : [T];
20
-
21
- type RepeatInTuple<Element, Count extends number, Acc extends unknown[] = []> = {
22
- [k in Count]: Acc['length'] extends k
23
- ? Acc
24
- : RepeatInTuple<Element, k, [...Acc, Element]>;
25
- }[Count];
26
-
27
- type Join<T extends string[], D extends string> =
28
- T extends []
29
- /**/ ? ''
30
- /**/ : T extends [infer F extends string]
31
- /**/ ? F
32
- /**/ : T extends [infer F extends string, ...infer R extends string[]]
33
- /**/ ? `${F}${D}${Join<R, D>}`
34
- /**/ : string;
35
-
36
- type Capture<T extends string, Start extends string, End extends string> = {
37
- [k in T]: k extends `${infer Before}${Start}${infer Captured}${End}${infer After}`
38
- /**/ ? { before: Before, captured: Captured, after: After }
39
- /**/ : { before: T, captured: "", after: "" };
40
- }[T]
41
-
42
- type SplitOnComma<T extends string> = { [k in SplitOn<T, ",">[number]]: k }[SplitOn<T, ",">[number]];
43
-
44
- type Parameter<Name extends string, Optional extends boolean, Type extends TypeRecord[keyof TypeRecord]> = { name: Name, optional: Optional, type: Type };
45
-
46
- type ExtractParameter<T extends string> = T extends `${infer Name}?: ${infer Type extends keyof TypeRecord}`
47
- /**/ ? Parameter<Name, true, Type>
48
- /**/ : T extends `${infer Name}: ${infer Type extends keyof TypeRecord}`
49
- /**/ ? Parameter<Name, false, Type>
50
- /**/ : never;
51
-
52
- type FunctionName<T extends string> = Capture<T, "(", ")">["before"];
53
-
54
- type ParameterRecord<T extends string> = {
55
- [k in WithoutLeadingWhitespace<SplitOnComma<Capture<T, "(", ")">["captured"]>> as ExtractParameter<k>["name"]]: ExtractParameter<k>["optional"] extends true ? TypeRecord[ExtractParameter<k>["type"]] | undefined : TypeRecord[ExtractParameter<k>["type"]]
56
- }
57
-
58
- type UndefinedToOptional<T> = {
59
- [K in keyof T as undefined extends T[K] ? K : never]?: Exclude<T[K], undefined>;
60
- } & {
61
- [K in keyof T as undefined extends T[K] ? never : K]: T[K];
62
- };
63
-
64
- type ParseMethodDefinition<T extends string> = { [t in T as FunctionName<t>]: UndefinedToOptional<ParameterRecord<t>> };
65
-
66
- type ParameterDefinition = `${string}${"?" | ""}: ${keyof TypeRecord}`;
67
- /** Can add more parameters by adding more numbers to the count union, but it adds a lot of complexity to the type */
68
- type ZeroOrMoreParameters = Join<RepeatInTuple<ParameterDefinition, 0 | 1 | 2>, ", ">;
69
- export type MethodDefinition = `${string}(${ZeroOrMoreParameters})`;
70
-
71
- export type MethodDefinitions = string[] | readonly string[];
72
-
73
- export type ParsingCandidates<T extends MethodDefinitions> = ExpandRecursively<{
74
- [k in keyof ParseMethodDefinition<T[number]>]: ParseMethodDefinition<T[number]>[k] & { name: k }
75
- }[keyof ParseMethodDefinition<T[number]>]>;
76
-
77
- export type Parser<T extends MethodDefinitions> = (query: string) => ParsingCandidates<T>;
78
- export type CreateParser = <T extends MethodDefinitions>(definitions: T) => Parser<T>;
@@ -1,132 +0,0 @@
1
- import { describe, test, expect } from "vitest";
2
- import { parseInvocation, parseDefinition, createParser, splitOnUnquotedComma } from "./utils";
3
- import { MethodDefinition } from "./types";
4
- import { COMMA_NOT_IN_PARENTHESIS } from "../utils";
5
-
6
- describe(parseInvocation.name, () => {
7
- const testCases = [
8
- ["code(ts,some-meta)", { name: "code", parameters: ["ts", "some-meta"] }],
9
- ["code", { name: "code", parameters: [] }],
10
- ["code()", { name: "code", parameters: [] }],
11
- ["code(ts)", { name: "code", parameters: ["ts"] }],
12
- ["code(,some-meta)", { name: "code", parameters: [undefined, "some-meta"] }],
13
- ["code(,some-meta,,,)", { name: "code", parameters: [undefined, "some-meta"] }],
14
- ["dropdown(hello-world,true)", { name: "dropdown", parameters: ["hello-world", "true"] }],
15
- ["code(,,anything)", { name: "code", parameters: [undefined, undefined, "anything"] }],
16
- ] as const;
17
-
18
- for (const [input, expected] of testCases) {
19
- test(input, () => {
20
- expect(parseInvocation(input)).toEqual(expected);
21
- });
22
- }
23
- });
24
-
25
- describe(parseDefinition.name, () => {
26
- const testCases = [
27
- ["code(lang?: string, meta?: string)", {
28
- name: "code",
29
- parameters: [
30
- { name: "lang", optional: true, type: "string" },
31
- { name: "meta", optional: true, type: "string" }
32
- ]
33
- }],
34
- ["quote", { name: "quote" }],
35
- ["dropdown(summary: string, open?: boolean)", {
36
- name: "dropdown",
37
- parameters: [
38
- { name: "summary", optional: false, type: "string" },
39
- { name: "open", optional: true, type: "boolean" }
40
- ]
41
- }],
42
- ["allTypes(a: string, b: boolean, c: number, d?: string, e?: boolean, f?: number)", {
43
- name: "allTypes",
44
- parameters: [
45
- { name: "a", optional: false, type: "string" },
46
- { name: "b", optional: false, type: "boolean" },
47
- { name: "c", optional: false, type: "number" },
48
- { name: "d", optional: true, type: "string" },
49
- { name: "e", optional: true, type: "boolean" },
50
- { name: "f", optional: true, type: "number" },
51
- ]
52
- }]
53
- ] as const;
54
-
55
- for (const [input, expected] of testCases) {
56
- test(input, () => {
57
- expect(parseDefinition(input)).toEqual(expected);
58
- });
59
- }
60
- });
61
-
62
- describe(createParser.name, () => {
63
- const definitions = [
64
- "code(lang?: string, meta?: string)" satisfies MethodDefinition,
65
- "quote",
66
- "dropdown(summary: string, open?: boolean)" satisfies MethodDefinition,
67
- ] as const;
68
-
69
- const parse = createParser(definitions);
70
-
71
- const invocations = [
72
- ["code", { name: "code" }],
73
- ["code()", { name: "code" }],
74
- ["code(ts)", { name: "code", lang: "ts" }],
75
- ["code(ts,some-meta)", { name: "code", lang: "ts", meta: "some-meta" }],
76
- ["code(,some-meta)", { name: "code", meta: "some-meta" }],
77
- ["code(,some-meta,)", { name: "code", meta: "some-meta" }],
78
- ["code(,,anything)", { error: true }],
79
- ["quote", { name: "quote" }],
80
- ["quote()", { name: "quote" }],
81
- ["dropdown()", { error: true }],
82
- ["dropdown(,true)", { error: true }],
83
- ["dropdown(hello-world,true)", { name: "dropdown", summary: "hello-world", open: true }],
84
- ["dropdown('hello world',true)", { name: "dropdown", summary: "hello world", open: true }],
85
-
86
- ] as const;
87
-
88
- for (const [input, expected] of invocations) {
89
- test(input, () => {
90
- if ('error' in expected) {
91
- expect(() => parse(input)).toThrow();
92
- } else {
93
- expect(parse(input)).toEqual(expected);
94
- }
95
- });
96
- }
97
-
98
- });
99
-
100
-
101
- describe("split on non-parenthesized comma", () => {
102
- const testCases = [
103
- ["hello,world", ["hello", "world"]],
104
- ["code(,,anything), code, quote, dropdown(hello-world,true)", ["code(,,anything)", "code", "quote", "dropdown(hello-world,true)"]],
105
- ] as const;
106
-
107
- for (const [input, expected] of testCases) {
108
- test(input, () => {
109
- expect(input.split(COMMA_NOT_IN_PARENTHESIS)).toEqual(expected);
110
- });
111
- }
112
-
113
- });
114
-
115
-
116
- describe(splitOnUnquotedComma.name, () => {
117
- test("simple", () => {
118
- expect(splitOnUnquotedComma("hello,world")).toEqual(["hello", "world"]);
119
- });
120
-
121
- test("single quotes", () => {
122
- expect(splitOnUnquotedComma("hello,'hello,world',hello")).toEqual(["hello", "hello,world", "hello"]);
123
- });
124
-
125
- test("preserve dual single quotes", () => {
126
- expect(splitOnUnquotedComma("hello,''hello,world'',hello")).toEqual(["hello", "''hello,world''", "hello"]);
127
- });
128
-
129
- test("preserve triple double quotes", () => {
130
- expect(splitOnUnquotedComma("hello,'''hello,world''',hello")).toEqual(["hello", "'''hello,world'''", "hello"]);
131
- });
132
- })
package/src/api/utils.ts DELETED
@@ -1,161 +0,0 @@
1
- import type { CreateParser, MethodDefinitions, ParsingCandidates, TypeRecord } from "./types";
2
-
3
- const supportedTypes = ["string", "number", "boolean"] as const satisfies (keyof TypeRecord)[];
4
-
5
- const isSupportedType = (type: string): type is keyof TypeRecord => supportedTypes.includes(type as keyof TypeRecord);
6
-
7
- // This regex is used to parse function-like invocations such as "code(ts,some-meta)"
8
- // Breaking down the regex pattern:
9
- // ^ - Asserts position at the start of the string
10
- // ([a-zA-Z0-9_-]+) - Capture group 1: The function name
11
- // [a-zA-Z0-9_-]+ - One or more alphanumeric characters, underscores, or hyphens
12
- // (?:\(([^)]*)\))? - Optional non-capturing group for the parameters section
13
- // \( - Literal opening parenthesis
14
- // ([^)]*) - Capture group 2: Zero or more characters that are not closing parentheses
15
- // \) - Literal closing parenthesis
16
- // ? - Makes the entire parameter section optional
17
- // $ - Asserts position at the end of the string
18
- const INVOCATION_REGEX = /^([a-zA-Z0-9_-]+)(?:\(([^)]*)\))?$/;
19
-
20
- export const parseInvocation = (input: string): { name: string, parameters: (string | undefined)[] } => {
21
- const match = input.match(INVOCATION_REGEX);
22
- if (!match) throw new Error(`Invalid invocation: ${input}`);
23
-
24
- const [, name, rawParams = ""] = match;
25
-
26
- if (!rawParams.trim()) return { name, parameters: [] };
27
-
28
- const parameters = splitOnUnquotedComma(rawParams);
29
- return { name, parameters };
30
- }
31
-
32
- const restIsUndefined = <T>(arr: T[], index: number) => {
33
- for (let i = index + 1; i < arr.length; i++)
34
- if (arr[i] !== undefined) return false;
35
- return true;
36
- }
37
-
38
- export const splitOnUnquotedComma = (input: string): (string | undefined)[] => {
39
- const result: (string | undefined)[] = [];
40
-
41
- let current = "";
42
- let inSingleQuotes = false;
43
-
44
- for (let i = 0; i < input.length; i++) {
45
- const ch = input[i];
46
- const isSingleQuote = ch === "'";
47
-
48
- if (isSingleQuote && input.at(i + 1) === "'") {
49
- const triple = input.at(i + 2) === "'";
50
- inSingleQuotes = !inSingleQuotes;
51
- current += triple ? "'''" : "''";
52
- i += triple ? 2 : 1;
53
- } else if (isSingleQuote) {
54
- inSingleQuotes = !inSingleQuotes;
55
- current += ch;
56
- } else if (ch === "," && !inSingleQuotes) {
57
- result.push(current.trim());
58
- current = "";
59
- } else current += ch;
60
- }
61
-
62
- result.push(current.trim());
63
-
64
- return result
65
- .map(item => item === "" ? undefined : item ? stripSurroundingSingleQuotes(item) : undefined)
66
- .filter((item, index, arr) => item !== undefined || !restIsUndefined(arr, index));
67
- }
68
-
69
- const stripSurroundingSingleQuotes = (input: string): string => {
70
- const isWrapped = input.length >= 2 && input[0] === "'" && input.at(-1) === "'";
71
- const isDoubleWrapped = isWrapped && (input.length >= 4 && input[1] === "'" && input.at(-2) === "'");
72
- return !isWrapped || isDoubleWrapped ? input : input.slice(1, -1);
73
- };
74
-
75
- type ParsedParameterDefinition = { name: string; optional: boolean; type: keyof TypeRecord };
76
- type ParsedMethodDefinition = { name: string; parameters?: ParsedParameterDefinition[] };
77
-
78
- export const parseDefinition = <T extends string>(definition: T): ParsedMethodDefinition => {
79
- // Match a method definition pattern:
80
- // ^ - start of string
81
- // (\w+) - capture group 1: one or more word characters (method name)
82
- // (?:\(([^)]*)\))? - optional non-capturing group:
83
- // \( - literal opening parenthesis
84
- // ([^)]*) - capture group 2: zero or more characters that are not closing parenthesis (parameter list)
85
- // \) - literal closing parenthesis
86
- const METHOD_REGEX = /^(\w+)(?:\(([^)]*)\))?/;
87
-
88
- const methodMatch = definition.match(METHOD_REGEX);
89
- if (!methodMatch) return { name: definition };
90
-
91
- const [, methodName, paramString] = methodMatch;
92
-
93
- if (!paramString) return { name: methodName };
94
-
95
- // (\w+) - Capture group 1: One or more word characters (parameter name)
96
- // (\?)? - Capture group 2: Optional question mark (indicates optional parameter)
97
- // : - Literal colon character
98
- // \s* - Zero or more whitespace characters
99
- // ([^,]+) - Capture group 3: One or more characters that are not commas (parameter type)
100
- // /g - Global flag: Find all matches in the string, not just the first one
101
- const PARAM_REGEX = /(\w+)(\?)?:\s*([^,]+)/g;
102
-
103
- const parameters: ParsedParameterDefinition[] = [];
104
-
105
- let match: RegExpExecArray | null;
106
- while ((match = PARAM_REGEX.exec(paramString)) !== null) {
107
- const [, name, optSymbol, paramType] = match;
108
- const type = paramType.trim();
109
- if (!isSupportedType(type)) throw new Error(`Unsupported type: ${type}`);
110
- parameters.push({ name, optional: optSymbol === "?", type });
111
- }
112
-
113
- return { name: methodName, parameters };
114
- }
115
-
116
- export const createParser: CreateParser = <T extends MethodDefinitions>(definitions: T) => {
117
- const parsedDefinitions = definitions
118
- .map(parseDefinition)
119
- .reduce(
120
- (map, { name, parameters }) => map.set(name, parameters),
121
- new Map<string, ParsedParameterDefinition[] | undefined>()
122
- );
123
- return (query: string) => {
124
- const { name, parameters } = parseInvocation(query);
125
- if (!parsedDefinitions.has(name))
126
- throw new Error(`Unknown method: ${name}`);
127
-
128
- const parameterDefinitions = parsedDefinitions.get(name);
129
- if (parameterDefinitions === undefined)
130
- return { name } satisfies ParsingCandidates<[string]> as ParsingCandidates<T>;
131
-
132
- if (parameters.length > parameterDefinitions.length) {
133
- const requiredCount = parameterDefinitions.filter(({ optional }) => !optional).length;
134
- const expected = requiredCount === parameterDefinitions.length
135
- ? requiredCount.toString()
136
- : `${requiredCount} - ${parameterDefinitions.length}`;
137
- throw new Error(`Too many parameters: ${parameters.length} for method '${name}' (expected: ${expected})`);
138
- }
139
-
140
- return parameterDefinitions.reduce((acc, { name: param, optional, type }, index) => {
141
- const value = parameters[index];
142
-
143
- if (value === undefined)
144
- if (optional) return acc;
145
- else throw new Error(`Missing required parameter: ${param} for method '${name}'`);
146
-
147
- switch (type) {
148
- case "string":
149
- acc[param] = value;
150
- break;
151
- case "number":
152
- case "boolean":
153
- acc[param] = JSON.parse(value);
154
- break;
155
- }
156
- if (typeof acc[param] !== type)
157
- throw new Error(`Invalid type: ${param} must be ${type}, got ${typeof acc[param]} for method '${name}'`);
158
- return acc;
159
- }, { name } as ParsingCandidates<T>);
160
- }
161
- }
package/src/cli.ts DELETED
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from '@commander-js/extra-typings';
3
- import { version } from '../package.json';
4
- import { populateMarkdownInclusions, depopulateMarkdownInclusions } from '.';
5
-
6
- const program = new Command()
7
- .version(version)
8
- .option('--nw, --no-write', 'Do NOT write result to file (defaults to false)', false as boolean)
9
- .option('--ni, --no-inclusions', 'Do NOT process file inclusions (defaults to false)', false as boolean)
10
- .option('-d, --depopulate', 'Remove populated inclusions from the file', false as boolean)
11
- .option('-f, --file <flag>', 'The file(s) to process', (value, arr) => (arr.push(value), arr), new Array<string>())
12
- .option('-r, --remap-imports', 'Remap import specifiers in code blocks from one destination to another')
13
- .parse();
14
-
15
- const { inclusions: noInclusions, depopulate, file, write: noWrite } = program.opts();
16
-
17
-
18
- if (file.length === 0) file.push("README.md");
19
-
20
- /** parkdown: process-order */
21
- const processors = [
22
- [populateMarkdownInclusions, !noInclusions],
23
- [depopulateMarkdownInclusions, depopulate],
24
- ] as const;
25
- /** parkdown: process-order */
26
-
27
- for (const [processor] of processors.filter(([_, condition]) => condition))
28
- for (const _file of file) {
29
- const result = processor(_file, !noWrite);
30
- if (noWrite) console.log(result);
31
- }