diff --git a/packages/wxt/e2e/tests/output-structure.test.ts b/packages/wxt/e2e/tests/output-structure.test.ts index 2ff8aab1..260157ae 100644 --- a/packages/wxt/e2e/tests/output-structure.test.ts +++ b/packages/wxt/e2e/tests/output-structure.test.ts @@ -362,7 +362,7 @@ describe('Output Directory Structure', () => { .toMatchInlineSnapshot(` ".output/chrome-mv3/background.js ---------------------------------------- - var _background = function() { + var background = function() { "use strict"; var _a, _b; function defineBackground(arg) { @@ -372,13 +372,13 @@ describe('Output Directory Structure', () => { function logHello(name) { console.log(\`Hello \${name}!\`); } - _background; + background; const definition = defineBackground({ main() { logHello("background"); } }); - _background; + background; function initPlugins() { } // @ts-expect-error @@ -411,7 +411,7 @@ describe('Output Directory Structure', () => { const result$1 = result; return result$1; }(); - _background; + background; " `); }); diff --git a/packages/wxt/package.json b/packages/wxt/package.json index 5652a97d..7da3eb74 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -118,6 +118,7 @@ "picocolors": "^1.0.1", "prompts": "^2.4.2", "publish-browser-extension": "^2.1.3", + "scule": "^1.3.0", "unimport": "^3.9.1", "vite": "^5.3.5", "vite-node": "^2.0.4", diff --git a/packages/wxt/src/core/utils/__tests__/strings.test.ts b/packages/wxt/src/core/utils/__tests__/strings.test.ts index 8974b64c..f1dbce8b 100644 --- a/packages/wxt/src/core/utils/__tests__/strings.test.ts +++ b/packages/wxt/src/core/utils/__tests__/strings.test.ts @@ -21,9 +21,10 @@ describe('String utils', () => { describe('safeVarName', () => { it.each([ - ['Hello world!', '_hello_world'], + ['Hello world!', 'helloWorld'], ['123', '_123'], - ['abc-123', '_abc_123'], + ['abc-123', 'abc123'], + ['abc-123-xyz', 'abc123Xyz'], ['', '_'], [' ', '_'], ['_', '_'], diff --git a/packages/wxt/src/core/utils/strings.ts b/packages/wxt/src/core/utils/strings.ts index 1e3df534..b48b7995 100644 --- a/packages/wxt/src/core/utils/strings.ts +++ b/packages/wxt/src/core/utils/strings.ts @@ -1,3 +1,5 @@ +import { camelCase } from 'scule'; + export function kebabCaseAlphanumeric(str: string): string { return str .toLowerCase() @@ -9,8 +11,17 @@ export function kebabCaseAlphanumeric(str: string): string { * Return a safe variable name for a given string. */ export function safeVarName(str: string): string { - // _ prefix to ensure it doesn't start with a number - return '_' + kebabCaseAlphanumeric(str.trim()).replace('-', '_'); + const name = camelCase(kebabCaseAlphanumeric(str)); + if (name.match(/^[a-z]/)) return name; + // _ prefix to ensure it doesn't start with a number or other invalid symbol + return '_' + name; +} + +/** + * Converts a string to a valid filename (NOT path), stripping out invalid characters. + */ +export function safeFilename(str: string): string { + return kebabCaseAlphanumeric(str); } /** diff --git a/packages/wxt/src/core/zip.ts b/packages/wxt/src/core/zip.ts index 534994fb..9226a48f 100644 --- a/packages/wxt/src/core/zip.ts +++ b/packages/wxt/src/core/zip.ts @@ -1,7 +1,7 @@ import { InlineConfig } from '../types'; import path from 'node:path'; import fs from 'fs-extra'; -import { kebabCaseAlphanumeric } from './utils/strings'; +import { safeFilename } from './utils/strings'; import { getPackageJson } from './utils/package'; import { minimatch } from 'minimatch'; import { formatDuration } from './utils/time'; @@ -27,9 +27,7 @@ export async function zip(config?: InlineConfig): Promise { const projectName = wxt.config.zip.name ?? - kebabCaseAlphanumeric( - (await getPackageJson())?.name || path.dirname(process.cwd()), - ); + safeFilename((await getPackageJson())?.name || path.dirname(process.cwd())); const applyTemplate = (template: string): string => template .replaceAll('{{name}}', projectName) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c5d1736..fcb3fedb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -374,6 +374,9 @@ importers: publish-browser-extension: specifier: ^2.1.3 version: 2.1.3 + scule: + specifier: ^1.3.0 + version: 1.3.0 unimport: specifier: ^3.9.1 version: 3.9.1(rollup@4.19.0)