extension-create 4.1.12 → 4.1.14
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/dist/lib/messages.d.ts +5 -1
- package/dist/lib/package-manager.d.ts +3 -0
- package/dist/module.cjs +223 -39
- package/dist/steps/import-external-template.d.ts +3 -0
- package/dist/steps/install-dependencies.d.ts +2 -1
- package/dist/steps/write-package-json.d.ts +4 -1
- package/dist/test-template-javascript/.extension-create.json +4 -3
- package/dist/test-template-javascript/STORE.md +2 -2
- package/dist/test-template-javascript/extension.config.js +4 -8
- package/dist/test-template-javascript/package.json +4 -3
- package/dist/test-template-javascript/src/{background.js → background.ts} +3 -3
- package/dist/test-template-javascript/src/content/{ContentApp.js → ContentApp.ts} +7 -12
- package/dist/test-template-javascript/src/content/{scripts.js → scripts.ts} +1 -1
- package/dist/test-template-javascript/src/content/types.d.ts +15 -0
- package/dist/test-template-javascript/src/images/icon.png +0 -0
- package/dist/test-template-javascript/src/manifest.json +3 -3
- package/dist/test-template-javascript/src/sidebar/{SidebarApp.js → SidebarApp.ts} +3 -4
- package/dist/test-template-javascript/src/sidebar/index.html +2 -2
- package/dist/test-template-javascript/src/sidebar/{scripts.js → scripts.ts} +1 -1
- package/dist/test-template-javascript/tsconfig.json +24 -0
- package/package.json +1 -1
package/dist/lib/messages.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { type ScaffoldPackageManager } from './package-manager';
|
|
1
2
|
export declare function destinationNotWriteable(workingDir: string): string;
|
|
2
3
|
export declare function directoryHasConflicts(projectPath: string, conflictingFiles: string[]): Promise<string>;
|
|
3
4
|
export declare function noProjectName(): string;
|
|
4
5
|
export declare function noUrlAllowed(): string;
|
|
5
|
-
export declare function scaffoldReady(projectPath: string, projectName: string, depsInstalled: boolean): Promise<string>;
|
|
6
|
+
export declare function scaffoldReady(projectPath: string, projectName: string, depsInstalled: boolean, packageManager?: ScaffoldPackageManager): Promise<string>;
|
|
6
7
|
export declare function startingNewExtension(projectName: string): string;
|
|
7
8
|
export declare function createDirectoryError(projectName: string, error: unknown): string;
|
|
8
9
|
export declare function writingTypeDefinitions(projectName: string): string;
|
|
@@ -13,6 +14,7 @@ export declare function installingFromTemplateError(template: string, error: unk
|
|
|
13
14
|
export declare function templateFetchTimedOut(templateName: string, ms: number): string;
|
|
14
15
|
export declare function templateNotFoundInCatalog(templateName: string, error?: unknown): string;
|
|
15
16
|
export declare function templateDownloadFailed(templateName: string, error: unknown): string;
|
|
17
|
+
export declare function templateOfflineFallback(requestedTemplate: string, fallbackTemplate: string, error: unknown): string;
|
|
16
18
|
export declare function removedStaleTemplateLockfiles(fileNames: string[]): string;
|
|
17
19
|
export declare function initializingGitForRepository(projectName: string): string;
|
|
18
20
|
export declare function initializingGitSkipped(projectName: string, reason: string): string;
|
|
@@ -39,3 +41,5 @@ export declare function writingGitIgnore(): string;
|
|
|
39
41
|
export declare function writingReadmeMetaDataError(error: unknown): string;
|
|
40
42
|
export declare function writingDirectoryError(error: unknown): string;
|
|
41
43
|
export declare function cantSetupBuiltInTests(error: unknown): string;
|
|
44
|
+
export declare function keepingExistingGitignore(projectName: string): string;
|
|
45
|
+
export declare function existingRepositoryKept(projectName: string): string;
|
|
@@ -5,3 +5,6 @@ export declare function detectPackageManagerFromEnv(): NodePackageManager;
|
|
|
5
5
|
export declare function isDenoRuntime(): boolean;
|
|
6
6
|
export type ScaffoldPackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun' | 'deno';
|
|
7
7
|
export declare function resolveScaffoldPackageManager(): ScaffoldPackageManager;
|
|
8
|
+
export declare function resolveProjectPackageManager(projectPath: string): ScaffoldPackageManager;
|
|
9
|
+
export declare function readPinnedPackageManager(projectPath: string): NodePackageManager | undefined;
|
|
10
|
+
export declare function resolvePackageManagerSpec(projectPath: string, manager: ScaffoldPackageManager): string | undefined;
|
package/dist/module.cjs
CHANGED
|
@@ -117,6 +117,8 @@ new Set([
|
|
|
117
117
|
'librewolf',
|
|
118
118
|
'waterfox'
|
|
119
119
|
]);
|
|
120
|
+
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
121
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
120
122
|
const external_prefers_yarn_namespaceObject = require("prefers-yarn");
|
|
121
123
|
const NODE_PACKAGE_MANAGERS = [
|
|
122
124
|
'pnpm',
|
|
@@ -138,6 +140,48 @@ function resolveScaffoldPackageManager() {
|
|
|
138
140
|
if (isDenoRuntime()) return 'deno';
|
|
139
141
|
return detectPackageManagerFromEnv();
|
|
140
142
|
}
|
|
143
|
+
function resolveProjectPackageManager(projectPath) {
|
|
144
|
+
if (isDenoRuntime()) return 'deno';
|
|
145
|
+
const pinned = readPinnedPackageManager(projectPath);
|
|
146
|
+
if (pinned) return pinned;
|
|
147
|
+
if (external_node_fs_namespaceObject.existsSync(external_node_path_namespaceObject.join(projectPath, 'pnpm-workspace.yaml'))) return 'pnpm';
|
|
148
|
+
return detectPackageManagerFromEnv();
|
|
149
|
+
}
|
|
150
|
+
function readPinnedPackageManager(projectPath) {
|
|
151
|
+
try {
|
|
152
|
+
const raw = external_node_fs_namespaceObject.readFileSync(external_node_path_namespaceObject.join(projectPath, 'package.json'), 'utf8');
|
|
153
|
+
const pin = String(JSON.parse(raw)?.packageManager || '');
|
|
154
|
+
const name = pin.split('@')[0].toLowerCase();
|
|
155
|
+
return NODE_PACKAGE_MANAGERS.includes(name) ? name : void 0;
|
|
156
|
+
} catch {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function resolvePackageManagerSpec(projectPath, manager) {
|
|
161
|
+
if ('deno' === manager) return;
|
|
162
|
+
try {
|
|
163
|
+
const raw = external_node_fs_namespaceObject.readFileSync(external_node_path_namespaceObject.join(projectPath, 'package.json'), 'utf8');
|
|
164
|
+
const pin = String(JSON.parse(raw)?.packageManager || '');
|
|
165
|
+
if (pin.toLowerCase().startsWith(`${manager}@`)) return pin;
|
|
166
|
+
} catch {}
|
|
167
|
+
const fromEnv = (0, external_prefers_yarn_namespaceObject.getPackageManagerSpec)();
|
|
168
|
+
if (fromEnv && fromEnv.startsWith(`${manager}@`)) return fromEnv;
|
|
169
|
+
try {
|
|
170
|
+
const version = (0, external_node_child_process_namespaceObject.execFileSync)(manager, [
|
|
171
|
+
'--version'
|
|
172
|
+
], {
|
|
173
|
+
encoding: 'utf8',
|
|
174
|
+
stdio: [
|
|
175
|
+
'ignore',
|
|
176
|
+
'pipe',
|
|
177
|
+
'ignore'
|
|
178
|
+
],
|
|
179
|
+
timeout: 5000,
|
|
180
|
+
shell: 'win32' === process.platform
|
|
181
|
+
}).trim().replace(/^v/, '');
|
|
182
|
+
if (/^\d+\.\d+\.\d+/.test(version)) return `${manager}@${version}`;
|
|
183
|
+
} catch {}
|
|
184
|
+
}
|
|
141
185
|
function destinationNotWriteable(workingDir) {
|
|
142
186
|
const workingDirFolder = external_node_path_namespaceObject.basename(workingDir);
|
|
143
187
|
return `${prefix('error')} Couldn't write to the destination directory.\n${fmt.label('PATH')} ${fmt.val(workingDirFolder)}\n${external_pintor_default().red('Choose a writable path, or update the folder permissions.')}`;
|
|
@@ -155,9 +199,9 @@ function noProjectName() {
|
|
|
155
199
|
function noUrlAllowed() {
|
|
156
200
|
return `${prefix('error')} A URL is not a valid project path.\n${external_pintor_default().red('Pass a project name or a local directory path.')}`;
|
|
157
201
|
}
|
|
158
|
-
async function scaffoldReady(projectPath, projectName, depsInstalled) {
|
|
202
|
+
async function scaffoldReady(projectPath, projectName, depsInstalled, packageManager) {
|
|
159
203
|
const relativePath = external_node_path_namespaceObject.relative(process.cwd(), projectPath);
|
|
160
|
-
const pm = resolveScaffoldPackageManager();
|
|
204
|
+
const pm = packageManager ?? resolveScaffoldPackageManager();
|
|
161
205
|
let command = 'npm run dev';
|
|
162
206
|
let installCmd = 'npm install';
|
|
163
207
|
switch(pm){
|
|
@@ -217,6 +261,9 @@ function templateNotFoundInCatalog(templateName, error) {
|
|
|
217
261
|
function templateDownloadFailed(templateName, error) {
|
|
218
262
|
return `${prefix('error')} Couldn't download the template ${external_pintor_default().blue(templateName)} from ${fmt.val('github.com/extension-js/examples')}.\n${fmt.label('REASON')} ${fmt.val(fmt.truncate(String(error?.message || error)))}\n${external_pintor_default().red('- Check your network connection and any GitHub rate limit, then try again.')}\n${external_pintor_default().red('- Set')} ${external_pintor_default().blue('EXTENSION_CREATE_TIMEOUT_MS')} ${external_pintor_default().red('to allow more time.')}`;
|
|
219
263
|
}
|
|
264
|
+
function templateOfflineFallback(requestedTemplate, fallbackTemplate, error) {
|
|
265
|
+
return `${prefix('info')} Couldn't download the template ${external_pintor_default().blue(requestedTemplate)} from ${fmt.val('github.com/extension-js/examples')}, so this scaffold uses the offline ${external_pintor_default().blue(fallbackTemplate)} template instead.\n${fmt.label('REASON')} ${fmt.val(fmt.truncate(String(error?.message || error)))}\n${external_pintor_default().gray('- Reconnect and run')} ${external_pintor_default().blue(`extension create --template ${requestedTemplate}`)} ${external_pintor_default().gray('to scaffold it.')}`;
|
|
266
|
+
}
|
|
220
267
|
function removedStaleTemplateLockfiles(fileNames) {
|
|
221
268
|
return `${prefix('info')} Removed the template ${fileNames.map((name)=>fmt.val(name)).join(', ')}. The first install writes a fresh one.`;
|
|
222
269
|
}
|
|
@@ -302,6 +349,12 @@ function writingDirectoryError(error) {
|
|
|
302
349
|
function cantSetupBuiltInTests(error) {
|
|
303
350
|
return `${prefix('error')} Couldn't set up the built-in tests.\n${fmt.label('REASON')} ${fmt.val(fmt.truncate(String(error)))}\n${external_pintor_default().red('The extension itself is fine. Re-run')} ${external_pintor_default().blue('extension create')}${external_pintor_default().red(', or skip the tests.')}`;
|
|
304
351
|
}
|
|
352
|
+
function keepingExistingGitignore(projectName) {
|
|
353
|
+
return `${prefix('info')} ${external_pintor_default().blue(projectName)} already has a ${external_pintor_default().blue('.gitignore')}.\nKeeping its rules and adding the template rules it lacks.`;
|
|
354
|
+
}
|
|
355
|
+
function existingRepositoryKept(projectName) {
|
|
356
|
+
return `${prefix('info')} ${external_pintor_default().blue(projectName)} is already a git repository with history.\nLeft it uncommitted. Review the scaffold and run ${external_pintor_default().blue('git add -A && git commit')} yourself.`;
|
|
357
|
+
}
|
|
305
358
|
const promises_namespaceObject = require("node:fs/promises");
|
|
306
359
|
async function copyDirectoryWithSymlinks(source, destination) {
|
|
307
360
|
const entries = await promises_namespaceObject.readdir(source, {
|
|
@@ -386,11 +439,13 @@ async function isDirectoryWriteable(directory, logger) {
|
|
|
386
439
|
function isTypeScriptTemplate(templateName) {
|
|
387
440
|
return templateName.includes("typescript") || templateName.includes('react') || templateName.includes('preact') || templateName.includes('svelte') || templateName.includes('solid');
|
|
388
441
|
}
|
|
389
|
-
const external_node_fs_namespaceObject = require("node:fs");
|
|
390
442
|
const allowlist = [
|
|
391
443
|
'LICENSE',
|
|
392
444
|
'node_modules'
|
|
393
445
|
];
|
|
446
|
+
const HIDDEN_FILES_TEMPLATES_SHIP = [
|
|
447
|
+
'.gitignore'
|
|
448
|
+
];
|
|
394
449
|
async function createDirectory(projectPath, projectName, logger) {
|
|
395
450
|
logger.log(startingNewExtension(projectName));
|
|
396
451
|
const directoryPreExisted = (0, external_node_fs_namespaceObject.existsSync)(projectPath);
|
|
@@ -409,6 +464,7 @@ async function createDirectory(projectPath, projectName, logger) {
|
|
|
409
464
|
const conflictMessage = await directoryHasConflicts(projectPath, conflictingFiles);
|
|
410
465
|
throw new Error(conflictMessage);
|
|
411
466
|
}
|
|
467
|
+
for (const hidden of HIDDEN_FILES_TEMPLATES_SHIP)if (currentDir.includes(hidden)) logger.log(keepingExistingGitignore(projectName));
|
|
412
468
|
} catch (error) {
|
|
413
469
|
throw new Error(createDirectoryError(projectName, error));
|
|
414
470
|
}
|
|
@@ -416,10 +472,67 @@ async function createDirectory(projectPath, projectName, logger) {
|
|
|
416
472
|
directoryCreated: !directoryPreExisted
|
|
417
473
|
};
|
|
418
474
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
475
|
+
const EXTENSION_ENV_TYPES_PACKAGE = 'extension';
|
|
476
|
+
const STYLE_TYPE = 'Readonly<Record<string, string>>';
|
|
477
|
+
const EXTENSION_ENV_WILDCARD_MODULES = Object.freeze([
|
|
478
|
+
{
|
|
479
|
+
pattern: '*.css',
|
|
480
|
+
type: STYLE_TYPE
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
pattern: '*.module.css',
|
|
484
|
+
type: STYLE_TYPE
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
pattern: '*.module.scss',
|
|
488
|
+
type: STYLE_TYPE
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
pattern: '*.module.sass',
|
|
492
|
+
type: STYLE_TYPE
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
pattern: '*.png',
|
|
496
|
+
type: 'string'
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
pattern: '*.jpg',
|
|
500
|
+
type: 'string'
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
pattern: '*.jpeg',
|
|
504
|
+
type: 'string'
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
pattern: '*.gif',
|
|
508
|
+
type: 'string'
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
pattern: '*.webp',
|
|
512
|
+
type: 'string'
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
pattern: '*.avif',
|
|
516
|
+
type: 'string'
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
pattern: '*.ico',
|
|
520
|
+
type: 'string'
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
pattern: '*.bmp',
|
|
524
|
+
type: 'string'
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
pattern: '*.svg',
|
|
528
|
+
type: 'any'
|
|
529
|
+
}
|
|
530
|
+
]);
|
|
531
|
+
function renderWildcardModuleDeclarations(modules = EXTENSION_ENV_WILDCARD_MODULES) {
|
|
532
|
+
return modules.map(({ pattern, type })=>`declare module '${pattern}' {\n const content: ${type}\n export default content\n}\n`).join('');
|
|
533
|
+
}
|
|
534
|
+
function renderExtensionEnvTypes(typePath = EXTENSION_ENV_TYPES_PACKAGE) {
|
|
535
|
+
return `\
|
|
423
536
|
// Required Extension.js types for TypeScript projects.
|
|
424
537
|
// This file is auto-generated and should not be excluded.
|
|
425
538
|
// If you need additional types, consider creating a new *.d.ts file and
|
|
@@ -429,7 +542,15 @@ async function generateExtensionTypes(projectPath, projectName, logger) {
|
|
|
429
542
|
|
|
430
543
|
// Polyfill types for browser.* APIs
|
|
431
544
|
/// <reference types="${typePath}/types/polyfill" />
|
|
432
|
-
|
|
545
|
+
|
|
546
|
+
// Asset and stylesheet imports. These wildcard declarations also live in
|
|
547
|
+
// ${typePath}/types, but TypeScript 7 native does not apply them through the
|
|
548
|
+
// reference above, so they are emitted here as well.
|
|
549
|
+
${renderWildcardModuleDeclarations()}`;
|
|
550
|
+
}
|
|
551
|
+
async function generateExtensionTypes(projectPath, projectName, logger) {
|
|
552
|
+
const extensionEnvFile = external_node_path_namespaceObject.join(projectPath, 'extension-env.d.ts');
|
|
553
|
+
const fileContent = renderExtensionEnvTypes();
|
|
433
554
|
try {
|
|
434
555
|
await promises_namespaceObject.mkdir(projectPath, {
|
|
435
556
|
recursive: true
|
|
@@ -489,6 +610,8 @@ const DEFAULT_TEMPLATES_REF = 'cb6a25377bd9516a1e55447a2010537019851ab2';
|
|
|
489
610
|
const BUNDLED_TEMPLATES = [
|
|
490
611
|
"javascript"
|
|
491
612
|
];
|
|
613
|
+
const DEFAULT_TEMPLATE_NAME = "typescript";
|
|
614
|
+
const OFFLINE_FALLBACK_TEMPLATE = "javascript";
|
|
492
615
|
function resolveCatalogUrls(ref, overrideUrl) {
|
|
493
616
|
if (overrideUrl) return [
|
|
494
617
|
overrideUrl
|
|
@@ -640,6 +763,19 @@ async function withSuppressedOutput(task) {
|
|
|
640
763
|
function bundledTemplateDir(templateName) {
|
|
641
764
|
return external_node_path_namespaceObject.join(__dirname, '..', 'templates', templateName);
|
|
642
765
|
}
|
|
766
|
+
async function copyBundledTemplate(templateName, projectPath, logger, ownerGitignore = null) {
|
|
767
|
+
const localTemplate = bundledTemplateDir(templateName);
|
|
768
|
+
if (!(0, external_node_fs_namespaceObject.existsSync)(localTemplate)) return;
|
|
769
|
+
await copyDirectoryWithSymlinks(localTemplate, projectPath);
|
|
770
|
+
await restoreOwnerGitignore(projectPath, ownerGitignore);
|
|
771
|
+
await removeTemplateScaffoldingFiles(projectPath);
|
|
772
|
+
const dropped = await removeStaleTemplateLockfiles(projectPath);
|
|
773
|
+
if (dropped.length) logger.log(removedStaleTemplateLockfiles(dropped));
|
|
774
|
+
return {
|
|
775
|
+
template: templateName,
|
|
776
|
+
source: 'bundled'
|
|
777
|
+
};
|
|
778
|
+
}
|
|
643
779
|
const TEMPLATE_SCAFFOLDING_FILES = [
|
|
644
780
|
'template.meta.json',
|
|
645
781
|
'template.spec.ts',
|
|
@@ -711,6 +847,28 @@ async function cleanupFailedImport(projectPath, ownsProjectDir, preExistingEntri
|
|
|
711
847
|
force: true
|
|
712
848
|
}).catch(()=>{})));
|
|
713
849
|
}
|
|
850
|
+
async function readOwnerGitignore(projectPath) {
|
|
851
|
+
try {
|
|
852
|
+
return await promises_namespaceObject.readFile(external_node_path_namespaceObject.join(projectPath, '.gitignore'), 'utf8');
|
|
853
|
+
} catch {
|
|
854
|
+
return null;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
async function restoreOwnerGitignore(projectPath, ownerContents) {
|
|
858
|
+
if (null === ownerContents) return;
|
|
859
|
+
const target = external_node_path_namespaceObject.join(projectPath, '.gitignore');
|
|
860
|
+
let templateContents = '';
|
|
861
|
+
try {
|
|
862
|
+
templateContents = await promises_namespaceObject.readFile(target, 'utf8');
|
|
863
|
+
} catch {
|
|
864
|
+
await promises_namespaceObject.writeFile(target, ownerContents);
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const ownerLines = new Set(ownerContents.split(/\r?\n/).map((line)=>line.trim()));
|
|
868
|
+
const added = templateContents.split(/\r?\n/).filter((line)=>line.trim().length > 0 && !ownerLines.has(line.trim()));
|
|
869
|
+
const merged = 0 === added.length ? ownerContents : `${ownerContents.replace(/\n?$/, '\n')}\n# Extension.js template rules\n${added.join('\n')}\n`;
|
|
870
|
+
await promises_namespaceObject.writeFile(target, merged);
|
|
871
|
+
}
|
|
714
872
|
async function importExternalTemplate(projectPath, projectName, template, logger, options) {
|
|
715
873
|
const templateName = external_node_path_namespaceObject.basename(template);
|
|
716
874
|
const resolvedTemplate = template;
|
|
@@ -724,22 +882,14 @@ async function importExternalTemplate(projectPath, projectName, template, logger
|
|
|
724
882
|
if (dirExistedBeforeImport) try {
|
|
725
883
|
preExistingEntries = await promises_namespaceObject.readdir(projectPath);
|
|
726
884
|
} catch {}
|
|
885
|
+
const ownerGitignore = dirExistedBeforeImport ? await readOwnerGitignore(projectPath) : null;
|
|
727
886
|
try {
|
|
728
887
|
await promises_namespaceObject.mkdir(projectPath, {
|
|
729
888
|
recursive: true
|
|
730
889
|
});
|
|
731
890
|
if (!isHttp && !isGithub && BUNDLED_TEMPLATES.includes(resolvedTemplate)) {
|
|
732
|
-
const
|
|
733
|
-
if (
|
|
734
|
-
await copyDirectoryWithSymlinks(localTemplate, projectPath);
|
|
735
|
-
await removeTemplateScaffoldingFiles(projectPath);
|
|
736
|
-
const dropped = await removeStaleTemplateLockfiles(projectPath);
|
|
737
|
-
if (dropped.length) logger.log(removedStaleTemplateLockfiles(dropped));
|
|
738
|
-
return {
|
|
739
|
-
template: resolvedTemplateName,
|
|
740
|
-
source: 'bundled'
|
|
741
|
-
};
|
|
742
|
-
}
|
|
891
|
+
const provenance = await copyBundledTemplate(resolvedTemplate, projectPath, logger, ownerGitignore);
|
|
892
|
+
if (provenance) return provenance;
|
|
743
893
|
}
|
|
744
894
|
const tempRoot = await promises_namespaceObject.mkdtemp(external_node_path_namespaceObject.join(external_node_os_namespaceObject.tmpdir(), 'extension-js-create-'));
|
|
745
895
|
const tempPath = external_node_path_namespaceObject.join(tempRoot, `${projectName}-temp`);
|
|
@@ -803,6 +953,7 @@ async function importExternalTemplate(projectPath, projectName, template, logger
|
|
|
803
953
|
} : {}
|
|
804
954
|
};
|
|
805
955
|
}
|
|
956
|
+
await restoreOwnerGitignore(projectPath, ownerGitignore);
|
|
806
957
|
await removeTemplateScaffoldingFiles(projectPath);
|
|
807
958
|
const droppedLockfiles = await removeStaleTemplateLockfiles(projectPath);
|
|
808
959
|
if (droppedLockfiles.length) logger.log(removedStaleTemplateLockfiles(droppedLockfiles));
|
|
@@ -812,6 +963,17 @@ async function importExternalTemplate(projectPath, projectName, template, logger
|
|
|
812
963
|
});
|
|
813
964
|
return provenance;
|
|
814
965
|
} catch (error) {
|
|
966
|
+
if (error instanceof TemplateDownloadError && options?.allowOfflineFallback && resolvedTemplate !== OFFLINE_FALLBACK_TEMPLATE && BUNDLED_TEMPLATES.includes(OFFLINE_FALLBACK_TEMPLATE)) {
|
|
967
|
+
await cleanupFailedImport(projectPath, ownsProjectDir, preExistingEntries);
|
|
968
|
+
await promises_namespaceObject.mkdir(projectPath, {
|
|
969
|
+
recursive: true
|
|
970
|
+
});
|
|
971
|
+
const fallback = await copyBundledTemplate(OFFLINE_FALLBACK_TEMPLATE, projectPath, logger, ownerGitignore);
|
|
972
|
+
if (fallback) {
|
|
973
|
+
logger.log(templateOfflineFallback(resolvedTemplateName, OFFLINE_FALLBACK_TEMPLATE, error));
|
|
974
|
+
return fallback;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
815
977
|
if (error instanceof TemplateNotFoundError) logger.error(templateNotFoundInCatalog(templateName, error.cause));
|
|
816
978
|
else if (error instanceof TemplateDownloadError) logger.error(templateDownloadFailed(templateName, error));
|
|
817
979
|
else logger.error(installingFromTemplateError(templateName, error));
|
|
@@ -887,8 +1049,22 @@ async function runGit(args, projectPath) {
|
|
|
887
1049
|
});
|
|
888
1050
|
});
|
|
889
1051
|
}
|
|
1052
|
+
async function hasCommittedHistory(projectPath) {
|
|
1053
|
+
const inside = await runGit([
|
|
1054
|
+
'rev-parse',
|
|
1055
|
+
'--is-inside-work-tree'
|
|
1056
|
+
], projectPath);
|
|
1057
|
+
if (!inside.ok) return false;
|
|
1058
|
+
const head = await runGit([
|
|
1059
|
+
'rev-parse',
|
|
1060
|
+
'--verify',
|
|
1061
|
+
'HEAD'
|
|
1062
|
+
], projectPath);
|
|
1063
|
+
return head.ok;
|
|
1064
|
+
}
|
|
890
1065
|
async function initializeGitRepository(projectPath, projectName, templateName, logger) {
|
|
891
1066
|
if (isDebug()) logger.log(initializingGitForRepository(projectName));
|
|
1067
|
+
if (await hasCommittedHistory(projectPath)) return void logger.log(existingRepositoryKept(projectName));
|
|
892
1068
|
const init = await runGit([
|
|
893
1069
|
'init',
|
|
894
1070
|
'--quiet'
|
|
@@ -1187,11 +1363,11 @@ async function hasDependenciesToInstall(projectPath) {
|
|
|
1187
1363
|
const devDepsCount = Object.keys(packageJson?.devDependencies || {}).length;
|
|
1188
1364
|
return depsCount + devDepsCount > 0;
|
|
1189
1365
|
}
|
|
1190
|
-
async function installDependencies(projectPath, projectName, logger) {
|
|
1366
|
+
async function installDependencies(projectPath, projectName, logger, packageManager) {
|
|
1191
1367
|
const nodeModulesPath = external_node_path_namespaceObject.join(projectPath, 'node_modules');
|
|
1192
1368
|
const shouldInstall = await hasDependenciesToInstall(projectPath);
|
|
1193
1369
|
if (!shouldInstall) return;
|
|
1194
|
-
const command = isDenoRuntime() ? 'deno' : await getInstallCommand();
|
|
1370
|
+
const command = packageManager ?? (isDenoRuntime() ? 'deno' : await getInstallCommand());
|
|
1195
1371
|
const dependenciesArgs = 'deno' === command ? [
|
|
1196
1372
|
'install'
|
|
1197
1373
|
] : getInstallArgs(command);
|
|
@@ -1515,7 +1691,8 @@ function resolveExtensionDevDependencyVersion(cliVersion) {
|
|
|
1515
1691
|
if (!resolved) return 'latest';
|
|
1516
1692
|
return resolved.includes('-') ? resolved : `^${resolved}`;
|
|
1517
1693
|
}
|
|
1518
|
-
async function overridePackageJson(projectPath,
|
|
1694
|
+
async function overridePackageJson(projectPath, options, logger) {
|
|
1695
|
+
const { template = "javascript", cliVersion } = options;
|
|
1519
1696
|
const extensionBinary = await resolveExtensionBinary();
|
|
1520
1697
|
const candidatePath = external_node_path_namespaceObject.join(projectPath, 'package.json');
|
|
1521
1698
|
let packageJson = {};
|
|
@@ -1537,7 +1714,8 @@ async function overridePackageJson(projectPath, { template = "javascript", cliVe
|
|
|
1537
1714
|
...packageJson.devDependencies || {},
|
|
1538
1715
|
extension: 'development' === process.env.EXTENSION_ENV ? '*' : resolveExtensionDevDependencyVersion(cliVersion)
|
|
1539
1716
|
};
|
|
1540
|
-
const
|
|
1717
|
+
const packageManager = options.packageManager ?? resolveProjectPackageManager(projectPath);
|
|
1718
|
+
const packageManagerSpec = resolvePackageManagerSpec(projectPath, packageManager);
|
|
1541
1719
|
const declaredDeps = {
|
|
1542
1720
|
...packageJson.dependencies || {},
|
|
1543
1721
|
...packageJson.devDependencies || {}
|
|
@@ -1545,7 +1723,7 @@ async function overridePackageJson(projectPath, { template = "javascript", cliVe
|
|
|
1545
1723
|
const usesMlNativeDeps = ML_DEP_TRIGGERS.some((dep)=>declaredDeps[dep]);
|
|
1546
1724
|
const nativeBuildDeps = usesMlNativeDeps ? ML_NATIVE_BUILD_DEPENDENCIES : [];
|
|
1547
1725
|
const existingPnpm = packageJson.pnpm && 'object' == typeof packageJson.pnpm ? packageJson.pnpm : {};
|
|
1548
|
-
const installsWithPnpm =
|
|
1726
|
+
const installsWithPnpm = 'pnpm' === packageManager;
|
|
1549
1727
|
const ignoredBuilt = uniq([
|
|
1550
1728
|
...existingPnpm.ignoredBuiltDependencies || [],
|
|
1551
1729
|
...installsWithPnpm ? BUILD_NOOP_DEPENDENCIES : []
|
|
@@ -1700,7 +1878,7 @@ const globalMisc = [
|
|
|
1700
1878
|
];
|
|
1701
1879
|
const localSessionState = [
|
|
1702
1880
|
'',
|
|
1703
|
-
'#
|
|
1881
|
+
'# Extension.js local session state',
|
|
1704
1882
|
'.extension-js'
|
|
1705
1883
|
];
|
|
1706
1884
|
const envFiles = [
|
|
@@ -1919,14 +2097,16 @@ async function writeTemplateProvenance(projectPath, provenance, logger) {
|
|
|
1919
2097
|
logger.error(writingTemplateProvenanceError(error));
|
|
1920
2098
|
}
|
|
1921
2099
|
}
|
|
1922
|
-
async function extensionCreate(projectNameInput, { cliVersion, template
|
|
2100
|
+
async function extensionCreate(projectNameInput, { cliVersion, template, install = false, logger = console }) {
|
|
1923
2101
|
if (!projectNameInput) throw new Error(noProjectName());
|
|
2102
|
+
const templateWasOmitted = null == template || '' === String(template).trim();
|
|
2103
|
+
const effectiveTemplate = templateWasOmitted ? DEFAULT_TEMPLATE_NAME : String(template);
|
|
1924
2104
|
if (projectNameInput.startsWith('http')) throw new Error(noUrlAllowed());
|
|
1925
2105
|
const projectPath = external_node_path_namespaceObject.isAbsolute(projectNameInput) ? projectNameInput : external_node_path_namespaceObject.join(process.cwd(), projectNameInput);
|
|
1926
2106
|
const projectName = external_node_path_namespaceObject.basename(projectPath);
|
|
1927
2107
|
const updateSuffix = process.env.EXTENSION_CLI_UPDATE_SUFFIX || '';
|
|
1928
2108
|
if (updateSuffix) delete process.env.EXTENSION_CLI_UPDATE_SUFFIX;
|
|
1929
|
-
const requestedTemplate =
|
|
2109
|
+
const requestedTemplate = effectiveTemplate;
|
|
1930
2110
|
logger.log(' ');
|
|
1931
2111
|
logger.log(card({
|
|
1932
2112
|
version: cliVersion || process.env.EXTENSION_CLI_VERSION,
|
|
@@ -1949,28 +2129,32 @@ async function extensionCreate(projectNameInput, { cliVersion, template = "javas
|
|
|
1949
2129
|
logger.log(' ');
|
|
1950
2130
|
process.env.EXTENSION_CLI_BANNER_PRINTED = 'true';
|
|
1951
2131
|
const createResult = await createDirectory(projectPath, projectName, logger);
|
|
1952
|
-
const templateProvenance = await importExternalTemplate(projectPath, projectName,
|
|
1953
|
-
ownsProjectDir: createResult?.directoryCreated ?? false
|
|
2132
|
+
const templateProvenance = await importExternalTemplate(projectPath, projectName, effectiveTemplate, logger, {
|
|
2133
|
+
ownsProjectDir: createResult?.directoryCreated ?? false,
|
|
2134
|
+
allowOfflineFallback: templateWasOmitted
|
|
1954
2135
|
});
|
|
1955
2136
|
if (templateProvenance?.template) logger.log(usingTemplate(templateProvenance.template, templateProvenance.source));
|
|
1956
|
-
const
|
|
2137
|
+
const scaffoldedTemplate = templateProvenance?.template ?? effectiveTemplate;
|
|
2138
|
+
const packageManager = resolveProjectPackageManager(projectPath);
|
|
2139
|
+
const isMonorepoTemplate = String(scaffoldedTemplate).toLowerCase().includes('monorepo');
|
|
1957
2140
|
if (isDenoRuntime() && !isMonorepoTemplate) await writeDenoJsonc(projectPath, {
|
|
1958
|
-
template,
|
|
2141
|
+
template: scaffoldedTemplate,
|
|
1959
2142
|
cliVersion,
|
|
1960
2143
|
primary: true
|
|
1961
2144
|
}, logger);
|
|
1962
2145
|
else {
|
|
1963
2146
|
await overridePackageJson(projectPath, {
|
|
1964
|
-
template,
|
|
1965
|
-
cliVersion
|
|
2147
|
+
template: scaffoldedTemplate,
|
|
2148
|
+
cliVersion,
|
|
2149
|
+
packageManager
|
|
1966
2150
|
}, logger);
|
|
1967
2151
|
await writeDenoJsonc(projectPath, {
|
|
1968
|
-
template
|
|
2152
|
+
template: scaffoldedTemplate
|
|
1969
2153
|
}, logger);
|
|
1970
2154
|
}
|
|
1971
2155
|
await writeTemplateProvenance(projectPath, templateProvenance, logger);
|
|
1972
2156
|
if (install) {
|
|
1973
|
-
await installDependencies(projectPath, projectName, logger);
|
|
2157
|
+
await installDependencies(projectPath, projectName, logger, packageManager);
|
|
1974
2158
|
await installInternalDependencies(projectPath, logger);
|
|
1975
2159
|
}
|
|
1976
2160
|
await writeReadmeFile(projectPath, projectName, logger);
|
|
@@ -1978,16 +2162,16 @@ async function extensionCreate(projectNameInput, { cliVersion, template = "javas
|
|
|
1978
2162
|
await writeStoreMetadata(projectPath, projectName, templateManifestName, logger);
|
|
1979
2163
|
await writeGitignore(projectPath, logger);
|
|
1980
2164
|
await setupBuiltInTests(projectPath, logger);
|
|
1981
|
-
if (isTypeScriptTemplate(
|
|
2165
|
+
if (isTypeScriptTemplate(scaffoldedTemplate)) await generateExtensionTypes(projectPath, projectName, logger);
|
|
1982
2166
|
await initializeGitRepository(projectPath, projectName, templateProvenance?.template, logger);
|
|
1983
|
-
const readyMessage = await scaffoldReady(projectPath, projectName, Boolean(install));
|
|
2167
|
+
const readyMessage = await scaffoldReady(projectPath, projectName, Boolean(install), packageManager);
|
|
1984
2168
|
logger.log(readyMessage);
|
|
1985
2169
|
return {
|
|
1986
2170
|
projectPath,
|
|
1987
2171
|
projectName,
|
|
1988
|
-
template: templateProvenance?.template ??
|
|
2172
|
+
template: templateProvenance?.template ?? scaffoldedTemplate,
|
|
1989
2173
|
depsInstalled: install,
|
|
1990
|
-
packageManager
|
|
2174
|
+
packageManager,
|
|
1991
2175
|
templateProvenance
|
|
1992
2176
|
};
|
|
1993
2177
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare const DEFAULT_TEMPLATES_REF = "cb6a25377bd9516a1e55447a2010537019851ab2";
|
|
2
2
|
export declare const BUNDLED_TEMPLATES: readonly string[];
|
|
3
|
+
export declare const DEFAULT_TEMPLATE_NAME = "typescript";
|
|
4
|
+
export declare const OFFLINE_FALLBACK_TEMPLATE = "javascript";
|
|
3
5
|
export declare function resolveCatalogUrls(ref: string, overrideUrl?: string): string[];
|
|
4
6
|
export interface TemplateProvenance {
|
|
5
7
|
template: string;
|
|
@@ -23,6 +25,7 @@ export declare const TEMPLATE_LOCKFILE_NAMES: string[];
|
|
|
23
25
|
export declare function removeStaleTemplateLockfiles(projectPath: string): Promise<string[]>;
|
|
24
26
|
export interface ImportExternalTemplateOptions {
|
|
25
27
|
ownsProjectDir?: boolean;
|
|
28
|
+
allowOfflineFallback?: boolean;
|
|
26
29
|
}
|
|
27
30
|
export declare function cleanupFailedImport(projectPath: string, ownsProjectDir: boolean, preExistingEntries: string[]): Promise<void>;
|
|
28
31
|
export declare function importExternalTemplate(projectPath: string, projectName: string, template: string, logger: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import { type ScaffoldPackageManager } from '../lib/package-manager';
|
|
1
2
|
export declare function installDependencies(projectPath: string, projectName: string, logger: {
|
|
2
3
|
log(...args: unknown[]): void;
|
|
3
4
|
error(...args: unknown[]): void;
|
|
4
|
-
}): Promise<void>;
|
|
5
|
+
}, packageManager?: ScaffoldPackageManager): Promise<void>;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { type ScaffoldPackageManager } from '../lib/package-manager';
|
|
1
2
|
export declare function resolveExtensionBinary(): Promise<string>;
|
|
2
3
|
export declare function getTemplateAwareScripts(template: string, extensionBinary: string): Record<string, string>;
|
|
3
4
|
interface OverridePackageJsonOptions {
|
|
4
5
|
/** Defaults to `javascript` when omitted (same as `extensionCreate`). */
|
|
5
6
|
template?: string;
|
|
6
7
|
cliVersion?: string;
|
|
8
|
+
/** The one manager the project uses; resolved from the scaffold when omitted. */
|
|
9
|
+
packageManager?: ScaffoldPackageManager;
|
|
7
10
|
}
|
|
8
11
|
export declare function resolveExtensionDevDependencyVersion(cliVersion?: string): string;
|
|
9
|
-
export declare function overridePackageJson(projectPath: string,
|
|
12
|
+
export declare function overridePackageJson(projectPath: string, options: OverridePackageJsonOptions, logger: {
|
|
10
13
|
log(...args: unknown[]): void;
|
|
11
14
|
error(...args: unknown[]): void;
|
|
12
15
|
}): Promise<void>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"createdWith": "extension-create@4.1.
|
|
3
|
-
"template": "
|
|
4
|
-
"source": "
|
|
2
|
+
"createdWith": "extension-create@4.1.13",
|
|
3
|
+
"template": "typescript",
|
|
4
|
+
"source": "https://codeload.github.com/extension-js/examples/zip/cb6a25377bd9516a1e55447a2010537019851ab2",
|
|
5
|
+
"ref": "cb6a25377bd9516a1e55447a2010537019851ab2"
|
|
5
6
|
}
|
|
@@ -9,7 +9,7 @@ Packaging your extension is local and free. Submitting the result to a
|
|
|
9
9
|
store is what [extension.dev](https://docs.extension.dev/publish/overview?utm_source=store-md)
|
|
10
10
|
does, and it sponsors Extension.js.
|
|
11
11
|
|
|
12
|
-
Last updated: 2026-09-
|
|
12
|
+
Last updated: 2026-09-06
|
|
13
13
|
|
|
14
14
|
## Listing
|
|
15
15
|
|
|
@@ -65,5 +65,5 @@ notes in most cases.
|
|
|
65
65
|
|
|
66
66
|
## Version history
|
|
67
67
|
|
|
68
|
-
- 1.0.0 (unreleased): initial version from the
|
|
68
|
+
- 1.0.0 (unreleased): initial version from the typescript template.
|
|
69
69
|
Not yet submitted to any store.
|
|
@@ -2,18 +2,14 @@
|
|
|
2
2
|
// Extension.js uses a fresh profile on every run.
|
|
3
3
|
// Prefer that default? Remove the profile config below.
|
|
4
4
|
const profile = (name) => `./dist/extension-profile-${name}`
|
|
5
|
-
const ciFlags = process.env.CI ? ['--no-sandbox', '--disable-gpu'] : []
|
|
6
5
|
|
|
7
6
|
export default {
|
|
8
7
|
browser: {
|
|
9
|
-
chrome: {profile: profile('chrome')
|
|
10
|
-
chromium: {profile: profile('chromium')
|
|
11
|
-
edge: {profile: profile('edge')
|
|
8
|
+
chrome: {profile: profile('chrome')},
|
|
9
|
+
chromium: {profile: profile('chromium')},
|
|
10
|
+
edge: {profile: profile('edge')},
|
|
12
11
|
firefox: {profile: profile('firefox')},
|
|
13
|
-
'chromium-based': {
|
|
14
|
-
profile: profile('chromium-based'),
|
|
15
|
-
browserFlags: ciFlags
|
|
16
|
-
},
|
|
12
|
+
'chromium-based': {profile: profile('chromium-based')},
|
|
17
13
|
'gecko-based': {profile: profile('gecko-based')}
|
|
18
14
|
}
|
|
19
15
|
}
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
"version": "1.0.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"devDependencies": {
|
|
9
|
+
"typescript": "7.0.2",
|
|
10
|
+
"extension": "^4.1.13"
|
|
11
|
+
},
|
|
8
12
|
"scripts": {
|
|
9
13
|
"dev": "extension dev",
|
|
10
14
|
"start": "extension start",
|
|
@@ -15,9 +19,6 @@
|
|
|
15
19
|
"build:edge": "extension build --browser edge"
|
|
16
20
|
},
|
|
17
21
|
"dependencies": {},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"extension": "^4.1.11"
|
|
20
|
-
},
|
|
21
22
|
"packageManager": "pnpm@10.28.0",
|
|
22
23
|
"pnpm": {
|
|
23
24
|
"ignoredBuiltDependencies": [
|
|
@@ -11,7 +11,7 @@ if (isFirefoxLike) {
|
|
|
11
11
|
browser.sidebarAction.open()
|
|
12
12
|
})
|
|
13
13
|
|
|
14
|
-
browser.runtime.onMessage.addListener((message) => {
|
|
14
|
+
browser.runtime.onMessage.addListener((message: any) => {
|
|
15
15
|
if (!message || message.type !== 'openSidebar') return
|
|
16
16
|
|
|
17
17
|
browser.sidebarAction.open()
|
|
@@ -19,7 +19,7 @@ if (isFirefoxLike) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (!isFirefoxLike) {
|
|
22
|
-
// setPanelBehavior only affects FUTURE action clicks
|
|
22
|
+
// setPanelBehavior only affects FUTURE action clicks — registering it
|
|
23
23
|
// inside onClicked would swallow the first toolbar click.
|
|
24
24
|
chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true})
|
|
25
25
|
}
|
|
@@ -32,7 +32,7 @@ chrome.runtime.onMessage.addListener((message) => {
|
|
|
32
32
|
if (!chrome.sidePanel.open) return
|
|
33
33
|
|
|
34
34
|
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
|
|
35
|
-
const activeTabId = tabs
|
|
35
|
+
const activeTabId = tabs && tabs[0] && tabs[0].id
|
|
36
36
|
if (!activeTabId) return
|
|
37
37
|
|
|
38
38
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logo from '../images/icon.png'
|
|
2
2
|
|
|
3
|
-
export default function createContentApp() {
|
|
3
|
+
export default function createContentApp(): HTMLDivElement {
|
|
4
4
|
const container = document.createElement('div')
|
|
5
5
|
container.className = 'content_script'
|
|
6
6
|
|
|
@@ -9,22 +9,17 @@ export default function createContentApp() {
|
|
|
9
9
|
pill.className = 'content_pill'
|
|
10
10
|
pill.setAttribute('aria-label', 'Open sidebar')
|
|
11
11
|
pill.addEventListener('click', () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
) {
|
|
17
|
-
browser.runtime.sendMessage({type: 'openSidebar'})
|
|
18
|
-
} else {
|
|
19
|
-
chrome.runtime.sendMessage({type: 'openSidebar'})
|
|
20
|
-
}
|
|
21
|
-
} catch (error) {
|
|
22
|
-
console.error(error)
|
|
12
|
+
if (import.meta.env.EXTENSION_PUBLIC_BROWSER === 'firefox') {
|
|
13
|
+
browser.runtime.sendMessage({type: 'openSidebar'})
|
|
14
|
+
} else {
|
|
15
|
+
chrome.runtime.sendMessage({type: 'openSidebar'})
|
|
23
16
|
}
|
|
24
17
|
})
|
|
25
18
|
|
|
26
19
|
const img = document.createElement('img')
|
|
27
20
|
img.className = 'content_pill_logo'
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
22
|
+
// @ts-ignore
|
|
28
23
|
img.src = logo
|
|
29
24
|
img.alt = ''
|
|
30
25
|
img.setAttribute('aria-hidden', 'true')
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface ImportMeta {
|
|
3
|
+
webpackHot?: {
|
|
4
|
+
accept: (module?: string, callback?: () => void) => void
|
|
5
|
+
dispose: (callback: () => void) => void
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare module '*.svg' {
|
|
11
|
+
const content: string
|
|
12
|
+
export default content
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export {}
|
|
Binary file
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"sidePanel"
|
|
54
54
|
],
|
|
55
55
|
"background": {
|
|
56
|
-
"chromium:service_worker": "background.
|
|
56
|
+
"chromium:service_worker": "background.ts",
|
|
57
57
|
"firefox:scripts": [
|
|
58
|
-
"background.
|
|
58
|
+
"background.ts"
|
|
59
59
|
]
|
|
60
60
|
},
|
|
61
61
|
"content_scripts": [
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"<all_urls>"
|
|
65
65
|
],
|
|
66
66
|
"js": [
|
|
67
|
-
"content/scripts.
|
|
67
|
+
"content/scripts.ts"
|
|
68
68
|
]
|
|
69
69
|
}
|
|
70
70
|
]
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import '
|
|
2
|
-
import javascriptLogo from '../images/icon.png'
|
|
1
|
+
import typescriptLogo from '../images/icon.png'
|
|
3
2
|
|
|
4
3
|
function SidebarApp() {
|
|
5
4
|
const root = document.getElementById('root')
|
|
@@ -9,8 +8,8 @@ function SidebarApp() {
|
|
|
9
8
|
<div class="sidebar_app">
|
|
10
9
|
<img
|
|
11
10
|
class="sidebar_logo"
|
|
12
|
-
src="${
|
|
13
|
-
alt="The
|
|
11
|
+
src="${typescriptLogo}"
|
|
12
|
+
alt="The TypeScript logo"
|
|
14
13
|
/>
|
|
15
14
|
<h1 class="sidebar_title">Sidebar Panel</h1>
|
|
16
15
|
<p class="sidebar_description">
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>
|
|
6
|
+
<title>TypeScript Sidebar</title>
|
|
7
7
|
</head>
|
|
8
8
|
<body>
|
|
9
9
|
<noscript>You need to enable JavaScript to run this extension.</noscript>
|
|
10
10
|
<div id="root"></div>
|
|
11
11
|
</body>
|
|
12
|
-
<script src="./scripts.
|
|
12
|
+
<script src="./scripts.ts"></script>
|
|
13
13
|
</html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"allowJs": true,
|
|
5
|
+
"allowSyntheticDefaultImports": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"forceConsistentCasingInFileNames": true,
|
|
8
|
+
"isolatedModules": true,
|
|
9
|
+
"jsx": "react-jsx",
|
|
10
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"module": "esnext",
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"strict": true,
|
|
16
|
+
"target": "esnext",
|
|
17
|
+
"verbatimModuleSyntax": false,
|
|
18
|
+
"useDefineForClassFields": true,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"allowImportingTsExtensions": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["./", "extension-env.d.ts", "browser-global.d.ts"],
|
|
23
|
+
"exclude": ["node_modules", "dist"]
|
|
24
|
+
}
|