Publish quixos-nix-helpers from 1de28b236de076d239752b77553f833dfbdb5b43

This commit is contained in:
Quixos Subtree Publisher
2026-09-16 23:49:09 +00:00
4 changed files with 568 additions and 434 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"version": 1,
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos",
"sourceCommit": "8484d99fcf78a49341a17597bc62211e5f1807dd",
"sourceCommit": "1de28b236de076d239752b77553f833dfbdb5b43",
"sourcePath": "quixos-instance/quixos-nix-helpers",
"exportName": "quixos-nix-helpers",
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
+57 -24
View File
@@ -1,10 +1,10 @@
import {createRequire} from "node:module";
import { createRequire } from "node:module";
import path from "node:path";
// Resolve build dependencies from the package's locked node_modules, not from
// the helper's own Nix-store location. This program runs only during the build.
const require = createRequire(path.join(process.cwd(), "package.json"));
const {build} = require("esbuild");
const { build } = require("esbuild");
const options = JSON.parse(process.argv[2]);
const platform = new Map([
["react", "/__quixos/platform/react/v18.mjs"],
@@ -12,25 +12,58 @@ const platform = new Map([
["react/jsx-dev-runtime", "/__quixos/platform/react-jsx-dev-runtime/v18.mjs"],
["@quixos/web-studio-react-runtime", "/__quixos/platform/web-studio-react-runtime/v1.mjs"],
]);
await build({...options, plugins: [{name: "quixos-browser-source", setup(api) {
api.onResolve({filter: /\?browser-source$/}, async ({path: specifier, resolveDir}) => {
if (!specifier.startsWith("./") && !specifier.startsWith("../")) throw new Error("Browser source imports must name a relative compiled module");
const resolved = await api.resolve(specifier.slice(0, -"?browser-source".length), {resolveDir, kind: "import-statement"});
if (resolved.errors.length) return {errors: resolved.errors};
return {path: resolved.path, namespace: "browser-source"};
});
api.onLoad({filter: /.*/, namespace: "browser-source"}, async ({path: entry}) => {
const browser = await build({entryPoints: [entry], bundle: true, write: false, outfile: "component.mjs",
format: "esm", platform: "browser", target: "es2022", metafile: true,
plugins: [{name: "quixos-platform", setup(browserApi) {
browserApi.onResolve({filter: /.*/}, ({path: name}) => platform.has(name) ? {path: platform.get(name), external: true} : undefined);
}}]});
const js = browser.outputFiles.find(file => file.path.endsWith(".mjs"));
if (!js) throw new Error("Browser source build produced no JavaScript");
const css = browser.outputFiles.find(file => file.path.endsWith(".css"));
if (css && Object.values(browser.metafile.outputs).some(output => output.exports?.includes("styles"))) throw new Error("Use either imported CSS or an explicit styles export, not both");
if (browser.outputFiles.some(file => !file.path.endsWith(".mjs") && !file.path.endsWith(".css"))) throw new Error("Browser assets must be embedded, not emitted as unserved files");
const source = js.text + (css ? `\nexport const styles = ${JSON.stringify(css.text)};\n` : "");
return {contents: `export default ${JSON.stringify(source)};`, loader: "js", watchFiles: Object.keys(browser.metafile.inputs)};
});
}}]});
await build({
...options,
plugins: [
{
name: "quixos-browser-source",
setup(api) {
api.onResolve({ filter: /\?browser-source$/ }, async ({ path: specifier, resolveDir }) => {
if (!specifier.startsWith("./") && !specifier.startsWith("../"))
throw new Error("Browser source imports must name a relative compiled module");
const resolved = await api.resolve(specifier.slice(0, -"?browser-source".length), {
resolveDir,
kind: "import-statement",
});
if (resolved.errors.length) return { errors: resolved.errors };
return { path: resolved.path, namespace: "browser-source" };
});
api.onLoad({ filter: /.*/, namespace: "browser-source" }, async ({ path: entry }) => {
const browser = await build({
entryPoints: [entry],
bundle: true,
write: false,
outfile: "component.mjs",
format: "esm",
platform: "browser",
target: "es2022",
metafile: true,
plugins: [
{
name: "quixos-platform",
setup(browserApi) {
browserApi.onResolve({ filter: /.*/ }, ({ path: name }) =>
platform.has(name) ? { path: platform.get(name), external: true } : undefined,
);
},
},
],
});
const js = browser.outputFiles.find((file) => file.path.endsWith(".mjs"));
if (!js) throw new Error("Browser source build produced no JavaScript");
const css = browser.outputFiles.find((file) => file.path.endsWith(".css"));
if (css && Object.values(browser.metafile.outputs).some((output) => output.exports?.includes("styles")))
throw new Error("Use either imported CSS or an explicit styles export, not both");
if (browser.outputFiles.some((file) => !file.path.endsWith(".mjs") && !file.path.endsWith(".css")))
throw new Error("Browser assets must be embedded, not emitted as unserved files");
const source = js.text + (css ? `\nexport const styles = ${JSON.stringify(css.text)};\n` : "");
return {
contents: `export default ${JSON.stringify(source)};`,
loader: "js",
watchFiles: Object.keys(browser.metafile.inputs),
};
});
},
},
],
});
+32 -9
View File
@@ -1,17 +1,40 @@
import fs from "node:fs";
import crypto from "node:crypto";
const [schemaPath, packageRevisionId, bindingOutput, generatorPath, output] = process.argv.slice(2);
if (!schemaPath || !packageRevisionId || !bindingOutput || !generatorPath || !output) throw new Error("Missing candidate check receipt inputs");
const canonical = (value) => Array.isArray(value) ? value.map(canonical) : value && typeof value === "object"
? Object.fromEntries(Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, entry]) => [key, canonical(entry)])) : value;
const hash = (value) => `sha256:${crypto.createHash("sha256").update(JSON.stringify(canonical(value))).digest("hex")}`;
if (!schemaPath || !packageRevisionId || !bindingOutput || !generatorPath || !output)
throw new Error("Missing candidate check receipt inputs");
const canonical = (value) =>
Array.isArray(value)
? value.map(canonical)
: value && typeof value === "object"
? Object.fromEntries(
Object.entries(value)
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
.map(([key, entry]) => [key, canonical(entry)]),
)
: value;
const hash = (value) =>
`sha256:${crypto
.createHash("sha256")
.update(JSON.stringify(canonical(value)))
.digest("hex")}`;
const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
if (!schema.packages.some((entry) => entry.revisionId === packageRevisionId)) throw new Error("Checked binding schema lacks the package");
if (!schema.packages.some((entry) => entry.revisionId === packageRevisionId))
throw new Error("Checked binding schema lacks the package");
const generated = fs.readFileSync(bindingOutput, "utf8");
if (generated !== fs.readFileSync(".qx-checked-bindings", "utf8")) throw new Error("Build replaced candidate-generated bindings; its check is not evidence for this candidate");
if (generated !== fs.readFileSync(".qx-checked-bindings", "utf8"))
throw new Error("Build replaced candidate-generated bindings; its check is not evidence for this candidate");
const receipt = {
schemaVersion: 1, packageRevisionId, success: true, bindingSchema: schema,
bindingSchemaDigest: hash(schema), generatedDigest: hash(generated),
checkerDigest: hash({ generatorPath, compiler: JSON.parse(fs.readFileSync("node_modules/typescript/package.json", "utf8")), lock: fs.readFileSync("yarn.lock", "utf8") }),
schemaVersion: 1,
packageRevisionId,
success: true,
bindingSchema: schema,
bindingSchemaDigest: hash(schema),
generatedDigest: hash(generated),
checkerDigest: hash({
generatorPath,
compiler: JSON.parse(fs.readFileSync("node_modules/typescript/package.json", "utf8")),
lock: fs.readFileSync("yarn.lock", "utf8"),
}),
};
fs.writeFileSync(output, `${JSON.stringify(receipt, null, 2)}\n`, { flag: "wx" });
+478 -400
View File
File diff suppressed because it is too large Load Diff