mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 05:53:38 +08:00
DEV: Add gjs support for themes (#23473)
This commit is contained in:
parent
2ec7455c89
commit
5a904949b2
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -75,4 +75,3 @@ openapi/*
|
||||||
|
|
||||||
# Cached License Data Files
|
# Cached License Data Files
|
||||||
/.licenses
|
/.licenses
|
||||||
/app/assets/javascripts/compiled-js-processor.js
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { registerUnbound } from "discourse-common/lib/helpers";
|
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||||
|
|
||||||
registerUnbound("i18n", (key, params) => I18n.t(key, params));
|
export default function i18n(key, params) {
|
||||||
|
return I18n.t(key, params);
|
||||||
|
}
|
||||||
|
registerUnbound("i18n", i18n);
|
||||||
|
|
||||||
registerUnbound("i18n-yes-no", (value, params) =>
|
registerUnbound("i18n-yes-no", (value, params) =>
|
||||||
I18n.t(value ? "yes_value" : "no_value", params)
|
I18n.t(value ? "yes_value" : "no_value", params)
|
||||||
);
|
);
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
"ember-test-selectors": "^6.0.0",
|
"ember-test-selectors": "^6.0.0",
|
||||||
"eslint": "^8.50.0",
|
"eslint": "^8.50.0",
|
||||||
"eslint-plugin-qunit": "^8.0.0",
|
"eslint-plugin-qunit": "^8.0.0",
|
||||||
|
"float-kit": "1.0.0",
|
||||||
"html-entities": "^2.4.0",
|
"html-entities": "^2.4.0",
|
||||||
"imports-loader": "^4.0.1",
|
"imports-loader": "^4.0.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
@ -101,7 +102,6 @@
|
||||||
"sass": "^1.68.0",
|
"sass": "^1.68.0",
|
||||||
"select-kit": "1.0.0",
|
"select-kit": "1.0.0",
|
||||||
"sinon": "^16.0.0",
|
"sinon": "^16.0.0",
|
||||||
"float-kit": "1.0.0",
|
|
||||||
"source-map": "^0.7.4",
|
"source-map": "^0.7.4",
|
||||||
"terser": "^5.20.0",
|
"terser": "^5.20.0",
|
||||||
"truth-helpers": "1.0.0",
|
"truth-helpers": "1.0.0",
|
||||||
|
|
|
@ -15,9 +15,10 @@
|
||||||
"discourse-widget-hbs",
|
"discourse-widget-hbs",
|
||||||
"ember-cli-progress-ci",
|
"ember-cli-progress-ci",
|
||||||
"ember-production-deprecations",
|
"ember-production-deprecations",
|
||||||
|
"float-kit",
|
||||||
"pretty-text",
|
"pretty-text",
|
||||||
"select-kit",
|
"select-kit",
|
||||||
"float-kit",
|
"theme-transpiler",
|
||||||
"truth-helpers",
|
"truth-helpers",
|
||||||
"wizard"
|
"wizard"
|
||||||
],
|
],
|
||||||
|
|
29
app/assets/javascripts/patches/content-tag+1.1.0.patch
Normal file
29
app/assets/javascripts/patches/content-tag+1.1.0.patch
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
diff --git a/node_modules/content-tag/content_tag.js b/node_modules/content-tag/content_tag.js
|
||||||
|
index 6ff5969..38915da 100644
|
||||||
|
--- a/node_modules/content-tag/content_tag.js
|
||||||
|
+++ b/node_modules/content-tag/content_tag.js
|
||||||
|
@@ -448,11 +448,17 @@ module.exports.__wbindgen_memory = function() {
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
|
||||||
|
-const path = require('path').join(__dirname, 'content_tag_bg.wasm');
|
||||||
|
-const bytes = require('fs').readFileSync(path);
|
||||||
|
-
|
||||||
|
-const wasmModule = new WebAssembly.Module(bytes);
|
||||||
|
-const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||||
|
-wasm = wasmInstance.exports;
|
||||||
|
-module.exports.__wasm = wasm;
|
||||||
|
+// Check for nodejs environment
|
||||||
|
+if (process.version) {
|
||||||
|
+ const path = require('path').join(__dirname, 'content_tag_bg.wasm');
|
||||||
|
+ const bytes = require('fs').readFileSync(path);
|
||||||
|
+
|
||||||
|
+ const wasmModule = new WebAssembly.Module(bytes);
|
||||||
|
+ const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||||
|
+ wasm = wasmInstance.exports;
|
||||||
|
+} else {
|
||||||
|
+ const load = require('./content_tag_bg.wasm').default;
|
||||||
|
+ wasm = load(imports);
|
||||||
|
+ module.exports.__wasm = wasm;
|
||||||
|
+}
|
||||||
|
|
68
app/assets/javascripts/theme-transpiler/build.js
Normal file
68
app/assets/javascripts/theme-transpiler/build.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// See: https://esbuild.github.io/plugins/#webassembly-plugin
|
||||||
|
|
||||||
|
const esbuild = require("esbuild");
|
||||||
|
const path = require("node:path");
|
||||||
|
const fs = require("node:fs");
|
||||||
|
const { argv } = require("node:process");
|
||||||
|
|
||||||
|
let wasmPlugin = {
|
||||||
|
name: "wasm",
|
||||||
|
|
||||||
|
setup(build) {
|
||||||
|
build.onResolve({ filter: /\.wasm$/ }, (args) => {
|
||||||
|
if (args.namespace === "wasm-stub") {
|
||||||
|
return {
|
||||||
|
path: args.path,
|
||||||
|
namespace: "wasm-binary",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.resolveDir === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
path: path.isAbsolute(args.path)
|
||||||
|
? args.path
|
||||||
|
: path.join(args.resolveDir, args.path),
|
||||||
|
namespace: "wasm-stub",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
build.onLoad({ filter: /.*/, namespace: "wasm-stub" }, async (args) => {
|
||||||
|
return {
|
||||||
|
contents: `import wasm from ${JSON.stringify(args.path)};
|
||||||
|
export default (imports) => {
|
||||||
|
const wasmModule = new WebAssembly.Module(wasm);
|
||||||
|
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
||||||
|
return wasmInstance.exports;
|
||||||
|
};`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
build.onLoad({ filter: /.*/, namespace: "wasm-binary" }, async (args) => {
|
||||||
|
return {
|
||||||
|
contents: await fs.promises.readFile(args.path),
|
||||||
|
loader: "binary",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
esbuild
|
||||||
|
.build({
|
||||||
|
logLevel: "warning",
|
||||||
|
bundle: true,
|
||||||
|
minify: true,
|
||||||
|
alias: {
|
||||||
|
util: "./app/assets/javascripts/node_modules/@zxing/text-encoding",
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
process: `{ "env": {} }`,
|
||||||
|
},
|
||||||
|
external: ["fs", "path"],
|
||||||
|
entryPoints: ["./app/assets/javascripts/theme-transpiler/transpiler.js"],
|
||||||
|
outfile: argv[2],
|
||||||
|
plugins: [wasmPlugin],
|
||||||
|
})
|
||||||
|
.then(() => {});
|
29
app/assets/javascripts/theme-transpiler/package.json
Normal file
29
app/assets/javascripts/theme-transpiler/package.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "theme-transpiler",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "Uses esbuild to create a 'theme transpiler' bundle for loading into mini-racer",
|
||||||
|
"author": "Discourse",
|
||||||
|
"license": "GPL-2.0-only",
|
||||||
|
"keywords": [],
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/standalone": "^7.23.1",
|
||||||
|
"@zxing/text-encoding": "^0.9.0",
|
||||||
|
"babel-plugin-ember-template-compilation": "^2.2.0",
|
||||||
|
"content-tag": "^1.1.0",
|
||||||
|
"discourse-common": "1.0.0",
|
||||||
|
"discourse-widget-hbs": "1.0.0",
|
||||||
|
"ember-cli-htmlbars": "^6.3.0",
|
||||||
|
"ember-source": "~3.28.12",
|
||||||
|
"ember-this-fallback": "^0.3.1",
|
||||||
|
"handlebars": "^4.7.8",
|
||||||
|
"path-browserify": "^1.0.1",
|
||||||
|
"polyfill-crypto.getrandomvalues": "^1.0.0",
|
||||||
|
"terser": "^5.20.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "16.* || >= 18",
|
||||||
|
"npm": "please-use-yarn",
|
||||||
|
"yarn": ">= 1.21.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,13 @@ import RawHandlebars from "discourse-common/addon/lib/raw-handlebars";
|
||||||
import { WidgetHbsCompiler } from "discourse-widget-hbs/lib/widget-hbs-compiler";
|
import { WidgetHbsCompiler } from "discourse-widget-hbs/lib/widget-hbs-compiler";
|
||||||
import EmberThisFallback from "ember-this-fallback";
|
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";
|
||||||
|
globalThis.crypto = { getRandomValues };
|
||||||
|
|
||||||
|
import { Preprocessor } from "content-tag";
|
||||||
|
|
||||||
const thisFallbackPlugin = EmberThisFallback._buildPlugin({
|
const thisFallbackPlugin = EmberThisFallback._buildPlugin({
|
||||||
enableLogging: false,
|
enableLogging: false,
|
||||||
isTheme: true,
|
isTheme: true,
|
||||||
|
@ -60,10 +67,10 @@ function buildEmberTemplateManipulatorPlugin(themeId) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTemplateCompilerBabelPlugins({ themeId }) {
|
function buildTemplateCompilerBabelPlugins({ extension, themeId }) {
|
||||||
const compiler = { precompile };
|
const compiler = { precompile };
|
||||||
|
|
||||||
if (themeId) {
|
if (themeId && extension !== "gjs") {
|
||||||
compiler.precompile = (src, opts) => {
|
compiler.precompile = (src, opts) => {
|
||||||
return precompile(src, {
|
return precompile(src, {
|
||||||
...opts,
|
...opts,
|
||||||
|
@ -116,10 +123,16 @@ globalThis.compileRawTemplate = function (source, themeId) {
|
||||||
};
|
};
|
||||||
|
|
||||||
globalThis.transpile = function (source, options = {}) {
|
globalThis.transpile = function (source, options = {}) {
|
||||||
const { moduleId, filename, skipModule, themeId, commonPlugins } = options;
|
const { moduleId, filename, extension, skipModule, themeId, commonPlugins } =
|
||||||
const plugins = [];
|
options;
|
||||||
|
|
||||||
plugins.push(...buildTemplateCompilerBabelPlugins({ themeId }));
|
if (extension === "gjs") {
|
||||||
|
const preprocessor = new Preprocessor();
|
||||||
|
source = preprocessor.process(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
const plugins = [];
|
||||||
|
plugins.push(...buildTemplateCompilerBabelPlugins({ extension, themeId }));
|
||||||
if (moduleId && !skipModule) {
|
if (moduleId && !skipModule) {
|
||||||
plugins.push(["transform-modules-amd", { noInterop: true }]);
|
plugins.push(["transform-modules-amd", { noInterop: true }]);
|
||||||
}
|
}
|
|
@ -119,25 +119,12 @@
|
||||||
lodash.debounce "^4.0.8"
|
lodash.debounce "^4.0.8"
|
||||||
resolve "^1.14.2"
|
resolve "^1.14.2"
|
||||||
|
|
||||||
"@babel/helper-environment-visitor@^7.22.20":
|
"@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5":
|
||||||
version "7.22.20"
|
version "7.22.20"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167"
|
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167"
|
||||||
integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
|
integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
|
||||||
|
|
||||||
"@babel/helper-environment-visitor@^7.22.5":
|
"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0":
|
||||||
version "7.22.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98"
|
|
||||||
integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==
|
|
||||||
|
|
||||||
"@babel/helper-function-name@^7.22.5":
|
|
||||||
version "7.22.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be"
|
|
||||||
integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==
|
|
||||||
dependencies:
|
|
||||||
"@babel/template" "^7.22.5"
|
|
||||||
"@babel/types" "^7.22.5"
|
|
||||||
|
|
||||||
"@babel/helper-function-name@^7.23.0":
|
|
||||||
version "7.23.0"
|
version "7.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759"
|
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759"
|
||||||
integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
|
integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
|
||||||
|
@ -233,16 +220,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f"
|
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f"
|
||||||
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
|
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
|
||||||
|
|
||||||
"@babel/helper-validator-identifier@^7.22.20":
|
"@babel/helper-validator-identifier@^7.22.20", "@babel/helper-validator-identifier@^7.22.5":
|
||||||
version "7.22.20"
|
version "7.22.20"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
|
||||||
integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
|
integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
|
||||||
|
|
||||||
"@babel/helper-validator-identifier@^7.22.5":
|
|
||||||
version "7.22.15"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz#601fa28e4cc06786c18912dca138cec73b882044"
|
|
||||||
integrity sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==
|
|
||||||
|
|
||||||
"@babel/helper-validator-option@^7.22.15":
|
"@babel/helper-validator-option@^7.22.15":
|
||||||
version "7.22.15"
|
version "7.22.15"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040"
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040"
|
||||||
|
@ -1225,7 +1207,7 @@
|
||||||
ember-cli-version-checker "^5.1.2"
|
ember-cli-version-checker "^5.1.2"
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
|
|
||||||
"@embroider/addon-shim@^1.0.0":
|
"@embroider/addon-shim@^1.0.0", "@embroider/addon-shim@^1.8.3", "@embroider/addon-shim@^1.8.4":
|
||||||
version "1.8.6"
|
version "1.8.6"
|
||||||
resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.8.6.tgz#b676991b4fa32c3a98dc7db7dc6cd655029c3f09"
|
resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.8.6.tgz#b676991b4fa32c3a98dc7db7dc6cd655029c3f09"
|
||||||
integrity sha512-siC9kP78uucEbpDcVyxjkwa76pcs5rVzDVpWO4PDc9EAXRX+pzmUuSTLAK3GztUwx7/PWhz1BenAivqdSvSgfg==
|
integrity sha512-siC9kP78uucEbpDcVyxjkwa76pcs5rVzDVpWO4PDc9EAXRX+pzmUuSTLAK3GztUwx7/PWhz1BenAivqdSvSgfg==
|
||||||
|
@ -1234,15 +1216,6 @@
|
||||||
broccoli-funnel "^3.0.8"
|
broccoli-funnel "^3.0.8"
|
||||||
semver "^7.3.8"
|
semver "^7.3.8"
|
||||||
|
|
||||||
"@embroider/addon-shim@^1.8.3", "@embroider/addon-shim@^1.8.4":
|
|
||||||
version "1.8.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.8.5.tgz#c0aae417f9583058f40550f206fc53444e325f11"
|
|
||||||
integrity sha512-pDgpdTsC9i/+5hHziygK5VIZc64OG8bupiqL0OxJp+bnINURalHMbu5B3Gikq/a0QIvMPzDFWzKxIZCBpeiHkg==
|
|
||||||
dependencies:
|
|
||||||
"@embroider/shared-internals" "^2.1.0"
|
|
||||||
broccoli-funnel "^3.0.8"
|
|
||||||
semver "^7.3.8"
|
|
||||||
|
|
||||||
"@embroider/babel-loader-9@3.1.0":
|
"@embroider/babel-loader-9@3.1.0":
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@embroider/babel-loader-9/-/babel-loader-9-3.1.0.tgz#eae859b82215fc7ee0e69ec867fda7b4eb4de2c0"
|
resolved "https://registry.yarnpkg.com/@embroider/babel-loader-9/-/babel-loader-9-3.1.0.tgz#eae859b82215fc7ee0e69ec867fda7b4eb4de2c0"
|
||||||
|
@ -1347,7 +1320,7 @@
|
||||||
resolve "^1.20.0"
|
resolve "^1.20.0"
|
||||||
semver "^7.3.2"
|
semver "^7.3.2"
|
||||||
|
|
||||||
"@embroider/shared-internals@2.5.0", "@embroider/shared-internals@^2.0.0", "@embroider/shared-internals@^2.1.0", "@embroider/shared-internals@^2.2.3":
|
"@embroider/shared-internals@2.5.0", "@embroider/shared-internals@^2.0.0", "@embroider/shared-internals@^2.2.3":
|
||||||
version "2.5.0"
|
version "2.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.5.0.tgz#4a0b5127c589718fae60fc22f81374ed558b944a"
|
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.5.0.tgz#4a0b5127c589718fae60fc22f81374ed558b944a"
|
||||||
integrity sha512-7qzrb7GVIyNqeY0umxoeIvjDC+ay1b+wb2yCVuYTUYrFfLAkLEy9FNI3iWCi3RdQ9OFjgcAxAnwsAiPIMZZ3pQ==
|
integrity sha512-7qzrb7GVIyNqeY0umxoeIvjDC+ay1b+wb2yCVuYTUYrFfLAkLEy9FNI3iWCi3RdQ9OFjgcAxAnwsAiPIMZZ3pQ==
|
||||||
|
@ -2126,6 +2099,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
|
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
|
||||||
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
|
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
|
||||||
|
|
||||||
|
"@zxing/text-encoding@^0.9.0":
|
||||||
|
version "0.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b"
|
||||||
|
integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==
|
||||||
|
|
||||||
a11y-dialog@8.0.2:
|
a11y-dialog@8.0.2:
|
||||||
version "8.0.2"
|
version "8.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/a11y-dialog/-/a11y-dialog-8.0.2.tgz#08b8315d500b7f8c4200ec37d3a0fd15ccd54738"
|
resolved "https://registry.yarnpkg.com/a11y-dialog/-/a11y-dialog-8.0.2.tgz#08b8315d500b7f8c4200ec37d3a0fd15ccd54738"
|
||||||
|
@ -4174,6 +4152,11 @@ content-disposition@0.5.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "5.2.1"
|
safe-buffer "5.2.1"
|
||||||
|
|
||||||
|
content-tag@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/content-tag/-/content-tag-1.1.0.tgz#fcef4bdcf1850f9b67bf0b6f7aee217c6d7ea9fa"
|
||||||
|
integrity sha512-bktivDORs9M890KwVKrIONYvHhwshfgF4b1G/TFPrjH12Ag2GDiSdxVHqIzMxWZ297VgIRPSImURlpcOzJP/LQ==
|
||||||
|
|
||||||
content-type@~1.0.4:
|
content-type@~1.0.4:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
|
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
|
||||||
|
@ -8115,6 +8098,11 @@ merge2@^1.2.3, merge2@^1.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||||
|
|
||||||
|
mersenne-twister@^1.0.1:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a"
|
||||||
|
integrity sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==
|
||||||
|
|
||||||
message-bus-client@^4.3.8:
|
message-bus-client@^4.3.8:
|
||||||
version "4.3.8"
|
version "4.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/message-bus-client/-/message-bus-client-4.3.8.tgz#5ee23c03236b250b13613034764a87881c350d4e"
|
resolved "https://registry.yarnpkg.com/message-bus-client/-/message-bus-client-4.3.8.tgz#5ee23c03236b250b13613034764a87881c350d4e"
|
||||||
|
@ -8832,6 +8820,11 @@ patch-package@^8.0.0:
|
||||||
tmp "^0.0.33"
|
tmp "^0.0.33"
|
||||||
yaml "^2.2.2"
|
yaml "^2.2.2"
|
||||||
|
|
||||||
|
path-browserify@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
|
||||||
|
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
|
||||||
|
|
||||||
path-exists@^3.0.0:
|
path-exists@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
|
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
|
||||||
|
@ -8939,6 +8932,13 @@ pkg-up@^3.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up "^3.0.0"
|
find-up "^3.0.0"
|
||||||
|
|
||||||
|
polyfill-crypto.getrandomvalues@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/polyfill-crypto.getrandomvalues/-/polyfill-crypto.getrandomvalues-1.0.0.tgz#5c95602976ebb6155b163cb65d77b9eede3b61a4"
|
||||||
|
integrity sha512-GIkU6bg4auRnDFOqUNit7eLn9hzznrJU1CGFuivQzDeVp4Ys8cY4OY6GhAdndJwo4jryz5cJyjg9ELhvQjdrtw==
|
||||||
|
dependencies:
|
||||||
|
mersenne-twister "^1.0.1"
|
||||||
|
|
||||||
portfinder@^1.0.32:
|
portfinder@^1.0.32:
|
||||||
version "1.0.32"
|
version "1.0.32"
|
||||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81"
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81"
|
||||||
|
|
|
@ -6,7 +6,7 @@ require "json_schemer"
|
||||||
class Theme < ActiveRecord::Base
|
class Theme < ActiveRecord::Base
|
||||||
include GlobalPath
|
include GlobalPath
|
||||||
|
|
||||||
BASE_COMPILER_VERSION = 75
|
BASE_COMPILER_VERSION = 76
|
||||||
|
|
||||||
attr_accessor :child_components
|
attr_accessor :child_components
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,7 @@ class ThemeField < ActiveRecord::Base
|
||||||
js_compiler.append_module(
|
js_compiler.append_module(
|
||||||
js,
|
js,
|
||||||
"discourse/initializers/#{initializer_name}",
|
"discourse/initializers/#{initializer_name}",
|
||||||
|
"js",
|
||||||
include_variables: true,
|
include_variables: true,
|
||||||
)
|
)
|
||||||
rescue ThemeJavascriptCompiler::CompileError => ex
|
rescue ThemeJavascriptCompiler::CompileError => ex
|
||||||
|
@ -276,6 +277,7 @@ class ThemeField < ActiveRecord::Base
|
||||||
js_compiler.append_module(
|
js_compiler.append_module(
|
||||||
js,
|
js,
|
||||||
"discourse/pre-initializers/theme-#{theme_id}-translations",
|
"discourse/pre-initializers/theme-#{theme_id}-translations",
|
||||||
|
"js",
|
||||||
include_variables: false,
|
include_variables: false,
|
||||||
)
|
)
|
||||||
rescue ThemeTranslationParser::InvalidYaml => e
|
rescue ThemeTranslationParser::InvalidYaml => e
|
||||||
|
|
|
@ -49,9 +49,9 @@ class DiscourseJsProcessor
|
||||||
{ data: data }
|
{ data: data }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.transpile(data, root_path, logical_path, theme_id: nil)
|
def self.transpile(data, root_path, logical_path, theme_id: nil, extension: nil)
|
||||||
transpiler = Transpiler.new(skip_module: skip_module?(data))
|
transpiler = Transpiler.new(skip_module: skip_module?(data))
|
||||||
transpiler.perform(data, root_path, logical_path, theme_id: theme_id)
|
transpiler.perform(data, root_path, logical_path, theme_id: theme_id, extension: extension)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.should_transpile?(filename)
|
def self.should_transpile?(filename)
|
||||||
|
@ -98,8 +98,14 @@ class DiscourseJsProcessor
|
||||||
end
|
end
|
||||||
|
|
||||||
class Transpiler
|
class Transpiler
|
||||||
JS_PROCESSOR_PATH =
|
TRANSPILER_PATH =
|
||||||
Rails.env.production? ? "tmp/js-processor.js" : "tmp/js-processor/#{Process.pid}.js"
|
(
|
||||||
|
if Rails.env.production?
|
||||||
|
"tmp/theme-transpiler.js"
|
||||||
|
else
|
||||||
|
"tmp/theme-transpiler/#{Process.pid}.js"
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
@mutex = Mutex.new
|
@mutex = Mutex.new
|
||||||
@ctx_init = Mutex.new
|
@ctx_init = Mutex.new
|
||||||
|
@ -109,19 +115,13 @@ class DiscourseJsProcessor
|
||||||
@mutex
|
@mutex
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.generate_js_processor
|
def self.build_theme_transpiler
|
||||||
Discourse::Utils.execute_command(
|
Discourse::Utils.execute_command(
|
||||||
"yarn",
|
"node",
|
||||||
"--silent",
|
"app/assets/javascripts/theme-transpiler/build.js",
|
||||||
"esbuild",
|
TRANSPILER_PATH,
|
||||||
"--log-level=warning",
|
|
||||||
"--bundle",
|
|
||||||
"--external:fs",
|
|
||||||
"--define:process='{\"env\":{}}'",
|
|
||||||
"app/assets/javascripts/js-processor.js",
|
|
||||||
"--outfile=#{JS_PROCESSOR_PATH}",
|
|
||||||
)
|
)
|
||||||
JS_PROCESSOR_PATH
|
TRANSPILER_PATH
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.create_new_context
|
def self.create_new_context
|
||||||
|
@ -135,10 +135,10 @@ class DiscourseJsProcessor
|
||||||
|
|
||||||
# Theme template AST transformation plugins
|
# Theme template AST transformation plugins
|
||||||
if Rails.env.development? || Rails.env.test?
|
if Rails.env.development? || Rails.env.test?
|
||||||
@processor_mutex.synchronize { generate_js_processor }
|
@processor_mutex.synchronize { build_theme_transpiler }
|
||||||
end
|
end
|
||||||
|
|
||||||
ctx.eval(File.read(JS_PROCESSOR_PATH), filename: "js-processor.js")
|
ctx.eval(File.read(TRANSPILER_PATH), filename: "theme-transpiler.js")
|
||||||
|
|
||||||
ctx
|
ctx
|
||||||
end
|
end
|
||||||
|
@ -190,7 +190,7 @@ class DiscourseJsProcessor
|
||||||
@skip_module = skip_module
|
@skip_module = skip_module
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform(source, root_path = nil, logical_path = nil, theme_id: nil)
|
def perform(source, root_path = nil, logical_path = nil, theme_id: nil, extension: nil)
|
||||||
self.class.v8_call(
|
self.class.v8_call(
|
||||||
"transpile",
|
"transpile",
|
||||||
source,
|
source,
|
||||||
|
@ -198,6 +198,7 @@ class DiscourseJsProcessor
|
||||||
skipModule: @skip_module,
|
skipModule: @skip_module,
|
||||||
moduleId: module_name(root_path, logical_path),
|
moduleId: module_name(root_path, logical_path),
|
||||||
filename: logical_path || "unknown",
|
filename: logical_path || "unknown",
|
||||||
|
extension: extension,
|
||||||
themeId: theme_id,
|
themeId: theme_id,
|
||||||
commonPlugins: DISCOURSE_COMMON_BABEL_PLUGINS,
|
commonPlugins: DISCOURSE_COMMON_BABEL_PLUGINS,
|
||||||
},
|
},
|
||||||
|
|
|
@ -309,16 +309,16 @@ task "assets:precompile:compress_js": "environment" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
task "assets:precompile:js_processor": "environment" do
|
task "assets:precompile:theme_transpiler": "environment" do
|
||||||
path = DiscourseJsProcessor::Transpiler.generate_js_processor
|
path = DiscourseJsProcessor::Transpiler.build_theme_transpiler
|
||||||
puts "Compiled js-processor: #{path}"
|
puts "Compiled theme-transpiler: #{path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run these tasks **before** Rails' "assets:precompile" task
|
# Run these tasks **before** Rails' "assets:precompile" task
|
||||||
task "assets:precompile": %w[
|
task "assets:precompile": %w[
|
||||||
assets:precompile:before
|
assets:precompile:before
|
||||||
maxminddb:refresh
|
maxminddb:refresh
|
||||||
assets:precompile:js_processor
|
assets:precompile:theme_transpiler
|
||||||
]
|
]
|
||||||
|
|
||||||
# Run these tasks **after** Rails' "assets:precompile" task
|
# Run these tasks **after** Rails' "assets:precompile" task
|
||||||
|
|
|
@ -220,7 +220,7 @@ task "db:migrate" => %w[
|
||||||
load_config
|
load_config
|
||||||
environment
|
environment
|
||||||
set_locale
|
set_locale
|
||||||
assets:precompile:js_processor
|
assets:precompile:theme_transpiler
|
||||||
] do |_, args|
|
] do |_, args|
|
||||||
DistributedMutex.synchronize(
|
DistributedMutex.synchronize(
|
||||||
"db_migration",
|
"db_migration",
|
||||||
|
|
|
@ -169,8 +169,8 @@ class ThemeJavascriptCompiler
|
||||||
tree.each_pair do |filename, content|
|
tree.each_pair do |filename, content|
|
||||||
module_name, extension = filename.split(".", 2)
|
module_name, extension = filename.split(".", 2)
|
||||||
module_name = "test/#{module_name}" if for_tests
|
module_name = "test/#{module_name}" if for_tests
|
||||||
if extension == "js"
|
if extension == "js" || extension == "gjs"
|
||||||
append_module(content, module_name)
|
append_module(content, module_name, extension)
|
||||||
elsif extension == "hbs"
|
elsif extension == "hbs"
|
||||||
append_ember_template(module_name, content)
|
append_ember_template(module_name, content)
|
||||||
elsif extension == "hbr"
|
elsif extension == "hbr"
|
||||||
|
@ -232,15 +232,15 @@ class ThemeJavascriptCompiler
|
||||||
@output_tree << [filename, script + "\n"]
|
@output_tree << [filename, script + "\n"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_module(script, name, include_variables: true)
|
def append_module(script, name, extension, include_variables: true)
|
||||||
original_filename = name
|
original_filename = name
|
||||||
name = "discourse/theme-#{@theme_id}/#{name}"
|
name = "discourse/theme-#{@theme_id}/#{name}"
|
||||||
|
|
||||||
script = "#{theme_settings}#{script}" if include_variables
|
script = "#{theme_settings}#{script}" if include_variables
|
||||||
transpiler = DiscourseJsProcessor::Transpiler.new
|
transpiler = DiscourseJsProcessor::Transpiler.new
|
||||||
@output_tree << ["#{original_filename}.js", <<~JS]
|
@output_tree << ["#{original_filename}.#{extension}", <<~JS]
|
||||||
if ('define' in window) {
|
if ('define' in window) {
|
||||||
#{transpiler.perform(script, "", name, theme_id: @theme_id).strip}
|
#{transpiler.perform(script, "", name, theme_id: @theme_id, extension: extension).strip}
|
||||||
}
|
}
|
||||||
JS
|
JS
|
||||||
rescue MiniRacer::RuntimeError, DiscourseJsProcessor::TranspileError => ex
|
rescue MiniRacer::RuntimeError, DiscourseJsProcessor::TranspileError => ex
|
||||||
|
|
|
@ -233,4 +233,27 @@ RSpec.describe ThemeJavascriptCompiler do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "ember-template-imports" do
|
||||||
|
it "applies its transforms" do
|
||||||
|
compiler.append_tree({ "discourse/components/my-component.gjs" => <<~JS })
|
||||||
|
import Component from "@glimmer/component";
|
||||||
|
|
||||||
|
export default class MyComponent extends Component {
|
||||||
|
<template>
|
||||||
|
{{this.value}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
value = "foo";
|
||||||
|
}
|
||||||
|
JS
|
||||||
|
|
||||||
|
expect(compiler.raw_content).to include(
|
||||||
|
"define(\"discourse/theme-1/discourse/components/my-component\", [\"exports\",",
|
||||||
|
)
|
||||||
|
expect(compiler.raw_content).to include("_defineProperty(this, \"value\", \"foo\");")
|
||||||
|
expect(compiler.raw_content).to include("setComponentTemplate")
|
||||||
|
expect(compiler.raw_content).to include("createTemplateFactory")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,11 +6,11 @@ RSpec.describe "assets:precompile" do
|
||||||
Discourse::Application.load_tasks
|
Discourse::Application.load_tasks
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "assets:precompile:js_processor" do
|
describe "assets:precompile:theme_transpiler" do
|
||||||
it "compiles the js processor" do
|
it "compiles the js processor" do
|
||||||
out = capture_stdout { Rake::Task["assets:precompile:js_processor"].invoke }
|
out = capture_stdout { Rake::Task["assets:precompile:theme_transpiler"].invoke }
|
||||||
|
|
||||||
expect(out).to match(%r{Compiled js-processor: tmp/js-processor})
|
expect(out).to match(%r{Compiled theme-transpiler: tmp/theme-transpiler})
|
||||||
path = out.match(/: (.+)/)[1]
|
path = out.match(/: (.+)/)[1]
|
||||||
expect(File.exist?(path)).to eq(true)
|
expect(File.exist?(path)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user