|
1 | | -import fs from 'node:fs/promises' |
2 | | -import path from 'node:path' |
3 | 1 | import process from 'node:process' |
4 | | -import { fileURLToPath } from 'node:url' |
5 | | -import { assetTargets } from '../assets-data.mjs' |
6 | | -import { templateChoices } from '../template-data.mjs' |
7 | | - |
8 | | -const scriptDir = path.dirname(fileURLToPath(import.meta.url)) |
9 | | -const packageDir = path.resolve(scriptDir, '..') |
10 | | -const repoRoot = path.resolve(packageDir, '..', '..') |
11 | | -const templatesDir = path.join(packageDir, 'templates') |
12 | | -const assetsDir = path.join(packageDir, 'assets') |
13 | | -const templateSkipDirs = new Set([ |
14 | | - 'node_modules', |
15 | | - 'dist', |
16 | | - '.turbo', |
17 | | - '.cache', |
18 | | - '.vite', |
19 | | - '.tmp', |
20 | | - '.vue-global-types', |
21 | | - '.wrangler', |
22 | | -]) |
23 | | -const skipFiles = new Set([ |
24 | | - '.DS_Store', |
25 | | - 'typed-router.d.ts', |
26 | | - 'worker-configuration.d.ts', |
27 | | -]) |
28 | | - |
29 | | -const publishBasename = 'gitignore' |
30 | | -const workspaceBasename = '.gitignore' |
31 | | - |
32 | | -function detectSeparator(input) { |
33 | | - if (input.includes('\\') && !input.includes('/')) { |
34 | | - return '\\' |
35 | | - } |
36 | | - return '/' |
37 | | -} |
38 | | - |
39 | | -function replaceBasename(input, from, to) { |
40 | | - if (!input) { |
41 | | - return input |
42 | | - } |
43 | | - const separator = detectSeparator(input) |
44 | | - const normalized = input.replace(/[\\/]/g, separator) |
45 | | - const hasTrailingSeparator = normalized.endsWith(separator) |
46 | | - const segments = normalized.split(separator) |
47 | | - if (hasTrailingSeparator && segments[segments.length - 1] === '') { |
48 | | - segments.pop() |
49 | | - } |
50 | | - const lastIndex = segments.length - 1 |
51 | | - if (lastIndex >= 0 && segments[lastIndex] === from) { |
52 | | - segments[lastIndex] = to |
53 | | - const rebuilt = segments.join(separator) |
54 | | - return hasTrailingSeparator ? `${rebuilt}${separator}` : rebuilt |
55 | | - } |
56 | | - return input |
57 | | -} |
58 | | - |
59 | | -function toPublishGitignorePath(input) { |
60 | | - return replaceBasename(input, workspaceBasename, publishBasename) |
61 | | -} |
62 | | - |
63 | | -function shouldSkipTemplatePath(rootDir, targetPath) { |
64 | | - const relative = path.relative(rootDir, targetPath) |
65 | | - if (!relative || relative.startsWith('..')) { |
66 | | - return false |
67 | | - } |
68 | | - const segments = relative.split(path.sep) |
69 | | - if (segments.some(segment => templateSkipDirs.has(segment))) { |
70 | | - return true |
71 | | - } |
72 | | - for (let i = 0; i < segments.length - 1; i += 1) { |
73 | | - if (segments[i] === '.vitepress' && segments[i + 1] === 'cache') { |
74 | | - return true |
75 | | - } |
76 | | - } |
77 | | - const basename = path.basename(targetPath) |
78 | | - if (skipFiles.has(basename)) { |
79 | | - return true |
80 | | - } |
81 | | - if (basename.endsWith('.tsbuildinfo')) { |
82 | | - return true |
83 | | - } |
84 | | - return false |
85 | | -} |
86 | | - |
87 | | -async function renameGitignoreFiles(targetDir) { |
88 | | - const entries = await fs.readdir(targetDir, { withFileTypes: true }) |
89 | | - await Promise.all(entries.map(async (entry) => { |
90 | | - const current = path.join(targetDir, entry.name) |
91 | | - if (entry.isDirectory()) { |
92 | | - await renameGitignoreFiles(current) |
93 | | - return |
94 | | - } |
95 | | - if (entry.name === workspaceBasename) { |
96 | | - const renamed = path.join(targetDir, publishBasename) |
97 | | - await fs.rename(current, renamed) |
98 | | - } |
99 | | - })) |
100 | | -} |
101 | | - |
102 | | -async function resetDir(targetDir) { |
103 | | - await fs.rm(targetDir, { recursive: true, force: true }) |
104 | | - await fs.mkdir(targetDir, { recursive: true }) |
105 | | -} |
106 | | - |
107 | | -async function copyAssets() { |
108 | | - for (const target of assetTargets) { |
109 | | - const from = path.join(repoRoot, target) |
110 | | - const to = path.join(assetsDir, toPublishGitignorePath(target)) |
111 | | - const stats = await fs.stat(from) |
112 | | - const copyOptions = { recursive: true } |
113 | | - if (target === '.husky') { |
114 | | - await fs.cp(from, to, { |
115 | | - ...copyOptions, |
116 | | - filter(src) { |
117 | | - return !/[\\/]_$/.test(src) |
118 | | - }, |
119 | | - }) |
120 | | - continue |
121 | | - } |
122 | | - await fs.cp(from, to, copyOptions) |
123 | | - if (stats.isDirectory()) { |
124 | | - await renameGitignoreFiles(to) |
125 | | - } |
126 | | - } |
127 | | -} |
128 | | - |
129 | | -async function copyTemplates() { |
130 | | - for (const template of templateChoices) { |
131 | | - const from = path.join(repoRoot, 'templates', template.source) |
132 | | - const to = path.join(templatesDir, template.source) |
133 | | - await fs.mkdir(path.dirname(to), { recursive: true }) |
134 | | - await fs.cp(from, to, { |
135 | | - recursive: true, |
136 | | - filter: src => !shouldSkipTemplatePath(from, src), |
137 | | - }) |
138 | | - await renameGitignoreFiles(to) |
139 | | - } |
140 | | -} |
141 | 2 |
|
142 | 3 | async function main() { |
143 | | - await resetDir(assetsDir) |
144 | | - await resetDir(templatesDir) |
145 | | - await copyAssets() |
146 | | - await copyTemplates() |
| 4 | + const entryUrl = new URL('../dist/index.mjs', import.meta.url) |
| 5 | + const { prepareAssets } = await import(entryUrl.href) |
| 6 | + await prepareAssets({ overwriteExisting: true }) |
147 | 7 | } |
148 | 8 |
|
149 | 9 | main().catch((error) => { |
|
0 commit comments