wxt 0.3.1 → 0.3.2

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.
@@ -0,0 +1,420 @@
1
+ import * as vite from 'vite';
2
+ import { Manifest, Scripting } from 'webextension-polyfill';
3
+ import { UnimportOptions } from 'unimport';
4
+
5
+ interface InlineConfig {
6
+ /**
7
+ * Your project's root directory containing the `package.json` used to fill out the
8
+ * `manifest.json`.
9
+ *
10
+ * @default process.cwd()
11
+ */
12
+ root?: string;
13
+ /**
14
+ * Directory containing all source code. Set to `"src"` to move all source code to a `src/`
15
+ * directory.
16
+ *
17
+ * @default config.root
18
+ */
19
+ srcDir?: string;
20
+ /**
21
+ * Directory containing files that will be copied to the output directory as-is.
22
+ *
23
+ * @default "${config.root}/public"
24
+ */
25
+ publicDir?: string;
26
+ /**
27
+ * @default "${config.srcDir}/entrypoints"
28
+ */
29
+ entrypointsDir?: string;
30
+ /**
31
+ * Path to `"wxt.config.ts"` file or false to disable config file discovery.
32
+ *
33
+ * @default "wxt.config.ts"
34
+ */
35
+ configFile?: string | false;
36
+ /**
37
+ * ID of the extension for each store. Used for publishing.
38
+ */
39
+ storeIds?: {
40
+ chrome?: string;
41
+ firefox?: string;
42
+ edge?: string;
43
+ };
44
+ /**
45
+ * Explicitly set a mode to run in. This will override the default mode for each command, and can
46
+ * be overridden by the command line `--mode` option.
47
+ */
48
+ mode?: string;
49
+ /**
50
+ * Customize auto-import options.
51
+ */
52
+ imports?: Partial<UnimportOptions>;
53
+ /**
54
+ * Explicitly set a browser to build for. This will override the default browser for each command,
55
+ * and can be overridden by the command line `--browser` option.
56
+ *
57
+ * @default
58
+ * "chrome"
59
+ */
60
+ browser?: TargetBrowser;
61
+ /**
62
+ * Explicitly set a manifest version to target. This will override the default manifest version
63
+ * for each command, and can be overridden by the command line `--mv2` or `--mv3` option.
64
+ */
65
+ manifestVersion?: TargetManifestVersion;
66
+ /**
67
+ * Override the logger used.
68
+ *
69
+ * @default
70
+ * consola
71
+ */
72
+ logger?: Logger;
73
+ /**
74
+ * Custom Vite options.
75
+ */
76
+ vite?: Omit<vite.UserConfig, 'root' | 'configFile' | 'mode'>;
77
+ /**
78
+ * Customize the `manifest.json` output. Can be an object, promise, or function that returns an
79
+ * object or promise.
80
+ */
81
+ manifest?: UserManifest | Promise<UserManifest> | UserManifestFn;
82
+ /**
83
+ * Custom server options.
84
+ */
85
+ server?: WxtDevServer;
86
+ /**
87
+ * Custom runner options. Options set here can be overridden in a `web-ext.config.ts` file.
88
+ */
89
+ runner?: ExtensionRunnerConfig;
90
+ zip?: {
91
+ /**
92
+ * Configure the filename output when zipping files.
93
+ *
94
+ * Available template variables:
95
+ *
96
+ * - `{name}` - The project's name converted to kebab-case
97
+ * - `{version}` - The version_name or version from the manifest
98
+ * - `{browser}` - The target browser from the `--browser` CLI flag
99
+ * - `{manifestVersion}` - Either "2" or "3"
100
+ *
101
+ * @default "{name}-{version}-{browser}.zip"
102
+ */
103
+ artifactTemplate?: string;
104
+ /**
105
+ * Configure the filename output when zipping files.
106
+ *
107
+ * Available template variables:
108
+ *
109
+ * - `{name}` - The project's name converted to kebab-case
110
+ * - `{version}` - The version_name or version from the manifest
111
+ * - `{browser}` - The target browser from the `--browser` CLI flag
112
+ * - `{manifestVersion}` - Either "2" or "3"
113
+ *
114
+ * @default "{name}-{version}-sources.zip"
115
+ */
116
+ sourcesTemplate?: string;
117
+ /**
118
+ * Override the artifactTemplate's `{name}` template variable. Defaults to the `package.json`'s
119
+ * name, or if that doesn't exist, the current working directories name.
120
+ */
121
+ name?: string;
122
+ /**
123
+ * Root directory to ZIP when generating the sources ZIP.
124
+ *
125
+ * @default config.root
126
+ */
127
+ sourcesRoot?: string;
128
+ /**
129
+ * [Minimatch](https://www.npmjs.com/package/minimatch) patterns of files to exclude when
130
+ * creating a ZIP of all your source code for Firfox. Patterns are relative to your
131
+ * `config.zip.sourcesRoot`.
132
+ *
133
+ * Hidden files, node_modules, and tests are ignored by default.
134
+ *
135
+ * @example
136
+ * [
137
+ * "coverage", // Ignore the coverage directory in the `sourcesRoot`
138
+ * ]
139
+ */
140
+ ignoredSources?: string[];
141
+ };
142
+ }
143
+ interface WxtInlineViteConfig extends Omit<vite.InlineConfig, 'root' | 'configFile' | 'mode' | 'build'> {
144
+ build?: Omit<vite.BuildOptions, 'outDir'>;
145
+ }
146
+ interface BuildOutput {
147
+ manifest: Manifest.WebExtensionManifest;
148
+ publicAssets: vite.Rollup.OutputAsset[];
149
+ steps: BuildStepOutput[];
150
+ }
151
+ interface BuildStepOutput {
152
+ entrypoints: EntrypointGroup;
153
+ chunks: (vite.Rollup.OutputChunk | vite.Rollup.OutputAsset)[];
154
+ }
155
+ interface WxtDevServer extends vite.ViteDevServer {
156
+ /**
157
+ * Ex: `3000`
158
+ */
159
+ port: number;
160
+ /**
161
+ * Ex: `"localhost"`
162
+ */
163
+ hostname: string;
164
+ /**
165
+ * Ex: `"http://localhost:3000"`
166
+ */
167
+ origin: string;
168
+ /**
169
+ * Stores the current build output of the server.
170
+ */
171
+ currentOutput: BuildOutput;
172
+ /**
173
+ * Start the server on the first open port.
174
+ */
175
+ start(): Promise<void>;
176
+ /**
177
+ * Tell the extension to reload by running `browser.runtime.reload`.
178
+ */
179
+ reloadExtension: () => void;
180
+ /**
181
+ * Tell an extension page to reload.
182
+ *
183
+ * The path is the bundle path, not the input paths, so if the input paths is
184
+ * "src/options/index.html", you would pass "options.html" because that's where it is written to
185
+ * in the dist directory, and where it's available at in the actual extension.
186
+ *
187
+ * @example
188
+ * server.reloadPage("popup.html")
189
+ * server.reloadPage("sandbox.html")
190
+ */
191
+ reloadPage: (path: string) => void;
192
+ /**
193
+ * Tell the extension to restart a content script.
194
+ *
195
+ * @param contentScript The manifest definition for a content script
196
+ */
197
+ reloadContentScript: (contentScript: Omit<Scripting.RegisteredContentScript, 'id'>) => void;
198
+ }
199
+ type TargetBrowser = 'chrome' | 'firefox' | 'safari' | 'edge' | 'opera';
200
+ type TargetManifestVersion = 2 | 3;
201
+ type UserConfig = Omit<InlineConfig, 'configFile'>;
202
+ interface Logger {
203
+ debug(...args: any[]): void;
204
+ log(...args: any[]): void;
205
+ info(...args: any[]): void;
206
+ warn(...args: any[]): void;
207
+ error(...args: any[]): void;
208
+ fatal(...args: any[]): void;
209
+ success(...args: any[]): void;
210
+ }
211
+ interface BaseEntrypoint {
212
+ /**
213
+ * The entrypoint's name. This is the filename or dirname without the type suffix.
214
+ *
215
+ * Examples:
216
+ * - `popup.html` &rarr; `popup`
217
+ * - `options/index.html` &rarr; `options`
218
+ * - `named.sandbox.html` &rarr; `named`
219
+ * - `named.sandbox/index.html` &rarr; `named`
220
+ * - `sandbox.html` &rarr; `sandbox`
221
+ * - `sandbox.index.html` &rarr; `sandbox`
222
+ * - `overlay.content.ts` &rarr; `overlay`
223
+ * - `overlay.content/index.ts` &rarr; `overlay`
224
+ *
225
+ * The name is used when generating an output file:
226
+ * `<entrypoint.outputDir>/<entrypoint.name>.<ext>`
227
+ */
228
+ name: string;
229
+ /**
230
+ * Absolute path to the entrypoint's input file.
231
+ */
232
+ inputPath: string;
233
+ /**
234
+ * Absolute path to the entrypoint's output directory. Can be the`InternalConfg.outDir` or a
235
+ * subdirectory of it.
236
+ */
237
+ outputDir: string;
238
+ }
239
+ interface GenericEntrypoint extends BaseEntrypoint {
240
+ type: 'sandbox' | 'bookmarks' | 'history' | 'newtab' | 'sidepanel' | 'devtools' | 'unlisted-page' | 'unlisted-script' | 'unlisted-style' | 'content-script-style';
241
+ }
242
+ interface BackgroundEntrypoint extends BaseEntrypoint {
243
+ type: 'background';
244
+ options: {
245
+ persistent?: boolean;
246
+ type?: 'module';
247
+ };
248
+ }
249
+ interface ContentScriptEntrypoint extends BaseEntrypoint {
250
+ type: 'content-script';
251
+ options: Omit<ContentScriptDefinition, 'main'>;
252
+ }
253
+ interface PopupEntrypoint extends BaseEntrypoint {
254
+ type: 'popup';
255
+ options: {
256
+ /**
257
+ * Defaults to "browser_action" to be equivalent to MV3's "action" key
258
+ */
259
+ mv2Key?: 'browser_action' | 'page_action';
260
+ defaultIcon?: Record<string, string>;
261
+ defaultTitle?: string;
262
+ };
263
+ }
264
+ interface OptionsEntrypoint extends BaseEntrypoint {
265
+ type: 'options';
266
+ options: {
267
+ openInTab?: boolean;
268
+ browserStyle?: boolean;
269
+ chromeStyle?: boolean;
270
+ };
271
+ }
272
+ type Entrypoint = GenericEntrypoint | BackgroundEntrypoint | ContentScriptEntrypoint | PopupEntrypoint | OptionsEntrypoint;
273
+ type OnContentScriptStopped = (cb: () => void) => void;
274
+ interface ContentScriptDefinition {
275
+ matches: Manifest.ContentScript['matches'];
276
+ /**
277
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
278
+ * @default "documentIdle"
279
+ */
280
+ runAt?: Manifest.ContentScript['run_at'];
281
+ /**
282
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
283
+ * @default false
284
+ */
285
+ matchAboutBlank?: Manifest.ContentScript['match_about_blank'];
286
+ /**
287
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
288
+ * @default []
289
+ */
290
+ excludeMatches?: Manifest.ContentScript['exclude_matches'];
291
+ /**
292
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
293
+ * @default []
294
+ */
295
+ includeGlobs?: Manifest.ContentScript['include_globs'];
296
+ /**
297
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
298
+ * @default []
299
+ */
300
+ excludeGlobs?: Manifest.ContentScript['exclude_globs'];
301
+ /**
302
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
303
+ * @default false
304
+ */
305
+ allFrames?: Manifest.ContentScript['all_frames'];
306
+ /**
307
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
308
+ * @default false
309
+ */
310
+ matchOriginAsFallback?: boolean;
311
+ /**
312
+ * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
313
+ * @default "ISOLATED"
314
+ */
315
+ world?: 'ISOLATED' | 'MAIN';
316
+ /**
317
+ * Main function executed when the content script is loaded.
318
+ */
319
+ main(): void | Promise<void>;
320
+ }
321
+ interface BackgroundScriptDefintition {
322
+ type?: 'module';
323
+ main(): void;
324
+ }
325
+ /**
326
+ * Manifest customization available in the `wxt.config.ts` file. You cannot configure entrypoints
327
+ * here, they are configured inline.
328
+ */
329
+ type UserManifest = Partial<Omit<Manifest.WebExtensionManifest, 'action' | 'background' | 'browser_action' | 'chrome_url_overrides' | 'content_scripts' | 'devtools_page' | 'manifest_version' | 'options_page' | 'options_ui' | 'sandbox' | 'page_action' | 'popup' | 'sidepanel' | 'sidebar_action'>>;
330
+ type UserManifestFn = (env: ConfigEnv) => UserManifest | Promise<UserManifest>;
331
+ interface ConfigEnv {
332
+ mode: string;
333
+ command: 'build' | 'serve';
334
+ /**
335
+ * Browser passed in from the CLI
336
+ */
337
+ browser: TargetBrowser;
338
+ /**
339
+ * Manifest version passed in from the CLI
340
+ */
341
+ manifestVersion: 2 | 3;
342
+ }
343
+ /**
344
+ * Configure how the browser starts up.
345
+ */
346
+ interface ExtensionRunnerConfig {
347
+ /**
348
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#browser-console
349
+ */
350
+ openConsole?: boolean;
351
+ /**
352
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#devtools
353
+ */
354
+ openDevtools?: boolean;
355
+ /**
356
+ * List of browser names and the binary that should be used to open the browser.
357
+ */
358
+ binaries?: {
359
+ /**
360
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#chromium-binary
361
+ */
362
+ chrome?: string;
363
+ /**
364
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#chromium-binary
365
+ */
366
+ edge?: string;
367
+ /**
368
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#chromium-binary
369
+ */
370
+ opera?: string;
371
+ /**
372
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#firefox
373
+ */
374
+ firefox?: 'firefox' | 'beta' | 'nightly' | 'deved' | 'firefoxdeveloperedition' | string;
375
+ };
376
+ /**
377
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#firefox-profile
378
+ */
379
+ firefoxProfile?: string;
380
+ /**
381
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#chromium-profile
382
+ */
383
+ chromiumProfile?: string;
384
+ /**
385
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#pref
386
+ */
387
+ firefoxPrefs?: Record<string, string>;
388
+ /**
389
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#args
390
+ */
391
+ firefoxArgs?: string[];
392
+ /**
393
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#args
394
+ */
395
+ chromiumArgs?: string[];
396
+ /**
397
+ * @see https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#start-url
398
+ */
399
+ startUrls?: string[];
400
+ }
401
+
402
+ type EntrypointGroup = Entrypoint | Entrypoint[];
403
+
404
+ var version = "0.3.2";
405
+
406
+ declare function defineConfig(config: UserConfig): UserConfig;
407
+
408
+ declare function defineRunnerConfig(config: ExtensionRunnerConfig): ExtensionRunnerConfig;
409
+
410
+ /**
411
+ * Bundles the extension for production. Returns a promise of the build result.
412
+ */
413
+ declare function build(config: InlineConfig): Promise<BuildOutput>;
414
+ /**
415
+ * Creates a dev server, pre-builds all the files that need to exist to load the extension, and open
416
+ * the browser with the extension installed.
417
+ */
418
+ declare function createServer(config?: InlineConfig): Promise<WxtDevServer>;
419
+
420
+ export { BackgroundEntrypoint, BackgroundScriptDefintition, BaseEntrypoint, BuildOutput, BuildStepOutput, ConfigEnv, ContentScriptDefinition, ContentScriptEntrypoint, Entrypoint, ExtensionRunnerConfig, GenericEntrypoint, InlineConfig, Logger, OnContentScriptStopped, OptionsEntrypoint, PopupEntrypoint, TargetBrowser, TargetManifestVersion, UserConfig, UserManifest, UserManifestFn, WxtDevServer, WxtInlineViteConfig, build, createServer, defineConfig, defineRunnerConfig, version };
package/dist/index.d.ts CHANGED
@@ -4,37 +4,33 @@ import { UnimportOptions } from 'unimport';
4
4
 
