From 2159ca48f838bfedd5a53e94198b4df210182de1 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 2 Jan 2025 14:34:05 +0000 Subject: [PATCH 01/36] wip rollup theme experiment --- .../javascripts/theme-transpiler/build.js | 3 + .../javascripts/theme-transpiler/package.json | 14 +- .../theme-transpiler/text-decoder-shim.js | 6 + .../theme-transpiler/transpiler.js | 282 +++++++++--------- lib/discourse_js_processor.rb | 31 +- pnpm-lock.yaml | 68 +++++ 6 files changed, 245 insertions(+), 159 deletions(-) create mode 100644 app/assets/javascripts/theme-transpiler/text-decoder-shim.js diff --git a/app/assets/javascripts/theme-transpiler/build.js b/app/assets/javascripts/theme-transpiler/build.js index 5619ad5312014..967538f41cd85 100644 --- a/app/assets/javascripts/theme-transpiler/build.js +++ b/app/assets/javascripts/theme-transpiler/build.js @@ -57,6 +57,9 @@ esbuild banner: { js: `var process = { "env": { "EMBER_ENV": "production" }, "cwd": () => "/" };`, }, + define: { + "import.meta.url": "'http://example.com'", + }, external: [], entryPoints: ["./transpiler.js"], plugins: [wasmPlugin], diff --git a/app/assets/javascripts/theme-transpiler/package.json b/app/assets/javascripts/theme-transpiler/package.json index 67cdf1013673e..033bda35ccdcf 100644 --- a/app/assets/javascripts/theme-transpiler/package.json +++ b/app/assets/javascripts/theme-transpiler/package.json @@ -9,24 +9,32 @@ "dependencies": { "@babel/standalone": "^7.27.2", "@csstools/postcss-light-dark-function": "^2.0.8", + "@rollup/browser": "^4.29.1", + "@rollup/wasm-node": "^4.29.1", + "@swc/wasm-web": "^1.10.4", "@zxing/text-encoding": "^0.9.0", "autoprefixer": "^10.4.21", "babel-plugin-ember-template-compilation": "^2.4.1", "content-tag": "^3.1.3", "core-js": "^3.42.0", "decorator-transforms": "^2.3.0", - "discourse": "workspace:0.0.0", "discourse-widget-hbs": "workspace:1.0.0", + "discourse": "workspace:0.0.0", "ember-cli-htmlbars": "^6.3.0", "ember-source": "~5.12.0", "ember-this-fallback": "^0.4.0", + "fastestsmallesttextencoderdecoder": "^1.0.22", + "handlebars": "^4.7.8", + "jsdom": "^25.0.1", "path-browserify": "^1.0.1", "polyfill-crypto.getrandomvalues": "^1.0.0", - "postcss": "^8.5.3", "postcss-js": "^4.0.1", "postcss-media-minmax": "^5.0.0", + "postcss": "^8.5.3", "source-map-js": "^1.2.1", - "terser": "^5.39.0" + "terser": "^5.39.0", + "url-polyfill": "^1.1.12", + "url-shim": "^1.0.1" }, "engines": { "node": ">= 18", diff --git a/app/assets/javascripts/theme-transpiler/text-decoder-shim.js b/app/assets/javascripts/theme-transpiler/text-decoder-shim.js new file mode 100644 index 0000000000000..9bee83266588b --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/text-decoder-shim.js @@ -0,0 +1,6 @@ +import { TextDecoder, TextEncoder } from "fastestsmallesttextencoderdecoder"; + +export default function patch() { + globalThis.TextEncoder = TextEncoder; + globalThis.TextDecoder = TextDecoder; +} diff --git a/app/assets/javascripts/theme-transpiler/transpiler.js b/app/assets/javascripts/theme-transpiler/transpiler.js index 32a02cc942325..da759fe8d92e9 100644 --- a/app/assets/javascripts/theme-transpiler/transpiler.js +++ b/app/assets/javascripts/theme-transpiler/transpiler.js @@ -1,167 +1,161 @@ -// This is executed in mini_racer to provide the JS logic for lib/discourse_js_processor.rb - -/* global rails */ +// import { JSDOM } from "jsdom"; +import "core-js/actual/url"; +import patch from "./text-decoder-shim"; +patch(); +import { rollup } from "/Users/david/discourse/rollup/browser/dist/es/rollup.browser.js"; const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; -globalThis.window = {}; +// globalThis.window = {}; + +const oldConsole = globalThis.console; globalThis.console = { log(...args) { - rails.logger.info(CONSOLE_PREFIX + args.join(" ")); + globalThis.rails?.logger.info(CONSOLE_PREFIX + args.join(" ")); + oldConsole.log(...args); }, warn(...args) { - rails.logger.warn(CONSOLE_PREFIX + args.join(" ")); + globalThis.rails?.logger.warn(CONSOLE_PREFIX + args.join(" ")); + oldConsole.warn(...args); }, error(...args) { - rails.logger.error(CONSOLE_PREFIX + args.join(" ")); + globalThis.rails?.logger.error(CONSOLE_PREFIX + args.join(" ")); + oldConsole.error(...args); }, }; -import { transform as babelTransform } from "@babel/standalone"; -import HTMLBarsInlinePrecompile from "babel-plugin-ember-template-compilation"; -import { Preprocessor } from "content-tag"; -import DecoratorTransforms from "decorator-transforms"; -import colocatedBabelPlugin from "ember-cli-htmlbars/lib/colocated-babel-plugin"; -import { precompile } from "ember-source/dist/ember-template-compiler"; -import EmberThisFallback from "ember-this-fallback"; -// A sub-dependency of content-tag (getrandom) needs `getRandomValues` -// so we polyfill it -import getRandomValues from "polyfill-crypto.getrandomvalues"; -import { minify as terserMinify } from "terser"; -import { WidgetHbsCompiler } from "discourse-widget-hbs/lib/widget-hbs-compiler"; -globalThis.crypto = { getRandomValues }; -import "./postcss"; -import { browsers } from "../discourse/config/targets"; - -const thisFallbackPlugin = EmberThisFallback._buildPlugin({ - enableLogging: false, - isTheme: true, -}).plugin; - -function manipulateAstNodeForTheme(node, themeId) { - // Magically add theme id as the first param for each of these helpers) - if ( - node.path.parts && - ["theme-i18n", "theme-prefix", "theme-setting"].includes(node.path.parts[0]) - ) { - if (node.params.length === 1) { - node.params.unshift({ - type: "NumberLiteral", - value: themeId, - original: themeId, - loc: { start: {}, end: {} }, - }); - } - } -} - -function buildEmberTemplateManipulatorPlugin(themeId) { - return function () { - return { - name: "theme-template-manipulator", - visitor: { - SubExpression: (node) => manipulateAstNodeForTheme(node, themeId), - MustacheStatement: (node) => manipulateAstNodeForTheme(node, themeId), - }, - }; - }; -} - -function buildTemplateCompilerBabelPlugins({ extension, themeId }) { - const compiler = { precompile }; - - if (themeId && extension !== "gjs") { - compiler.precompile = (src, opts) => { - return precompile(src, { - ...opts, - plugins: { - ast: [ - buildEmberTemplateManipulatorPlugin(themeId), - thisFallbackPlugin, - ], - }, - }); - }; - } - - return [ - colocatedBabelPlugin, - WidgetHbsCompiler, - [ - HTMLBarsInlinePrecompile, - { - compiler, - enableLegacyModules: [ - "ember-cli-htmlbars", - "ember-cli-htmlbars-inline-precompile", - "htmlbars-inline-precompile", - ], - }, - ], - ]; -} - -globalThis.transpile = function (source, options = {}) { - const { moduleId, filename, extension, skipModule, themeId } = options; - - if (extension === "gjs") { - const preprocessor = new Preprocessor(); - source = preprocessor.process(source).code; - } +globalThis.crypto = { + getRandomValues() { + // todo... not much random going on here + console.log("getRandomValues"); + }, +}; - const plugins = []; - plugins.push(...buildTemplateCompilerBabelPlugins({ extension, themeId })); - if (moduleId && !skipModule) { - plugins.push(["transform-modules-amd", { noInterop: true }]); +// console.log(TextDecoder); +import BindingsWasm from "/Users/david/discourse/rollup/browser/dist/bindings_wasm_bg.wasm"; +// import BindingsWasm from "./node_modules/@rollup/wasm-node/dist/wasm-node/bindings_wasm_bg.wasm"; +// import BindingsWasm from "./memory.wasm"; +// console.log(BindingsWasm); +// new WebAssembly.instantiate(BindingsWasm, ); +// console.log(BindingsWasm); + +const oldInstantiate = WebAssembly.instantiate; +WebAssembly.instantiate = async function (bytes, bindings) { + for (let [key, value] of Object.entries(bindings.wbg)) { + // bindings.wbg[key] = (...args) => { + // console.log("called", key); + // return value.apply(bindings, args); + // }; } - plugins.push([DecoratorTransforms, { runEarly: true }]); - - try { - return babelTransform(source, { - moduleId, - filename, - ast: false, - plugins, - presets: [ - [ - "env", - { - modules: false, - targets: { - browsers, - }, - }, - ], - ], - }).code; - } catch (error) { - // Workaround for https://github.com/rubyjs/mini_racer/issues/262 - error.message = JSON.stringify(error.message); - throw error; + console.log("instantiated", Object.keys(bindings.wbg)); + if (bytes === BindingsWasm) { + const mod = new WebAssembly.Module(bytes); + // console.log("returning"); + const instance = new WebAssembly.Instance(mod, bindings); + console.log("returning instance"); + return instance; + } else { + return oldInstantiate(...arguments); } + // console.log(bindings); + + // return new Promise((resolve) => resolve({})); }; -// mini_racer doesn't have native support for getting the result of an async operation. -// To work around that, we provide a getMinifyResult which can be used to fetch the result -// in a followup method call. -let lastMinifyError, lastMinifyResult; - -globalThis.minify = async function (sources, options) { - lastMinifyError = lastMinifyResult = null; - try { - lastMinifyResult = await terserMinify(sources, options); - } catch (e) { - lastMinifyError = e; +console.log("trying..."); +// const memory = new WebAssembly.Memory({ +// initial: 10, +// maximum: 100, +// }); +// const importObject = { +// my_namespace: { imported_func: (arg) => console.log(arg) }, +// }; +// const mod = new WebAssembly.Module(BindingsWasm); +// const wasm = new WebAssembly.Instance(mod, { js: { mem: memory } }); +// const summands = new DataView(memory.buffer); + +// for (let i = 0; i < 10; i++) { +// summands.setUint32(i * 4, i, true); // WebAssembly is little endian +// } +// const sum = wasm.exports.accumulate(0, 10); +// console.log(sum); + +// console.log(wasmInstance); +// WebAssembly.instantiate(BindingsWasm, {}) +// .then((result) => { +// console.log("result", result); +// }) +// .catch((error) => console.error("error: ", error)); + +globalThis.fetch = function (url) { + // console.log(url); + if (url.toString() === "http://example.com/bindings_wasm_bg.wasm") { + // console.log("stubbing fetch"); + console.log("FETCH"); + return new Promise((resolve) => resolve(BindingsWasm)); } + console.error("fetch not implemented"); + throw "fetch not implemented"; }; -globalThis.getMinifyResult = function () { - const error = lastMinifyError; - const result = lastMinifyResult; +// WebAssembly.instantiate = console.log; - lastMinifyError = lastMinifyResult = null; +// const dom = new JSDOM(`

Hello world

`); - if (error) { - throw error.toString(); - } +// globalThis.window = dom.window.window; +// globalThis.document = dom.window.document; + +const modules = { + "main.js": `import foo from 'foo.js'; console.log(foo); { + @test + someProp(){ + console.log("prop"); + } + + `, + "foo.js": "export default 42;", +}; + +const rollupResult = rollup({ + input: "main.js", + logLevel: "info", + onLog(level, message) { + console.log(level, message); + }, + plugins: [ + { + name: "loader", + resolveId(source) { + console.log("resolveid"); + if (modules.hasOwnProperty(source)) { + return source; + } + }, + load(id) { + if (modules.hasOwnProperty(id)) { + return modules[id]; + } + }, + }, + ], +}); + +rollupResult + .then((bundle) => { + console.log("Hello 1"); + return bundle.generate({ format: "es" }); + }) + .then(({ output }) => console.log("result", output[0].code)) + .catch((error) => console.error("error: ", error, error.stack)); + +let result; +globalThis.getResult = function () { return result; }; + +globalThis.doSomething = async function doSomething() { + await new Promise((resolve) => resolve()); + console.log("returned"); + return "thing"; +}; + +// console.log("done eval", rollupResult); \ No newline at end of file diff --git a/lib/discourse_js_processor.rb b/lib/discourse_js_processor.rb index fdfa68626fbe4..061463531c48b 100644 --- a/lib/discourse_js_processor.rb +++ b/lib/discourse_js_processor.rb @@ -2,6 +2,8 @@ require "execjs" require "mini_racer" +# MiniRacer::Platform.set_flags!(:trace_wasm_memory) + class DiscourseJsProcessor class TranspileError < StandardError end @@ -28,12 +30,15 @@ def self.mutex def self.build_theme_transpiler FileUtils.rm_rf("tmp/theme-transpiler") # cleanup old files - remove after Jan 2025 - Discourse::Utils.execute_command( - "pnpm", - "-C=app/assets/javascripts/theme-transpiler", - "node", - "build.js", - ) + result = + Discourse::Utils.execute_command( + "pnpm", + "-C=app/assets/javascripts/theme-transpiler", + "node", + "build.js", + ) + File.write("app/assets/javascripts/theme-transpiler/theme-transpiler.js", result) + result end def self.build_production_theme_transpiler @@ -50,12 +55,14 @@ def self.create_new_context ctx.attach("rails.logger.warn", proc { |err| Rails.logger.warn(err.to_s) }) ctx.attach("rails.logger.error", proc { |err| Rails.logger.error(err.to_s) }) - source = - if Rails.env.production? - File.read(TRANSPILER_PATH) - else - @processor_mutex.synchronize { build_theme_transpiler } - end + # source = + # if Rails.env.production? + # File.read(TRANSPILER_PATH) + # else + # @processor_mutex.synchronize { build_theme_transpiler } + # end + + source = File.read("app/assets/javascripts/theme-transpiler/theme-transpiler.js") ctx.eval(source, filename: "theme-transpiler.js") diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03a8d7b9f8ed1..ae4d7b4e263c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1024,6 +1024,15 @@ importers: '@csstools/postcss-light-dark-function': specifier: ^2.0.8 version: 2.0.8(postcss@8.5.3) + '@rollup/browser': + specifier: ^4.29.1 + version: 4.29.1 + '@rollup/wasm-node': + specifier: ^4.29.1 + version: 4.29.1 + '@swc/wasm-web': + specifier: ^1.10.4 + version: 1.10.4 '@zxing/text-encoding': specifier: ^0.9.0 version: 0.9.0 @@ -1057,6 +1066,15 @@ importers: ember-this-fallback: specifier: ^0.4.0 version: 0.4.0(patch_hash=znalyv6akdxlqfpmxunrdi3osa)(ember-cli-htmlbars@6.3.0)(ember-source@5.12.0(patch_hash=xx7mvsb7nmshqkkqhmf45r3hse)(@glimmer/component@1.1.2(@babel/core@7.27.1))(@glint/template@1.4.1-unstable.34c4510)(rsvp@4.8.5)(webpack@5.99.8(@swc/core@1.11.24)(esbuild@0.25.4))) + fastestsmallesttextencoderdecoder: + specifier: ^1.0.22 + version: 1.0.22 + handlebars: + specifier: ^4.7.8 + version: 4.7.8 + jsdom: + specifier: ^25.0.1 + version: 25.0.1(supports-color@8.1.1) path-browserify: specifier: ^1.0.1 version: 1.0.1 @@ -1078,6 +1096,12 @@ importers: terser: specifier: ^5.39.0 version: 5.39.0 + url-polyfill: + specifier: ^1.1.12 + version: 1.1.12 + url-shim: + specifier: ^1.0.1 + version: 1.0.1 app/assets/javascripts/truth-helpers: dependencies: @@ -2466,6 +2490,14 @@ packages: peerDependencies: prettier: 3.x + '@rollup/browser@4.29.1': + resolution: {integrity: sha512-CsDzu5HTqbY9++9B/jk6Ue/QzozVCnHqSau9ziD/x8nzxEfFsRniycDshZWaSGpHIqHn67PJbwFea83Nu6FQfQ==} + + '@rollup/wasm-node@4.29.1': + resolution: {integrity: sha512-AOtO2Y+XzElJfmJgAECOgbutmKAK5XcKH7CipGDQDBMfLY04ezEoCHWEpmoX5L7/WH3k17rXMCClNiwDbWW+mw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -2590,6 +2622,9 @@ packages: '@swc/types@0.1.21': resolution: {integrity: sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ==} + '@swc/wasm-web@1.10.4': + resolution: {integrity: sha512-BWikGSYvlaOfEvoeMg+9FLrzV8jl5swd8iVvTIVMV5P7HtKDkc+QY3HCUCpQHUWhfNT0uN+MUvA3EsLJUPrq3Q==} + '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} @@ -2634,6 +2669,9 @@ packages: '@types/eslint@9.6.1': resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} @@ -4900,6 +4938,9 @@ packages: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + fastq@1.18.0: resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} @@ -8494,6 +8535,13 @@ packages: resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} deprecated: Please see https://github.com/lydell/urix#deprecated + url-polyfill@1.1.12: + resolution: {integrity: sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==} + + url-shim@1.0.1: + resolution: {integrity: sha512-8nwZkCP7pbI8ifcifTZSLRO3W+CWuh/mafPvc7utPRqgxAORnsZIzQ5K8LUsHiQ4mTtJrKRAJmW2ZHxQk0rKUA==} + engines: {node: '>= 6'} + use@3.1.1: resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} engines: {node: '>=0.10.0'} @@ -10702,6 +10750,16 @@ snapshots: prettier: 3.5.3 rxjs: 6.6.7 + '@rollup/browser@4.29.1': + dependencies: + '@types/estree': 1.0.6 + + '@rollup/wasm-node@4.29.1': + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + fsevents: 2.3.2 + '@rtsao/scc@1.1.0': {} '@sigstore/bundle@2.3.2': @@ -10812,6 +10870,8 @@ snapshots: dependencies: '@swc/counter': 0.1.3 + '@swc/wasm-web@1.10.4': {} + '@tootallnate/quickjs-emscripten@0.23.0': {} '@transloadit/prettier-bytes@0.3.4': {} @@ -10861,6 +10921,8 @@ snapshots: '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 + '@types/estree@1.0.6': {} + '@types/estree@1.0.7': {} '@types/express-serve-static-core@4.19.6': @@ -14037,6 +14099,8 @@ snapshots: fastest-levenshtein@1.0.16: {} + fastestsmallesttextencoderdecoder@1.0.22: {} + fastq@1.18.0: dependencies: reusify: 1.0.4 @@ -18140,6 +18204,10 @@ snapshots: urix@0.1.0: {} + url-polyfill@1.1.12: {} + + url-shim@1.0.1: {} + use@3.1.1: {} username-sync@1.0.3: {} From 601f6b5001edc2f1355c9ee61f5c056abe942abd Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 8 May 2025 11:28:22 +0100 Subject: [PATCH 02/36] wip --- .../javascripts/theme-transpiler/package.json | 2 +- .../theme-transpiler/transpiler.js | 100 +++++++++--------- lib/discourse_js_processor.rb | 16 +-- pnpm-lock.yaml | 13 +-- spec/lib/discourse_js_processor_spec.rb | 10 ++ 5 files changed, 76 insertions(+), 65 deletions(-) diff --git a/app/assets/javascripts/theme-transpiler/package.json b/app/assets/javascripts/theme-transpiler/package.json index 033bda35ccdcf..0f57516b9b39a 100644 --- a/app/assets/javascripts/theme-transpiler/package.json +++ b/app/assets/javascripts/theme-transpiler/package.json @@ -9,7 +9,7 @@ "dependencies": { "@babel/standalone": "^7.27.2", "@csstools/postcss-light-dark-function": "^2.0.8", - "@rollup/browser": "^4.29.1", + "@rollup/browser": "^4.40.2", "@rollup/wasm-node": "^4.29.1", "@swc/wasm-web": "^1.10.4", "@zxing/text-encoding": "^0.9.0", diff --git a/app/assets/javascripts/theme-transpiler/transpiler.js b/app/assets/javascripts/theme-transpiler/transpiler.js index da759fe8d92e9..d412f49037667 100644 --- a/app/assets/javascripts/theme-transpiler/transpiler.js +++ b/app/assets/javascripts/theme-transpiler/transpiler.js @@ -3,9 +3,9 @@ import "core-js/actual/url"; import patch from "./text-decoder-shim"; patch(); -import { rollup } from "/Users/david/discourse/rollup/browser/dist/es/rollup.browser.js"; +import { rollup } from "@rollup/browser"; const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; -// globalThis.window = {}; +globalThis.window = {}; const oldConsole = globalThis.console; globalThis.console = { @@ -104,58 +104,54 @@ globalThis.fetch = function (url) { // globalThis.window = dom.window.window; // globalThis.document = dom.window.document; -const modules = { - "main.js": `import foo from 'foo.js'; console.log(foo); { - @test - someProp(){ - console.log("prop"); - } - - `, - "foo.js": "export default 42;", -}; +// const modules = { +// "main.js": `import foo from 'foo.js'; console.log(foo);`, +// "foo.js": "export default 42;", +// }; -const rollupResult = rollup({ - input: "main.js", - logLevel: "info", - onLog(level, message) { - console.log(level, message); - }, - plugins: [ - { - name: "loader", - resolveId(source) { - console.log("resolveid"); - if (modules.hasOwnProperty(source)) { - return source; - } - }, - load(id) { - if (modules.hasOwnProperty(id)) { - return modules[id]; - } - }, +let lastRollupResult; +let lastRollupError; +globalThis.rollup = function (modules, options) { + const resultPromise = rollup({ + input: "main.js", + logLevel: "info", + onLog(level, message) { + console.log(level, message); }, - ], -}); - -rollupResult - .then((bundle) => { - console.log("Hello 1"); - return bundle.generate({ format: "es" }); - }) - .then(({ output }) => console.log("result", output[0].code)) - .catch((error) => console.error("error: ", error, error.stack)); - -let result; -globalThis.getResult = function () { - return result; + plugins: [ + { + name: "loader", + resolveId(source) { + console.log("resolveid"); + if (modules.hasOwnProperty(source)) { + return source; + } + }, + load(id) { + if (modules.hasOwnProperty(id)) { + return modules[id]; + } + }, + }, + ], + }); + + resultPromise + .then((bundle) => { + return bundle.generate({ format: "es" }); + }) + .then(({ output }) => (lastRollupResult = output)) + .catch((error) => (lastRollupError = error)); }; -globalThis.doSomething = async function doSomething() { - await new Promise((resolve) => resolve()); - console.log("returned"); - return "thing"; -}; +globalThis.getRollupResult = function () { + const error = lastRollupError; + const result = lastRollupResult; + + lastRollupError = lastRollupResult = null; -// console.log("done eval", rollupResult); \ No newline at end of file + if (error) { + throw error; + } + return result; +}; \ No newline at end of file diff --git a/lib/discourse_js_processor.rb b/lib/discourse_js_processor.rb index 061463531c48b..34b041a593437 100644 --- a/lib/discourse_js_processor.rb +++ b/lib/discourse_js_processor.rb @@ -55,12 +55,12 @@ def self.create_new_context ctx.attach("rails.logger.warn", proc { |err| Rails.logger.warn(err.to_s) }) ctx.attach("rails.logger.error", proc { |err| Rails.logger.error(err.to_s) }) - # source = - # if Rails.env.production? - # File.read(TRANSPILER_PATH) - # else - # @processor_mutex.synchronize { build_theme_transpiler } - # end + source = + if Rails.env.production? + File.read(TRANSPILER_PATH) + else + @processor_mutex.synchronize { build_theme_transpiler } + end source = File.read("app/assets/javascripts/theme-transpiler/theme-transpiler.js") @@ -155,6 +155,10 @@ def terser(tree, opts) self.class.v8_call("minify", tree, opts, fetch_result_call: "getMinifyResult") end + def rollup(tree, opts) + self.class.v8_call("rollup", tree, opts, fetch_result_call: "getRollupResult") + end + def post_css(css:, map:, source_map_file:) self.class.v8_call( "postCss", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae4d7b4e263c8..bc5c4e738cdd8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1025,8 +1025,8 @@ importers: specifier: ^2.0.8 version: 2.0.8(postcss@8.5.3) '@rollup/browser': - specifier: ^4.29.1 - version: 4.29.1 + specifier: ^4.40.2 + version: 4.40.2 '@rollup/wasm-node': specifier: ^4.29.1 version: 4.29.1 @@ -2105,6 +2105,7 @@ packages: '@faker-js/faker@9.7.0': resolution: {integrity: sha512-aozo5vqjCmDoXLNUJarFZx2IN/GgGaogY4TMJ6so/WLZOWpSV7fvj2dmrV6sEAnUm1O7aCrhTibjpzeDFgNqbg==} engines: {node: '>=18.0.0', npm: '>=9.0.0'} + deprecated: Please update to a newer version '@floating-ui/core@1.7.0': resolution: {integrity: sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==} @@ -2490,8 +2491,8 @@ packages: peerDependencies: prettier: 3.x - '@rollup/browser@4.29.1': - resolution: {integrity: sha512-CsDzu5HTqbY9++9B/jk6Ue/QzozVCnHqSau9ziD/x8nzxEfFsRniycDshZWaSGpHIqHn67PJbwFea83Nu6FQfQ==} + '@rollup/browser@4.40.2': + resolution: {integrity: sha512-X4Wn+Hgj1EPS3SVaP1qp3BN/X5hscLTLg2XtajnulKloJgBjl02viUonCdDUr2hwx+FjN5z00D8rGjiu/MAYuw==} '@rollup/wasm-node@4.29.1': resolution: {integrity: sha512-AOtO2Y+XzElJfmJgAECOgbutmKAK5XcKH7CipGDQDBMfLY04ezEoCHWEpmoX5L7/WH3k17rXMCClNiwDbWW+mw==} @@ -10750,9 +10751,9 @@ snapshots: prettier: 3.5.3 rxjs: 6.6.7 - '@rollup/browser@4.29.1': + '@rollup/browser@4.40.2': dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@rollup/wasm-node@4.29.1': dependencies: diff --git a/spec/lib/discourse_js_processor_spec.rb b/spec/lib/discourse_js_processor_spec.rb index 2d85f6dc7a29c..38031392851ac 100644 --- a/spec/lib/discourse_js_processor_spec.rb +++ b/spec/lib/discourse_js_processor_spec.rb @@ -191,4 +191,14 @@ def standard_compile(template) expect(map["sourcesContent"]).to contain_exactly(*sources.values) end end + + describe "Transpiler#rollup" do + it "can rollup code" do + sources = { "main.js" => "console.log('hello world');" } + + result = DiscourseJsProcessor::Transpiler.new.rollup(sources, {}) + + puts result + end + end end From 37859e5d3193d77a0a0aa16476cb8d779002edfb Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 8 May 2025 11:59:03 +0100 Subject: [PATCH 03/36] bump --- .../theme-transpiler/transpiler.js | 64 +------------------ spec/lib/discourse_js_processor_spec.rb | 9 ++- 2 files changed, 11 insertions(+), 62 deletions(-) diff --git a/app/assets/javascripts/theme-transpiler/transpiler.js b/app/assets/javascripts/theme-transpiler/transpiler.js index d412f49037667..6cf734032f43f 100644 --- a/app/assets/javascripts/theme-transpiler/transpiler.js +++ b/app/assets/javascripts/theme-transpiler/transpiler.js @@ -4,6 +4,7 @@ import patch from "./text-decoder-shim"; patch(); import { rollup } from "@rollup/browser"; + const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; globalThis.window = {}; @@ -30,85 +31,26 @@ globalThis.crypto = { }, }; -// console.log(TextDecoder); -import BindingsWasm from "/Users/david/discourse/rollup/browser/dist/bindings_wasm_bg.wasm"; -// import BindingsWasm from "./node_modules/@rollup/wasm-node/dist/wasm-node/bindings_wasm_bg.wasm"; -// import BindingsWasm from "./memory.wasm"; -// console.log(BindingsWasm); -// new WebAssembly.instantiate(BindingsWasm, ); -// console.log(BindingsWasm); +import BindingsWasm from "./node_modules/@rollup/browser/dist/bindings_wasm_bg.wasm"; const oldInstantiate = WebAssembly.instantiate; WebAssembly.instantiate = async function (bytes, bindings) { - for (let [key, value] of Object.entries(bindings.wbg)) { - // bindings.wbg[key] = (...args) => { - // console.log("called", key); - // return value.apply(bindings, args); - // }; - } - console.log("instantiated", Object.keys(bindings.wbg)); if (bytes === BindingsWasm) { const mod = new WebAssembly.Module(bytes); - // console.log("returning"); const instance = new WebAssembly.Instance(mod, bindings); - console.log("returning instance"); return instance; } else { return oldInstantiate(...arguments); } - // console.log(bindings); - - // return new Promise((resolve) => resolve({})); }; -console.log("trying..."); -// const memory = new WebAssembly.Memory({ -// initial: 10, -// maximum: 100, -// }); -// const importObject = { -// my_namespace: { imported_func: (arg) => console.log(arg) }, -// }; -// const mod = new WebAssembly.Module(BindingsWasm); -// const wasm = new WebAssembly.Instance(mod, { js: { mem: memory } }); -// const summands = new DataView(memory.buffer); - -// for (let i = 0; i < 10; i++) { -// summands.setUint32(i * 4, i, true); // WebAssembly is little endian -// } -// const sum = wasm.exports.accumulate(0, 10); -// console.log(sum); - -// console.log(wasmInstance); -// WebAssembly.instantiate(BindingsWasm, {}) -// .then((result) => { -// console.log("result", result); -// }) -// .catch((error) => console.error("error: ", error)); - globalThis.fetch = function (url) { - // console.log(url); if (url.toString() === "http://example.com/bindings_wasm_bg.wasm") { - // console.log("stubbing fetch"); - console.log("FETCH"); return new Promise((resolve) => resolve(BindingsWasm)); } - console.error("fetch not implemented"); throw "fetch not implemented"; }; -// WebAssembly.instantiate = console.log; - -// const dom = new JSDOM(`

Hello world

`); - -// globalThis.window = dom.window.window; -// globalThis.document = dom.window.document; - -// const modules = { -// "main.js": `import foo from 'foo.js'; console.log(foo);`, -// "foo.js": "export default 42;", -// }; - let lastRollupResult; let lastRollupError; globalThis.rollup = function (modules, options) { @@ -154,4 +96,4 @@ globalThis.getRollupResult = function () { throw error; } return result; -}; \ No newline at end of file +}; diff --git a/spec/lib/discourse_js_processor_spec.rb b/spec/lib/discourse_js_processor_spec.rb index 38031392851ac..50cfec815083a 100644 --- a/spec/lib/discourse_js_processor_spec.rb +++ b/spec/lib/discourse_js_processor_spec.rb @@ -194,11 +194,18 @@ def standard_compile(template) describe "Transpiler#rollup" do it "can rollup code" do - sources = { "main.js" => "console.log('hello world');" } + sources = { + "main.js" => "import 'hello.js'; console.log('hello world 2');", + "hello.js" => "console.log('hello world');", + } result = DiscourseJsProcessor::Transpiler.new.rollup(sources, {}) puts result + + code = result[0]["code"] + expect(code).to include("'hello world'") + expect(code).to include("'hello world 2'") end end end From 79d975527fd279a65aa6bafccdcc18824baea80c Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 8 May 2025 12:00:27 +0100 Subject: [PATCH 04/36] crypto --- app/assets/javascripts/theme-transpiler/transpiler.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/theme-transpiler/transpiler.js b/app/assets/javascripts/theme-transpiler/transpiler.js index 6cf734032f43f..81fda0a8ff9c5 100644 --- a/app/assets/javascripts/theme-transpiler/transpiler.js +++ b/app/assets/javascripts/theme-transpiler/transpiler.js @@ -3,6 +3,9 @@ import "core-js/actual/url"; import patch from "./text-decoder-shim"; patch(); +import getRandomValues from "polyfill-crypto.getrandomvalues"; +globalThis.crypto = { getRandomValues }; + import { rollup } from "@rollup/browser"; const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; @@ -24,13 +27,6 @@ globalThis.console = { }, }; -globalThis.crypto = { - getRandomValues() { - // todo... not much random going on here - console.log("getRandomValues"); - }, -}; - import BindingsWasm from "./node_modules/@rollup/browser/dist/bindings_wasm_bg.wasm"; const oldInstantiate = WebAssembly.instantiate; From ef410fc84fe98e206abc0dfe1506697edfc5a913 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 8 May 2025 12:25:46 +0100 Subject: [PATCH 05/36] bump --- .../javascripts/theme-transpiler/build.js | 2 + .../javascripts/theme-transpiler/noop.js | 1 + .../javascripts/theme-transpiler/package.json | 5 +- .../theme-transpiler/text-decoder-shim.js | 6 +++ .../theme-transpiler/transpiler.js | 7 +++ pnpm-lock.yaml | 52 +++++++++++++++++++ spec/lib/discourse_js_processor_spec.rb | 11 +++- 7 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/theme-transpiler/noop.js diff --git a/app/assets/javascripts/theme-transpiler/build.js b/app/assets/javascripts/theme-transpiler/build.js index 967538f41cd85..03bcc411c31d3 100644 --- a/app/assets/javascripts/theme-transpiler/build.js +++ b/app/assets/javascripts/theme-transpiler/build.js @@ -53,6 +53,8 @@ esbuild path: "path-browserify", url: "./url-polyfill", "source-map-js": "source-map-js", + assert: "./noop", + fs: "./noop", }, banner: { js: `var process = { "env": { "EMBER_ENV": "production" }, "cwd": () => "/" };`, diff --git a/app/assets/javascripts/theme-transpiler/noop.js b/app/assets/javascripts/theme-transpiler/noop.js new file mode 100644 index 0000000000000..ff8b4c56321a3 --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/noop.js @@ -0,0 +1 @@ +export default {}; diff --git a/app/assets/javascripts/theme-transpiler/package.json b/app/assets/javascripts/theme-transpiler/package.json index 0f57516b9b39a..8afcb06aa61e8 100644 --- a/app/assets/javascripts/theme-transpiler/package.json +++ b/app/assets/javascripts/theme-transpiler/package.json @@ -10,6 +10,7 @@ "@babel/standalone": "^7.27.2", "@csstools/postcss-light-dark-function": "^2.0.8", "@rollup/browser": "^4.40.2", + "@rollup/plugin-babel": "^6.0.4", "@rollup/wasm-node": "^4.29.1", "@swc/wasm-web": "^1.10.4", "@zxing/text-encoding": "^0.9.0", @@ -18,8 +19,8 @@ "content-tag": "^3.1.3", "core-js": "^3.42.0", "decorator-transforms": "^2.3.0", - "discourse-widget-hbs": "workspace:1.0.0", "discourse": "workspace:0.0.0", + "discourse-widget-hbs": "workspace:1.0.0", "ember-cli-htmlbars": "^6.3.0", "ember-source": "~5.12.0", "ember-this-fallback": "^0.4.0", @@ -28,9 +29,9 @@ "jsdom": "^25.0.1", "path-browserify": "^1.0.1", "polyfill-crypto.getrandomvalues": "^1.0.0", + "postcss": "^8.5.3", "postcss-js": "^4.0.1", "postcss-media-minmax": "^5.0.0", - "postcss": "^8.5.3", "source-map-js": "^1.2.1", "terser": "^5.39.0", "url-polyfill": "^1.1.12", diff --git a/app/assets/javascripts/theme-transpiler/text-decoder-shim.js b/app/assets/javascripts/theme-transpiler/text-decoder-shim.js index 9bee83266588b..0f688695c9456 100644 --- a/app/assets/javascripts/theme-transpiler/text-decoder-shim.js +++ b/app/assets/javascripts/theme-transpiler/text-decoder-shim.js @@ -4,3 +4,9 @@ export default function patch() { globalThis.TextEncoder = TextEncoder; globalThis.TextDecoder = TextDecoder; } + +import path from "path"; + +path.win32 = { + sep: "/", +}; diff --git a/app/assets/javascripts/theme-transpiler/transpiler.js b/app/assets/javascripts/theme-transpiler/transpiler.js index 81fda0a8ff9c5..d43cf3fb5fb2e 100644 --- a/app/assets/javascripts/theme-transpiler/transpiler.js +++ b/app/assets/javascripts/theme-transpiler/transpiler.js @@ -7,6 +7,8 @@ import getRandomValues from "polyfill-crypto.getrandomvalues"; globalThis.crypto = { getRandomValues }; import { rollup } from "@rollup/browser"; +import { babel } from "@rollup/plugin-babel"; +import DecoratorTransforms from "decorator-transforms"; const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; globalThis.window = {}; @@ -71,6 +73,11 @@ globalThis.rollup = function (modules, options) { } }, }, + babel({ + extensions: [".js", ".gjs"], + babelHelpers: "bundled", + plugins: [DecoratorTransforms], + }), ], }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc5c4e738cdd8..04645da378306 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1027,6 +1027,9 @@ importers: '@rollup/browser': specifier: ^4.40.2 version: 4.40.2 + '@rollup/plugin-babel': + specifier: ^6.0.4 + version: 6.0.4(@babel/core@7.27.1) '@rollup/wasm-node': specifier: ^4.29.1 version: 4.29.1 @@ -1075,6 +1078,9 @@ importers: jsdom: specifier: ^25.0.1 version: 25.0.1(supports-color@8.1.1) + node-path: + specifier: ^0.0.3 + version: 0.0.3 path-browserify: specifier: ^1.0.1 version: 1.0.1 @@ -2494,6 +2500,28 @@ packages: '@rollup/browser@4.40.2': resolution: {integrity: sha512-X4Wn+Hgj1EPS3SVaP1qp3BN/X5hscLTLg2XtajnulKloJgBjl02viUonCdDUr2hwx+FjN5z00D8rGjiu/MAYuw==} + '@rollup/plugin-babel@6.0.4': + resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + rollup: + optional: true + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/wasm-node@4.29.1': resolution: {integrity: sha512-AOtO2Y+XzElJfmJgAECOgbutmKAK5XcKH7CipGDQDBMfLY04ezEoCHWEpmoX5L7/WH3k17rXMCClNiwDbWW+mw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -4811,6 +4839,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -6665,6 +6696,9 @@ packages: node-notifier@10.0.1: resolution: {integrity: sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==} + node-path@0.0.3: + resolution: {integrity: sha512-S+n5Gb8mQHr8AAzrLo/VD+6gq+45b8B/U0o0/Cnx+vBctvC9EvzapdV5Jem5rJT95mNrweZnxAuQErlTWSDjiA==} + node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -10755,6 +10789,20 @@ snapshots: dependencies: '@types/estree': 1.0.7 + '@rollup/plugin-babel@6.0.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-module-imports': 7.27.1(supports-color@8.1.1) + '@rollup/pluginutils': 5.1.4 + transitivePeerDependencies: + - supports-color + + '@rollup/pluginutils@5.1.4': + dependencies: + '@types/estree': 1.0.7 + estree-walker: 2.0.2 + picomatch: 4.0.2 + '@rollup/wasm-node@4.29.1': dependencies: '@types/estree': 1.0.6 @@ -13858,6 +13906,8 @@ snapshots: estraverse@5.3.0: {} + estree-walker@2.0.2: {} + esutils@2.0.3: {} etag@1.8.1: {} @@ -15997,6 +16047,8 @@ snapshots: uuid: 8.3.2 which: 2.0.2 + node-path@0.0.3: {} + node-releases@2.0.19: {} node-watch@0.7.3: {} diff --git a/spec/lib/discourse_js_processor_spec.rb b/spec/lib/discourse_js_processor_spec.rb index 50cfec815083a..f6988f230bb31 100644 --- a/spec/lib/discourse_js_processor_spec.rb +++ b/spec/lib/discourse_js_processor_spec.rb @@ -196,7 +196,15 @@ def standard_compile(template) it "can rollup code" do sources = { "main.js" => "import 'hello.js'; console.log('hello world 2');", - "hello.js" => "console.log('hello world');", + "hello.js" => <<~JS, + someDecorator = () => {} + class MyClass { + @someDecorator + myMethod() { + console.log('hello world'); + } + } + JS } result = DiscourseJsProcessor::Transpiler.new.rollup(sources, {}) @@ -206,6 +214,7 @@ def standard_compile(template) code = result[0]["code"] expect(code).to include("'hello world'") expect(code).to include("'hello world 2'") + expect(code).to include("dt7948") # Decorator transform end end end From 63b88d720f4bc6d55d8d9d9eab9038ebbf169b59 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 8 May 2025 13:17:24 +0100 Subject: [PATCH 06/36] gjs --- .../theme-transpiler/babel-replace-imports.js | 48 ++++++++++++++++ .../theme-transpiler/transpiler.js | 55 +++++++++++++++++-- lib/discourse_js_processor.rb | 4 +- spec/lib/discourse_js_processor_spec.rb | 7 ++- 4 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 app/assets/javascripts/theme-transpiler/babel-replace-imports.js diff --git a/app/assets/javascripts/theme-transpiler/babel-replace-imports.js b/app/assets/javascripts/theme-transpiler/babel-replace-imports.js new file mode 100644 index 0000000000000..f0439f46890b8 --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/babel-replace-imports.js @@ -0,0 +1,48 @@ +export default function (babel) { + const { types: t } = babel; + + return { + visitor: { + ImportDeclaration(path) { + const moduleName = path.node.source.value; + if (moduleName.startsWith(".")) { + return; + } + + const properties = path.node.specifiers.map((specifier) => { + if (specifier.type === "ImportDefaultSpecifier") { + return t.objectProperty( + t.identifier("default"), + t.identifier(specifier.local.name) + ); + } else { + return t.objectProperty( + t.identifier(specifier.imported.name), + t.identifier(specifier.local.name) + ); + } + }); + + const replacement = t.variableDeclaration("const", [ + t.variableDeclarator( + t.objectPattern(properties), + t.awaitExpression( + t.callExpression( + t.memberExpression( + t.memberExpression( + t.identifier("window"), + t.identifier("moduleBroker") + ), + t.identifier("lookup") + ), + [t.stringLiteral(moduleName)] + ) + ) + ), + ]); + + path.replaceWith(replacement); + }, + }, + }; +} diff --git a/app/assets/javascripts/theme-transpiler/transpiler.js b/app/assets/javascripts/theme-transpiler/transpiler.js index d43cf3fb5fb2e..99ca3f9f44301 100644 --- a/app/assets/javascripts/theme-transpiler/transpiler.js +++ b/app/assets/javascripts/theme-transpiler/transpiler.js @@ -2,13 +2,18 @@ import "core-js/actual/url"; import patch from "./text-decoder-shim"; patch(); - +import { dirname, relative } from "path"; import getRandomValues from "polyfill-crypto.getrandomvalues"; globalThis.crypto = { getRandomValues }; - import { rollup } from "@rollup/browser"; import { babel } from "@rollup/plugin-babel"; +import HTMLBarsInlinePrecompile from "babel-plugin-ember-template-compilation"; +import { Preprocessor } from "content-tag"; import DecoratorTransforms from "decorator-transforms"; +import { precompile } from "ember-source/dist/ember-template-compiler"; +import BabelReplaceImports from "./babel-replace-imports"; + +const preprocessor = new Preprocessor(); const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; globalThis.window = {}; @@ -61,8 +66,14 @@ globalThis.rollup = function (modules, options) { plugins: [ { name: "loader", - resolveId(source) { - console.log("resolveid"); + resolve: { + extensions: [".js", ".gjs"], + }, + resolveId(source, context) { + if (source.startsWith(".")) { + source = relative(dirname(context), source); + } + console.log("resolveid", source, context); if (modules.hasOwnProperty(source)) { return source; } @@ -76,8 +87,42 @@ globalThis.rollup = function (modules, options) { babel({ extensions: [".js", ".gjs"], babelHelpers: "bundled", - plugins: [DecoratorTransforms], + plugins: [ + DecoratorTransforms, + BabelReplaceImports, + [ + HTMLBarsInlinePrecompile, + { + compiler: { precompile }, + enableLegacyModules: [ + "ember-cli-htmlbars", + "ember-cli-htmlbars-inline-precompile", + "htmlbars-inline-precompile", + ], + }, + ], + ], }), + { + name: "gjs-transform", + + transform: { + // Enforce running the gjs transform before any others like babel that expect valid JS + order: "pre", + handler(input, id) { + if (!id.endsWith(".gjs")) { + return null; + } + let { code, map } = preprocessor.process(input, { + filename: id, + }); + return { + code, + map, + }; + }, + }, + }, ], }); diff --git a/lib/discourse_js_processor.rb b/lib/discourse_js_processor.rb index 34b041a593437..c390a71d04b75 100644 --- a/lib/discourse_js_processor.rb +++ b/lib/discourse_js_processor.rb @@ -51,8 +51,8 @@ def self.create_new_context ctx = MiniRacer::Context.new(timeout: 15_000, ensure_gc_after_idle: 2000) # General shims - ctx.attach("rails.logger.info", proc { |err| Rails.logger.info(err.to_s) }) - ctx.attach("rails.logger.warn", proc { |err| Rails.logger.warn(err.to_s) }) + ctx.attach("rails.logger.info", proc { |err| Rails.logger.info(p(err.to_s)) }) + ctx.attach("rails.logger.warn", proc { |err| Rails.logger.warn(p(err.to_s)) }) ctx.attach("rails.logger.error", proc { |err| Rails.logger.error(err.to_s) }) source = diff --git a/spec/lib/discourse_js_processor_spec.rb b/spec/lib/discourse_js_processor_spec.rb index f6988f230bb31..5a38cff2df641 100644 --- a/spec/lib/discourse_js_processor_spec.rb +++ b/spec/lib/discourse_js_processor_spec.rb @@ -195,14 +195,17 @@ def standard_compile(template) describe "Transpiler#rollup" do it "can rollup code" do sources = { - "main.js" => "import 'hello.js'; console.log('hello world 2');", - "hello.js" => <<~JS, + "main.js" => "import './hello.gjs'; console.log('hello world 2');", + "hello.gjs" => <<~JS, someDecorator = () => {} class MyClass { @someDecorator myMethod() { console.log('hello world'); } + } JS } From de2a11dafd7e4cdeaa1d36ba83c1e8dfbed73427 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Fri, 9 May 2025 13:38:58 +0100 Subject: [PATCH 07/36] tidy --- .../theme-transpiler/content-tag.js | 9 + .../javascripts/theme-transpiler/shims.js | 29 +++ .../theme-transpiler/text-decoder-shim.js | 12 - .../theme-transpiler/theme-rollup.js | 122 +++++++++ .../theme-transpiler/transpiler.js | 246 +++++++++--------- package.json | 1 - patches/content-tag@3.1.3.patch | 24 -- pnpm-lock.yaml | 27 +- 8 files changed, 291 insertions(+), 179 deletions(-) create mode 100644 app/assets/javascripts/theme-transpiler/content-tag.js create mode 100644 app/assets/javascripts/theme-transpiler/shims.js delete mode 100644 app/assets/javascripts/theme-transpiler/text-decoder-shim.js create mode 100644 app/assets/javascripts/theme-transpiler/theme-rollup.js delete mode 100644 patches/content-tag@3.1.3.patch diff --git a/app/assets/javascripts/theme-transpiler/content-tag.js b/app/assets/javascripts/theme-transpiler/content-tag.js new file mode 100644 index 0000000000000..3b2bebe1a8eda --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/content-tag.js @@ -0,0 +1,9 @@ +import { + initSync, + Preprocessor, +} from "./node_modules/content-tag/pkg/standalone/content_tag.js"; +import contentTagWasm from "./node_modules/content-tag/pkg/standalone/content_tag_bg.wasm"; + +export { Preprocessor }; + +initSync(contentTagWasm); diff --git a/app/assets/javascripts/theme-transpiler/shims.js b/app/assets/javascripts/theme-transpiler/shims.js new file mode 100644 index 0000000000000..e6470c5884dd8 --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/shims.js @@ -0,0 +1,29 @@ +/* global rails */ + +import "core-js/actual/url"; +import { TextDecoder, TextEncoder } from "fastestsmallesttextencoderdecoder"; +import path from "path"; +import getRandomValues from "polyfill-crypto.getrandomvalues"; + +const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; +globalThis.window = {}; +globalThis.console = { + log(...args) { + rails.logger.info(CONSOLE_PREFIX + args.join(" ")); + }, + warn(...args) { + rails.logger.warn(CONSOLE_PREFIX + args.join(" ")); + }, + error(...args) { + rails.logger.error(CONSOLE_PREFIX + args.join(" ")); + }, +}; + +globalThis.TextEncoder = TextEncoder; +globalThis.TextDecoder = TextDecoder; + +path.win32 = { + sep: "/", +}; + +globalThis.crypto = { getRandomValues }; diff --git a/app/assets/javascripts/theme-transpiler/text-decoder-shim.js b/app/assets/javascripts/theme-transpiler/text-decoder-shim.js deleted file mode 100644 index 0f688695c9456..0000000000000 --- a/app/assets/javascripts/theme-transpiler/text-decoder-shim.js +++ /dev/null @@ -1,12 +0,0 @@ -import { TextDecoder, TextEncoder } from "fastestsmallesttextencoderdecoder"; - -export default function patch() { - globalThis.TextEncoder = TextEncoder; - globalThis.TextDecoder = TextDecoder; -} - -import path from "path"; - -path.win32 = { - sep: "/", -}; diff --git a/app/assets/javascripts/theme-transpiler/theme-rollup.js b/app/assets/javascripts/theme-transpiler/theme-rollup.js new file mode 100644 index 0000000000000..1547cad5cb949 --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/theme-rollup.js @@ -0,0 +1,122 @@ +import { rollup } from "@rollup/browser"; +import { babel } from "@rollup/plugin-babel"; +import HTMLBarsInlinePrecompile from "babel-plugin-ember-template-compilation"; +import DecoratorTransforms from "decorator-transforms"; +import { precompile } from "ember-source/dist/ember-template-compiler"; +import { dirname, relative } from "path"; +import BabelReplaceImports from "./babel-replace-imports"; +import { Preprocessor } from "./content-tag"; + +const preprocessor = new Preprocessor(); + +import BindingsWasm from "./node_modules/@rollup/browser/dist/bindings_wasm_bg.wasm"; + +const oldInstantiate = WebAssembly.instantiate; +WebAssembly.instantiate = async function (bytes, bindings) { + if (bytes === BindingsWasm) { + const mod = new WebAssembly.Module(bytes); + const instance = new WebAssembly.Instance(mod, bindings); + return instance; + } else { + return oldInstantiate(...arguments); + } +}; + +globalThis.fetch = function (url) { + if (url.toString() === "http://example.com/bindings_wasm_bg.wasm") { + return new Promise((resolve) => resolve(BindingsWasm)); + } + throw "fetch not implemented"; +}; + +let lastRollupResult; +let lastRollupError; +globalThis.rollup = function (modules, options) { + const resultPromise = rollup({ + input: "main.js", + logLevel: "info", + onLog(level, message) { + console.log(level, message); + }, + plugins: [ + { + name: "loader", + resolve: { + extensions: [".js", ".gjs"], + }, + resolveId(source, context) { + if (source.startsWith(".")) { + source = relative(dirname(context), source); + } + console.log("resolveid", source, context); + if (modules.hasOwnProperty(source)) { + return source; + } + }, + load(id) { + if (modules.hasOwnProperty(id)) { + return modules[id]; + } + }, + }, + babel({ + extensions: [".js", ".gjs"], + babelHelpers: "bundled", + plugins: [ + DecoratorTransforms, + BabelReplaceImports, + [ + HTMLBarsInlinePrecompile, + { + compiler: { precompile }, + enableLegacyModules: [ + "ember-cli-htmlbars", + "ember-cli-htmlbars-inline-precompile", + "htmlbars-inline-precompile", + ], + }, + ], + ], + }), + { + name: "gjs-transform", + + transform: { + // Enforce running the gjs transform before any others like babel that expect valid JS + order: "pre", + handler(input, id) { + if (!id.endsWith(".gjs")) { + return null; + } + let { code, map } = preprocessor.process(input, { + filename: id, + }); + return { + code, + map, + }; + }, + }, + }, + ], + }); + + resultPromise + .then((bundle) => { + return bundle.generate({ format: "es" }); + }) + .then(({ output }) => (lastRollupResult = output)) + .catch((error) => (lastRollupError = error)); +}; + +globalThis.getRollupResult = function () { + const error = lastRollupError; + const result = lastRollupResult; + + lastRollupError = lastRollupResult = null; + + if (error) { + throw error; + } + return result; +}; diff --git a/app/assets/javascripts/theme-transpiler/transpiler.js b/app/assets/javascripts/theme-transpiler/transpiler.js index 99ca3f9f44301..3858025b75815 100644 --- a/app/assets/javascripts/theme-transpiler/transpiler.js +++ b/app/assets/javascripts/theme-transpiler/transpiler.js @@ -1,147 +1,147 @@ -// import { JSDOM } from "jsdom"; -import "core-js/actual/url"; -import patch from "./text-decoder-shim"; -patch(); -import { dirname, relative } from "path"; -import getRandomValues from "polyfill-crypto.getrandomvalues"; -globalThis.crypto = { getRandomValues }; -import { rollup } from "@rollup/browser"; -import { babel } from "@rollup/plugin-babel"; +import "./shims"; +import "./postcss"; +import "./theme-rollup"; +import { transform as babelTransform } from "@babel/standalone"; import HTMLBarsInlinePrecompile from "babel-plugin-ember-template-compilation"; -import { Preprocessor } from "content-tag"; import DecoratorTransforms from "decorator-transforms"; +import colocatedBabelPlugin from "ember-cli-htmlbars/lib/colocated-babel-plugin"; import { precompile } from "ember-source/dist/ember-template-compiler"; -import BabelReplaceImports from "./babel-replace-imports"; +import EmberThisFallback from "ember-this-fallback"; +import { minify as terserMinify } from "terser"; +import { WidgetHbsCompiler } from "discourse-widget-hbs/lib/widget-hbs-compiler"; +import { browsers } from "../discourse/config/targets"; +import { Preprocessor } from "./content-tag"; -const preprocessor = new Preprocessor(); +const thisFallbackPlugin = EmberThisFallback._buildPlugin({ + enableLogging: false, + isTheme: true, +}).plugin; -const CONSOLE_PREFIX = "[DiscourseJsProcessor] "; -globalThis.window = {}; - -const oldConsole = globalThis.console; -globalThis.console = { - log(...args) { - globalThis.rails?.logger.info(CONSOLE_PREFIX + args.join(" ")); - oldConsole.log(...args); - }, - warn(...args) { - globalThis.rails?.logger.warn(CONSOLE_PREFIX + args.join(" ")); - oldConsole.warn(...args); - }, - error(...args) { - globalThis.rails?.logger.error(CONSOLE_PREFIX + args.join(" ")); - oldConsole.error(...args); - }, -}; +function manipulateAstNodeForTheme(node, themeId) { + // Magically add theme id as the first param for each of these helpers) + if ( + node.path.parts && + ["theme-i18n", "theme-prefix", "theme-setting"].includes(node.path.parts[0]) + ) { + if (node.params.length === 1) { + node.params.unshift({ + type: "NumberLiteral", + value: themeId, + original: themeId, + loc: { start: {}, end: {} }, + }); + } + } +} -import BindingsWasm from "./node_modules/@rollup/browser/dist/bindings_wasm_bg.wasm"; +function buildEmberTemplateManipulatorPlugin(themeId) { + return function () { + return { + name: "theme-template-manipulator", + visitor: { + SubExpression: (node) => manipulateAstNodeForTheme(node, themeId), + MustacheStatement: (node) => manipulateAstNodeForTheme(node, themeId), + }, + }; + }; +} -const oldInstantiate = WebAssembly.instantiate; -WebAssembly.instantiate = async function (bytes, bindings) { - if (bytes === BindingsWasm) { - const mod = new WebAssembly.Module(bytes); - const instance = new WebAssembly.Instance(mod, bindings); - return instance; - } else { - return oldInstantiate(...arguments); - } -}; +function buildTemplateCompilerBabelPlugins({ extension, themeId }) { + const compiler = { precompile }; -globalThis.fetch = function (url) { - if (url.toString() === "http://example.com/bindings_wasm_bg.wasm") { - return new Promise((resolve) => resolve(BindingsWasm)); + if (themeId && extension !== "gjs") { + compiler.precompile = (src, opts) => { + return precompile(src, { + ...opts, + plugins: { + ast: [ + buildEmberTemplateManipulatorPlugin(themeId), + thisFallbackPlugin, + ], + }, + }); + }; } - throw "fetch not implemented"; -}; -let lastRollupResult; -let lastRollupError; -globalThis.rollup = function (modules, options) { - const resultPromise = rollup({ - input: "main.js", - logLevel: "info", - onLog(level, message) { - console.log(level, message); - }, - plugins: [ + return [ + colocatedBabelPlugin, + WidgetHbsCompiler, + [ + HTMLBarsInlinePrecompile, { - name: "loader", - resolve: { - extensions: [".js", ".gjs"], - }, - resolveId(source, context) { - if (source.startsWith(".")) { - source = relative(dirname(context), source); - } - console.log("resolveid", source, context); - if (modules.hasOwnProperty(source)) { - return source; - } - }, - load(id) { - if (modules.hasOwnProperty(id)) { - return modules[id]; - } - }, + compiler, + enableLegacyModules: [ + "ember-cli-htmlbars", + "ember-cli-htmlbars-inline-precompile", + "htmlbars-inline-precompile", + ], }, - babel({ - extensions: [".js", ".gjs"], - babelHelpers: "bundled", - plugins: [ - DecoratorTransforms, - BabelReplaceImports, - [ - HTMLBarsInlinePrecompile, - { - compiler: { precompile }, - enableLegacyModules: [ - "ember-cli-htmlbars", - "ember-cli-htmlbars-inline-precompile", - "htmlbars-inline-precompile", - ], + ], + ]; +} + +globalThis.transpile = function (source, options = {}) { + const { moduleId, filename, extension, skipModule, themeId } = options; + + if (extension === "gjs") { + const preprocessor = new Preprocessor(); + source = preprocessor.process(source).code; + } + + const plugins = []; + plugins.push(...buildTemplateCompilerBabelPlugins({ extension, themeId })); + if (moduleId && !skipModule) { + plugins.push(["transform-modules-amd", { noInterop: true }]); + } + plugins.push([DecoratorTransforms, { runEarly: true }]); + + try { + return babelTransform(source, { + moduleId, + filename, + ast: false, + plugins, + presets: [ + [ + "env", + { + modules: false, + targets: { + browsers, }, - ], + }, ], - }), - { - name: "gjs-transform", + ], + }).code; + } catch (error) { + // Workaround for https://github.com/rubyjs/mini_racer/issues/262 + error.message = JSON.stringify(error.message); + throw error; + } +}; - transform: { - // Enforce running the gjs transform before any others like babel that expect valid JS - order: "pre", - handler(input, id) { - if (!id.endsWith(".gjs")) { - return null; - } - let { code, map } = preprocessor.process(input, { - filename: id, - }); - return { - code, - map, - }; - }, - }, - }, - ], - }); +// mini_racer doesn't have native support for getting the result of an async operation. +// To work around that, we provide a getMinifyResult which can be used to fetch the result +// in a followup method call. +let lastMinifyError, lastMinifyResult; - resultPromise - .then((bundle) => { - return bundle.generate({ format: "es" }); - }) - .then(({ output }) => (lastRollupResult = output)) - .catch((error) => (lastRollupError = error)); +globalThis.minify = async function (sources, options) { + lastMinifyError = lastMinifyResult = null; + try { + lastMinifyResult = await terserMinify(sources, options); + } catch (e) { + lastMinifyError = e; + } }; -globalThis.getRollupResult = function () { - const error = lastRollupError; - const result = lastRollupResult; +globalThis.getMinifyResult = function () { + const error = lastMinifyError; + const result = lastMinifyResult; - lastRollupError = lastRollupResult = null; + lastMinifyError = lastMinifyResult = null; if (error) { - throw error; + throw error.toString(); } return result; }; diff --git a/package.json b/package.json index 64c633cf677e5..a941d1dd867a9 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "babel-plugin-debug-macros@0.3.4": "patches/babel-plugin-debug-macros@0.3.4.patch", "virtual-dom@2.1.1": "patches/virtual-dom@2.1.1.patch", "licensee@11.1.1": "patches/licensee@11.1.1.patch", - "content-tag@3.1.3": "patches/content-tag@3.1.3.patch", "@ember-compat/tracked-built-ins@0.9.1": "patches/@ember-compat__tracked-built-ins@0.9.1.patch", "ember-source@5.12.0": "patches/ember-source@5.12.0.patch" }, diff --git a/patches/content-tag@3.1.3.patch b/patches/content-tag@3.1.3.patch deleted file mode 100644 index 70d6c29a93b0c..0000000000000 --- a/patches/content-tag@3.1.3.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/pkg/standalone/content_tag.js b/pkg/standalone/content_tag.js -index ffac649b59d3c00ee025807971082cfea4e1cb2c..511c7ccf57b16e2d95dcd94da737d79ef170387f 100644 ---- a/pkg/standalone/content_tag.js -+++ b/pkg/standalone/content_tag.js -@@ -1,5 +1,6 @@ - let wasm; - -+const { TextDecoder, TextEncoder } = require('util'); - const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); - - if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; -diff --git a/pkg/standalone.js b/pkg/standalone.js -index cb50046539df05b41dcc842ffb98e354236f8d26..10eea2962ffd804905d85057bb25d5b30b4d2e11 100644 ---- a/pkg/standalone.js -+++ b/pkg/standalone.js -@@ -1,5 +1,6 @@ --import init from "./standalone/content_tag.js"; -+import { initSync } from "./standalone/content_tag.js"; -+import module from "./standalone/content_tag_bg.wasm"; - export { Preprocessor } from "./standalone/content_tag.js"; - --await init(); -+initSync(module); - diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04645da378306..59c466c52b111 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,9 +11,6 @@ patchedDependencies: babel-plugin-debug-macros@0.3.4: hash: wki6cycbrrm5sscamn5w4cujby path: patches/babel-plugin-debug-macros@0.3.4.patch - content-tag@3.1.3: - hash: lgdkxhmahesfzwpl4vwprolz5m - path: patches/content-tag@3.1.3.patch ember-source@5.12.0: hash: xx7mvsb7nmshqkkqhmf45r3hse path: patches/ember-source@5.12.0.patch @@ -1047,7 +1044,7 @@ importers: version: 2.4.1 content-tag: specifier: ^3.1.3 - version: 3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m) + version: 3.1.3 core-js: specifier: ^3.42.0 version: 3.42.0 @@ -1078,9 +1075,6 @@ importers: jsdom: specifier: ^25.0.1 version: 25.0.1(supports-color@8.1.1) - node-path: - specifier: ^0.0.3 - version: 0.0.3 path-browserify: specifier: ^1.0.1 version: 1.0.1 @@ -6696,9 +6690,6 @@ packages: node-notifier@10.0.1: resolution: {integrity: sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==} - node-path@0.0.3: - resolution: {integrity: sha512-S+n5Gb8mQHr8AAzrLo/VD+6gq+45b8B/U0o0/Cnx+vBctvC9EvzapdV5Jem5rJT95mNrweZnxAuQErlTWSDjiA==} - node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -12509,11 +12500,11 @@ snapshots: content-tag-utils@0.3.1: dependencies: - content-tag: 3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m) + content-tag: 3.1.3 content-tag@2.0.3: {} - content-tag@3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m): {} + content-tag@3.1.3: {} content-type@1.0.5: {} @@ -13144,7 +13135,7 @@ snapshots: compression: 1.8.0 configstore: 5.0.1 console-ui: 3.1.2 - content-tag: 3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m) + content-tag: 3.1.3 core-object: 3.1.5 dag-map: 2.0.2 diff: 7.0.0 @@ -13446,7 +13437,7 @@ snapshots: ember-template-imports@4.3.0: dependencies: broccoli-stew: 3.0.0 - content-tag: 3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m) + content-tag: 3.1.3 ember-cli-version-checker: 5.1.2 transitivePeerDependencies: - supports-color @@ -13462,7 +13453,7 @@ snapshots: aria-query: 5.3.2 chalk: 5.4.1 ci-info: 4.2.0 - content-tag: 3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m) + content-tag: 3.1.3 content-tag-utils: 0.3.1 date-fns: 3.6.0 ember-template-recast: 6.1.5 @@ -15527,7 +15518,7 @@ snapshots: lint-to-the-future-ember-template@3.1.0(ember-template-lint@7.0.1(@babel/core@7.27.1)): dependencies: - content-tag: 3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m) + content-tag: 3.1.3 debug: 4.4.0(supports-color@8.1.1) ember-template-lint: 7.0.1(@babel/core@7.27.1) globby: 14.1.0 @@ -16047,8 +16038,6 @@ snapshots: uuid: 8.3.2 which: 2.0.2 - node-path@0.0.3: {} - node-releases@2.0.19: {} node-watch@0.7.3: {} @@ -16584,7 +16573,7 @@ snapshots: prettier-plugin-ember-template-tag@2.0.5(prettier@3.5.3): dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - content-tag: 3.1.3(patch_hash=lgdkxhmahesfzwpl4vwprolz5m) + content-tag: 3.1.3 prettier: 3.5.3 transitivePeerDependencies: - supports-color From ddb1ea11d3acccfb7fbdda8693d7ed3a0b9c01e4 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Fri, 9 May 2025 15:33:43 +0100 Subject: [PATCH 08/36] hax --- app/assets/javascripts/discourse/app/app.js | 14 + .../public/assets/scripts/start-app.js | 18 +- .../javascripts/theme-transpiler/package.json | 1 + .../theme-transpiler/theme-rollup.js | 74 +- app/models/theme.rb | 5 +- lib/discourse_js_processor.rb | 2 +- lib/theme_javascript_compiler.rb | 54 +- pnpm-lock.yaml | 1031 +++++++++++++++-- spec/lib/discourse_js_processor_spec.rb | 28 +- spec/lib/theme_javascript_compiler_spec.rb | 14 +- 10 files changed, 1092 insertions(+), 149 deletions(-) diff --git a/app/assets/javascripts/discourse/app/app.js b/app/assets/javascripts/discourse/app/app.js index fa7b901c0ea5a..9c7ebe1817e9b 100644 --- a/app/assets/javascripts/discourse/app/app.js +++ b/app/assets/javascripts/discourse/app/app.js @@ -19,6 +19,14 @@ import { buildResolver } from "discourse/resolver"; const _pluginCallbacks = []; let _unhandledThemeErrors = []; +console.log("run"); +window.moduleBroker = { + lookup: function (moduleName) { + return require(moduleName); + }, +}; +window.themePrefix = (str) => str; + class Discourse extends Application { modulePrefix = "discourse"; rootElement = "#main"; @@ -156,6 +164,12 @@ function loadInitializers(app) { app.instanceInitializer(resolveDiscourseInitializer(moduleName, themeId)); } + window.themeInitializers.forEach((obj) => { + for (const [moduleName, initializer] of Object.entries(obj)) { + app.instanceInitializer(initializer); + } + }); + // Plugins that are registered via ` + + HTML end when :translations diff --git a/lib/discourse_js_processor.rb b/lib/discourse_js_processor.rb index c390a71d04b75..8abe496e50b5e 100644 --- a/lib/discourse_js_processor.rb +++ b/lib/discourse_js_processor.rb @@ -156,7 +156,7 @@ def terser(tree, opts) end def rollup(tree, opts) - self.class.v8_call("rollup", tree, opts, fetch_result_call: "getRollupResult") + self.class.v8_call("rollup", tree, opts, fetch_result_call: "getRollupResult")[0] end def post_css(css:, map:, source_map_file:) diff --git a/lib/theme_javascript_compiler.rb b/lib/theme_javascript_compiler.rb index 7b6b2eb396585..9d66302308911 100644 --- a/lib/theme_javascript_compiler.rb +++ b/lib/theme_javascript_compiler.rb @@ -33,10 +33,8 @@ def compile! output = if !has_content? { "code" => "" } - elsif @@terser_disabled || !@minify - { "code" => raw_content } else - DiscourseJsProcessor::Transpiler.new.terser(@output_tree.to_h, terser_config) + DiscourseJsProcessor::Transpiler.new.rollup(@output_tree.to_h, {}) end @content = output["code"] @@ -161,61 +159,19 @@ def append_tree(tree, include_variables: true) end # Transpile and write to output - tree.each_pair do |filename, content| - module_name, extension = filename.split(".", 2) - - if extension == "js" || extension == "gjs" - append_module(content, module_name, extension, include_variables:) - elsif extension == "hbs" - append_ember_template(module_name, content) - else - append_js_error(filename, "unknown file extension '#{extension}' (#{filename})") - end - rescue CompileError => e - append_js_error filename, "#{e.message} (#{filename})" - end + tree.each_pair { |filename, content| @output_tree << [filename, content] } end def append_ember_template(name, hbs_template) - module_name = name - module_name = "/#{module_name}" if !module_name.start_with?("/") - module_name = "discourse/theme-#{@theme_id}#{module_name}" - - # Mimics the ember-cli implementation - # https://github.com/ember-cli/ember-cli-htmlbars/blob/d5aa14b3/lib/template-compiler-plugin.js#L18-L26 - script = <<~JS - import { hbs } from 'ember-cli-htmlbars'; - export default hbs(#{hbs_template.to_json}, { moduleName: #{module_name.to_json} }); - JS - - template_module = DiscourseJsProcessor.transpile(script, "", module_name, theme_id: @theme_id) - @output_tree << ["#{name}.js", <<~JS] - if ('define' in window) { - #{template_module} - } - JS - rescue MiniRacer::RuntimeError, DiscourseJsProcessor::TranspileError => ex - raise CompileError.new ex.message + # TODO end def append_raw_script(filename, script) - @output_tree << [filename, script + "\n"] + #todo end def append_module(script, name, extension, include_variables: true) - original_filename = name - name = "discourse/theme-#{@theme_id}/#{name}" - - script = "#{theme_settings}#{script}" if include_variables - transpiler = DiscourseJsProcessor::Transpiler.new - - @output_tree << ["#{original_filename}.#{extension}", <<~JS] - if ('define' in window) { - #{transpiler.perform(script, "", name, theme_id: @theme_id, extension: extension).strip} - } - JS - rescue MiniRacer::RuntimeError, DiscourseJsProcessor::TranspileError => ex - raise CompileError.new ex.message + #todo end def append_js_error(filename, message) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 59c466c52b111..a813785a9a4f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1015,6 +1015,9 @@ importers: app/assets/javascripts/theme-transpiler: dependencies: + '@babel/preset-env': + specifier: ^7.27.2 + version: 7.27.2(@babel/core@7.27.1) '@babel/standalone': specifier: ^7.27.2 version: 7.27.2 @@ -1027,6 +1030,9 @@ importers: '@rollup/plugin-babel': specifier: ^6.0.4 version: 6.0.4(@babel/core@7.27.1) + '@rollup/plugin-terser': + specifier: ^0.4.4 + version: 0.4.4 '@rollup/wasm-node': specifier: ^4.29.1 version: 4.29.1 @@ -1129,6 +1135,10 @@ packages: resolution: {integrity: sha512-Q+E+rd/yBzNQhXkG+zQnF58e4zoZfBedaxwzPmicKsiK3nt8iJYrSrDbjwFFDGC4f+rPafqRaPH6TsDoSvMf7A==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.27.2': + resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} + engines: {node: '>=6.9.0'} + '@babel/core@7.27.1': resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} engines: {node: '>=6.9.0'} @@ -1152,6 +1162,10 @@ packages: resolution: {integrity: sha512-2YaDd/Rd9E598B5+WIc8wJPmWETiiJXFYVE60oX8FDohv7rAUU3CQj+A1MgeEmcsk2+dQuEjIe/GDvig0SqL4g==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.27.1': resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} engines: {node: '>=6.9.0'} @@ -1164,6 +1178,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-create-regexp-features-plugin@7.27.1': + resolution: {integrity: sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-define-polyfill-provider@0.6.3': resolution: {integrity: sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==} peerDependencies: @@ -1197,6 +1217,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-replace-supers@7.27.1': resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} engines: {node: '>=6.9.0'} @@ -1223,6 +1249,10 @@ packages: resolution: {integrity: sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==} engines: {node: '>=6.9.0'} + '@babel/helper-wrap-function@7.27.1': + resolution: {integrity: sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.27.1': resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} engines: {node: '>=6.9.0'} @@ -1238,30 +1268,60 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1': + resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9': resolution: {integrity: sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9': resolution: {integrity: sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9': resolution: {integrity: sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9': resolution: {integrity: sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1': + resolution: {integrity: sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-proposal-class-properties@7.18.6': resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} @@ -1312,12 +1372,24 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-assertions@7.27.1': + resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-attributes@7.26.0': resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-private-property-in-object@7.14.5': resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} @@ -1342,246 +1414,492 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-async-generator-functions@7.26.8': resolution: {integrity: sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-async-generator-functions@7.27.1': + resolution: {integrity: sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-async-to-generator@7.25.9': resolution: {integrity: sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-async-to-generator@7.27.1': + resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-block-scoped-functions@7.26.5': resolution: {integrity: sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-block-scoping@7.25.9': resolution: {integrity: sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-block-scoping@7.27.1': + resolution: {integrity: sha512-QEcFlMl9nGTgh1rn2nIeU5bkfb9BAjaQcWbiP4LvKxUot52ABcTkpcyJ7f2Q2U2RuQ84BNLgts3jRme2dTx6Fw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-class-properties@7.25.9': resolution: {integrity: sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-class-properties@7.27.1': + resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-class-static-block@7.26.0': resolution: {integrity: sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 + '@babel/plugin-transform-class-static-block@7.27.1': + resolution: {integrity: sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + '@babel/plugin-transform-classes@7.25.9': resolution: {integrity: sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-classes@7.27.1': + resolution: {integrity: sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-computed-properties@7.25.9': resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-computed-properties@7.27.1': + resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-destructuring@7.25.9': resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-destructuring@7.27.1': + resolution: {integrity: sha512-ttDCqhfvpE9emVkXbPD8vyxxh4TWYACVybGkDj+oReOGwnp066ITEivDlLwe0b1R0+evJ13IXQuLNB5w1fhC5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-dotall-regex@7.25.9': resolution: {integrity: sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-dotall-regex@7.27.1': + resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-duplicate-keys@7.25.9': resolution: {integrity: sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9': resolution: {integrity: sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-transform-dynamic-import@7.25.9': resolution: {integrity: sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-exponentiation-operator@7.26.3': resolution: {integrity: sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-exponentiation-operator@7.27.1': + resolution: {integrity: sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-export-namespace-from@7.25.9': resolution: {integrity: sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-for-of@7.26.9': resolution: {integrity: sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-function-name@7.25.9': resolution: {integrity: sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-json-strings@7.25.9': resolution: {integrity: sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-json-strings@7.27.1': + resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-literals@7.25.9': resolution: {integrity: sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-logical-assignment-operators@7.25.9': resolution: {integrity: sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-logical-assignment-operators@7.27.1': + resolution: {integrity: sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-member-expression-literals@7.25.9': resolution: {integrity: sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-amd@7.25.9': resolution: {integrity: sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-commonjs@7.26.3': resolution: {integrity: sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-systemjs@7.25.9': resolution: {integrity: sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-systemjs@7.27.1': + resolution: {integrity: sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-umd@7.25.9': resolution: {integrity: sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-named-capturing-groups-regex@7.25.9': resolution: {integrity: sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-transform-new-target@7.25.9': resolution: {integrity: sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-nullish-coalescing-operator@7.26.6': resolution: {integrity: sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': + resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-numeric-separator@7.25.9': resolution: {integrity: sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-numeric-separator@7.27.1': + resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-object-rest-spread@7.25.9': resolution: {integrity: sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-object-rest-spread@7.27.2': + resolution: {integrity: sha512-AIUHD7xJ1mCrj3uPozvtngY3s0xpv7Nu7DoUSnzNY6Xam1Cy4rUznR//pvMHOhQ4AvbCexhbqXCtpxGHOGOO6g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-object-super@7.25.9': resolution: {integrity: sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-optional-catch-binding@7.25.9': resolution: {integrity: sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-optional-catch-binding@7.27.1': + resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-optional-chaining@7.25.9': resolution: {integrity: sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-optional-chaining@7.27.1': + resolution: {integrity: sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-parameters@7.25.9': resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-parameters@7.27.1': + resolution: {integrity: sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-private-methods@7.25.9': resolution: {integrity: sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-private-methods@7.27.1': + resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-private-property-in-object@7.25.9': resolution: {integrity: sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-private-property-in-object@7.27.1': + resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-property-literals@7.25.9': resolution: {integrity: sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-regenerator@7.25.9': resolution: {integrity: sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-regenerator@7.27.1': + resolution: {integrity: sha512-B19lbbL7PMrKr52BNPjCqg1IyNUIjTcxKj8uX9zHO+PmWN93s19NDr/f69mIkEp2x9nmDJ08a7lgHaTTzvW7mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-regexp-modifiers@7.26.0': resolution: {integrity: sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-transform-regexp-modifiers@7.27.1': + resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-transform-reserved-words@7.25.9': resolution: {integrity: sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-runtime@7.26.10': resolution: {integrity: sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==} engines: {node: '>=6.9.0'} @@ -1594,30 +1912,60 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-spread@7.25.9': resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-spread@7.27.1': + resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-sticky-regex@7.25.9': resolution: {integrity: sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-template-literals@7.26.8': resolution: {integrity: sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-typeof-symbol@7.26.7': resolution: {integrity: sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-typescript@7.27.1': resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} engines: {node: '>=6.9.0'} @@ -1635,24 +1983,48 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-unicode-property-regex@7.25.9': resolution: {integrity: sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-unicode-property-regex@7.27.1': + resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-unicode-regex@7.25.9': resolution: {integrity: sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-unicode-sets-regex@7.25.9': resolution: {integrity: sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-transform-unicode-sets-regex@7.27.1': + resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/polyfill@7.12.1': resolution: {integrity: sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==} deprecated: 🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information. @@ -1663,6 +2035,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/preset-env@7.27.2': + resolution: {integrity: sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/preset-modules@0.1.6-no-external-plugins': resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: @@ -2507,6 +2885,15 @@ packages: rollup: optional: true + '@rollup/plugin-terser@0.4.4': + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/pluginutils@5.1.4': resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} engines: {node: '>=14.0.0'} @@ -7851,6 +8238,9 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + smob@1.5.0: + resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -8951,6 +9341,8 @@ snapshots: '@babel/compat-data@7.27.1': {} + '@babel/compat-data@7.27.2': {} + '@babel/core@7.27.1(supports-color@8.1.1)': dependencies: '@ampproject/remapping': 2.3.0 @@ -8999,6 +9391,14 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 + lru-cache: 5.1.1 + semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9019,10 +9419,17 @@ snapshots: regexpu-core: 6.2.0 semver: 6.3.1 + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.1 + regexpu-core: 6.2.0 + semver: 6.3.1 + '@babel/helper-define-polyfill-provider@0.6.3(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-compilation-targets': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 debug: 4.4.0(supports-color@8.1.1) lodash.debounce: 4.0.8 @@ -9068,6 +9475,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-wrap-function': 7.27.1 + '@babel/traverse': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9098,6 +9514,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-wrap-function@7.27.1': + dependencies: + '@babel/template': 7.27.1 + '@babel/traverse': 7.27.1(supports-color@8.1.1) + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/helpers@7.27.1': dependencies: '@babel/template': 7.27.1 @@ -9115,16 +9539,34 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9134,6 +9576,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9142,6 +9593,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9150,241 +9609,426 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-decorators@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-proposal-decorators@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + + '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-async-generator-functions@7.26.8(@babel/core@7.27.1)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/traverse': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-generator-functions@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.27.1) + '@babel/traverse': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-module-imports': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.27.1)(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-module-imports': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.26.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.26.0(@babel/core@7.27.1)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-compilation-targets': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/traverse': 7.27.1(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/traverse': 7.27.1(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.27.1) - transitivePeerDependencies: - - supports-color + '@babel/template': 7.27.1 - '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.27.1)': + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - transitivePeerDependencies: - - supports-color + '@babel/template': 7.27.1 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.27.1)': + '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.27.1)': + '@babel/plugin-transform-destructuring@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-annotate-as-pure': 7.27.1 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) - transitivePeerDependencies: - - supports-color - '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.27.1)': + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.27.1)': + '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.27.1)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.27.1)': + '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-async-generator-functions@7.26.8(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-exponentiation-operator@7.26.3(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.27.1)(supports-color@8.1.1) - '@babel/traverse': 7.27.1(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-module-imports': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.27.1)(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-block-scoped-functions@7.26.5(@babel/core@7.27.1)': + '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-for-of@7.26.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.26.0(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-annotate-as-pure': 7.27.1 '@babel/helper-compilation-targets': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/traverse': 7.27.1(supports-color@8.1.1) - globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/template': 7.27.1 + '@babel/traverse': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-literals@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-exponentiation-operator@7.26.3(@babel/core@7.27.1)': + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-for-of@7.26.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-compilation-targets': 7.27.1 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.27.1)': - dependencies: - '@babel/core': 7.27.1(supports-color@8.1.1) - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-transform-literals@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-modules-commonjs@7.26.3(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.27.1)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.26.3(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) @@ -9398,21 +10042,42 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-nullish-coalescing-operator@7.26.6(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-numeric-separator@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-object-rest-spread@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9420,6 +10085,14 @@ snapshots: '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.27.1) + '@babel/plugin-transform-object-rest-spread@7.27.2(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9428,11 +10101,24 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-optional-catch-binding@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9441,11 +10127,24 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-parameters@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-private-methods@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9454,6 +10153,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-private-property-in-object@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9463,28 +10170,58 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-regenerator@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 regenerator-transform: 0.15.2 + '@babel/plugin-transform-regenerator@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-regexp-modifiers@7.26.0(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-runtime@7.26.10(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9502,6 +10239,11 @@ snapshots: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-spread@7.25.9(@babel/core@7.27.1)(supports-color@8.1.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9510,21 +10252,44 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-template-literals@7.26.8(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-typeof-symbol@7.26.7(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -9550,24 +10315,47 @@ snapshots: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-property-regex@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-sets-regex@7.25.9(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.27.1) '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/polyfill@7.12.1': dependencies: core-js: 2.6.12 @@ -9648,6 +10436,81 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/preset-env@7.27.2(@babel/core@7.27.1)': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/core': 7.27.1(supports-color@8.1.1) + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.27.1) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.27.1) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-async-generator-functions': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-block-scoping': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-class-static-block': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-classes': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-destructuring': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-object-rest-spread': 7.27.2(@babel/core@7.27.1) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-regenerator': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.27.1) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.27.1) + babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.27.1)(supports-color@8.1.1) + babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.27.1)(supports-color@8.1.1) + babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.27.1)(supports-color@8.1.1) + core-js-compat: 3.40.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1(supports-color@8.1.1) @@ -10788,6 +11651,12 @@ snapshots: transitivePeerDependencies: - supports-color + '@rollup/plugin-terser@0.4.4': + dependencies: + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.39.0 + '@rollup/pluginutils@5.1.4': dependencies: '@types/estree': 1.0.7 @@ -11585,7 +12454,7 @@ snapshots: babel-plugin-polyfill-corejs2@0.4.12(@babel/core@7.27.1)(supports-color@8.1.1): dependencies: - '@babel/compat-data': 7.27.1 + '@babel/compat-data': 7.27.2 '@babel/core': 7.27.1(supports-color@8.1.1) '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.27.1)(supports-color@8.1.1) semver: 6.3.1 @@ -12889,7 +13758,7 @@ snapshots: '@babel/plugin-transform-runtime': 7.26.10(@babel/core@7.27.1) '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) '@babel/polyfill': 7.12.1 - '@babel/preset-env': 7.26.9(@babel/core@7.27.1)(supports-color@8.1.1) + '@babel/preset-env': 7.27.2(@babel/core@7.27.1) '@babel/runtime': 7.12.18 amd-name-resolver: 1.3.1 babel-plugin-debug-macros: 0.3.4(patch_hash=wki6cycbrrm5sscamn5w4cujby)(@babel/core@7.27.1) @@ -17326,6 +18195,8 @@ snapshots: smart-buffer@4.2.0: {} + smob@1.5.0: {} + snake-case@3.0.4: dependencies: dot-case: 3.0.4 diff --git a/spec/lib/discourse_js_processor_spec.rb b/spec/lib/discourse_js_processor_spec.rb index 5a38cff2df641..ed11306dea82e 100644 --- a/spec/lib/discourse_js_processor_spec.rb +++ b/spec/lib/discourse_js_processor_spec.rb @@ -212,12 +212,30 @@ class MyClass { result = DiscourseJsProcessor::Transpiler.new.rollup(sources, {}) - puts result - - code = result[0]["code"] - expect(code).to include("'hello world'") - expect(code).to include("'hello world 2'") + code = result["code"] + expect(code).to include('"hello world"') + expect(code).to include('"hello world 2"') expect(code).to include("dt7948") # Decorator transform + + expect(result["map"]).not_to be_nil + end + + it "supports decorators and class properties without error" do + script = <<~JS.chomp + class MyClass { + classProperty = 1; + #privateProperty = 1; + #privateMethod() { + console.log("hello world"); + } + @decorated + myMethod(){ + } + } + JS + + result = DiscourseJsProcessor::Transpiler.new.rollup({ "main.js" => script }, {}) + expect(result["code"]).to include("(()=>dt7948.n") end end end diff --git a/spec/lib/theme_javascript_compiler_spec.rb b/spec/lib/theme_javascript_compiler_spec.rb index 0a6721791892d..01578aaf3a557 100644 --- a/spec/lib/theme_javascript_compiler_spec.rb +++ b/spec/lib/theme_javascript_compiler_spec.rb @@ -89,6 +89,16 @@ it "can handle multiple modules" do compiler.append_tree( { + "discourse/initializers/my-initializer.js" => <<~JS, + import MyComponent from "../components/mycomponent"; + + export default { + name: "my-initializer", + initialize() { + console.log("my-initializer", MyComponent); + }, + }; + JS "discourse/components/mycomponent.js" => <<~JS, import Component from "@glimmer/component"; export default class MyComponent extends Component {} @@ -96,10 +106,10 @@ "discourse/templates/components/mycomponent.hbs" => "{{my-component-template}}", }, ) - expect(compiler.raw_content).to include( + expect(compiler.content).to include( 'define("discourse/theme-1/discourse/components/mycomponent"', ) - expect(compiler.raw_content).to include( + expect(compiler.content).to include( 'define("discourse/theme-1/discourse/templates/components/mycomponent"', ) end From 50efce58c7d6ede15cf7ac4e14f8b93bbe4aa01d Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Tue, 13 May 2025 14:12:43 +0200 Subject: [PATCH 09/36] wip the new plugin --- .../theme-transpiler/add-theme-globals.js | 85 +++++++++++++++++++ .../theme-transpiler/theme-rollup.js | 18 +++- spec/lib/discourse_js_processor_spec.rb | 47 ++++++++-- 3 files changed, 141 insertions(+), 9 deletions(-) create mode 100644 app/assets/javascripts/theme-transpiler/add-theme-globals.js diff --git a/app/assets/javascripts/theme-transpiler/add-theme-globals.js b/app/assets/javascripts/theme-transpiler/add-theme-globals.js new file mode 100644 index 0000000000000..003ce0b3ad0dd --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/add-theme-globals.js @@ -0,0 +1,85 @@ +export default function (babel) { + const { types: t } = babel; + + const visitor = { + CallExpression(path) { + if (path.node.callee.name === "precompileTemplate") { + let scope = path.node.arguments[1].properties.find( + (prop) => prop.key.name === "scope" + ); + if (!scope) { + scope = t.objectProperty( + t.identifier("scope"), + t.arrowFunctionExpression([], t.objectExpression([])) + ); + path.node.arguments[1].properties.push(scope); + } + + scope.value.body.properties.push( + t.objectProperty( + t.identifier("themePrefix"), + t.identifier("themePrefix"), + false, + true + ) + ); + scope.value.body.properties.push( + t.objectProperty( + t.identifier("settings"), + t.identifier("settings"), + false, + true + ) + ); + } + }, + + Program(path) { + const importDeclarations = []; + + if (path.scope.bindings.themePrefix) { + if (path.scope.bindings.themePrefix.kind !== "module") { + throw new Error("duplicate themePrefix"); + } else { + // TODO: maybe check the import path + } + } else { + importDeclarations.push( + t.importSpecifier( + t.identifier("themePrefix"), + t.identifier("themePrefix") + ) + ); + } + + if (path.scope.bindings.settings) { + if (path.scope.bindings.settings.kind !== "module") { + throw new Error("duplicate settings"); + } else { + // TODO: maybe check the import path + } + } else { + importDeclarations.push( + t.importSpecifier(t.identifier("settings"), t.identifier("settings")) + ); + } + + if (importDeclarations.length > 0) { + path.node.body.push( + t.importDeclaration( + importDeclarations, + t.stringLiteral("discourse-theme") + ) + ); + + path.scope.crawl(); + } + }, + }; + + return { + pre(file) { + babel.traverse(file.ast, visitor, file.scope); + }, + }; +} diff --git a/app/assets/javascripts/theme-transpiler/theme-rollup.js b/app/assets/javascripts/theme-transpiler/theme-rollup.js index b75c8efcb1604..da972fe2a0d9c 100644 --- a/app/assets/javascripts/theme-transpiler/theme-rollup.js +++ b/app/assets/javascripts/theme-transpiler/theme-rollup.js @@ -7,6 +7,7 @@ import { precompile } from "ember-source/dist/ember-template-compiler"; import { dirname, join } from "path"; import { minify as terserMinify } from "terser"; import { browsers } from "../discourse/config/targets"; +import AddThemeGlobals from "./add-theme-globals"; import BabelReplaceImports from "./babel-replace-imports"; import { Preprocessor } from "./content-tag"; @@ -95,7 +96,21 @@ globalThis.rollup = function (modules, options) { babelHelpers: "bundled", plugins: [ [DecoratorTransforms, { runEarly: true }], - BabelReplaceImports, + // BabelReplaceImports, + [ + HTMLBarsInlinePrecompile, + { + // compiler: { precompile }, + targetFormat: "hbs", + // enableLegacyModules: [ + // "ember-cli-htmlbars", + // "ember-cli-htmlbars-inline-precompile", + // "htmlbars-inline-precompile", + // ], + }, + "first-pass", + ], + AddThemeGlobals, [ HTMLBarsInlinePrecompile, { @@ -106,6 +121,7 @@ globalThis.rollup = function (modules, options) { "htmlbars-inline-precompile", ], }, + "second-pass", ], // TODO: Ember this fallback // TODO: template colocation diff --git a/spec/lib/discourse_js_processor_spec.rb b/spec/lib/discourse_js_processor_spec.rb index ed11306dea82e..863d90a2eba77 100644 --- a/spec/lib/discourse_js_processor_spec.rb +++ b/spec/lib/discourse_js_processor_spec.rb @@ -194,11 +194,9 @@ def standard_compile(template) describe "Transpiler#rollup" do it "can rollup code" do - sources = { - "main.js" => "import './hello.gjs'; console.log('hello world 2');", - "hello.gjs" => <<~JS, + sources = { "discourse/initializers/hello.gjs" => <<~JS } someDecorator = () => {} - class MyClass { + export default class MyClass { @someDecorator myMethod() { console.log('hello world'); @@ -208,13 +206,11 @@ class MyClass { } JS - } result = DiscourseJsProcessor::Transpiler.new.rollup(sources, {}) code = result["code"] expect(code).to include('"hello world"') - expect(code).to include('"hello world 2"') expect(code).to include("dt7948") # Decorator transform expect(result["map"]).not_to be_nil @@ -222,7 +218,7 @@ class MyClass { it "supports decorators and class properties without error" do script = <<~JS.chomp - class MyClass { + export default class MyClass { classProperty = 1; #privateProperty = 1; #privateMethod() { @@ -234,7 +230,42 @@ class MyClass { } JS - result = DiscourseJsProcessor::Transpiler.new.rollup({ "main.js" => script }, {}) + result = + DiscourseJsProcessor::Transpiler.new.rollup( + { "discourse/initializers/foo.js" => script }, + {}, + ) + expect(result["code"]).to include("(()=>dt7948.n") + end + + it "can use themePrefix in a template" do + script = <<~JS.chomp + themePrefix(); + export default class Foo { + + } + JS + + result = + DiscourseJsProcessor::Transpiler.new.rollup( + { "discourse/initializers/foo.gjs" => script }, + {}, + ) + expect(result["code"]).to include("(()=>dt7948.n") + end + + it "can use themePrefix not in a template" do + script = <<~JS.chomp + export default function foo() { + themePrefix("bar"); + } + JS + + result = + DiscourseJsProcessor::Transpiler.new.rollup( + { "discourse/initializers/foo.js" => script }, + {}, + ) expect(result["code"]).to include("(()=>dt7948.n") end end From 717e7b7c57af6157a40957bfb86ededf7bab66a2 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Tue, 13 May 2025 14:12:57 +0200 Subject: [PATCH 10/36] lockfile --- pnpm-lock.yaml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a813785a9a4f9..6de13e4f5bd08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1030,9 +1030,6 @@ importers: '@rollup/plugin-babel': specifier: ^6.0.4 version: 6.0.4(@babel/core@7.27.1) - '@rollup/plugin-terser': - specifier: ^0.4.4 - version: 0.4.4 '@rollup/wasm-node': specifier: ^4.29.1 version: 4.29.1 @@ -2885,15 +2882,6 @@ packages: rollup: optional: true - '@rollup/plugin-terser@0.4.4': - resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/pluginutils@5.1.4': resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} engines: {node: '>=14.0.0'} @@ -8238,9 +8226,6 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - smob@1.5.0: - resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} - snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -11651,12 +11636,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@rollup/plugin-terser@0.4.4': - dependencies: - serialize-javascript: 6.0.2 - smob: 1.5.0 - terser: 5.39.0 - '@rollup/pluginutils@5.1.4': dependencies: '@types/estree': 1.0.7 @@ -18195,8 +18174,6 @@ snapshots: smart-buffer@4.2.0: {} - smob@1.5.0: {} - snake-case@3.0.4: dependencies: dot-case: 3.0.4 From 5b8b8f23c0fafefd4cde225120d3a50b6413d3d0 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 13 May 2025 13:33:12 +0100 Subject: [PATCH 11/36] single-pass version --- .../theme-transpiler/add-theme-globals.js | 35 +------------------ .../theme-transpiler/theme-rollup.js | 16 +-------- 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/app/assets/javascripts/theme-transpiler/add-theme-globals.js b/app/assets/javascripts/theme-transpiler/add-theme-globals.js index 003ce0b3ad0dd..1d2de31955995 100644 --- a/app/assets/javascripts/theme-transpiler/add-theme-globals.js +++ b/app/assets/javascripts/theme-transpiler/add-theme-globals.js @@ -2,38 +2,6 @@ export default function (babel) { const { types: t } = babel; const visitor = { - CallExpression(path) { - if (path.node.callee.name === "precompileTemplate") { - let scope = path.node.arguments[1].properties.find( - (prop) => prop.key.name === "scope" - ); - if (!scope) { - scope = t.objectProperty( - t.identifier("scope"), - t.arrowFunctionExpression([], t.objectExpression([])) - ); - path.node.arguments[1].properties.push(scope); - } - - scope.value.body.properties.push( - t.objectProperty( - t.identifier("themePrefix"), - t.identifier("themePrefix"), - false, - true - ) - ); - scope.value.body.properties.push( - t.objectProperty( - t.identifier("settings"), - t.identifier("settings"), - false, - true - ) - ); - } - }, - Program(path) { const importDeclarations = []; @@ -71,8 +39,6 @@ export default function (babel) { t.stringLiteral("discourse-theme") ) ); - - path.scope.crawl(); } }, }; @@ -80,6 +46,7 @@ export default function (babel) { return { pre(file) { babel.traverse(file.ast, visitor, file.scope); + file.scope.crawl(); }, }; } diff --git a/app/assets/javascripts/theme-transpiler/theme-rollup.js b/app/assets/javascripts/theme-transpiler/theme-rollup.js index da972fe2a0d9c..a9d3c815d1358 100644 --- a/app/assets/javascripts/theme-transpiler/theme-rollup.js +++ b/app/assets/javascripts/theme-transpiler/theme-rollup.js @@ -96,20 +96,7 @@ globalThis.rollup = function (modules, options) { babelHelpers: "bundled", plugins: [ [DecoratorTransforms, { runEarly: true }], - // BabelReplaceImports, - [ - HTMLBarsInlinePrecompile, - { - // compiler: { precompile }, - targetFormat: "hbs", - // enableLegacyModules: [ - // "ember-cli-htmlbars", - // "ember-cli-htmlbars-inline-precompile", - // "htmlbars-inline-precompile", - // ], - }, - "first-pass", - ], + BabelReplaceImports, AddThemeGlobals, [ HTMLBarsInlinePrecompile, @@ -121,7 +108,6 @@ globalThis.rollup = function (modules, options) { "htmlbars-inline-precompile", ], }, - "second-pass", ], // TODO: Ember this fallback // TODO: template colocation From 60ef424b6492cc16a101804349194cd22b42065e Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 15 May 2025 12:20:17 +0100 Subject: [PATCH 12/36] bump --- .../theme-transpiler/add-theme-globals.js | 2 +- .../theme-transpiler/babel-replace-imports.js | 4 +- .../rollup-virtual-imports.js | 39 ++++ .../theme-transpiler/theme-rollup.js | 32 +-- app/models/theme.rb | 7 +- app/models/theme_field.rb | 194 +++++++++--------- lib/theme_javascript_compiler.rb | 18 +- spec/lib/discourse_js_processor_spec.rb | 12 +- 8 files changed, 165 insertions(+), 143 deletions(-) create mode 100644 app/assets/javascripts/theme-transpiler/rollup-virtual-imports.js diff --git a/app/assets/javascripts/theme-transpiler/add-theme-globals.js b/app/assets/javascripts/theme-transpiler/add-theme-globals.js index 1d2de31955995..688a5e95a83b6 100644 --- a/app/assets/javascripts/theme-transpiler/add-theme-globals.js +++ b/app/assets/javascripts/theme-transpiler/add-theme-globals.js @@ -36,7 +36,7 @@ export default function (babel) { path.node.body.push( t.importDeclaration( importDeclarations, - t.stringLiteral("discourse-theme") + t.stringLiteral("virtual:theme") ) ); } diff --git a/app/assets/javascripts/theme-transpiler/babel-replace-imports.js b/app/assets/javascripts/theme-transpiler/babel-replace-imports.js index f0439f46890b8..91715f86c2892 100644 --- a/app/assets/javascripts/theme-transpiler/babel-replace-imports.js +++ b/app/assets/javascripts/theme-transpiler/babel-replace-imports.js @@ -1,3 +1,5 @@ +import rollupVirtualImports from "./rollup-virtual-imports"; + export default function (babel) { const { types: t } = babel; @@ -5,7 +7,7 @@ export default function (babel) { visitor: { ImportDeclaration(path) { const moduleName = path.node.source.value; - if (moduleName.startsWith(".")) { + if (moduleName.startsWith(".") || rollupVirtualImports[moduleName]) { return; } diff --git a/app/assets/javascripts/theme-transpiler/rollup-virtual-imports.js b/app/assets/javascripts/theme-transpiler/rollup-virtual-imports.js new file mode 100644 index 0000000000000..5a96e33fec6b1 --- /dev/null +++ b/app/assets/javascripts/theme-transpiler/rollup-virtual-imports.js @@ -0,0 +1,39 @@ +export default { + "virtual:main": (tree, { themeId, settings }) => { + const initializers = Object.keys(tree).filter((key) => + key.includes("/initializers/") + ); + + let output = ` + import "virtual:init-settings"; + `; + + output += "export const initializers = {};\n"; + + let i = 1; + for (const initializer of initializers) { + output += `import Init${i} from "${initializer}";\n`; + output += `initializers["${initializer}"] = Init${i};\n`; + i += 1; + } + + return output; + }, + "virtual:init-settings": (_, { themeId, settings }) => { + return ` + import { registerSettings } from "discourse/lib/theme-settings-store"; + registerSettings(${themeId}, ${JSON.stringify(settings)}); + `; + }, + "virtual:theme": (_, { themeId }) => { + return ` + import { getObjectForTheme } from "discourse/lib/theme-settings-store"; + + export const settings = getObjectForTheme(${themeId}); + + export function themePrefix(key) { + return \`theme_translations.${themeId}.\${key}\`; + } + `; + }, +}; diff --git a/app/assets/javascripts/theme-transpiler/theme-rollup.js b/app/assets/javascripts/theme-transpiler/theme-rollup.js index a9d3c815d1358..eab25e05655cf 100644 --- a/app/assets/javascripts/theme-transpiler/theme-rollup.js +++ b/app/assets/javascripts/theme-transpiler/theme-rollup.js @@ -1,6 +1,6 @@ import BabelPresetEnv from "@babel/preset-env"; import { rollup } from "@rollup/browser"; -import { babel } from "@rollup/plugin-babel"; +import { babel, getBabelOutputPlugin } from "@rollup/plugin-babel"; import HTMLBarsInlinePrecompile from "babel-plugin-ember-template-compilation"; import DecoratorTransforms from "decorator-transforms"; import { precompile } from "ember-source/dist/ember-template-compiler"; @@ -10,6 +10,7 @@ import { browsers } from "../discourse/config/targets"; import AddThemeGlobals from "./add-theme-globals"; import BabelReplaceImports from "./babel-replace-imports"; import { Preprocessor } from "./content-tag"; +import rollupVirtualImports from "./rollup-virtual-imports"; const preprocessor = new Preprocessor(); @@ -33,26 +34,9 @@ globalThis.fetch = function (url) { throw "fetch not implemented"; }; -function generateMain(tree) { - const initializers = Object.keys(tree).filter((key) => - key.includes("/initializers/") - ); - - let output = "export const initializers = {};\n"; - - let i = 1; - for (const initializer of initializers) { - output += `import Init${i} from "${initializer}";\n`; - output += `initializers["${initializer}"] = Init${i};\n`; - i += 1; - } - - return output; -} - let lastRollupResult; let lastRollupError; -globalThis.rollup = function (modules, options) { +globalThis.rollup = function (modules, opts) { const resultPromise = rollup({ input: "virtual:main", logLevel: "info", @@ -66,7 +50,7 @@ globalThis.rollup = function (modules, options) { extensions: [".js", ".gjs"], }, resolveId(source, context) { - if (source === "virtual:main") { + if (rollupVirtualImports[source]) { return source; } @@ -83,20 +67,22 @@ globalThis.rollup = function (modules, options) { return false; }, load(id) { - if (id === "virtual:main") { - return generateMain(modules); + if (rollupVirtualImports[id]) { + return rollupVirtualImports[id](modules, opts); } if (modules.hasOwnProperty(id)) { return modules[id]; } }, }, + getBabelOutputPlugin({ + plugins: [BabelReplaceImports], + }), babel({ extensions: [".js", ".gjs"], babelHelpers: "bundled", plugins: [ [DecoratorTransforms, { runEarly: true }], - BabelReplaceImports, AddThemeGlobals, [ HTMLBarsInlinePrecompile, diff --git a/app/models/theme.rb b/app/models/theme.rb index 28fef61ddf7b3..c91c9885d0fc5 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -6,7 +6,7 @@ class Theme < ActiveRecord::Base include GlobalPath - BASE_COMPILER_VERSION = 93 + BASE_COMPILER_VERSION = 99 class SettingsMigrationError < StandardError end @@ -184,11 +184,8 @@ def update_javascript_cache! .to_h if all_extra_js.present? - js_compiler = ThemeJavascriptCompiler.new(id, name) + js_compiler = ThemeJavascriptCompiler.new(id, name, build_settings_hash) js_compiler.append_tree(all_extra_js) - settings_hash = build_settings_hash - - js_compiler.prepend_settings(settings_hash) if settings_hash.present? javascript_cache || build_javascript_cache javascript_cache.update!(content: js_compiler.content, source_map: js_compiler.source_map) diff --git a/app/models/theme_field.rb b/app/models/theme_field.rb index 922336d73f42a..2269becb7e424 100644 --- a/app/models/theme_field.rb +++ b/app/models/theme_field.rb @@ -122,102 +122,102 @@ def process_html(html) errors << I18n.t("themes.errors.optimized_link") if contains_optimized_link?(html) - js_compiler = ThemeJavascriptCompiler.new(theme_id, self.theme.name) - - doc = Nokogiri::HTML5.fragment(html) - - doc - .css('script[type="text/x-handlebars"]') - .each do |node| - name = node["name"] || node["data-template-name"] || "broken" - is_raw = name =~ /\.(raw|hbr)\z/ - hbs_template = node.inner_html - - begin - if is_raw - js_compiler.append_js_error( - "discourse/templates/#{name}", - "Raw templates are no longer supported", - ) - else - js_compiler.append_ember_template( - "discourse/templates/#{name.delete_prefix("/")}", - hbs_template, - ) - end - rescue ThemeJavascriptCompiler::CompileError => ex - js_compiler.append_js_error("discourse/templates/#{name}", ex.message) - errors << ex.message - end - - node.remove - end - - doc - .css('script[type="text/discourse-plugin"]') - .each_with_index do |node, index| - version = node["version"] - next if version.blank? - - initializer_name = - "theme-field" + "-#{self.id}" + "-#{Theme.targets[self.target_id]}" + - "-#{ThemeField.types[self.type_id]}" + "-script-#{index + 1}" - begin - js = <<~JS - import { withPluginApi } from "discourse/lib/plugin-api"; - - export default { - name: #{initializer_name.inspect}, - after: "inject-objects", - - initialize() { - withPluginApi(#{version.inspect}, (api) => { - #{node.inner_html} - }); - } - }; - JS - - js_compiler.append_module( - js, - "discourse/initializers/#{initializer_name}", - "js", - include_variables: true, - ) - rescue ThemeJavascriptCompiler::CompileError => ex - js_compiler.append_js_error("discourse/initializers/#{initializer_name}", ex.message) - errors << ex.message - end - - node.remove - end - - doc - .css("script") - .each_with_index do |node, index| - if inline_javascript?(node) - js_compiler.append_raw_script( - "_html/#{Theme.targets[self.target_id]}/#{name}_#{index + 1}.js", - node.inner_html, - ) - node.remove - else - node["nonce"] = CSP_NONCE_PLACEHOLDER - end - end - - settings_hash = theme.build_settings_hash - if js_compiler.has_content? && settings_hash.present? - js_compiler.prepend_settings(settings_hash) - end - javascript_cache.content = js_compiler.content - javascript_cache.source_map = js_compiler.source_map - javascript_cache.save! - - doc.add_child(<<~HTML.html_safe) if javascript_cache.content.present? - - HTML - [doc.to_s, errors&.join("\n")] + # js_compiler = ThemeJavascriptCompiler.new(theme_id, self.theme.name) + + # doc = Nokogiri::HTML5.fragment(html) + + # doc + # .css('script[type="text/x-handlebars"]') + # .each do |node| + # name = node["name"] || node["data-template-name"] || "broken" + # is_raw = name =~ /\.(raw|hbr)\z/ + # hbs_template = node.inner_html + + # begin + # if is_raw + # js_compiler.append_js_error( + # "discourse/templates/#{name}", + # "Raw templates are no longer supported", + # ) + # else + # js_compiler.append_ember_template( + # "discourse/templates/#{name.delete_prefix("/")}", + # hbs_template, + # ) + # end + # rescue ThemeJavascriptCompiler::CompileError => ex + # js_compiler.append_js_error("discourse/templates/#{name}", ex.message) + # errors << ex.message + # end + + # node.remove + # end + + # doc + # .css('script[type="text/discourse-plugin"]') + # .each_with_index do |node, index| + # version = node["version"] + # next if version.blank? + + # initializer_name = + # "theme-field" + "-#{self.id}" + "-#{Theme.targets[self.target_id]}" + + # "-#{ThemeField.types[self.type_id]}" + "-script-#{index + 1}" + # begin + # js = <<~JS + # import { withPluginApi } from "discourse/lib/plugin-api"; + + # export default { + # name: #{initializer_name.inspect}, + # after: "inject-objects", + + # initialize() { + # withPluginApi(#{version.inspect}, (api) => { + # #{node.inner_html} + # }); + # } + # }; + # JS + + # js_compiler.append_module( + # js, + # "discourse/initializers/#{initializer_name}", + # "js", + # include_variables: true, + # ) + # rescue ThemeJavascriptCompiler::CompileError => ex + # js_compiler.append_js_error("discourse/initializers/#{initializer_name}", ex.message) + # errors << ex.message + # end + + # node.remove + # end + + # doc + # .css("script") + # .each_with_index do |node, index| + # if inline_javascript?(node) + # js_compiler.append_raw_script( + # "_html/#{Theme.targets[self.target_id]}/#{name}_#{index + 1}.js", + # node.inner_html, + # ) + # node.remove + # else + # node["nonce"] = CSP_NONCE_PLACEHOLDER + # end + # end + + # settings_hash = theme.build_settings_hash + # if js_compiler.has_content? && settings_hash.present? + # js_compiler.prepend_settings(settings_hash) + # end + # javascript_cache.content = js_compiler.content + # javascript_cache.source_map = js_compiler.source_map + # javascript_cache.save! + + # doc.add_child(<<~HTML.html_safe) if javascript_cache.content.present? + # + # HTML + [html, errors&.join("\n")] end def validate_svg_sprite_xml @@ -286,7 +286,7 @@ def translation_data(with_overrides: true, internal: false, fallback_fields: nil def process_translation errors = [] javascript_cache || build_javascript_cache - js_compiler = ThemeJavascriptCompiler.new(theme_id, self.theme.name) + js_compiler = ThemeJavascriptCompiler.new(theme_id, self.theme.name, {}) begin data = translation_data diff --git a/lib/theme_javascript_compiler.rb b/lib/theme_javascript_compiler.rb index 9d66302308911..0f115338b52ec 100644 --- a/lib/theme_javascript_compiler.rb +++ b/lib/theme_javascript_compiler.rb @@ -18,11 +18,12 @@ def self.enable_terser! @@terser_disabled = false end - def initialize(theme_id, theme_name, minify: true) + def initialize(theme_id, theme_name, settings, minify: true) @theme_id = theme_id @output_tree = [] @theme_name = theme_name @minify = minify + @settings = settings end def compile! @@ -34,7 +35,10 @@ def compile! if !has_content? { "code" => "" } else - DiscourseJsProcessor::Transpiler.new.rollup(@output_tree.to_h, {}) + DiscourseJsProcessor::Transpiler.new.rollup( + @output_tree.to_h, + { themeId: @theme_id, settings: @settings }, + ) end @content = output["code"] @@ -83,16 +87,6 @@ def has_content? @output_tree.present? end - def prepend_settings(settings_hash) - @output_tree.prepend ["settings.js", <<~JS] - (function() { - if ('require' in window) { - require("discourse/lib/theme-settings-store").registerSettings(#{@theme_id}, #{settings_hash.to_json}); - } - })(); - JS - end - def append_tree(tree, include_variables: true) # Replace legacy extensions tree.transform_keys! do |filename| diff --git a/spec/lib/discourse_js_processor_spec.rb b/spec/lib/discourse_js_processor_spec.rb index 863d90a2eba77..2aaef4c57752d 100644 --- a/spec/lib/discourse_js_processor_spec.rb +++ b/spec/lib/discourse_js_processor_spec.rb @@ -249,9 +249,11 @@ def standard_compile(template) result = DiscourseJsProcessor::Transpiler.new.rollup( { "discourse/initializers/foo.gjs" => script }, - {}, + { themeId: 22 }, ) - expect(result["code"]).to include("(()=>dt7948.n") + expect(result["code"]).to include( + 'window.moduleBroker.lookup("discourse/lib/theme-settings-store")', + ) end it "can use themePrefix not in a template" do @@ -264,9 +266,11 @@ def standard_compile(template) result = DiscourseJsProcessor::Transpiler.new.rollup( { "discourse/initializers/foo.js" => script }, - {}, + { themeId: 22 }, ) - expect(result["code"]).to include("(()=>dt7948.n") + expect(result["code"]).to include( + 'window.moduleBroker.lookup("discourse/lib/theme-settings-store")', + ) end end end From 9ada91deee66deb1f64a00bf446678e7cce5eb73 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 15 May 2025 12:33:25 +0100 Subject: [PATCH 13/36] translations --- .../theme-transpiler/theme-rollup.js | 1 - app/models/theme.rb | 2 +- app/models/theme_field.rb | 37 ++++++------------- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/app/assets/javascripts/theme-transpiler/theme-rollup.js b/app/assets/javascripts/theme-transpiler/theme-rollup.js index eab25e05655cf..d38a0af283ef2 100644 --- a/app/assets/javascripts/theme-transpiler/theme-rollup.js +++ b/app/assets/javascripts/theme-transpiler/theme-rollup.js @@ -97,7 +97,6 @@ globalThis.rollup = function (modules, opts) { ], // TODO: Ember this fallback // TODO: template colocation - // TODO: themePrefix etc. // TODO: widgetHbs (remove from d-calendar) ], presets: [ diff --git a/app/models/theme.rb b/app/models/theme.rb index c91c9885d0fc5..1f827162b2fe7 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -6,7 +6,7 @@ class Theme < ActiveRecord::Base include GlobalPath - BASE_COMPILER_VERSION = 99 + BASE_COMPILER_VERSION = 101 class SettingsMigrationError < StandardError end diff --git a/app/models/theme_field.rb b/app/models/theme_field.rb index 2269becb7e424..abbab85482c79 100644 --- a/app/models/theme_field.rb +++ b/app/models/theme_field.rb @@ -286,44 +286,31 @@ def translation_data(with_overrides: true, internal: false, fallback_fields: nil def process_translation errors = [] javascript_cache || build_javascript_cache - js_compiler = ThemeJavascriptCompiler.new(theme_id, self.theme.name, {}) begin data = translation_data js = <<~JS - export default { - name: "theme-#{theme_id}-translations", - initialize() { - /* Translation data for theme #{self.theme_id} (#{self.name})*/ - const data = #{data.to_json}; - - for (let lang in data){ - let cursor = I18n.translations; - for (let key of [lang, "js", "theme_translations"]){ - cursor = cursor[key] = cursor[key] || {}; - } - cursor[#{self.theme_id}] = data[lang]; - } + /* Translation data for theme #{self.theme_id} (#{self.name})*/ + const data = #{data.to_json}; + + for (let lang in data){ + let cursor = I18n.translations; + for (let key of [lang, "js", "theme_translations"]){ + cursor = cursor[key] = cursor[key] || {}; } - }; + cursor[#{self.theme_id}] = data[lang]; + } JS - - js_compiler.append_module( - js, - "discourse/pre-initializers/theme-#{theme_id}-translations", - "js", - include_variables: false, - ) rescue ThemeTranslationParser::InvalidYaml => e errors << e.message end - javascript_cache.content = js_compiler.content - javascript_cache.source_map = js_compiler.source_map + javascript_cache.content = js + javascript_cache.source_map = nil javascript_cache.save! doc = "" doc = <<~HTML.html_safe if javascript_cache.content.present? - + HTML [doc, errors&.join("\n")] end From d906703f47a89b69f9f8a87f0a0c7365ec498b9a Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 15 May 2025 12:35:02 +0100 Subject: [PATCH 14/36] todos --- app/assets/javascripts/theme-transpiler/theme-rollup.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/javascripts/theme-transpiler/theme-rollup.js b/app/assets/javascripts/theme-transpiler/theme-rollup.js index d38a0af283ef2..fdb15f02f0845 100644 --- a/app/assets/javascripts/theme-transpiler/theme-rollup.js +++ b/app/assets/javascripts/theme-transpiler/theme-rollup.js @@ -95,9 +95,12 @@ globalThis.rollup = function (modules, opts) { ], }, ], + // TODO: add components/helpers/modifiers to resolver (for hbs) // TODO: Ember this fallback // TODO: template colocation // TODO: widgetHbs (remove from d-calendar) + // TODO: sourcemaps + // TODO: connectors ], presets: [ [ From b4456b14b7688954d0e4b5c7d2fe53e48df955e2 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 15 May 2025 12:36:47 +0100 Subject: [PATCH 15/36] todo2 --- app/assets/javascripts/theme-transpiler/theme-rollup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/theme-transpiler/theme-rollup.js b/app/assets/javascripts/theme-transpiler/theme-rollup.js index fdb15f02f0845..81f5e89a60f22 100644 --- a/app/assets/javascripts/theme-transpiler/theme-rollup.js +++ b/app/assets/javascripts/theme-transpiler/theme-rollup.js @@ -101,6 +101,7 @@ globalThis.rollup = function (modules, opts) { // TODO: widgetHbs (remove from d-calendar) // TODO: sourcemaps // TODO: connectors + // TODO: should babel presetEnv be on output? ], presets: [ [ From fca15c89e3311a0ecda81fee4b39497c43506472 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 20 May 2025 12:08:13 +0100 Subject: [PATCH 16/36] compatModules --- app/assets/javascripts/discourse/app/app.js | 8 ------- .../public/assets/scripts/start-app.js | 18 ++++++--------- .../rollup-virtual-imports.js | 22 +++++++++++-------- app/models/theme.rb | 2 +- spec/lib/discourse_js_processor_spec.rb | 2 +- 5 files changed, 22 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/discourse/app/app.js b/app/assets/javascripts/discourse/app/app.js index 9c7ebe1817e9b..9b9d169368487 100644 --- a/app/assets/javascripts/discourse/app/app.js +++ b/app/assets/javascripts/discourse/app/app.js @@ -19,13 +19,11 @@ import { buildResolver } from "discourse/resolver"; const _pluginCallbacks = []; let _unhandledThemeErrors = []; -console.log("run"); window.moduleBroker = { lookup: function (moduleName) { return require(moduleName); }, }; -window.themePrefix = (str) => str; class Discourse extends Application { modulePrefix = "discourse"; @@ -164,12 +162,6 @@ function loadInitializers(app) { app.instanceInitializer(resolveDiscourseInitializer(moduleName, themeId)); } - window.themeInitializers.forEach((obj) => { - for (const [moduleName, initializer] of Object.entries(obj)) { - app.instanceInitializer(initializer); - } - }); - // Plugins that are registered via `