extension-develop 0.1.0

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/dist/add-dynamic-public-path.js +3 -0
  3. package/dist/add-hmr-accept-code.js +3 -0
  4. package/dist/add-query-param-to-imported-css.js +1 -0
  5. package/dist/ensure-hmr-for-scripts.js +3 -0
  6. package/dist/extensions/manager-extension/background.js +57 -0
  7. package/dist/extensions/manager-extension/define-initial-tab.js +67 -0
  8. package/dist/extensions/manager-extension/manifest.json +17 -0
  9. package/dist/extensions/manager-extension/pages/sakura-dark.css +268 -0
  10. package/dist/extensions/manager-extension/pages/sakura.css +267 -0
  11. package/dist/extensions/manager-extension/pages/welcome.html +49 -0
  12. package/dist/extensions/manager-extension/pages/welcome.js +34 -0
  13. package/dist/extensions/manager-extension/public/logo.png +0 -0
  14. package/dist/extensions/manager-extension/reload-service.js +145 -0
  15. package/dist/extensions/manager-extension-firefox/background.js +68 -0
  16. package/dist/extensions/manager-extension-firefox/define-initial-tab.js +57 -0
  17. package/dist/extensions/manager-extension-firefox/manifest.json +16 -0
  18. package/dist/extensions/manager-extension-firefox/pages/sakura-dark.css +268 -0
  19. package/dist/extensions/manager-extension-firefox/pages/sakura.css +267 -0
  20. package/dist/extensions/manager-extension-firefox/pages/welcome.html +49 -0
  21. package/dist/extensions/manager-extension-firefox/pages/welcome.js +34 -0
  22. package/dist/extensions/manager-extension-firefox/public/logo.png +0 -0
  23. package/dist/extensions/manager-extension-firefox/reload-service.js +130 -0
  24. package/dist/inject-chromium-client-loader.js +52 -0
  25. package/dist/inject-content-css-during-dev.js +10 -0
  26. package/dist/inject-firefox-client-loader.js +48 -0
  27. package/dist/minimum-chromium-file.mjs +1 -0
  28. package/dist/minimum-content-file.mjs +1 -0
  29. package/dist/minimum-firefox-file.mjs +1 -0
  30. package/dist/minimum-script-file.mjs +0 -0
  31. package/dist/module.d.ts +44 -0
  32. package/dist/module.js +178 -0
  33. package/dist/resolver-loader.js +1 -0
  34. package/dist/resolver-module.js +1 -0
  35. package/dist/stylelint.config.js +7 -0
  36. package/dist/tailwind.config.js +25 -0
  37. package/dist/types/css-content.d.ts +7 -0
  38. package/dist/types/css-modules.d.ts +19 -0
  39. package/dist/types/images.d.ts +58 -0
  40. package/dist/types/index.d.ts +13 -0
  41. package/dist/types/index.ts +7 -0
  42. package/dist/types/polyfill.d.ts +1 -0
  43. package/package.json +113 -0
@@ -0,0 +1,130 @@
1
+ let webSocket = null
2
+
3
+ export async function connect() {
4
+ if (webSocket) {
5
+ // If already connected, do nothing
6
+ return
7
+ }
8
+
9
+ webSocket = new WebSocket('wss://127.0.0.1:__RELOAD_PORT__')
10
+
11
+ webSocket.onerror = (event) => {
12
+ console.error(`[Reload Service] Connection error: ${JSON.stringify(event)}`)
13
+ webSocket.close()
14
+ }
15
+
16
+ webSocket.onopen = () => {
17
+ console.info(`[Reload Service] Connection opened.`)
18
+ }
19
+
20
+ webSocket.onmessage = async (event) => {
21
+ const message = JSON.parse(event.data)
22
+
23
+ if (message.status === 'serverReady') {
24
+ console.info('[Reload Service] Connection ready.')
25
+ await requestInitialLoadData()
26
+ }
27
+
28
+ if (message.changedFile) {
29
+ console.info(
30
+ `[Reload Service] Changes detected on ${message.changedFile}. Reloading extension...`
31
+ )
32
+
33
+ await messageAllExtensions(message.changedFile)
34
+ }
35
+ }
36
+
37
+ webSocket.onclose = () => {
38
+ console.info('[Reload Service] Connection closed.')
39
+ webSocket = null
40
+ }
41
+ }
42
+
43
+ export function disconnect() {
44
+ if (webSocket) {
45
+ webSocket.close()
46
+ }
47
+ }
48
+
49
+ async function getDevExtensions() {
50
+ const allExtensions = await browser.management.getAll()
51
+
52
+ return allExtensions.filter((extension) => {
53
+ return (
54
+ // Do not include itself
55
+ extension.id !== browser.runtime.id &&
56
+ // Manager extension
57
+ extension.name !== 'Add-On Manager' &&
58
+ // Show only unpackaged extensions
59
+ extension.installType === 'development'
60
+ )
61
+ })
62
+ }
63
+
64
+ async function messageAllExtensions(changedFile) {
65
+ // Check if the external extension is ready
66
+ const isExtensionReady = await checkExtensionReadiness()
67
+
68
+ if (isExtensionReady) {
69
+ const devExtensions = await getDevExtensions()
70
+ for (const extension of devExtensions) {
71
+ try {
72
+ await browser.runtime.sendMessage(extension.id, {changedFile})
73
+ console.info('[Reload Service] Add-On reloaded and ready.')
74
+ } catch (error) {
75
+ console.error(
76
+ `Error sending message to ${extension.id}: ${error.message}`
77
+ )
78
+ }
79
+ }
80
+ } else {
81
+ console.info('[Reload Service] External extension is not ready.')
82
+ }
83
+ }
84
+
85
+ async function requestInitialLoadData() {
86
+ const devExtensions = await getDevExtensions()
87
+
88
+ const responses = await Promise.all(
89
+ devExtensions.map(async (extension) => {
90
+ try {
91
+ const result = await browser.runtime.sendMessage(extension.id, {
92
+ initialLoadData: true
93
+ })
94
+
95
+ return result
96
+ } catch (error) {
97
+ console.error(
98
+ `Error sending message to ${extension.id}: ${error.message}`
99
+ )
100
+ return null
101
+ }
102
+ })
103
+ )
104
+
105
+ // We received the info from the use extension.
106
+ // All good, client is ready. Inform the server.
107
+ if (webSocket && webSocket.readyState === WebSocket.OPEN) {
108
+ const message = JSON.stringify({
109
+ status: 'clientReady',
110
+ data: responses.find((response) => response !== null)
111
+ })
112
+
113
+ webSocket.send(message)
114
+ }
115
+ }
116
+
117
+ async function checkExtensionReadiness() {
118
+ // Delay for 1 second
119
+ await delay(1000)
120
+ // Assume the extension is ready
121
+ return true
122
+ }
123
+
124
+ async function delay(ms) {
125
+ return await new Promise((resolve) => setTimeout(resolve, ms)).catch(
126
+ (error) => {
127
+ console.error(`Error delaying: ${error.message}`)
128
+ }
129
+ )
130
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";var f=Object.create;var a=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var r in t)a(e,r,{get:t[r],enumerable:!0})},m=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of p(t))!k.call(e,n)&&n!==r&&a(e,n,{get:()=>t[n],enumerable:!(s=g(t,n))||s.enumerable});return e};var q=(e,t,r)=>(r=e!=null?f(b(e)):{},m(t||!e||!e.__esModule?a(r,"default",{value:e,enumerable:!0}):r,e)),x=e=>m(a({},"__esModule",{value:!0}),e);var y={};v(y,{default:()=>R});module.exports=x(y);var o=q(require("path")),l=require("loader-utils"),u=require("schema-utils"),w={type:"object",properties:{test:{type:"string"},manifestPath:{type:"string"}}};function R(e){let t=this.getOptions(),r=t.manifestPath,s=o.default.dirname(r),n=require(r);(0,u.validate)(w,t,{name:"Inject Reload (background.scripts and background.service_worker) Script",baseDataPath:"options"});let c=(0,l.urlToRequest)(this.resourcePath),d=`
2
+ ;chrome.runtime.onMessageExternal.addListener(
3
+ async (request, _sender, sendResponse) => {
4
+ const managementInfo = await new Promise((resolve) => {
5
+ chrome.management.getSelf(resolve);
6
+ });
7
+
8
+ // Ping-pong between the user extension background page(this)
9
+ // and the middleware socket client (reloadService.ts),
10
+ // which will then send a message to the server
11
+ // (startServer.ts) so it can display the extension info.
12
+ if (request.initialLoadData) {
13
+ sendResponse({
14
+ id: chrome.runtime.id,
15
+ manifest: chrome.runtime.getManifest(),
16
+ management: managementInfo,
17
+ })
18
+ return true
19
+ }
20
+
21
+ // Reload the extension runtime if the manifest or
22
+ // service worker changes.
23
+ if (
24
+ request.changedFile === 'manifest.json' ||
25
+ request.changedFile === 'service_worker' ||
26
+ request.changedFile === '_locales'
27
+ ) {
28
+ setTimeout(() => {
29
+ sendResponse({reloaded: true})
30
+ chrome.runtime.reload()
31
+ }, 750)
32
+ }
33
+
34
+ // Reload all tabs if the contextMenus code changes.
35
+ if (request.changedFile === 'contextMenus') {
36
+ sendResponse({reloaded: true})
37
+ chrome.tabs.query({}, (tabs) => {
38
+ if (!tabs) return
39
+ tabs.forEach((tab) => chrome.tabs.reload(tab.id))
40
+ })
41
+ }
42
+
43
+ // Reload all tabs if the declarative_net_request code changes.
44
+ if (request.changedFile === 'declarative_net_request') {
45
+ sendResponse({reloaded: true})
46
+ chrome.runtime.reload()
47
+ }
48
+
49
+ return true
50
+ }
51
+ );
52
+ `;if(n.background){if(n.background.scripts)for(let i of[n.background.scripts[0]]){let h=o.default.resolve(s,i);if(c.includes(h))return`${d}${e}`}if(n.background.service_worker){let i=o.default.resolve(s,n.background.service_worker);if(c.includes(i))return`${d}${e}`}}return e}
@@ -0,0 +1,10 @@
1
+ "use strict";var D=Object.create;var g=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var O=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var R=(e,n)=>{for(var r in n)g(e,r,{get:n[r],enumerable:!0})},y=(e,n,r,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of k(n))!I.call(e,t)&&t!==r&&g(e,t,{get:()=>n[t],enumerable:!(s=S(n,t))||s.enumerable});return e};var a=(e,n,r)=>(r=e!=null?D(O(e)):{},y(n||!e||!e.__esModule?g(r,"default",{value:e,enumerable:!0}):r,e)),C=e=>y(g({},"__esModule",{value:!0}),e);var J={};R(J,{default:()=>N});module.exports=C(J);var x=a(require("path")),j=require("loader-utils"),w=require("schema-utils");var h=a(require("fs")),m=a(require("path"));var U=a(require("path")),P=a(require("fs")),W=require("child_process"),q=require("detect-package-manager");var A=a(require("path")),o=require("@colors/colors/safe");var v=a(require("path")),_=v.default.join(process.cwd(),"node_modules/extension-develop/dist/certs");function H(e){return e.replace(/\\/g,"/")}function $(e,n){return n?(Array.isArray(n)?n:[n]).some(s=>{if(typeof s!="string")return!1;let t=H(s);return e.includes(t.startsWith("/")?t.slice(1):t)}):!1}function b(e,n){return(Array.isArray(e)?e||[]:e?[e]:[]).filter(t=>{let d=h.default.existsSync(t)&&!$(t,n),i=m.default.extname(t);return d&&t?.includes(i)})}function E(e,n){return(Array.isArray(e)?e||[]:e?[e]:[]).filter(t=>h.default.existsSync(t)&&!$(t,n)&&t.endsWith(".css")||t.endsWith(".scss")||t.endsWith(".sass")||t.endsWith(".less"))}function F(e,n){let r=m.default.relative(m.default.dirname(e),n);return!r.startsWith(".")&&!r.startsWith("..")&&(r="./"+r),r}var z={type:"object",properties:{test:{type:"string"},manifestPath:{type:"string"},includeList:{type:"object"},excludeList:{type:"object"}}},V=`/**
2
+ * Welcome to to your content_scripts CSS file during development!
3
+ * To speed up the development process, your styles
4
+ * are being injected directly into the head of the webpage,
5
+ * and will be removed when you build your application, along
6
+ * with this file. If you are seeing this file in a production build,
7
+ * it means that something is wrong with your build configuration.
8
+ */`;function N(e){let n=this.getOptions();(0,w.validate)(z,n,{name:"scripts:inject-content-css-during-dev",baseDataPath:"options"});let r=n.includeList||{},s=[],t=Object.entries(r).filter(([i,l])=>i.startsWith("content")&&l);if(!t.length)return e;for(let i of t){let[l,f]=i,c=[...b(f,n.excludeList||{})],u=E(f,n.excludeList||{});if(u.length&&!c.length){let p=x.default.resolve(__dirname,"minimum-content-file.mjs");c.push(p)}s.push({feature:l,scriptPath:c[0],cssImports:u.map(p=>F(c[0],p))})}let d=(0,j.urlToRequest)(this.resourcePath);return s.forEach(({feature:i,scriptPath:l,cssImports:f})=>{if(d.includes(l)){let c=f.map(u=>{let[,p]=i.split("/"),T=p.split("-")[1],M=x.default.basename(u);return`import(/* webpackChunkName: "${`web_accessible_resources/resource-${T}/${M.replace(".","_")}`}" */ '${u}').then(css => console.info('content_script.css loaded', css)).catch(err => console.error(err));`}).join(`
9
+ `);this.emitFile(`${i}.css`,V),e=`${c}
10
+ ${e}`}}),e}
@@ -0,0 +1,48 @@
1
+ "use strict";var g=Object.create;var a=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var k=(e,t)=>{for(var r in t)a(e,r,{get:t[r],enumerable:!0})},l=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of b(t))!w.call(e,n)&&n!==r&&a(e,n,{get:()=>t[n],enumerable:!(s=h(t,n))||s.enumerable});return e};var v=(e,t,r)=>(r=e!=null?g(p(e)):{},l(t||!e||!e.__esModule?a(r,"default",{value:e,enumerable:!0}):r,e)),q=e=>l(a({},"__esModule",{value:!0}),e);var _={};k(_,{default:()=>y});module.exports=q(_);var o=v(require("path")),u=require("loader-utils"),m=require("schema-utils"),x={type:"object",properties:{test:{type:"string"},manifestPath:{type:"string"}}};function y(e){let t=this.getOptions(),r=t.manifestPath,s=o.default.dirname(r),n=require(r);(0,m.validate)(x,t,{name:"Inject Reload (background.scripts and background.service_worker) Script",baseDataPath:"options"});let c=(0,u.urlToRequest)(this.resourcePath),d=`
2
+ ;browser.runtime.onMessageExternal.addListener(
3
+ async (request, _sender) => {
4
+ const managementInfo = await new Promise((resolve) => {
5
+ browser.management.getSelf(resolve);
6
+ });
7
+
8
+ // Ping-pong between the user extension background page(this)
9
+ // and the middleware socket client (reloadService.ts),
10
+ // which will then send a message to the server
11
+ // (startServer.ts) so it can display the extension info.
12
+ if (request.initialLoadData) {
13
+ return {
14
+ id: browser.runtime.id,
15
+ manifest: browser.runtime.getManifest(),
16
+ management: managementInfo,
17
+ };
18
+ }
19
+
20
+ // Reload the extension runtime if the manifest or
21
+ // service worker changes.
22
+ if (
23
+ request.changedFile === "manifest.json" ||
24
+ request.changedFile === "service_worker" ||
25
+ request.changedFile === "_locales"
26
+ ) {
27
+ setTimeout(() => {
28
+ browser.runtime.reload();
29
+ }, 750);
30
+ }
31
+
32
+ // Reload all tabs if the contextMenus code changes.
33
+ if (request.changedFile === "contextMenus") {
34
+ browser.tabs.query({}, (tabs) => {
35
+ if (!tabs) return;
36
+ tabs.forEach((tab) => browser.tabs.reload(tab.id));
37
+ });
38
+ }
39
+
40
+ // Reload all tabs if the declarative_net_request code changes.
41
+ if (request.changedFile === "declarative_net_request") {
42
+ browser.runtime.reload();
43
+ }
44
+
45
+ return { reloaded: true };
46
+ }
47
+ );
48
+ `;if(n.background){if(n.background.scripts)for(let i of[n.background.scripts[0]]){let f=o.default.resolve(s,i);if(c.includes(f))return`${d}${e}`}if(n.background.service_worker){let i=o.default.resolve(s,n.background.service_worker);if(c.includes(i))return`${d}${e}`}}return e}
@@ -0,0 +1 @@
1
+ chrome.runtime.onMessageExternal.addListener(async(e,i,a)=>{let r=await new Promise(n=>{chrome.management.getSelf(n)});return e.initialLoadData?(a({id:chrome.runtime.id,manifest:chrome.runtime.getManifest(),management:r}),!0):((e.changedFile==="manifest.json"||e.changedFile==="service_worker"||e.changedFile==="_locales")&&setTimeout(()=>{a({reloaded:!0}),chrome.runtime.reload()},750),e.changedFile==="declarative_net_request"&&(a({reloaded:!0}),chrome.runtime.reload()),!0)});
@@ -0,0 +1 @@
1
+ import.meta.webpackHot&&import.meta.webpackHot.accept();
@@ -0,0 +1 @@
1
+ browser.runtime.onMessageExternal.addListener(async(e,n)=>{let r=await browser.management.getSelf();return e.initialLoadData?{id:browser.runtime.id,manifest:browser.runtime.getManifest(),management:r}:((e.changedFile==="manifest.json"||e.changedFile==="service_worker"||e.changedFile==="_locales")&&setTimeout(()=>(browser.runtime.reload(),{reloaded:!0}),750),e.changedFile==="declarative_net_request"?(browser.runtime.reload(),{reloaded:!0}):!0)});
File without changes
@@ -0,0 +1,44 @@
1
+ interface DevOptions {
2
+ browser: 'chrome' | 'edge' | 'firefox';
3
+ mode: 'development' | 'production' | 'none' | undefined;
4
+ port?: number;
5
+ noOpen?: boolean;
6
+ userDataDir?: string;
7
+ profile?: string;
8
+ preferences?: Record<string, any>;
9
+ browserFlags?: string[];
10
+ startingUrl?: string;
11
+ polyfill?: boolean;
12
+ }
13
+ declare function extensionDev(pathOrRemoteUrl: string | undefined, { ...devOptions }?: DevOptions): Promise<void>;
14
+
15
+ interface BuildOptions {
16
+ browser?: DevOptions['browser'];
17
+ zipFilename?: string;
18
+ zip?: boolean;
19
+ zipSource?: boolean;
20
+ polyfill?: boolean;
21
+ }
22
+ declare function extensionBuild(pathOrRemoteUrl: string | undefined, buildOptions: BuildOptions): Promise<void>;
23
+
24
+ interface PreviewOptions {
25
+ mode?: 'development' | 'production';
26
+ browser?: DevOptions['browser'];
27
+ port?: number;
28
+ noOpen?: boolean;
29
+ userDataDir?: string | boolean;
30
+ polyfill?: boolean;
31
+ }
32
+ declare function extensionPreview(pathOrRemoteUrl: string | undefined, previewOptions?: PreviewOptions): Promise<void>;
33
+
34
+ interface StartOptions {
35
+ mode?: 'development' | 'production';
36
+ browser?: DevOptions['browser'];
37
+ port?: number;
38
+ noOpen?: boolean;
39
+ userDataDir?: string | boolean;
40
+ polyfill?: boolean;
41
+ }
42
+ declare function extensionStart(pathOrRemoteUrl: string | undefined, startOptions?: StartOptions): Promise<void>;
43
+
44
+ export { type BuildOptions, type DevOptions, type PreviewOptions, type StartOptions, extensionBuild, extensionDev, extensionPreview, extensionStart };