5
5
  interface InlineConfig {
6
6
  /**
7
- * Project root directory.
7
+ * Your project's root directory containing the `package.json` used to fill out the
8
+ * `manifest.json`.
8
9
  *
9
- * @default
10
- * process.cwd()
10
+ * @default process.cwd()
11
11
  */
12
12
  root?: string;
13
13
  /**
14
14
  * Directory containing all source code. Set to `"src"` to move all source code to a `src/`
15
15
  * directory.
16
16
  *
17
- * @default
18
- * "<rootDir>"
17
+ * @default config.root
19
18
  */
20
19
  srcDir?: string;
21
20
  /**
22
21
  * Directory containing files that will be copied to the output directory as-is.
23
22
  *
24
- * @default
25
- * "<rootDir>/publicDir"
23
+ * @default "${config.root}/public"
26
24
  */
27
25
  publicDir?: string;
28
26
  /**
29
- * @default
30
- * "<srcDir>/entrypoints"
27
+ * @default "${config.srcDir}/entrypoints"
31
28
  */
32
29
  entrypointsDir?: string;
33
30
  /**
34
31
  * Path to `"wxt.config.ts"` file or false to disable config file discovery.
35
32
  *
36
- * @default
37
- * "wxt.config.ts"
33
+ * @default "wxt.config.ts"
38
34
  */
39
35
  configFile?: string | false;
40
36
  /**
@@ -55,7 +51,7 @@ interface InlineConfig {
55
51
  */
56
52
  imports?: Partial<UnimportOptions>;
57
53
  /**
58
- * Explicitly set a browser to target. This will override the default browser for each command,
54
+ * Explicitly set a browser to build for. This will override the default browser for each command,
59
55
  * and can be overridden by the command line `--browser` option.
60
56
  *
61
57
  * @default
@@ -97,12 +93,12 @@ interface InlineConfig {
97
93
  *
98
94
  * Available template variables:
99
95
  *
100
- * - `{{name}}` - The project's name converted to kebab-case
101
- * - `{{version}} - The version_name or version from the manifest
102
- * - `{{browser}} - The target browser from the `--browser` CLI flag
103
- * - `{{manifestVersion}}` - Either "2" or "3"
96
+ * - `{name}` - The project's name converted to kebab-case
97
+ * - `{version}` - The version_name or version from the manifest
98
+ * - `{browser}` - The target browser from the `--browser` CLI flag
99
+ * - `{manifestVersion}` - Either "2" or "3"
104
100
  *
105
- * @default "{{name}}-{{version}}-{{browser}}.zip"
101
+ * @default "{name}-{version}-{browser}.zip"
106
102
  */
107
103
  artifactTemplate?: string;
108
104
  /**
@@ -110,22 +106,23 @@ interface InlineConfig {
110
106
  *
111
107
  * Available template variables:
112
108
  *
113
- * - `{{name}}` - The project's name converted to kebab-case
114
- * - `{{version}} - The version_name or version from the manifest
115
- * - `{{browser}} - The target browser from the `--browser` CLI flag
116
- * - `{{manifestVersion}}` - Either "2" or "3"
109
+ * - `{name}` - The project's name converted to kebab-case
110
+ * - `{version}` - The version_name or version from the manifest
111
+ * - `{browser}` - The target browser from the `--browser` CLI flag
112
+ * - `{manifestVersion}` - Either "2" or "3"
117
113
  *
118
- * @default "{{name}}-{{version}}-sources.zip"
114
+ * @default "{name}-{version}-sources.zip"
119
115
  */
120
116
  sourcesTemplate?: string;
121
117
  /**
122
- * Override the artifactTemplate's `{{name}}` template variable. Defaults to the package.json's
118
+ * Override the artifactTemplate's `{name}` template variable. Defaults to the `package.json`'s
123
119
  * name, or if that doesn't exist, the current working directories name.
124
120
  */
125
121
  name?: string;
126
122
  /**
127
- * Root directory to ZIP. The ZIP can be uploaded to the Firefox Addon Store as your source
128
- * code. Defaults to the `config.root` directory.
123
+ * Root directory to ZIP when generating the sources ZIP.
124
+ *
125
+ * @default config.root
129
126
  */
130
127
  sourcesRoot?: string;
131
128
  /**
@@ -404,7 +401,7 @@ interface ExtensionRunnerConfig {
404
401
 
405
402
  type EntrypointGroup = Entrypoint | Entrypoint[];
406
403
 
407
- var version = "0.3.1";
404
+ var version = "0.3.2";
408
405
 
409
406
  declare function defineConfig(config: UserConfig): UserConfig;
410
407
 
package/dist/index.js CHANGED
@@ -236,7 +236,7 @@ function getUnimportOptions(config) {
236
236
  imports: [{ name: "defineConfig", from: "wxt" }],
237
237
  presets: [{ package: "wxt/client" }, { package: "wxt/browser" }],
238
238
  warn: config.logger.warn,
239
- dirs: ["./components/*", "./composables/*", "./hooks/*", "./utils/*"]
239
+ dirs: ["components", "composables", "hooks", "utils"]
240
240
  };
241
241
  return mergeConfig(
242
242
  defaultOptions,
@@ -1309,7 +1309,8 @@ async function generateMainfest(entrypoints, buildOutput, config) {
1309
1309
  version: pkg?.version && simplifyVersion(pkg.version),
1310
1310
  // Only add the version name to chromium and if the user hasn't specified a custom version.
1311
1311
  version_name: config.browser !== "firefox" && !config.manifest.version ? pkg?.version : void 0,
1312
- short_name: pkg?.shortName
1312
+ short_name: pkg?.shortName,
1313
+ icons: discoverIcons(buildOutput)
1313
1314
  },
1314
1315
  config.manifest
1315
1316
  );
@@ -1513,6 +1514,39 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
1513
1514
  }
1514
1515
  }
1515
1516
  }
1517
+ function discoverIcons(buildOutput) {
1518
+ const icons = [];
1519
+ const iconRegex = [
1520
+ /^icon-([0-9]+)\.(png|bmp|jpeg|jpg|ico|gif)$/,
1521
+ // icon-16.png
1522
+ /^icon-([0-9]+)x[0-9]+\.(png|bmp|jpeg|jpg|ico|gif)$/,
1523
+ // icon-16x16.png
1524
+ /^icon@([0-9]+)w\.(png|bmp|jpeg|jpg|ico|gif)$/,
1525
+ // icon@16w.png
1526
+ /^icon@([0-9]+)h\.(png|bmp|jpeg|jpg|ico|gif)$/,
1527
+ // icon@16h.png
1528
+ /^icon@([0-9]+)\.(png|bmp|jpeg|jpg|ico|gif)$/,
1529
+ // icon@16.png
1530
+ /^icon[\/\\]([0-9]+)\.(png|bmp|jpeg|jpg|ico|gif)$/,
1531
+ // icon/16.png
1532
+ /^icon[\/\\]([0-9]+)x[0-9]+\.(png|bmp|jpeg|jpg|ico|gif)$/
1533
+ // icon/16x16.png
1534
+ ];
1535
+ buildOutput.publicAssets.forEach((asset) => {
1536
+ let size;
1537
+ for (const regex of iconRegex) {
1538
+ const match = asset.fileName.match(regex);
1539
+ if (match?.[1] != null) {
1540
+ size = match[1];
1541
+ break;
1542
+ }
1543
+ }
1544
+ if (size == null)
1545
+ return;
1546
+ icons.push([size, normalizePath2(asset.fileName)]);
1547
+ });
1548
+ return icons.length > 0 ? Object.fromEntries(icons) : void 0;
1549
+ }
1516
1550
  function addDevModeCsp(manifest, config) {
1517
1551
  const permission = `http://${config.server?.hostname ?? ""}/*`;
1518
1552
  const allowedCsp = config.server?.origin ?? "http://localhost:*";
@@ -1631,7 +1665,7 @@ import fs12 from "fs-extra";
1631
1665
  import { filesize } from "filesize";
1632
1666
 
1633
1667
  // src/core/log/printTable.ts
1634
- function printTable(log, rows, gap = 2) {
1668
+ function printTable(log, header, rows, gap = 2) {
1635
1669
  if (rows.length === 0)
1636
1670
  return;
1637
1671
  const columnWidths = rows.reduce(
@@ -1653,11 +1687,12 @@ function printTable(log, rows, gap = 2) {
1653
1687
  if (i !== rows.length - 1)
1654
1688
  str += "\n";
1655
1689
  });
1656
- log(str);
1690
+ log(`${header}
1691
+ ${str}`);
1657
1692
  }
1658
1693
 
1659
1694
  // src/core/log/printFileList.ts
1660
- async function printFileList(log, baseDir, files) {
1695
+ async function printFileList(log, header, baseDir, files) {
1661
1696
  let totalSize = 0;
1662
1697
  const fileRows = await Promise.all(
1663
1698
  files.map(async (file, i) => {
@@ -1676,8 +1711,8 @@ async function printFileList(log, baseDir, files) {
1676
1711
  ];
1677
1712
  })
1678
1713
  );
1679
- printTable(log, fileRows);
1680
- log(`${pc.cyan("\u03A3 Total size:")} ${String(filesize(totalSize))}`);
1714
+ fileRows.push([`${pc.cyan("\u03A3 Total size:")} ${String(filesize(totalSize))}`]);
1715
+ printTable(log, header, fileRows);
1681
1716
  }
1682
1717
  var DEFAULT_COLOR = pc.blue;
1683
1718
  var CHUNK_COLORS = {
@@ -1692,7 +1727,7 @@ function getChunkColor(filename) {
1692
1727
  }
1693
1728
 
1694
1729
  // src/core/log/printBuildSummary.ts
1695
- async function printBuildSummary(output, config) {
1730
+ async function printBuildSummary(log, header, output, config) {
1696
1731
  const chunks = [
1697
1732
  ...output.steps.flatMap((step) => step.chunks),
1698
1733
  ...output.publicAssets
@@ -1705,7 +1740,7 @@ async function printBuildSummary(output, config) {
1705
1740
  return l.fileName.localeCompare(r.fileName);
1706
1741
  });
1707
1742
  const files = chunks.map((chunk) => resolve13(config.outDir, chunk.fileName));
1708
- await printFileList(config.logger.log, config.outDir, files);
1743
+ await printFileList(log, header, config.outDir, files);
1709
1744
  }
1710
1745
  var DEFAULT_SORT_WEIGHT = 100;
1711
1746
  var CHUNK_SORT_WEIGHTS = {
@@ -1736,10 +1771,12 @@ async function buildInternal(config) {
1736
1771
  const entrypoints = await findEntrypoints(config);
1737
1772
  const groups = groupEntrypoints(entrypoints);
1738
1773
  const { output } = await rebuild(config, groups, void 0);
1739
- config.logger.success(
1740
- `Built extension in ${formatDuration(Date.now() - startTime)}`
1774
+ await printBuildSummary(
1775
+ config.logger.success,
1776
+ `Built extension in ${formatDuration(Date.now() - startTime)}`,
1777
+ output,
1778
+ config
1741
1779
  );
1742
- await printBuildSummary(output, config);
1743
1780
  return output;
1744
1781
  }
1745
1782
  async function rebuild(config, entrypointGroups, existingOutput = {
@@ -1927,7 +1964,7 @@ function reloadHtmlPages(groups, server, config) {
1927
1964
  }
1928
1965
 
1929
1966
  // package.json
1930
- var version2 = "0.3.1";
1967
+ var version2 = "0.3.2";
1931
1968
 
1932
1969
  // src/core/utils/defineConfig.ts
1933
1970
  function defineConfig(config) {