create-addfox-app 0.1.1-beta.10 → 0.1.1-beta.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 +1 -1
- package/dist/cli.js +94 -81
- package/package.json +2 -1
- package/templates/README.md +3 -0
- package/templates/template-preact-js/addfox.config.js +27 -0
- package/templates/template-preact-js/app/background/index.js +8 -0
- package/templates/template-preact-js/app/content/index.js +1 -0
- package/templates/template-preact-js/app/options/App.jsx +5 -0
- package/templates/template-preact-js/app/options/index.jsx +5 -0
- package/templates/template-preact-js/app/popup/App.jsx +23 -0
- package/templates/template-preact-js/app/popup/index.jsx +5 -0
- package/templates/template-preact-js/app/sidepanel/App.jsx +5 -0
- package/templates/template-preact-js/app/sidepanel/index.jsx +5 -0
- package/templates/template-preact-js/package.json +19 -0
- package/templates/template-preact-js/public/icons/icon_128.png +0 -0
- package/templates/template-preact-js/public/welcome.html +19 -0
- package/templates/template-preact-ts/addfox.config.ts +27 -0
- package/templates/template-preact-ts/app/background/index.ts +8 -0
- package/templates/template-preact-ts/app/content/index.ts +1 -0
- package/templates/template-preact-ts/app/options/App.tsx +5 -0
- package/templates/template-preact-ts/app/options/index.tsx +5 -0
- package/templates/template-preact-ts/app/popup/App.tsx +23 -0
- package/templates/template-preact-ts/app/popup/index.tsx +5 -0
- package/templates/template-preact-ts/app/sidepanel/App.tsx +5 -0
- package/templates/template-preact-ts/app/sidepanel/index.tsx +5 -0
- package/templates/template-preact-ts/package.json +21 -0
- package/templates/template-preact-ts/public/icons/icon_128.png +0 -0
- package/templates/template-preact-ts/public/welcome.html +19 -0
- package/templates/template-preact-ts/tsconfig.json +19 -0
- package/templates/template-react-js/addfox.config.js +27 -0
- package/templates/template-react-js/app/background/index.js +8 -0
- package/templates/template-react-js/app/content/index.js +1 -0
- package/templates/template-react-js/app/options/App.jsx +3 -0
- package/templates/template-react-js/app/options/index.jsx +5 -0
- package/templates/template-react-js/app/popup/App.jsx +21 -0
- package/templates/template-react-js/app/popup/index.jsx +5 -0
- package/templates/template-react-js/app/sidepanel/App.jsx +3 -0
- package/templates/template-react-js/app/sidepanel/index.jsx +5 -0
- package/templates/template-react-js/package.json +20 -0
- package/templates/template-react-js/public/icons/icon_128.png +0 -0
- package/templates/template-react-js/public/welcome.html +19 -0
- package/templates/template-react-ts/addfox.config.ts +27 -0
- package/templates/template-react-ts/app/background/index.ts +8 -0
- package/templates/template-react-ts/app/content/index.ts +1 -0
- package/templates/template-react-ts/app/options/App.tsx +3 -0
- package/templates/template-react-ts/app/options/index.tsx +5 -0
- package/templates/template-react-ts/app/popup/App.tsx +21 -0
- package/templates/template-react-ts/app/popup/index.tsx +5 -0
- package/templates/template-react-ts/app/sidepanel/App.tsx +3 -0
- package/templates/template-react-ts/app/sidepanel/index.tsx +5 -0
- package/templates/template-react-ts/package.json +24 -0
- package/templates/template-react-ts/public/icons/icon_128.png +0 -0
- package/templates/template-react-ts/public/welcome.html +19 -0
- package/templates/template-react-ts/tsconfig.json +19 -0
- package/templates/template-solid-js/addfox.config.js +28 -0
- package/templates/template-solid-js/app/background/index.js +8 -0
- package/templates/template-solid-js/app/content/index.js +1 -0
- package/templates/template-solid-js/app/options/App.jsx +3 -0
- package/templates/template-solid-js/app/options/index.jsx +5 -0
- package/templates/template-solid-js/app/popup/App.jsx +26 -0
- package/templates/template-solid-js/app/popup/index.jsx +5 -0
- package/templates/template-solid-js/app/sidepanel/App.jsx +3 -0
- package/templates/template-solid-js/app/sidepanel/index.jsx +5 -0
- package/templates/template-solid-js/package.json +20 -0
- package/templates/template-solid-js/public/icons/icon_128.png +0 -0
- package/templates/template-solid-js/public/welcome.html +19 -0
- package/templates/template-solid-ts/addfox.config.ts +28 -0
- package/templates/template-solid-ts/app/background/index.ts +8 -0
- package/templates/template-solid-ts/app/content/index.ts +1 -0
- package/templates/template-solid-ts/app/options/App.tsx +3 -0
- package/templates/template-solid-ts/app/options/index.tsx +5 -0
- package/templates/template-solid-ts/app/popup/App.tsx +26 -0
- package/templates/template-solid-ts/app/popup/index.tsx +5 -0
- package/templates/template-solid-ts/app/sidepanel/App.tsx +3 -0
- package/templates/template-solid-ts/app/sidepanel/index.tsx +5 -0
- package/templates/template-solid-ts/package.json +22 -0
- package/templates/template-solid-ts/public/icons/icon_128.png +0 -0
- package/templates/template-solid-ts/public/welcome.html +19 -0
- package/templates/template-solid-ts/tsconfig.json +19 -0
- package/templates/template-svelte-js/addfox.config.js +27 -0
- package/templates/template-svelte-js/app/background/index.js +8 -0
- package/templates/template-svelte-js/app/content/index.js +1 -0
- package/templates/template-svelte-js/app/options/App.svelte +4 -0
- package/templates/template-svelte-js/app/options/index.js +4 -0
- package/templates/template-svelte-js/app/popup/App.svelte +24 -0
- package/templates/template-svelte-js/app/popup/index.js +4 -0
- package/templates/template-svelte-js/app/sidepanel/App.svelte +4 -0
- package/templates/template-svelte-js/app/sidepanel/index.js +4 -0
- package/templates/template-svelte-js/package.json +19 -0
- package/templates/template-svelte-js/public/icons/icon_128.png +0 -0
- package/templates/template-svelte-js/public/welcome.html +19 -0
- package/templates/template-svelte-ts/addfox.config.ts +27 -0
- package/templates/template-svelte-ts/app/background/index.ts +8 -0
- package/templates/template-svelte-ts/app/content/index.ts +1 -0
- package/templates/template-svelte-ts/app/options/App.svelte +4 -0
- package/templates/template-svelte-ts/app/options/index.ts +4 -0
- package/templates/template-svelte-ts/app/popup/App.svelte +24 -0
- package/templates/template-svelte-ts/app/popup/index.ts +4 -0
- package/templates/template-svelte-ts/app/sidepanel/App.svelte +4 -0
- package/templates/template-svelte-ts/app/sidepanel/index.ts +4 -0
- package/templates/template-svelte-ts/package.json +21 -0
- package/templates/template-svelte-ts/public/icons/icon_128.png +0 -0
- package/templates/template-svelte-ts/public/welcome.html +19 -0
- package/templates/template-svelte-ts/tsconfig.json +19 -0
- package/templates/template-vanilla-js/addfox.config.js +25 -0
- package/templates/template-vanilla-js/app/background/index.js +8 -0
- package/templates/template-vanilla-js/app/content/index.js +1 -0
- package/templates/template-vanilla-js/app/options/index.js +2 -0
- package/templates/template-vanilla-js/app/popup/index.js +37 -0
- package/templates/template-vanilla-js/app/sidepanel/index.js +2 -0
- package/templates/template-vanilla-js/package.json +15 -0
- package/templates/template-vanilla-js/public/icons/icon_128.png +0 -0
- package/templates/template-vanilla-js/public/welcome.html +19 -0
- package/templates/template-vanilla-ts/addfox.config.ts +25 -0
- package/templates/template-vanilla-ts/app/background/index.ts +8 -0
- package/templates/template-vanilla-ts/app/content/index.ts +1 -0
- package/templates/template-vanilla-ts/app/options/index.ts +2 -0
- package/templates/template-vanilla-ts/app/popup/index.ts +37 -0
- package/templates/template-vanilla-ts/app/sidepanel/index.ts +2 -0
- package/templates/template-vanilla-ts/package.json +17 -0
- package/templates/template-vanilla-ts/public/icons/icon_128.png +0 -0
- package/templates/template-vanilla-ts/public/welcome.html +19 -0
- package/templates/template-vanilla-ts/tsconfig.json +17 -0
- package/templates/template-vue-js/addfox.config.js +27 -0
- package/templates/template-vue-js/app/background/index.js +8 -0
- package/templates/template-vue-js/app/content/index.js +1 -0
- package/templates/template-vue-js/app/options/App.vue +6 -0
- package/templates/template-vue-js/app/options/index.js +5 -0
- package/templates/template-vue-js/app/popup/App.vue +28 -0
- package/templates/template-vue-js/app/popup/index.js +5 -0
- package/templates/template-vue-js/app/sidepanel/App.vue +6 -0
- package/templates/template-vue-js/app/sidepanel/index.js +5 -0
- package/templates/template-vue-js/package.json +20 -0
- package/templates/template-vue-js/public/icons/icon_128.png +0 -0
- package/templates/template-vue-js/public/welcome.html +19 -0
- package/templates/template-vue-ts/addfox.config.ts +27 -0
- package/templates/template-vue-ts/app/background/index.ts +8 -0
- package/templates/template-vue-ts/app/content/index.ts +1 -0
- package/templates/template-vue-ts/app/options/App.vue +6 -0
- package/templates/template-vue-ts/app/options/index.ts +5 -0
- package/templates/template-vue-ts/app/popup/App.vue +26 -0
- package/templates/template-vue-ts/app/popup/index.ts +5 -0
- package/templates/template-vue-ts/app/sidepanel/App.vue +6 -0
- package/templates/template-vue-ts/app/sidepanel/index.ts +5 -0
- package/templates/template-vue-ts/package.json +23 -0
- package/templates/template-vue-ts/public/icons/icon_128.png +0 -0
- package/templates/template-vue-ts/public/welcome.html +19 -0
- package/templates/template-vue-ts/tsconfig.json +19 -0
package/README.md
CHANGED
|
@@ -15,4 +15,4 @@ Interactive scaffolder: generates a addfox-based extension project from options
|
|
|
15
15
|
|
|
16
16
|
## Templates
|
|
17
17
|
|
|
18
|
-
Scaffold templates
|
|
18
|
+
Scaffold templates ship inside this package under **`templates/`** (e.g. `template-vanilla-ts`, `template-react-ts`). They are included in the published npm tarball; the CLI copies the chosen folder into your new project (no remote download). The template’s **`addfox.config`** (including `manifest`) is **preserved**; the CLI only **merges** Rsbuild Less/Sass plugins when those style engines are selected. If no config file exists, a full fallback config is generated.
|
package/dist/cli.js
CHANGED
|
@@ -8,91 +8,40 @@ import prompts from "prompts";
|
|
|
8
8
|
import { blue, cyan, dim, gray, green, lightBlue, magenta, red, trueColor, yellow } from "kolorist";
|
|
9
9
|
import minimist from "minimist";
|
|
10
10
|
import { cp, mkdir } from "node:fs/promises";
|
|
11
|
-
import { gunzipSync } from "node:zlib";
|
|
12
11
|
import { detectPackageManager, getExecCommand, getInstallCommand, getRunCommand } from "@addfox/pkg-manager";
|
|
13
|
-
const GITHUB_REPO = "addfox/addfox";
|
|
14
12
|
const TEMPLATE_BASE = "templates";
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
function getPackageRoot() {
|
|
14
|
+
return external_node_path_resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
}
|
|
16
|
+
function getBundledTemplatesDir() {
|
|
17
|
+
return join(getPackageRoot(), TEMPLATE_BASE);
|
|
18
18
|
}
|
|
19
19
|
function hasLocalTemplate(templateName) {
|
|
20
|
-
|
|
21
|
-
return existsSync(join(repoRoot, TEMPLATE_BASE, templateName));
|
|
20
|
+
return existsSync(join(getBundledTemplatesDir(), templateName));
|
|
22
21
|
}
|
|
23
|
-
const
|
|
22
|
+
const SKIP_RELATIVE_SEGMENTS = new Set([
|
|
24
23
|
"node_modules",
|
|
25
24
|
".git",
|
|
26
25
|
".pnpm"
|
|
27
26
|
]);
|
|
28
|
-
function shouldCopyLocalTemplatePath(src) {
|
|
29
|
-
const
|
|
30
|
-
|
|
27
|
+
function shouldCopyLocalTemplatePath(src, templateRoot) {
|
|
28
|
+
const root = external_node_path_resolve(templateRoot);
|
|
29
|
+
const rel = relative(root, external_node_path_resolve(src));
|
|
30
|
+
if (rel.startsWith("..")) return true;
|
|
31
|
+
for (const part of rel.split(/[/\\]/))if (SKIP_RELATIVE_SEGMENTS.has(part)) return false;
|
|
31
32
|
return true;
|
|
32
33
|
}
|
|
33
|
-
async function
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
if (!existsSync(templatePath)) return false;
|
|
34
|
+
async function copyBundledTemplate(templateName, destDir) {
|
|
35
|
+
const templatePath = join(getBundledTemplatesDir(), templateName);
|
|
36
|
+
if (!existsSync(templatePath)) throw new Error(`Bundled template "${templateName}" not found under create-addfox-app. Reinstall the package.`);
|
|
37
37
|
await mkdir(destDir, {
|
|
38
38
|
recursive: true
|
|
39
39
|
});
|
|
40
|
-
|
|
40
|
+
const resolvedTemplate = external_node_path_resolve(templatePath);
|
|
41
|
+
await cp(resolvedTemplate, destDir, {
|
|
41
42
|
recursive: true,
|
|
42
|
-
filter: (src)=>shouldCopyLocalTemplatePath(src)
|
|
43
|
+
filter: (src)=>shouldCopyLocalTemplatePath(src, resolvedTemplate)
|
|
43
44
|
});
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
function parseTarHeader(buf) {
|
|
47
|
-
if (buf.every((b)=>0 === b)) return null;
|
|
48
|
-
const rawName = buf.subarray(0, 100).toString("utf8").replace(/\0+$/, "");
|
|
49
|
-
const sizeStr = buf.subarray(124, 136).toString("utf8").replace(/\0+$/, "").trim();
|
|
50
|
-
const type = String.fromCharCode(buf[156]);
|
|
51
|
-
const prefix = buf.subarray(345, 500).toString("utf8").replace(/\0+$/, "");
|
|
52
|
-
return {
|
|
53
|
-
name: prefix ? `${prefix}/${rawName}` : rawName,
|
|
54
|
-
size: parseInt(sizeStr, 8) || 0,
|
|
55
|
-
type
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function extractMatchingFiles(tarBuffer, templatePrefix, destDir) {
|
|
59
|
-
let offset = 0;
|
|
60
|
-
while(offset + 512 <= tarBuffer.length){
|
|
61
|
-
const header = parseTarHeader(tarBuffer.subarray(offset, offset + 512));
|
|
62
|
-
offset += 512;
|
|
63
|
-
if (!header) break;
|
|
64
|
-
const dataBlocks = 512 * Math.ceil(header.size / 512);
|
|
65
|
-
const idx = header.name.indexOf(templatePrefix);
|
|
66
|
-
if (-1 !== idx) {
|
|
67
|
-
const relativePath = header.name.substring(idx + templatePrefix.length).replace(/^\//, "");
|
|
68
|
-
if (relativePath) {
|
|
69
|
-
const destPath = join(destDir, relativePath);
|
|
70
|
-
const isDir = "5" === header.type || relativePath.endsWith("/");
|
|
71
|
-
if (isDir) mkdirSync(destPath, {
|
|
72
|
-
recursive: true
|
|
73
|
-
});
|
|
74
|
-
else if ("0" === header.type || "\0" === header.type) {
|
|
75
|
-
mkdirSync(dirname(destPath), {
|
|
76
|
-
recursive: true
|
|
77
|
-
});
|
|
78
|
-
writeFileSync(destPath, tarBuffer.subarray(offset, offset + header.size));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
offset += dataBlocks;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
async function downloadTemplate(templateName, destDir, branch = "main") {
|
|
86
|
-
const url = `https://codeload.github.com/${GITHUB_REPO}/tar.gz/${branch}`;
|
|
87
|
-
const templatePrefix = `${TEMPLATE_BASE}/${templateName}/`;
|
|
88
|
-
const response = await fetch(url);
|
|
89
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
90
|
-
const compressed = Buffer.from(await response.arrayBuffer());
|
|
91
|
-
const tarBuffer = gunzipSync(compressed);
|
|
92
|
-
mkdirSync(destDir, {
|
|
93
|
-
recursive: true
|
|
94
|
-
});
|
|
95
|
-
extractMatchingFiles(tarBuffer, templatePrefix, destDir);
|
|
96
45
|
}
|
|
97
46
|
const FRAMES = [
|
|
98
47
|
"⠋",
|
|
@@ -295,7 +244,7 @@ function getStylePlugin(engine) {
|
|
|
295
244
|
};
|
|
296
245
|
return null;
|
|
297
246
|
}
|
|
298
|
-
const MINIMAL_MANIFEST = ' name: "My Extension",\n version: "1.0.0",\n manifest_version: 3,\n description: "Browser extension built with addfox",\n permissions: ["
|
|
247
|
+
const MINIMAL_MANIFEST = ' name: "My Extension",\n version: "1.0.0",\n manifest_version: 3,\n description: "Browser extension built with addfox",\n permissions: ["activeTab"],\n icons: {\n "16": "icons/icon_128.png",\n "48": "icons/icon_128.png",\n "128": "icons/icon_128.png",\n },\n action: {\n default_icon: {\n "16": "icons/icon_128.png",\n "48": "icons/icon_128.png",\n "128": "icons/icon_128.png",\n },\n },';
|
|
299
248
|
function generateAddfoxConfig(framework, _language, styleEngine) {
|
|
300
249
|
const importLines = [];
|
|
301
250
|
const fwImport = getFrameworkPluginImport(framework);
|
|
@@ -323,6 +272,67 @@ function generateAddfoxConfig(framework, _language, styleEngine) {
|
|
|
323
272
|
];
|
|
324
273
|
return parts.filter(Boolean).join("\n");
|
|
325
274
|
}
|
|
275
|
+
const MANIFEST_LINE = " manifest: { chromium: manifest, firefox: { ...manifest } },";
|
|
276
|
+
function findMatchingArrayClose(source, openBracketIdx) {
|
|
277
|
+
if ("[" !== source[openBracketIdx]) return -1;
|
|
278
|
+
let depth = 0;
|
|
279
|
+
for(let i = openBracketIdx; i < source.length; i++){
|
|
280
|
+
const c = source[i];
|
|
281
|
+
if ("[" === c) depth++;
|
|
282
|
+
else if ("]" === c) {
|
|
283
|
+
depth--;
|
|
284
|
+
if (0 === depth) return i;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return -1;
|
|
288
|
+
}
|
|
289
|
+
function hasImportFromModule(source, modulePath) {
|
|
290
|
+
return source.includes(`from "${modulePath}"`) || source.includes(`from '${modulePath}'`) || source.includes(`from \`${modulePath}\``);
|
|
291
|
+
}
|
|
292
|
+
function insertImportAfterLastImport(source, importLine) {
|
|
293
|
+
const trimmed = importLine.trim();
|
|
294
|
+
const moduleMatch = /from\s+["']([^"']+)["']/.exec(trimmed);
|
|
295
|
+
if (moduleMatch && hasImportFromModule(source, moduleMatch[1])) return source;
|
|
296
|
+
const lines = source.split("\n");
|
|
297
|
+
let lastImportIdx = -1;
|
|
298
|
+
for(let i = 0; i < lines.length; i++)if (lines[i].trim().startsWith("import ")) lastImportIdx = i;
|
|
299
|
+
if (-1 === lastImportIdx) return `${importLine}\n${source}`;
|
|
300
|
+
const next = [
|
|
301
|
+
...lines
|
|
302
|
+
];
|
|
303
|
+
next.splice(lastImportIdx + 1, 0, importLine);
|
|
304
|
+
return next.join("\n");
|
|
305
|
+
}
|
|
306
|
+
function pluginCallPresent(inner, call) {
|
|
307
|
+
const fn = call.replace(/\(\)$/, "");
|
|
308
|
+
return inner.includes(`${fn}(`);
|
|
309
|
+
}
|
|
310
|
+
function mergeCallsIntoPluginsArray(source, calls) {
|
|
311
|
+
const pluginsIdx = source.indexOf("plugins:");
|
|
312
|
+
if (-1 === pluginsIdx) return addPluginsBlockAfterManifest(source, calls);
|
|
313
|
+
const bracketStart = source.indexOf("[", pluginsIdx);
|
|
314
|
+
if (-1 === bracketStart) return source;
|
|
315
|
+
const bracketEnd = findMatchingArrayClose(source, bracketStart);
|
|
316
|
+
if (-1 === bracketEnd) return source;
|
|
317
|
+
let inner = source.slice(bracketStart + 1, bracketEnd).trim();
|
|
318
|
+
for (const c of calls)if (!pluginCallPresent(inner, c)) inner = inner ? `${inner}, ${c}` : c;
|
|
319
|
+
return source.slice(0, bracketStart + 1) + inner + source.slice(bracketEnd);
|
|
320
|
+
}
|
|
321
|
+
function addPluginsBlockAfterManifest(source, calls) {
|
|
322
|
+
const idx = source.indexOf(MANIFEST_LINE);
|
|
323
|
+
if (-1 === idx) return source;
|
|
324
|
+
const insertPos = idx + MANIFEST_LINE.length;
|
|
325
|
+
return `${source.slice(0, insertPos)}\n plugins: [${calls.join(", ")}],${source.slice(insertPos)}`;
|
|
326
|
+
}
|
|
327
|
+
function mergeScaffoldIntoAddfoxConfig(source, styleEngine) {
|
|
328
|
+
const st = getStylePlugin(styleEngine);
|
|
329
|
+
if (!st) return source;
|
|
330
|
+
let out = insertImportAfterLastImport(source, st.importLine);
|
|
331
|
+
out = mergeCallsIntoPluginsArray(out, [
|
|
332
|
+
st.call
|
|
333
|
+
]);
|
|
334
|
+
return out;
|
|
335
|
+
}
|
|
326
336
|
const UTF8_BOM = "\uFEFF";
|
|
327
337
|
function stripUtf8Bom(text) {
|
|
328
338
|
return text.startsWith(UTF8_BOM) ? text.slice(UTF8_BOM.length) : text;
|
|
@@ -941,21 +951,20 @@ async function main() {
|
|
|
941
951
|
if (!testSelection) process.exit(0);
|
|
942
952
|
const pm = options.packageManager;
|
|
943
953
|
const templateName = getTemplateName(options.framework, options.language);
|
|
944
|
-
const
|
|
945
|
-
const templateLabel =
|
|
946
|
-
const
|
|
954
|
+
const templateReady = hasLocalTemplate(templateName);
|
|
955
|
+
const templateLabel = "Copying template...";
|
|
956
|
+
const TEMPLATE_SPINNER_MIN_MS = 800;
|
|
947
957
|
try {
|
|
948
958
|
await runWithTemplateSpinner(templateLabel, async ()=>{
|
|
949
|
-
await new Promise((
|
|
950
|
-
setImmediate(
|
|
959
|
+
await new Promise((resolveSpinner)=>{
|
|
960
|
+
setImmediate(resolveSpinner);
|
|
951
961
|
});
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
minVisibleMs: LOCAL_TEMPLATE_SPINNER_MIN_MS
|
|
962
|
+
await copyBundledTemplate(templateName, root);
|
|
963
|
+
}, templateReady ? {
|
|
964
|
+
minVisibleMs: TEMPLATE_SPINNER_MIN_MS
|
|
956
965
|
} : void 0);
|
|
957
966
|
} catch (err) {
|
|
958
|
-
console.error(red(`\n Failed to
|
|
967
|
+
console.error(red(`\n Failed to copy template: ${err.message}\n`));
|
|
959
968
|
process.exit(1);
|
|
960
969
|
}
|
|
961
970
|
const useAllEntries = options.entries.includes("__all__");
|
|
@@ -966,7 +975,11 @@ async function main() {
|
|
|
966
975
|
if (!useAllEntries && effectiveEntries.length > 0) filterAppEntries(root, effectiveEntries);
|
|
967
976
|
const configExt = "ts" === options.language ? "ts" : "js";
|
|
968
977
|
const configPath = external_node_path_resolve(root, `addfox.config.${configExt}`);
|
|
969
|
-
|
|
978
|
+
let configContent;
|
|
979
|
+
if (existsSync(configPath)) {
|
|
980
|
+
const existing = readFileSync(configPath, "utf-8");
|
|
981
|
+
configContent = existing.trim().length > 0 && existing.includes("defineConfig") ? mergeScaffoldIntoAddfoxConfig(existing, options.styleEngine) : generateAddfoxConfig(options.framework, options.language, options.styleEngine);
|
|
982
|
+
} else configContent = generateAddfoxConfig(options.framework, options.language, options.styleEngine);
|
|
970
983
|
writeFileSync(configPath, configContent, "utf-8");
|
|
971
984
|
updatePackageName(root, targetDir);
|
|
972
985
|
applyStyleEngine(root, options.framework, options.language, options.styleEngine);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-addfox-app",
|
|
3
|
-
"version": "0.1.1-beta.
|
|
3
|
+
"version": "0.1.1-beta.12",
|
|
4
4
|
"description": "Interactive scaffolder for addfox extension projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
+
"templates",
|
|
12
13
|
"LICENSE"
|
|
13
14
|
],
|
|
14
15
|
"dependencies": {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Scaffold templates
|
|
2
|
+
|
|
3
|
+
Templates used by **create-addfox-app**. Each subdirectory (e.g. `template-vanilla-ts`, `template-react-ts`) is a full project skeleton. They live under this package and ship with the published npm tarball; the CLI copies the chosen folder into the new project directory.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineConfig } from "addfox";
|
|
2
|
+
import { pluginPreact } from "@rsbuild/plugin-preact";
|
|
3
|
+
|
|
4
|
+
const manifest = {
|
|
5
|
+
name: "My Extension",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
manifest_version: 3,
|
|
8
|
+
description: "Browser extension built with addfox",
|
|
9
|
+
permissions: ["activeTab"],
|
|
10
|
+
icons: {
|
|
11
|
+
"16": "icons/icon_128.png",
|
|
12
|
+
"48": "icons/icon_128.png",
|
|
13
|
+
"128": "icons/icon_128.png",
|
|
14
|
+
},
|
|
15
|
+
action: {
|
|
16
|
+
default_icon: {
|
|
17
|
+
"16": "icons/icon_128.png",
|
|
18
|
+
"48": "icons/icon_128.png",
|
|
19
|
+
"128": "icons/icon_128.png",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default defineConfig({
|
|
25
|
+
manifest: { chromium: manifest, firefox: { ...manifest } },
|
|
26
|
+
plugins: [pluginPreact()],
|
|
27
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function openWelcomePage() {
|
|
2
|
+
chrome.tabs.create({ url: chrome.runtime.getURL("welcome.html") });
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
chrome.runtime.onInstalled.addListener((details) => {
|
|
6
|
+
if (details.reason === "install" || details.reason === "update") openWelcomePage();
|
|
7
|
+
console.log("Extension installed");
|
|
8
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Content script loaded");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
|
|
3
|
+
export default function App() {
|
|
4
|
+
const popupStyle = {
|
|
5
|
+
width: 320,
|
|
6
|
+
minHeight: 200,
|
|
7
|
+
padding: 16,
|
|
8
|
+
boxSizing: "border-box",
|
|
9
|
+
display: "flex",
|
|
10
|
+
flexDirection: "column",
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
justifyContent: "center",
|
|
13
|
+
gap: 12,
|
|
14
|
+
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div style={popupStyle}>
|
|
19
|
+
<img src="/icons/icon_128.png" alt="" width={64} height={64} />
|
|
20
|
+
<div style={{ fontSize: 18, fontWeight: 600 }}>AddFox Preact</div>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-extension",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "addfox dev",
|
|
8
|
+
"build": "addfox build"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"addfox": "^0.1.1-beta.7",
|
|
12
|
+
"@rsbuild/core": "^1.7.3",
|
|
13
|
+
"@addfox/utils": "^0.1.1-beta.5",
|
|
14
|
+
"preact": "^10.29.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@rsbuild/plugin-preact": "^1.7.2"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Welcome - Addfox + Preact</title>
|
|
7
|
+
<style>
|
|
8
|
+
body { font-family: system-ui, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa; color: #1a1a1a; }
|
|
9
|
+
h1 { font-size: 1.75rem; font-weight: 700; margin: 0 0 0.5rem; }
|
|
10
|
+
p { font-size: 1rem; color: #666; margin: 0; }
|
|
11
|
+
.welcome-icon { width: 96px; height: 96px; margin-bottom: 1rem; object-fit: contain; border-radius: 12px; }
|
|
12
|
+
</style>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<img class="welcome-icon" src="/icons/icon_128.png" alt="" width="96" height="96" />
|
|
16
|
+
<h1>Addfox + Preact</h1>
|
|
17
|
+
<p>Your extension is ready. Happy building!</p>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineConfig } from "addfox";
|
|
2
|
+
import { pluginPreact } from "@rsbuild/plugin-preact";
|
|
3
|
+
|
|
4
|
+
const manifest = {
|
|
5
|
+
name: "My Extension",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
manifest_version: 3,
|
|
8
|
+
description: "Browser extension built with addfox",
|
|
9
|
+
permissions: ["activeTab"],
|
|
10
|
+
icons: {
|
|
11
|
+
"16": "icons/icon_128.png",
|
|
12
|
+
"48": "icons/icon_128.png",
|
|
13
|
+
"128": "icons/icon_128.png",
|
|
14
|
+
},
|
|
15
|
+
action: {
|
|
16
|
+
default_icon: {
|
|
17
|
+
"16": "icons/icon_128.png",
|
|
18
|
+
"48": "icons/icon_128.png",
|
|
19
|
+
"128": "icons/icon_128.png",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default defineConfig({
|
|
25
|
+
manifest: { chromium: manifest, firefox: { ...manifest } },
|
|
26
|
+
plugins: [pluginPreact()],
|
|
27
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function openWelcomePage() {
|
|
2
|
+
chrome.tabs.create({ url: chrome.runtime.getURL("welcome.html") });
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
chrome.runtime.onInstalled.addListener((details) => {
|
|
6
|
+
if (details.reason === "install" || details.reason === "update") openWelcomePage();
|
|
7
|
+
console.log("Extension installed");
|
|
8
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Content script loaded");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
|
|
3
|
+
export default function App() {
|
|
4
|
+
const popupStyle = {
|
|
5
|
+
width: 320,
|
|
6
|
+
minHeight: 200,
|
|
7
|
+
padding: 16,
|
|
8
|
+
boxSizing: "border-box" as const,
|
|
9
|
+
display: "flex",
|
|
10
|
+
flexDirection: "column" as const,
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
justifyContent: "center",
|
|
13
|
+
gap: 12,
|
|
14
|
+
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div style={popupStyle}>
|
|
19
|
+
<img src="/icons/icon_128.png" alt="" width={64} height={64} />
|
|
20
|
+
<div style={{ fontSize: 18, fontWeight: 600 }}>AddFox Preact</div>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-extension",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "addfox dev",
|
|
8
|
+
"build": "addfox build"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"addfox": "^0.1.1-beta.7",
|
|
12
|
+
"@rsbuild/core": "^1.7.3",
|
|
13
|
+
"@addfox/utils": "^0.1.1-beta.5",
|
|
14
|
+
"preact": "^10.29.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@rsbuild/plugin-preact": "^1.7.2",
|
|
18
|
+
"typescript": "^5.9.3",
|
|
19
|
+
"@types/chrome": "^0.1.38"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Welcome - Addfox + Preact</title>
|
|
7
|
+
<style>
|
|
8
|
+
body { font-family: system-ui, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa; color: #1a1a1a; }
|
|
9
|
+
h1 { font-size: 1.75rem; font-weight: 700; margin: 0 0 0.5rem; }
|
|
10
|
+
p { font-size: 1rem; color: #666; margin: 0; }
|
|
11
|
+
.welcome-icon { width: 96px; height: 96px; margin-bottom: 1rem; object-fit: contain; border-radius: 12px; }
|
|
12
|
+
</style>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<img class="welcome-icon" src="/icons/icon_128.png" alt="" width="96" height="96" />
|
|
16
|
+
<h1>Addfox + Preact</h1>
|
|
17
|
+
<p>Your extension is ready. Happy building!</p>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"isolatedModules": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"types": [
|
|
13
|
+
"chrome"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"include": [
|
|
17
|
+
"app"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineConfig } from "addfox";
|
|
2
|
+
import { pluginReact } from "@rsbuild/plugin-react";
|
|
3
|
+
|
|
4
|
+
const manifest = {
|
|
5
|
+
name: "My Extension",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
manifest_version: 3,
|
|
8
|
+
description: "Browser extension built with addfox",
|
|
9
|
+
permissions: ["activeTab"],
|
|
10
|
+
icons: {
|
|
11
|
+
"16": "icons/icon_128.png",
|
|
12
|
+
"48": "icons/icon_128.png",
|
|
13
|
+
"128": "icons/icon_128.png",
|
|
14
|
+
},
|
|
15
|
+
action: {
|
|
16
|
+
default_icon: {
|
|
17
|
+
"16": "icons/icon_128.png",
|
|
18
|
+
"48": "icons/icon_128.png",
|
|
19
|
+
"128": "icons/icon_128.png",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default defineConfig({
|
|
25
|
+
manifest: { chromium: manifest, firefox: { ...manifest } },
|
|
26
|
+
plugins: [pluginReact()],
|
|
27
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function openWelcomePage() {
|
|
2
|
+
chrome.tabs.create({ url: chrome.runtime.getURL("welcome.html") });
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
chrome.runtime.onInstalled.addListener((details) => {
|
|
6
|
+
if (details.reason === "install" || details.reason === "update") openWelcomePage();
|
|
7
|
+
console.log("Extension installed");
|
|
8
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Content script loaded");
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default function App() {
|
|
2
|
+
const popupStyle = {
|
|
3
|
+
width: 320,
|
|
4
|
+
minHeight: 200,
|
|
5
|
+
padding: 16,
|
|
6
|
+
boxSizing: "border-box",
|
|
7
|
+
display: "flex",
|
|
8
|
+
flexDirection: "column",
|
|
9
|
+
alignItems: "center",
|
|
10
|
+
justifyContent: "center",
|
|
11
|
+
gap: 12,
|
|
12
|
+
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div style={popupStyle}>
|
|
17
|
+
<img src="/icons/icon_128.png" alt="" width={64} height={64} />
|
|
18
|
+
<div style={{ fontSize: 18, fontWeight: 600 }}>AddFox React</div>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|