chore(docx-editor): first-party update channel, not the community catalogue
This is our own extension, so it belongs on the channel the operator key signs — theseus.x/extensions/docx-editor/ — alongside screenshot, aegis and pdf-editor. The community catalogue is for extensions published by whoever owns a BNS name, and routing ours through it would have meant asking a name owner to vouch for code we wrote. Drops the community packing script: with one channel there is one publish path, and it is the one already written down in docs/ADDON-UPDATES.md. Worth stating plainly, because it is currently true and awkward: Settings can only *install* from the community catalogue. An extension that is neither bundled nor catalogued has a working update channel and no way for anyone to get the first copy. Either it goes back into the build or it needs a first-party entry point.
This commit is contained in:
parent
74bf9d4e50
commit
4af11d28fb
4 changed files with 27 additions and 89 deletions
|
|
@ -1,65 +0,0 @@
|
||||||
// Package the extension for the community channel.
|
|
||||||
//
|
|
||||||
// node pack.mjs (from addon-build/docx-editor/)
|
|
||||||
//
|
|
||||||
// Produces out/docx-editor-<version>.tar.gz and prints its sha256.
|
|
||||||
//
|
|
||||||
// This channel is NOT the operator-signed one that bundled add-ons use
|
|
||||||
// (scripts/sign-addon-update.mjs). A community extension is signed by the
|
|
||||||
// owner of a BNS name, with that name's wallet, and uploaded to the gateway:
|
|
||||||
//
|
|
||||||
// PUT https://silentmode.st/api/ext/<publisher-name>/docx-editor/<version>
|
|
||||||
// x-bns-sig: BNS-EXT1\n<name>\n<id>\n<version>\n<sha256>\n<ts>
|
|
||||||
// x-bns-entry-sig: silentmode.extension-v1|<id>|<version>|<sha256>|<name>
|
|
||||||
// body: this tarball
|
|
||||||
//
|
|
||||||
// Both signatures are 65-byte BCH message signatures over the raw sha256
|
|
||||||
// digest, made by the key that owns the publisher name's NFT. Nothing here
|
|
||||||
// can produce them — the wallet is the user's. The easy route is the publish
|
|
||||||
// page at theseus.x/extensions/publish, which unlocks a wallet in the
|
|
||||||
// browser, checks ownership, signs and PUTs the tarball you drop on it.
|
|
||||||
//
|
|
||||||
// Once the gateway accepts it, the extension appears in the catalog, which is
|
|
||||||
// what Settings › Extensions › Community and theseus.x/extensions both read.
|
|
||||||
import { execFileSync } from "node:child_process";
|
|
||||||
import { fileURLToPath } from "node:url";
|
|
||||||
import fs from "node:fs";
|
|
||||||
import path from "node:path";
|
|
||||||
import crypto from "node:crypto";
|
|
||||||
|
|
||||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
||||||
const addonDir = path.resolve(here, "../../extensions/docx-editor");
|
|
||||||
const outDir = path.join(here, "out");
|
|
||||||
|
|
||||||
const manifest = JSON.parse(fs.readFileSync(path.join(addonDir, "addon.json"), "utf8"));
|
|
||||||
const { id, version } = manifest;
|
|
||||||
if (!id || !version) throw new Error("addon.json is missing id or version");
|
|
||||||
|
|
||||||
if (!fs.existsSync(path.join(addonDir, "vendor", "docx-vendor.js"))) {
|
|
||||||
throw new Error("vendor/docx-vendor.js is missing — run `npm run build` first");
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.mkdirSync(outDir, { recursive: true });
|
|
||||||
const tarPath = path.join(outDir, `${id}-${version}.tar.gz`);
|
|
||||||
|
|
||||||
// Tar the CONTENTS of the folder so addon.json sits at the archive root,
|
|
||||||
// which is where both the gateway's validator and the installer look.
|
|
||||||
//
|
|
||||||
// On Windows, Git-Bash tar mistakes a drive letter for remote-archive
|
|
||||||
// host:file syntax and mangles backslashes on the way to argv;
|
|
||||||
// --force-local fixes the first and forward slashes fix the second.
|
|
||||||
const posix = (p) => p.replace(/\\/g, "/");
|
|
||||||
execFileSync("tar", ["--force-local", "-c", "-z", "-f", posix(tarPath),
|
|
||||||
"-C", posix(addonDir), "."], { stdio: "inherit" });
|
|
||||||
|
|
||||||
const bytes = fs.readFileSync(tarPath);
|
|
||||||
const sha256 = crypto.createHash("sha256").update(bytes).digest("hex");
|
|
||||||
const MAX = 8 * 1024 * 1024;
|
|
||||||
|
|
||||||
console.log(`\n${id} ${version}`);
|
|
||||||
console.log(` tarball : ${tarPath}`);
|
|
||||||
console.log(` size : ${(bytes.length / 1024).toFixed(0)} KB${bytes.length > MAX ? " ** over the gateway's 8 MB limit **" : ""}`);
|
|
||||||
console.log(` sha256 : ${sha256}`);
|
|
||||||
console.log(`\nPublish it from theseus.x/extensions/publish — unlock the publisher name's`);
|
|
||||||
console.log(`wallet there, drop this tarball in, and it signs and uploads.`);
|
|
||||||
if (bytes.length > MAX) process.exit(1);
|
|
||||||
|
|
@ -2,11 +2,10 @@
|
||||||
"name": "docx-editor-vendor-build",
|
"name": "docx-editor-vendor-build",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "Build-time only: bundles mammoth + ProseMirror + docx into extensions/docx-editor/vendor/, and packs the extension for the community channel.",
|
"description": "Build-time only: bundles mammoth + ProseMirror + docx into extensions/docx-editor/vendor/, and rasterises the icon.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node build.mjs",
|
"build": "node build.mjs",
|
||||||
"pack": "node pack.mjs",
|
|
||||||
"icons": "node make-icons.mjs"
|
"icons": "node make-icons.mjs"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Word editor — a Theseus community extension
|
# Word editor — a Theseus extension
|
||||||
|
|
||||||
Opens, edits and saves Word documents (`.docx`) in a full Theseus tab, and
|
Opens, edits and saves Word documents (`.docx`) in a full Theseus tab, and
|
||||||
exports them as PDF.
|
exports them as PDF.
|
||||||
|
|
@ -11,15 +11,18 @@ Chromium's own print pipeline from `lib/doc-css.js`, the same stylesheet the
|
||||||
editor displays, on the paper size the document itself specifies — so the
|
editor displays, on the paper size the document itself specifies — so the
|
||||||
export matches the preview rather than being a second opinion about it.
|
export matches the preview rather than being a second opinion about it.
|
||||||
|
|
||||||
This is **not** a bundled add-on. It isn't in `bundled-addons/`, it isn't in
|
It is a first-party extension: written here, signed with the Silent Mode
|
||||||
the installer's `extraResources`, and a fresh Theseus profile doesn't have it.
|
operator key, and updated over the channel at
|
||||||
Users get it the same way they'd get anyone else's extension: from
|
`theseus.x/extensions/docx-editor/` like every other add-on Theseus ships.
|
||||||
**Settings › Extensions › Community**, which lists whatever is in the
|
It does not go through the community catalogue, which is for extensions
|
||||||
catalogue at theseus.x/extensions.
|
published by whoever owns a BNS name.
|
||||||
|
|
||||||
Living outside the browser build is the point. A .docx editor is a big
|
It currently lives outside `bundled-addons/`, so it is not compiled into the
|
||||||
dependency — a megabyte of vendored library — and nobody should carry it
|
browser and a fresh profile doesn't have it. That keeps a megabyte of
|
||||||
because they wanted a browser.
|
vendored library off everyone who only wanted a browser — but note that
|
||||||
|
Settings can only *install* from the community catalogue, so until it is
|
||||||
|
either bundled or listed there, the update channel keeps an existing copy
|
||||||
|
current without giving anyone a way to get the first one.
|
||||||
|
|
||||||
## The icon
|
## The icon
|
||||||
|
|
||||||
|
|
@ -43,7 +46,7 @@ before it can carry everything the editor edits:
|
||||||
cd ../../addon-build/docx-editor
|
cd ../../addon-build/docx-editor
|
||||||
npm install
|
npm install
|
||||||
npm run build # writes vendor/docx-vendor.js here
|
npm run build # writes vendor/docx-vendor.js here
|
||||||
npm run pack # writes out/docx-editor-<version>.tar.gz
|
npm run icons # re-rasterises icon.svg after editing it
|
||||||
|
|
||||||
`vendor/docx-vendor.js` is committed, so the extension is installable straight
|
`vendor/docx-vendor.js` is committed, so the extension is installable straight
|
||||||
from a checkout; re-run `npm run build` after touching anything under
|
from a checkout; re-run `npm run build` after touching anything under
|
||||||
|
|
@ -51,19 +54,20 @@ from a checkout; re-run `npm run build` after touching anything under
|
||||||
|
|
||||||
## Publishing
|
## Publishing
|
||||||
|
|
||||||
`npm run pack` produces the tarball and its sha256. Uploading it is a separate
|
The full recipe is in [docs/ADDON-UPDATES.md](../../docs/ADDON-UPDATES.md);
|
||||||
step, and this repo can't do it: a community extension is signed by the
|
the short version, signed with the operator key and always from a clean copy
|
||||||
**owner of a BNS name**, using that name's wallet.
|
of the commit rather than the working tree:
|
||||||
|
|
||||||
The straightforward route is the publish page at
|
git archive HEAD TheseusNavigator/extensions/docx-editor | tar -x -C <clean>
|
||||||
**theseus.x/extensions/publish** — it unlocks a wallet in the browser, checks
|
node scripts/sign-addon-update.mjs <clean>/TheseusNavigator/extensions/docx-editor https://navigate.st/bns/theseus.x/extensions/docx-editor "$USERPROFILE/.silentmode/ops/addon-update-key.pem" --out out/
|
||||||
that the name is yours, then signs and `PUT`s the tarball to
|
|
||||||
`/api/ext/<publisher-name>/docx-editor/<version>`. The gateway verifies both
|
|
||||||
signatures against the name's current owner, stores the tarball on Sia and
|
|
||||||
updates `catalog.json`, which is what Settings and the site both read.
|
|
||||||
|
|
||||||
Version numbers must increase, and the id `docx-editor` belongs to whichever
|
node ../Argus/src/lib/sia-upload.js out/docx-editor-<version>.tar.gz bns/theseus/extensions/docx-editor
|
||||||
name publishes it first.
|
node ../Argus/src/lib/sia-upload.js out/updates.json bns/theseus/extensions/docx-editor
|
||||||
|
|
||||||
|
The channel lives on Sia only — nothing goes to the VPS filesystem — and is
|
||||||
|
served through the gateway at `https://navigate.st/bns/theseus.x/extensions/`.
|
||||||
|
A first release has no `updates.json` to prepend to, so it ships one holding
|
||||||
|
just its own entry. Versions must increase.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,5 @@
|
||||||
"sidebar-panel",
|
"sidebar-panel",
|
||||||
"open-tab"
|
"open-tab"
|
||||||
],
|
],
|
||||||
"updateURL": "https://navigate.st/bns/theseus.x/extensions/community/docx-editor/updates.json"
|
"updateURL": "https://navigate.st/bns/theseus.x/extensions/docx-editor/updates.json"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue