browser-extension-manager 1.0.14 → 1.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 (242) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/CLAUDE.md +672 -0
  3. package/TODO.md +3 -0
  4. package/dist/assets/css/browser-extension-manager.scss +18 -0
  5. package/dist/assets/css/components/content/index.scss +5 -0
  6. package/dist/assets/css/components/options/index.scss +5 -0
  7. package/dist/assets/css/components/pages/index.scss +5 -0
  8. package/dist/assets/css/components/popup/index.scss +5 -0
  9. package/dist/assets/css/core/_animations.scss +64 -0
  10. package/dist/assets/css/core/_initialize.scss +23 -0
  11. package/dist/assets/css/core/_utilities.scss +80 -0
  12. package/dist/assets/themes/_template/_theme.js +5 -0
  13. package/dist/assets/themes/_template/_theme.scss +5 -0
  14. package/dist/assets/themes/bootstrap/_theme.js +16 -0
  15. package/dist/assets/themes/bootstrap/_theme.scss +232 -0
  16. package/dist/assets/themes/bootstrap/js/index.esm.js +19 -0
  17. package/dist/assets/themes/bootstrap/js/index.umd.js +34 -0
  18. package/dist/assets/themes/bootstrap/js/src/alert.js +87 -0
  19. package/dist/assets/themes/bootstrap/js/src/base-component.js +86 -0
  20. package/dist/assets/themes/bootstrap/js/src/button.js +72 -0
  21. package/dist/assets/themes/bootstrap/js/src/carousel.js +474 -0
  22. package/dist/assets/themes/bootstrap/js/src/collapse.js +297 -0
  23. package/dist/assets/themes/bootstrap/js/src/dom/data.js +55 -0
  24. package/dist/assets/themes/bootstrap/js/src/dom/event-handler.js +317 -0
  25. package/dist/assets/themes/bootstrap/js/src/dom/manipulator.js +71 -0
  26. package/dist/assets/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
  27. package/dist/assets/themes/bootstrap/js/src/dropdown.js +458 -0
  28. package/dist/assets/themes/bootstrap/js/src/modal.js +378 -0
  29. package/dist/assets/themes/bootstrap/js/src/offcanvas.js +282 -0
  30. package/dist/assets/themes/bootstrap/js/src/popover.js +97 -0
  31. package/dist/assets/themes/bootstrap/js/src/scrollspy.js +296 -0
  32. package/dist/assets/themes/bootstrap/js/src/tab.js +315 -0
  33. package/dist/assets/themes/bootstrap/js/src/toast.js +224 -0
  34. package/dist/assets/themes/bootstrap/js/src/tooltip.js +632 -0
  35. package/dist/assets/themes/bootstrap/js/src/util/backdrop.js +151 -0
  36. package/dist/assets/themes/bootstrap/js/src/util/component-functions.js +35 -0
  37. package/dist/assets/themes/bootstrap/js/src/util/config.js +65 -0
  38. package/dist/assets/themes/bootstrap/js/src/util/focustrap.js +115 -0
  39. package/dist/assets/themes/bootstrap/js/src/util/index.js +306 -0
  40. package/dist/assets/themes/bootstrap/js/src/util/sanitizer.js +117 -0
  41. package/dist/assets/themes/bootstrap/js/src/util/scrollbar.js +114 -0
  42. package/dist/assets/themes/bootstrap/js/src/util/swipe.js +146 -0
  43. package/dist/assets/themes/bootstrap/js/src/util/template-factory.js +160 -0
  44. package/dist/assets/themes/bootstrap/scss/_accordion.scss +153 -0
  45. package/dist/assets/themes/bootstrap/scss/_alert.scss +68 -0
  46. package/dist/assets/themes/bootstrap/scss/_badge.scss +38 -0
  47. package/dist/assets/themes/bootstrap/scss/_breadcrumb.scss +40 -0
  48. package/dist/assets/themes/bootstrap/scss/_button-group.scss +147 -0
  49. package/dist/assets/themes/bootstrap/scss/_buttons.scss +216 -0
  50. package/dist/assets/themes/bootstrap/scss/_card.scss +238 -0
  51. package/dist/assets/themes/bootstrap/scss/_carousel.scss +226 -0
  52. package/dist/assets/themes/bootstrap/scss/_close.scss +66 -0
  53. package/dist/assets/themes/bootstrap/scss/_containers.scss +41 -0
  54. package/dist/assets/themes/bootstrap/scss/_dropdown.scss +250 -0
  55. package/dist/assets/themes/bootstrap/scss/_forms.scss +9 -0
  56. package/dist/assets/themes/bootstrap/scss/_functions.scss +302 -0
  57. package/dist/assets/themes/bootstrap/scss/_grid.scss +39 -0
  58. package/dist/assets/themes/bootstrap/scss/_helpers.scss +12 -0
  59. package/dist/assets/themes/bootstrap/scss/_images.scss +42 -0
  60. package/dist/assets/themes/bootstrap/scss/_list-group.scss +199 -0
  61. package/dist/assets/themes/bootstrap/scss/_maps.scss +174 -0
  62. package/dist/assets/themes/bootstrap/scss/_mixins.scss +42 -0
  63. package/dist/assets/themes/bootstrap/scss/_modal.scss +240 -0
  64. package/dist/assets/themes/bootstrap/scss/_nav.scss +197 -0
  65. package/dist/assets/themes/bootstrap/scss/_navbar.scss +289 -0
  66. package/dist/assets/themes/bootstrap/scss/_offcanvas.scss +147 -0
  67. package/dist/assets/themes/bootstrap/scss/_pagination.scss +109 -0
  68. package/dist/assets/themes/bootstrap/scss/_placeholders.scss +51 -0
  69. package/dist/assets/themes/bootstrap/scss/_popover.scss +196 -0
  70. package/dist/assets/themes/bootstrap/scss/_progress.scss +68 -0
  71. package/dist/assets/themes/bootstrap/scss/_reboot.scss +611 -0
  72. package/dist/assets/themes/bootstrap/scss/_root.scss +187 -0
  73. package/dist/assets/themes/bootstrap/scss/_spinners.scss +85 -0
  74. package/dist/assets/themes/bootstrap/scss/_tables.scss +171 -0
  75. package/dist/assets/themes/bootstrap/scss/_toasts.scss +73 -0
  76. package/dist/assets/themes/bootstrap/scss/_tooltip.scss +119 -0
  77. package/dist/assets/themes/bootstrap/scss/_transitions.scss +27 -0
  78. package/dist/assets/themes/bootstrap/scss/_type.scss +106 -0
  79. package/dist/assets/themes/bootstrap/scss/_utilities.scss +806 -0
  80. package/dist/assets/themes/bootstrap/scss/_variables-dark.scss +102 -0
  81. package/dist/assets/themes/bootstrap/scss/_variables.scss +1753 -0
  82. package/dist/assets/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
  83. package/dist/assets/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
  84. package/dist/assets/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
  85. package/dist/assets/themes/bootstrap/scss/bootstrap.scss +52 -0
  86. package/dist/assets/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
  87. package/dist/assets/themes/bootstrap/scss/forms/_form-check.scss +189 -0
  88. package/dist/assets/themes/bootstrap/scss/forms/_form-control.scss +214 -0
  89. package/dist/assets/themes/bootstrap/scss/forms/_form-range.scss +91 -0
  90. package/dist/assets/themes/bootstrap/scss/forms/_form-select.scss +80 -0
  91. package/dist/assets/themes/bootstrap/scss/forms/_form-text.scss +11 -0
  92. package/dist/assets/themes/bootstrap/scss/forms/_input-group.scss +132 -0
  93. package/dist/assets/themes/bootstrap/scss/forms/_labels.scss +36 -0
  94. package/dist/assets/themes/bootstrap/scss/forms/_validation.scss +12 -0
  95. package/dist/assets/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
  96. package/dist/assets/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
  97. package/dist/assets/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
  98. package/dist/assets/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
  99. package/dist/assets/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
  100. package/dist/assets/themes/bootstrap/scss/helpers/_position.scss +36 -0
  101. package/dist/assets/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
  102. package/dist/assets/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
  103. package/dist/assets/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
  104. package/dist/assets/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
  105. package/dist/assets/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
  106. package/dist/assets/themes/bootstrap/scss/helpers/_vr.scss +8 -0
  107. package/dist/assets/themes/bootstrap/scss/mixins/_alert.scss +18 -0
  108. package/dist/assets/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
  109. package/dist/assets/themes/bootstrap/scss/mixins/_banner.scss +7 -0
  110. package/dist/assets/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
  111. package/dist/assets/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
  112. package/dist/assets/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
  113. package/dist/assets/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
  114. package/dist/assets/themes/bootstrap/scss/mixins/_caret.scss +69 -0
  115. package/dist/assets/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
  116. package/dist/assets/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
  117. package/dist/assets/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
  118. package/dist/assets/themes/bootstrap/scss/mixins/_container.scss +11 -0
  119. package/dist/assets/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
  120. package/dist/assets/themes/bootstrap/scss/mixins/_forms.scss +163 -0
  121. package/dist/assets/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
  122. package/dist/assets/themes/bootstrap/scss/mixins/_grid.scss +151 -0
  123. package/dist/assets/themes/bootstrap/scss/mixins/_image.scss +16 -0
  124. package/dist/assets/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
  125. package/dist/assets/themes/bootstrap/scss/mixins/_lists.scss +7 -0
  126. package/dist/assets/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
  127. package/dist/assets/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
  128. package/dist/assets/themes/bootstrap/scss/mixins/_resize.scss +6 -0
  129. package/dist/assets/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
  130. package/dist/assets/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
  131. package/dist/assets/themes/bootstrap/scss/mixins/_transition.scss +26 -0
  132. package/dist/assets/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
  133. package/dist/assets/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
  134. package/dist/assets/themes/bootstrap/scss/tests/jasmine.js +16 -0
  135. package/dist/assets/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
  136. package/dist/assets/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
  137. package/dist/assets/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
  138. package/dist/assets/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
  139. package/dist/assets/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
  140. package/dist/assets/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
  141. package/dist/assets/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
  142. package/dist/assets/themes/bootstrap/scss/utilities/_api.scss +47 -0
  143. package/dist/assets/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
  144. package/dist/assets/themes/classy/README.md +75 -0
  145. package/dist/assets/themes/classy/_config.scss +185 -0
  146. package/dist/assets/themes/classy/_theme.js +29 -0
  147. package/dist/assets/themes/classy/_theme.scss +34 -0
  148. package/dist/assets/themes/classy/css/base/_animations.scss +27 -0
  149. package/dist/assets/themes/classy/css/base/_backgrounds.scss +191 -0
  150. package/dist/assets/themes/classy/css/base/_borders.scss +65 -0
  151. package/dist/assets/themes/classy/css/base/_root.scss +58 -0
  152. package/dist/assets/themes/classy/css/base/_soft-colors.scss +92 -0
  153. package/dist/assets/themes/classy/css/base/_spacing.scss +64 -0
  154. package/dist/assets/themes/classy/css/base/_typography.scss +179 -0
  155. package/dist/assets/themes/classy/css/base/_utilities.scss +77 -0
  156. package/dist/assets/themes/classy/css/components/_accordion.scss +33 -0
  157. package/dist/assets/themes/classy/css/components/_avatars.scss +32 -0
  158. package/dist/assets/themes/classy/css/components/_badges.scss +25 -0
  159. package/dist/assets/themes/classy/css/components/_buttons.scss +397 -0
  160. package/dist/assets/themes/classy/css/components/_cards.scss +33 -0
  161. package/dist/assets/themes/classy/css/components/_carousel.scss +41 -0
  162. package/dist/assets/themes/classy/css/components/_forms.scss +115 -0
  163. package/dist/assets/themes/classy/css/components/_links.scss +19 -0
  164. package/dist/assets/themes/classy/css/components/_logo-scroll.scss +57 -0
  165. package/dist/assets/themes/classy/css/components/_spinners.scss +19 -0
  166. package/dist/assets/themes/classy/css/components/_text.scss +41 -0
  167. package/dist/assets/themes/classy/css/layout/_blog.scss +42 -0
  168. package/dist/assets/themes/classy/css/layout/_general.scss +139 -0
  169. package/dist/assets/themes/classy/css/layout/_navigation.scss +576 -0
  170. package/dist/assets/themes/classy/css/layout/_team.scss +18 -0
  171. package/dist/assets/themes/classy/js/logo-scroll.js +83 -0
  172. package/dist/assets/themes/classy/js/navbar-scroll.js +65 -0
  173. package/dist/background.js +236 -260
  174. package/dist/build.js +93 -4
  175. package/dist/commands/setup.js +0 -268
  176. package/dist/config/manifest.json +11 -3
  177. package/dist/config/page-template.html +21 -0
  178. package/dist/defaults/.nvmrc +1 -1
  179. package/dist/defaults/CLAUDE.md +8 -0
  180. package/dist/defaults/config/browser-extension-manager.json +37 -0
  181. package/dist/defaults/src/assets/css/components/content/index.scss +11 -0
  182. package/dist/defaults/src/assets/css/components/options/index.scss +14 -0
  183. package/dist/defaults/src/assets/css/components/pages/index.scss +10 -0
  184. package/dist/defaults/src/assets/css/components/popup/index.scss +10 -0
  185. package/dist/defaults/src/assets/css/components/sidepanel/index.scss +6 -0
  186. package/dist/defaults/src/assets/css/main.scss +32 -0
  187. package/dist/defaults/src/assets/js/components/background/index.js +22 -0
  188. package/dist/defaults/src/assets/js/components/content/index.js +22 -0
  189. package/dist/defaults/src/assets/js/components/options/index.js +22 -0
  190. package/dist/defaults/src/assets/js/components/pages/index.js +22 -0
  191. package/dist/defaults/src/assets/js/components/popup/index.js +22 -0
  192. package/dist/defaults/src/assets/js/components/sidepanel/index.js +20 -0
  193. package/dist/defaults/src/assets/vendor/.gitkeep +0 -0
  194. package/dist/defaults/src/manifest.json +11 -6
  195. package/dist/defaults/src/views/options/index.html +8 -0
  196. package/dist/defaults/src/views/pages/index.html +10 -0
  197. package/dist/defaults/src/views/popup/index.html +4 -0
  198. package/dist/defaults/src/views/sidepanel/index.html +4 -0
  199. package/dist/gulp/main.js +11 -5
  200. package/dist/gulp/plugins/webpack/strip-dev-blocks.js +53 -0
  201. package/dist/gulp/tasks/{_package.js → BU/_package.js} +1 -1
  202. package/dist/gulp/tasks/{developmentRebuild.js → BU/developmentRebuild.js} +1 -1
  203. package/dist/gulp/tasks/{themes.js → BU/themes.js} +2 -1
  204. package/dist/gulp/tasks/{test.js → _.js} +3 -3
  205. package/dist/gulp/tasks/audit.js +154 -0
  206. package/dist/gulp/tasks/defaults.js +308 -0
  207. package/dist/gulp/tasks/distribute.js +71 -78
  208. package/dist/gulp/tasks/html.js +150 -0
  209. package/dist/gulp/tasks/icons.js +3 -2
  210. package/dist/gulp/tasks/package.js +202 -13
  211. package/dist/gulp/tasks/sass.js +188 -43
  212. package/dist/gulp/tasks/serve.js +1 -0
  213. package/dist/gulp/tasks/utils/template-transform.js +50 -0
  214. package/dist/gulp/tasks/webpack.js +338 -134
  215. package/dist/index.js +34 -34
  216. package/dist/options.js +40 -0
  217. package/dist/page.js +40 -0
  218. package/dist/popup.js +40 -0
  219. package/dist/sidepanel.js +40 -0
  220. package/firebase-debug.log +322 -0
  221. package/package.json +25 -18
  222. package/dist/assets/css/main.scss +0 -3
  223. package/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css +0 -12057
  224. package/dist/assets/themes/bootstrap/5.3.3/css/bootstrap.css.map +0 -1
  225. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js +0 -6314
  226. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.bundle.js.map +0 -1
  227. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.js +0 -4494
  228. package/dist/assets/themes/bootstrap/5.3.3/js/bootstrap.js.map +0 -1
  229. package/dist/defaults/src/assets/css/content.scss +0 -2
  230. package/dist/defaults/src/assets/css/options.scss +0 -11
  231. package/dist/defaults/src/assets/css/popup.scss +0 -14
  232. package/dist/defaults/src/assets/js/background.js +0 -18
  233. package/dist/defaults/src/assets/js/content.js +0 -15
  234. package/dist/defaults/src/assets/js/options.js +0 -17
  235. package/dist/defaults/src/assets/js/popup.js +0 -17
  236. package/dist/defaults/src/pages/options.html +0 -26
  237. package/dist/defaults/src/pages/popup.html +0 -26
  238. /package/dist/{defaults/src/assets/images/_ → assets/css/bundles/.gitkeep} +0 -0
  239. /package/dist/assets/css/{fontawesome.scss → core/_fontawesome.scss} +0 -0
  240. /package/dist/defaults/src/assets/{vendor/_ → images/.gitkeep} +0 -0
  241. /package/dist/gulp/tasks/{_importer.js → BU/_importer.js} +0 -0
  242. /package/dist/gulp/tasks/{_vendor.js → BU/_vendor.js} +0 -0
@@ -10,6 +10,7 @@ const JSON5 = require('json5');
10
10
  // Load package
11
11
  const package = Manager.getPackage('main');
12
12
  const project = Manager.getPackage('project');
13
+ const config = Manager.getConfig('project');
13
14
  const rootPathPackage = Manager.getRootPath('main');
14
15
  const rootPathProject = Manager.getRootPath('project');
15
16
 
@@ -24,6 +25,141 @@ const input = [
24
25
  const output = 'dist';
25
26
  const delay = 250;
26
27
 
28
+ // Set index
29
+ let index = -1;
30
+
31
+ // JSONP Template for build.js
32
+ const JSONP_TEMPLATE = `
33
+ (function() {
34
+ // Create a global variable for the config
35
+ const config = { config };
36
+
37
+ // Assign to various global scopes for compatibility
38
+ if (typeof self !== 'undefined') self.BEM_BUILD_JSON = config;
39
+ if (typeof window !== 'undefined') window.BEM_BUILD_JSON = config;
40
+ if (typeof globalThis !== 'undefined') globalThis.BEM_BUILD_JSON = config;
41
+ })();
42
+ `.trim();
43
+
44
+ // Generate build.js file
45
+ async function generateBuildJs(outputDir) {
46
+ try {
47
+ // Get git info
48
+ const gitInfo = getGitInfo();
49
+
50
+ // Get manifest
51
+ const manifestPath = path.join('dist', 'manifest.json');
52
+ const manifest = JSON5.parse(jetpack.read(manifestPath));
53
+
54
+ // Get web-manager config from project config
55
+ const webManagerConfig = config.webManager || {};
56
+
57
+ // Build config object matching web-manager's expected structure
58
+ const buildConfig = {
59
+ timestamp: new Date().toISOString(),
60
+ repo: gitInfo,
61
+ environment: Manager.getEnvironment(),
62
+ packages: {
63
+ 'browser-extension-manager': package.version,
64
+ 'web-manager': getPackageVersion('web-manager'),
65
+ },
66
+ config: {
67
+ // Core metadata
68
+ version: manifest.version,
69
+ environment: Manager.getEnvironment(),
70
+ buildTime: Date.now(),
71
+
72
+ // Brand configuration (from browser-extension-manager.json or manifest)
73
+ brand: {
74
+ id: config.app?.id || manifest.app?.id || 'extension',
75
+ name: config.brand?.name || manifest.brand?.name || 'Extension',
76
+ url: config.brand?.url || manifest.brand?.url || '',
77
+ email: config.brand?.email || manifest.brand?.email || '',
78
+ brandmark: config.brand?.brandmark || '',
79
+ wordmark: config.brand?.wordmark || '',
80
+ combomark: config.brand?.combomark || '',
81
+ },
82
+
83
+ // BEM-specific config
84
+ bem: {
85
+ environment: Manager.getEnvironment(),
86
+ cache_breaker: Math.round(new Date().getTime() / 1000),
87
+ liveReloadPort: config.liveReloadPort || 35729,
88
+ },
89
+
90
+ // Web-manager features (matching expected structure)
91
+ auth: webManagerConfig.auth || { enabled: true, config: {} },
92
+
93
+ firebase: {
94
+ app: {
95
+ enabled: !!(config.firebaseConfig?.apiKey || webManagerConfig.firebase?.app?.config?.apiKey),
96
+ config: config.firebaseConfig || webManagerConfig.firebase?.app?.config || {},
97
+ },
98
+ appCheck: webManagerConfig.firebase?.appCheck || { enabled: false, config: {} },
99
+ },
100
+
101
+ cookieConsent: webManagerConfig.cookieConsent || { enabled: true, config: {} },
102
+ chatsy: webManagerConfig.chatsy || { enabled: true, config: {} },
103
+ sentry: webManagerConfig.sentry || {
104
+ enabled: !!config.sentry?.dsn,
105
+ config: config.sentry || {}
106
+ },
107
+ exitPopup: webManagerConfig.exitPopup || { enabled: false, config: {} },
108
+ lazyLoading: webManagerConfig.lazyLoading || { enabled: true, config: {} },
109
+ socialSharing: webManagerConfig.socialSharing || { enabled: false, config: {} },
110
+ pushNotifications: webManagerConfig.pushNotifications || { enabled: false, config: {} },
111
+ validRedirectHosts: webManagerConfig.validRedirectHosts || ['itwcreativeworks.com'],
112
+ refreshNewVersion: webManagerConfig.refreshNewVersion || { enabled: true, config: {} },
113
+ serviceWorker: webManagerConfig.serviceWorker || { enabled: false, config: {} },
114
+
115
+ // Theme config
116
+ theme: config.theme || {},
117
+ }
118
+ };
119
+
120
+ // Write JSON version
121
+ const jsonPath = path.join(outputDir, 'build.json');
122
+ jetpack.write(jsonPath, JSON.stringify(buildConfig, null, 2));
123
+
124
+ // Write JSONP version for service worker
125
+ const jsonpContent = JSONP_TEMPLATE.replace('{ config }', JSON.stringify(buildConfig, null, 2));
126
+ const jsonpPath = path.join(outputDir, 'build.js');
127
+ jetpack.write(jsonpPath, jsonpContent);
128
+
129
+ logger.log(`Generated build.js and build.json`);
130
+ } catch (e) {
131
+ logger.error(`Error generating build.js`, e);
132
+ }
133
+ }
134
+
135
+ // Get git info
136
+ function getGitInfo() {
137
+ try {
138
+ const { execSync } = require('child_process');
139
+ const user = execSync('git config user.name', { encoding: 'utf8' }).trim();
140
+ const repo = execSync('git config --get remote.origin.url', { encoding: 'utf8' })
141
+ .trim()
142
+ .replace(/.*[\/:]([\w-]+)\/([\w-]+)(\.git)?$/, '$2');
143
+
144
+ return { user, name: repo };
145
+ } catch (e) {
146
+ return { user: 'unknown', name: 'unknown' };
147
+ }
148
+ }
149
+
150
+ // Get package version
151
+ function getPackageVersion(packageName) {
152
+ try {
153
+ const pkgPath = require.resolve(`${packageName}/package.json`, {
154
+ paths: [process.cwd()]
155
+ });
156
+ const pkg = require(pkgPath);
157
+ return pkg.version;
158
+ } catch (e) {
159
+ return 'unknown';
160
+ }
161
+ }
162
+
27
163
  // Special Compilation Task for manifest.json with default settings
28
164
  async function compileManifest(outputDir) {
29
165
  try {
@@ -124,12 +260,18 @@ async function packageRaw() {
124
260
  const value = redactions[key];
125
261
  const regex = new RegExp(key, 'g'); // Create a global regex for the key
126
262
  content = content.replace(regex, value);
263
+
264
+ // Log replacement
265
+ logger.log(`Redacted ${key} in ${filePath}`);
127
266
  });
128
267
 
129
268
  // Write the new content to the file
130
269
  jetpack.write(filePath, content);
131
270
  });
