@brillout/docpress 0.15.10-commit-f89d08f → 0.15.10-commit-05c2883

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/detypePlugin.ts DELETED
@@ -1,159 +0,0 @@
1
- export { detypePlugin }
2
-
3
- import type { PluginOption } from 'vite'
4
- import module from 'node:module'
5
- import { assertUsage } from './utils/assert.js'
6
- import pc from '@brillout/picocolors'
7
- import { getMagicString } from './utils/getMagicString.js'
8
- // Cannot use `import { transform } from 'detype'` as it results in errors,
9
- // and the package has no default export. Using `module.createRequire` instead.
10
- const { transform: detype } = module.createRequire(import.meta.url)('detype') as typeof import('detype')
11
-
12
- const prettierOptions: NonNullable<Parameters<typeof detype>[2]>['prettierOptions'] = {
13
- semi: false,
14
- singleQuote: true,
15
- printWidth: 100,
16
- trailingComma: 'none',
17
- }
18
- // RegExp to find TypeScript code blocks.
19
- //
20
- // For example:
21
- // ~~~mdx
22
- // ```ts
23
- // const hello: string = 'world'
24
- // ```
25
- // ~~~
26
- //
27
- // But also indented code blocks:
28
- // ~~~mdx
29
- // > Also works:
30
- // > - In blockquotes
31
- // > - In bullet points
32
- // > ```ts
33
- // > const hello: string = 'world'
34
- // > ```
35
- // ~~~
36
- const codeBlockRE = /^(.*)```(tsx?|vue|yaml)[^\n]*\n([\s\S]*?)```/gm
37
-
38
- function detypePlugin(): PluginOption {
39
- return {
40
- name: '@brillout/docpress:detypePlugin',
41
- enforce: 'pre',
42
- transform: async (code: string, moduleId: string) => {
43
- if (!moduleId.endsWith('.mdx')) return
44
- return await transformCode(code, moduleId)
45
- },
46
- }
47
- }
48
-
49
- async function transformCode(code: string, moduleId: string) {
50
- const matches = Array.from(code.matchAll(codeBlockRE))
51
- if (matches.length === 0) return
52
-
53
- const { magicString, getMagicStringResult } = getMagicString(code, moduleId)
54
-
55
- magicString.prepend(`import { CodeSnippets, CodeSnippet } from '@brillout/docpress';\n\n`)
56
-
57
- // [Claude AI] Process matches in reverse order to avoid offset issues
58
- for (let i = matches.length - 1; i >= 0; i--) {
59
- const match = matches[i]
60
- const [codeBlockOuterStr, codeBlockIndent, codeBlockLang, codeBlockContentWithIndent] = match
61
- const isYaml = codeBlockLang === 'yaml'
62
-
63
- // Remove indentation
64
- const codeBlockOpen = codeBlockOuterStr.split('\n')[0].slice(codeBlockIndent.length)
65
- const codeBlockContent = removeCodeBlockIndent(codeBlockContentWithIndent, codeBlockIndent, moduleId)
66
-
67
- let replacement: string
68
- if (codeBlockOpen.includes('ts-only') && !isYaml) {
69
- replacement = `${codeBlockIndent}<CodeSnippet codeLang="ts" tsOnly>\n${codeBlockOuterStr}\n${codeBlockIndent}</CodeSnippet>`
70
- } else {
71
- // someFileName.ts => someFileName.js
72
- let codeBlockContentJs = codeBlockContent.replaceAll('.ts', '.js')
73
- const codeBlockClose = '```'
74
- if (isYaml && codeBlockContentJs === codeBlockContent) {
75
- continue
76
- }
77
-
78
- // Remove TypeScript
79
- if (!isYaml) {
80
- codeBlockContentJs = await detype(codeBlockContentJs, `some-dummy-filename.${codeBlockLang}`, {
81
- removeTsComments: true,
82
- prettierOptions,
83
- })
84
- }
85
-
86
- // Update code block open delimiter
87
- const codeBlockLangJs =
88
- codeBlockLang === 'vue'
89
- ? 'vue'
90
- : // ts => js | tsx => jsx
91
- codeBlockLang.replace('t', 'j')
92
- const codeBlockOpenJs = codeBlockOpen.replace(codeBlockLang, codeBlockLangJs)
93
-
94
- // Wrap each with <CodeSnippet>
95
- let codeSnippets = [
96
- wrapCodeSnippet('ts', `${codeBlockOpen}\n${codeBlockContent}${codeBlockClose}`),
97
- wrapCodeSnippet('js', `${codeBlockOpenJs}\n${codeBlockContentJs}${codeBlockClose}`),
98
- ].join('\n')
99
-
100
- // Wrap with <CodeSnippets> (if not YAML)
101
- codeSnippets = isYaml
102
- ? codeSnippets
103
- : // Rename/Replace Words via Custom Magic Comments
104
- processMagicComments(`<CodeSnippets>\n${codeSnippets}\n</CodeSnippets>`)
105
-
106
- // Restore indentation
107
- codeSnippets = restoreCodeBlockIndent(codeSnippets, codeBlockIndent)
108
-
109
- // Done
110
- replacement = codeSnippets
111
- }
112
-
113
- const blockStartIndex = match.index!
114
- const blockEndIndex = blockStartIndex + codeBlockOuterStr.length
115
- magicString.overwrite(blockStartIndex, blockEndIndex, replacement)
116
- }
117
-
118
- return getMagicStringResult()
119
- }
120
-
121
- function wrapCodeSnippet(lang: string, content: string) {
122
- return `<CodeSnippet codeLang="${lang}">\n${content}\n</CodeSnippet>`
123
- }
124
- function removeCodeBlockIndent(code: string, codeBlockIndent: string, moduleId: string) {
125
- if (!codeBlockIndent.length) return code
126
- return code
127
- .split('\n')
128
- .map((line) => {
129
- const lineStart = codeBlockIndent.trimEnd()
130
- assertUsage(
131
- line.startsWith(lineStart),
132
- `In ${pc.bold(pc.blue(moduleId))} the line '${pc.bold(line)}' must start with '${pc.bold(lineStart)}'`,
133
- )
134
- return line.slice(codeBlockIndent.length)
135
- })
136
- .join('\n')
137
- }
138
- function restoreCodeBlockIndent(code: string, codeBlockIndent: string) {
139
- if (!codeBlockIndent.length) return code
140
- return code
141
- .split('\n')
142
- .map((line) => `${codeBlockIndent}${line}`)
143
- .join('\n')
144
- }
145
- function processMagicComments(code: string) {
146
- // @detype-rename DummyLayout>Layout
147
- const renameCommentRE = /^\/\/\s@detype-rename\s(\w+)>(\w+)\n/gm
148
- const matches = Array.from(code.matchAll(renameCommentRE))
149
-
150
- if (matches.length) {
151
- for (let i = 0; i < matches.length / 2; i++) {
152
- const match = matches[i]
153
- const [fullMatch, renameFrom, renameTo] = match
154
- code = code.split(fullMatch).join('').replaceAll(renameFrom, renameTo)
155
- }
156
- }
157
-
158
- return code.replaceAll('//~', '')
159
- }
@@ -1,3 +0,0 @@
1
- export { detypePlugin };
2
- import type { PluginOption } from 'vite';
3
- declare function detypePlugin(): PluginOption;
@@ -1,139 +0,0 @@
1
- export { detypePlugin };
2
- import module from 'node:module';
3
- import { assertUsage } from './utils/assert.js';
4
- import pc from '@brillout/picocolors';
5
- import { getMagicString } from './utils/getMagicString.js';
6
- // Cannot use `import { transform } from 'detype'` as it results in errors,
7
- // and the package has no default export. Using `module.createRequire` instead.
8
- const { transform: detype } = module.createRequire(import.meta.url)('detype');
9
- const prettierOptions = {
10
- semi: false,
11
- singleQuote: true,
12
- printWidth: 100,
13
- trailingComma: 'none',
14
- };
15
- // RegExp to find TypeScript code blocks.
16
- //
17
- // For example:
18
- // ~~~mdx
19
- // ```ts
20
- // const hello: string = 'world'
21
- // ```
22
- // ~~~
23
- //
24
- // But also indented code blocks:
25
- // ~~~mdx
26
- // > Also works:
27
- // > - In blockquotes
28
- // > - In bullet points
29
- // > ```ts
30
- // > const hello: string = 'world'
31
- // > ```
32
- // ~~~
33
- const codeBlockRE = /^(.*)```(tsx?|vue|yaml)[^\n]*\n([\s\S]*?)```/gm;
34
- function detypePlugin() {
35
- return {
36
- name: '@brillout/docpress:detypePlugin',
37
- enforce: 'pre',
38
- transform: async (code, moduleId) => {
39
- if (!moduleId.endsWith('.mdx'))
40
- return;
41
- return await transformCode(code, moduleId);
42
- },
43
- };
44
- }
45
- async function transformCode(code, moduleId) {
46
- const matches = Array.from(code.matchAll(codeBlockRE));
47
- if (matches.length === 0)
48
- return;
49
- const { magicString, getMagicStringResult } = getMagicString(code, moduleId);
50
- magicString.prepend(`import { CodeSnippets, CodeSnippet } from '@brillout/docpress';\n\n`);
51
- // [Claude AI] Process matches in reverse order to avoid offset issues
52
- for (let i = matches.length - 1; i >= 0; i--) {
53
- const match = matches[i];
54
- const [codeBlockOuterStr, codeBlockIndent, codeBlockLang, codeBlockContentWithIndent] = match;
55
- const isYaml = codeBlockLang === 'yaml';
56
- // Remove indentation
57
- const codeBlockOpen = codeBlockOuterStr.split('\n')[0].slice(codeBlockIndent.length);
58
- const codeBlockContent = removeCodeBlockIndent(codeBlockContentWithIndent, codeBlockIndent, moduleId);
59
- let replacement;
60
- if (codeBlockOpen.includes('ts-only') && !isYaml) {
61
- replacement = `${codeBlockIndent}<CodeSnippet codeLang="ts" tsOnly>\n${codeBlockOuterStr}\n${codeBlockIndent}</CodeSnippet>`;
62
- }
63
- else {
64
- // someFileName.ts => someFileName.js
65
- let codeBlockContentJs = codeBlockContent.replaceAll('.ts', '.js');
66
- const codeBlockClose = '```';
67
- if (isYaml && codeBlockContentJs === codeBlockContent) {
68
- continue;
69
- }
70
- // Remove TypeScript
71
- if (!isYaml) {
72
- codeBlockContentJs = await detype(codeBlockContentJs, `some-dummy-filename.${codeBlockLang}`, {
73
- removeTsComments: true,
74
- prettierOptions,
75
- });
76
- }
77
- // Update code block open delimiter
78
- const codeBlockLangJs = codeBlockLang === 'vue'
79
- ? 'vue'
80
- : // ts => js | tsx => jsx
81
- codeBlockLang.replace('t', 'j');
82
- const codeBlockOpenJs = codeBlockOpen.replace(codeBlockLang, codeBlockLangJs);
83
- // Wrap each with <CodeSnippet>
84
- let codeSnippets = [
85
- wrapCodeSnippet('ts', `${codeBlockOpen}\n${codeBlockContent}${codeBlockClose}`),
86
- wrapCodeSnippet('js', `${codeBlockOpenJs}\n${codeBlockContentJs}${codeBlockClose}`),
87
- ].join('\n');
88
- // Wrap with <CodeSnippets> (if not YAML)
89
- codeSnippets = isYaml
90
- ? codeSnippets
91
- : // Rename/Replace Words via Custom Magic Comments
92
- processMagicComments(`<CodeSnippets>\n${codeSnippets}\n</CodeSnippets>`);
93
- // Restore indentation
94
- codeSnippets = restoreCodeBlockIndent(codeSnippets, codeBlockIndent);
95
- // Done
96
- replacement = codeSnippets;
97
- }
98
- const blockStartIndex = match.index;
99
- const blockEndIndex = blockStartIndex + codeBlockOuterStr.length;
100
- magicString.overwrite(blockStartIndex, blockEndIndex, replacement);
101
- }
102
- return getMagicStringResult();
103
- }
104
- function wrapCodeSnippet(lang, content) {
105
- return `<CodeSnippet codeLang="${lang}">\n${content}\n</CodeSnippet>`;
106
- }
107
- function removeCodeBlockIndent(code, codeBlockIndent, moduleId) {
108
- if (!codeBlockIndent.length)
109
- return code;
110
- return code
111
- .split('\n')
112
- .map((line) => {
113
- const lineStart = codeBlockIndent.trimEnd();
114
- assertUsage(line.startsWith(lineStart), `In ${pc.bold(pc.blue(moduleId))} the line '${pc.bold(line)}' must start with '${pc.bold(lineStart)}'`);
115
- return line.slice(codeBlockIndent.length);
116
- })
117
- .join('\n');
118
- }
119
- function restoreCodeBlockIndent(code, codeBlockIndent) {
120
- if (!codeBlockIndent.length)
121
- return code;
122
- return code
123
- .split('\n')
124
- .map((line) => `${codeBlockIndent}${line}`)
125
- .join('\n');
126
- }
127
- function processMagicComments(code) {
128
- // @detype-rename DummyLayout>Layout
129
- const renameCommentRE = /^\/\/\s@detype-rename\s(\w+)>(\w+)\n/gm;
130
- const matches = Array.from(code.matchAll(renameCommentRE));
131
- if (matches.length) {
132
- for (let i = 0; i < matches.length / 2; i++) {
133
- const match = matches[i];
134
- const [fullMatch, renameFrom, renameTo] = match;
135
- code = code.split(fullMatch).join('').replaceAll(renameFrom, renameTo);
136
- }
137
- }
138
- return code.replaceAll('//~', '');
139
- }
@@ -1,9 +0,0 @@
1
- export { getMagicString };
2
- import MagicString from 'magic-string';
3
- declare function getMagicString(code: string, id: string): {
4
- magicString: MagicString;
5
- getMagicStringResult: () => {
6
- code: string;
7
- map: import("magic-string").SourceMap;
8
- };
9
- };
@@ -1,13 +0,0 @@
1
- export { getMagicString };
2
- import MagicString from 'magic-string';
3
- // Used everywhere instead of `new MagicString()` for consistent source map generation
4
- function getMagicString(code, id) {
5
- const magicString = new MagicString(code);
6
- const getMagicStringResult = () => {
7
- return {
8
- code: magicString.toString(),
9
- map: magicString.generateMap({ hires: true, source: id }),
10
- };
11
- };
12
- return { magicString, getMagicStringResult };
13
- }
@@ -1,17 +0,0 @@
1
- export { getMagicString }
2
-
3
- import MagicString from 'magic-string'
4
-
5
- // Used everywhere instead of `new MagicString()` for consistent source map generation
6
- function getMagicString(code: string, id: string) {
7
- const magicString = new MagicString(code)
8
-
9
- const getMagicStringResult = () => {
10
- return {
11
- code: magicString.toString(),
12
- map: magicString.generateMap({ hires: true, source: id }),
13
- }
14
- }
15
-
16
- return { magicString, getMagicStringResult }
17
- }