132
271
 
272
+ // Generate build.js and build.json
273
+ await generateBuildJs(outputDir);
274
+
133
275
  // Compile manifest and locales
134
276
  await compileManifest(outputDir);
135
277
  await compileLocales(outputDir);
@@ -194,23 +336,37 @@ function liveReload() {
194
336
 
195
337
  // Package Task
196
338
  async function packageFn(complete) {
197
- // Log
198
- logger.log('Starting...');
339
+ try {
340
+ // Log
341
+ logger.log('Starting...');
199
342
 
200
- // Run packageRaw
201
- await packageRaw();
343
+ // Increment index
344
+ index++;
202
345
 
203
- // Run packageZip
204
- await packageZip();
346
+ // Run build:pre hook
347
+ await hook('build:pre', index);
205
348
 
206
- // Run liveReload
207
- liveReload();
349
+ // Run packageRaw
350
+ await packageRaw();
208
351
 
209
- // Log
210
- logger.log('Finished!');
352
+ // Run packageZip
353
+ await packageZip();
211
354
 
212
- // Complete
213
- return complete();
355
+ // Run build:post hook
356
+ await hook('build:post', index);
357
+
358
+ // Run liveReload
359
+ liveReload();
360
+
361
+ // Log
362
+ logger.log('Finished!');
363
+
364
+ // Complete
365
+ return complete();
366
+ } catch (error) {
367
+ // Handle any errors that occur during package build
368
+ return Manager.reportBuildError(Object.assign(error, { plugin: 'Package' }), complete);
369
+ }
214
370
  }
215
371
 
216
372
  // Watcher Task
@@ -225,7 +381,7 @@ function packageFnWatcher(complete) {
225
381
  logger.log('[watcher] Watching for changes...');
226
382
 
227
383
  // Watch for changes in the dist folder
228
- watch(input, { delay: delay }, packageFn)
384
+ watch(input, { delay: delay, dot: true }, packageFn)
229
385
  .on('change', function (path) {
230
386
  logger.log(`[watcher] File ${path} was changed`);
231
387
  });
@@ -237,6 +393,39 @@ function packageFnWatcher(complete) {
237
393
  // Export tasks
238
394
  module.exports = series(packageFn, packageFnWatcher);
239
395
 
396
+ // Run hooks
397
+ async function hook(file, index) {
398
+ // Full path
399
+ const fullPath = path.join(process.cwd(), 'hooks', `${file}.js`);
400
+
401
+ // Log
402
+ // logger.log(`Loading hook: ${fullPath}`);
403
+
404
+ // Check if it exists
405
+ if (!jetpack.exists(fullPath)) {
406
+ return console.warn(`Hook not found: ${fullPath}`);
407
+ }
408
+
409
+ // Log
410
+ logger.log(`Running hook: ${fullPath}`);
411
+
412
+ // Load hook
413
+ let hook;
414
+ try {
415
+ // Load the hook
416
+ hook = require(fullPath);
417
+ } catch (e) {
418
+ throw new Error(`Error loading hook: ${fullPath} ${e.stack}`);
419
+ }
420
+
421
+ // Execute hook
422
+ try {
423
+ return await hook(index);
424
+ } catch (e) {
425
+ throw new Error(`Error running hook: ${fullPath} ${e.stack}`);
426
+ }
427
+ }
428
+
240
429
  // Get redactions
241
430
  function getRedactions() {
242
431
  const REDACTED = './REDACTED_REMOTE_CODE';
@@ -2,74 +2,180 @@
2
2
  const Manager = new (require('../../build.js'));
3
3
  const logger = Manager.logger('sass');
4
4
  const { src, dest, watch, series } = require('gulp');
5
+ const glob = require('glob').globSync;
5
6
  const path = require('path');
7
+ const jetpack = require('fs-jetpack');
6
8
  const compiler = require('gulp-sass')(require('sass'));
7
9
  const cleanCSS = require('gulp-clean-css');
8
10
  const rename = require('gulp-rename');
11
+ const filter = require('gulp-filter').default;
9
12
 
10
13
  // Load package
11
14
  const package = Manager.getPackage('main');
12
15
  const project = Manager.getPackage('project');
16
+ const config = Manager.getConfig('project');
13
17
  const rootPathPackage = Manager.getRootPath('main');
14
18
  const rootPathProject = Manager.getRootPath('project');
15
19
 
20
+ // Define bundle files separately for easier tracking
21
+ const bundleFiles = [
22
+ // Main bundles (if any exist in bundles/ directory)
23
+ `${rootPathPackage}/dist/assets/css/bundles/*.scss`,
24
+
25
+ // Project bundles
26
+ 'src/assets/css/bundles/*.scss',
27
+ ];
28
+
16
29
  // Glob
17
30
  const input = [
18
- // Files to include
19
- 'src/assets/css/**/*.{css,scss,sass}',
31
+ // Bundle files (if any exist)
32
+ ...bundleFiles,
20
33
 
21
- // Main files
22
- `${rootPathPackage}/dist/assets/css/**/*`,
34
+ // Project entry point (main.scss)
35
+ 'src/assets/css/main.scss',
23
36
 
24
- // Files to exclude
25
- // '!dist/**',
37
+ // Component-specific CSS
38
+ `${rootPathPackage}/dist/assets/css/components/**/*.scss`,
39
+ 'src/assets/css/components/**/*.scss',
26
40
  ];
41
+
42
+ // Additional files to watch (but not compile as entry points)
43
+ const watchInput = [
44
+ // Watch the paths we're compiling
45
+ ...input,
46
+
47
+ // Core CSS - watch for changes but don't compile as entry points
48
+ `${rootPathPackage}/dist/assets/css/**/*.scss`,
49
+
50
+ // Theme CSS - watch for changes but don't compile as entry points
51
+ `${rootPathPackage}/dist/assets/themes/**/*.scss`,
52
+ 'src/assets/themes/**/*.scss',
53
+ ];
54
+
27
55
  const output = 'dist/assets/css';
28
56
  const delay = 250;
57
+ const compiled = {};
58
+
59
+ // Configuration
60
+ const MAIN_BUNDLE_COMPONENT_PARTIALS = false; // Set to true to merge components into _component-specific.scss, false to compile separately
29
61
 
30
62
  // SASS Compilation Task
31
63
  function sass(complete) {
32
64
  // Log
33
65
  logger.log('Starting...');
66
+ Manager.logMemory(logger, 'Start');
67
+
68
+ // Generate component-specific scss
69
+ generateComponentScss();
34
70
 
35
71
  // Compile
36
- return src(input)
37
- .pipe(compiler({ outputStyle: 'compressed' }).on('error', compiler.logError))
38
- // .pipe(
39
- // compiler({
40
- // outputStyle: 'compressed',
41
- // // importer: alias.create({
42
- // // // '@themes': path.resolve(rootPathProject, `node_modules/${package.name}/dist/assets`),
43
- // // '@themes': '/node_modules/browser-extension-manager/dist/assets/themes',
44
- // // }),
45
- // // importers: [customAliasImporter],
46
- // // includePaths: [
47
- // // // path.resolve(rootPathProject, `node_modules/${package.name}/dist/assets`),
48
- // // '/Users/ian/Developer/Repositories/Slinko/slinko-browser-extension/node_modules/browser-extension-manager/dist/assets',
49
- // // ]
50
- // // includePaths: [
51
- // // path.join(__dirname, '..', '..', 'src'),
52
- // // path.resolve(__dirname, '../../src/assets'),
53
- // // path.resolve(__dirname, '../../src'),
54
- // // ],
55
- // // includePaths: [
56
- // // path.resolve(__dirname, '../../'),
57
- // // path.resolve(process.cwd(), '../../'),
58
- // // ],
59
- // // loadPaths: [
60
- // // path.resolve(rootPathProject, `node_modules/${package.name}/dist/assets`),
61
- // // ],
62
- // }).on('error', compiler.logError)
63
- // )
64
- .pipe(cleanCSS())
65
- .pipe(rename((path) => {
66
- path.basename += '.bundle';
72
+ let stream = src(input, { sourcemaps: true })
73
+ // Skip files based on configuration
74
+ .pipe(filter(file => !shouldSkip(file.path), { restore: true }))
75
+ // Compile SASS
76
+ .pipe(compiler({
77
+ loadPaths: [
78
+ // So we can use "@use 'browser-extension-manager' as *;"
79
+ path.resolve(rootPathPackage, 'dist/assets/css'),
80
+
81
+ // So we can use "@use 'theme' as *;" which resolves to the active theme
82
+ path.resolve(rootPathPackage, 'dist/assets/themes', config.theme?.id || 'classy'),
83
+
84
+ // So we can load _component-specific.scss from the project's dist
85
+ path.resolve(rootPathProject, 'dist/assets/css'),
86
+
87
+ // Allow importing from node_modules (e.g., @import '@fortawesome/fontawesome-free/css/all.min.css')
88
+ path.resolve(rootPathProject, 'node_modules'),
89
+ ],
90
+ // Suppress deprecation warnings
91
+ quietDeps: true,
92
+ // Only show warnings once
93
+ verbose: false
94
+ })
95
+ .on('error', (error) => Manager.reportBuildError(Object.assign(error, { plugin: 'SASS' }), complete)));
96
+
97
+ // Process
98
+ return stream
99
+ .pipe(cleanCSS({
100
+ format: Manager.actLikeProduction() ? 'compressed' : 'beautify',
101
+ }))
102
+ .pipe(rename((file) => {
103
+ // Get list of expected bundle names from the bundle files glob
104
+ // These are files that should be in the root CSS directory
105
+ let bundleFilesFound = [];
106
+ try {
107
+ bundleFilesFound = glob(bundleFiles);
108
+ } catch (e) {
109
+ // Directory doesn't exist, that's ok
110
+ }
111
+ const bundleNames = bundleFilesFound.map(f => path.basename(f, '.scss'));
112
+ bundleNames.push('main'); // main.scss is always a root bundle
113
+
114
+ // Check if this is a root-level bundle
115
+ const baseName = file.basename;
116
+ const isBundle = bundleNames.includes(baseName);
117
+
118
+ // Check
119
+ if (isBundle) {
120
+ // Root-level bundles (main, or any future bundle in bundles/ directory)
121
+ // Keep in root directory
122
+ file.dirname = '.';
123
+ } else {
124
+ // Component files: special handling for pages vs other components
125
+ //
126
+ // ⚠️ CRITICAL: The 'pages' directory is treated differently!
127
+ //
128
+ // Pages directory can have MULTIPLE files (index, pricing, login, etc.)
129
+ // - pages/index.scss → components/pages/index.bundle.css ✓
130
+ // - pages/pricing.scss → components/pages/pricing.bundle.css ✓
131
+ // - pages/login.scss → components/pages/login.bundle.css ✓
132
+ //
133
+ // Other components only have ONE file (index.html), so we strip /index:
134
+ // - popup/index.scss → components/popup.bundle.css ✓
135
+ // - options/index.scss → components/options.bundle.css ✓
136
+ // - sidepanel/index.scss → components/sidepanel.bundle.css ✓
137
+ //
138
+ // ❌ DO NOT GENERATE: components/pages.bundle.css
139
+ // ✓ DO GENERATE: components/pages/index.bundle.css, components/pages/pricing.bundle.css, etc.
140
+
141
+ const isInPages = file.dirname.includes(path.sep + 'pages' + path.sep)
142
+ || file.dirname.endsWith(path.sep + 'pages')
143
+ || file.dirname === 'pages';
144
+
145
+ if (file.basename === 'index' && !isInPages) {
146
+ // For non-pages components: strip /index
147
+ // components/popup/index.scss -> components/popup.bundle.css
148
+ const parts = file.dirname.split(path.sep);
149
+ const parentDir = parts[parts.length - 1];
150
+ file.basename = parentDir;
151
+ parts.pop();
152
+ file.dirname = parts.join(path.sep);
153
+ }
154
+ // For pages or non-index files: keep full path
155
+ // components/pages/index.scss -> components/pages/index.bundle.css
156
+ // components/pages/pricing.scss -> components/pages/pricing.bundle.css
157
+
158
+ // Add components/ prefix if not already there
159
+ if (!file.dirname.startsWith('components/') && !file.dirname.startsWith('components\\')) {
160
+ file.dirname = `components/${file.dirname}`;
161
+ }
162
+ }
163
+
164
+ // Add bundle to the name
165
+ file.basename += '.bundle';
166
+
167
+ // Track the full output path
168
+ const fullPath = path.resolve(output, file.dirname, `${file.basename}${file.extname}`);
169
+ compiled[fullPath] = true;
67
170
  }))
68
- .pipe(dest(output))
69
- .on('end', () => {
171
+ .pipe(dest(output, { sourcemaps: '.' }))
172
+ .on('finish', () => {
70
173
  // Log
71
174
  logger.log('Finished!');
72
175
 
176
+ // Trigger rebuild
177
+ Manager.triggerRebuild(compiled);
178
+
73
179
  // Complete
74
180
  return complete();
75
181
  });
@@ -87,14 +193,53 @@ function sassWatcher(complete) {
87
193
  logger.log('[watcher] Watching for changes...');
88
194
 
89
195
  // Watch for changes
90
- watch(input, { delay: delay }, sass)
91
- .on('change', function(path) {
92
- logger.log(`[watcher] File ${path} was changed`);
196
+ watch(watchInput, { delay: delay, dot: true }, sass)
197
+ .on('change', (path) => {
198
+ logger.log(`[watcher] File changed (${path})`);
93
199
  });
94
200
 
95
201
  // Complete
96
202
  return complete();
97
203
  }
98
204
 
205
+ function generateComponentScss() {
206
+ // Only generate _component-specific.scss if we're skipping component partials
207
+ if (!MAIN_BUNDLE_COMPONENT_PARTIALS) {
208
+ // When compiling components separately, create an empty file with a comment
209
+ const outputPath = path.resolve(rootPathProject, 'dist/assets/css/_component-specific.scss');
210
+ const content = `/*
211
+ AUTO-GENERATED COMPONENT-SPECIFIC SCSS
212
+ Components are now compiled separately when MAIN_BUNDLE_COMPONENT_PARTIALS = false
213
+ Find compiled component CSS in dist/assets/css/components/
214
+ */
215
+
216
+ `;
217
+
218
+ jetpack.write(outputPath, content);
219
+ Manager.triggerRebuild(outputPath);
220
+ return;
221
+ }
222
+
223
+ // TODO: Implement merged component partials if needed in the future
224
+ // This would be similar to UJ's page-specific merging
225
+ logger.log('Merged component partials not yet implemented');
226
+ }
227
+
228
+ function isComponentPartial(file) {
229
+ return file.includes('/assets/css/components/') && file.endsWith('index.scss');
230
+ }
231
+
232
+ function shouldSkip(file) {
233
+ // Skip component partials only if MAIN_BUNDLE_COMPONENT_PARTIALS is true
234
+ if (MAIN_BUNDLE_COMPONENT_PARTIALS && isComponentPartial(file)) {
235
+ return true;
236
+ }
237
+ return false;
238
+ }
239
+
99
240
  // Default Task
100
- module.exports = series(sass, sassWatcher);
241
+ // Export
242
+ module.exports = series(
243
+ sass,
244
+ sassWatcher
245
+ );
@@ -7,6 +7,7 @@ const WebSocket = require('ws');
7
7
  // Load package
8
8
  const package = Manager.getPackage('main');
9
9
  const project = Manager.getPackage('project');
10
+ const config = Manager.getConfig('project');
10
11
  const rootPathPackage = Manager.getRootPath('main');
11
12
  const rootPathProject = Manager.getRootPath('project');
12
13
 
@@ -0,0 +1,50 @@
1
+ // Libraries
2
+ const through2 = require('through2');
3
+ const { template } = require('node-powertools');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * Creates a through2 transform stream that processes template variables in files
8
+ **/
9
+ function createTemplateTransform(data) {
10
+ const extensions = ['html', 'md', 'liquid', 'json']
11
+
12
+ return through2.obj(function(file, encoding, callback) {
13
+ // Skip directories
14
+ if (file.isDirectory()) {
15
+ return callback(null, file);
16
+ }
17
+
18
+ // Check if file extension matches
19
+ const ext = path.extname(file.path).toLowerCase().slice(1);
20
+ if (!extensions.includes(ext)) {
21
+ return callback(null, file);
22
+ }
23
+
24
+ // Log
25
+ // console.log(`Processing file: ${file.path}`);
26
+
27
+ // Process the file contents
28
+ try {
29
+ const contents = file.contents.toString();
30
+
31
+ // Process templates
32
+ const templated = template(contents, data, {
33
+ brackets: ['[', ']'],
34
+ });
35
+
36
+ // Update file contents if changed
37
+ if (contents !== templated) {
38
+ file.contents = Buffer.from(templated);
39
+ const relativePath = file.relative || file.path;
40
+ }
41
+ } catch (error) {
42
+ console.error(`Error processing templates in ${file.path}:`, error);
43
+ }
44
+
45
+ // Pass the file through
46
+ callback(null, file);
47
+ });
48
+ }
49
+
50
+ module.exports = createTemplateTransform;