Commit graph

26 commits

Author SHA1 Message Date
John McLear
85c941fe95
feat(padOptions): pass plugin-namespaced ep_* keys through applyPadSettings (#7698)
* feat(padOptions): pass plugin-namespaced ep_* keys through applyPadSettings

Native pad-wide settings ride a single padOptions object: the server seeds
clientVars.initialOptions, the client mutates via pad.changePadOption(), and
the existing padoptions COLLABROOM message broadcasts changes. Plugins can't
use the same rail today because applyPadSettings (client) and
normalizePadSettings (server) silently drop any key not in their hardcoded
whitelist.

Add a passthrough loop that preserves keys matching /^ep_[a-z0-9_]+$/ on both
sides. Plugins can now stash their pad-wide values under their own namespace
(e.g. pad.padOptions.ep_table_of_contents = {enabled: true}) and inherit the
existing broadcast, persistence, creator-only-write enforcement, and
enforceSettings semantics for free.

A new src/node/utils/PluginCapabilities module exposes
padOptionsPluginPassthrough = true so plugins can feature-detect via
require() and fall back to per-user behavior on older cores.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Address Qodo review on PR #7698

Four concerns raised by Qodo (qodo-free-for-open-source-projects):

1. Feature flag — AGENTS.MD §52 requires new features behind a flag,
   disabled by default. Add `enablePluginPadOptions` (default false) gating
   the passthrough on both server (normalizePadSettings) and client
   (applyPadSettings, via clientVars). Plugins detect the runtime state
   through clientVars.enablePluginPadOptions; the static
   PluginCapabilities flag stays as the "core can do this" signal.

2. Documentation — add a "Plugin-namespaced pad-wide options" section to
   doc/plugins.md covering capability detection, the runtime flag, the
   key namespace pattern, and the validation rules. Mirror the flag
   description in settings.json.template.

3. Unbounded payload — values for ep_* keys are persisted with the pad and
   broadcast to every connected client, so an unvalidated path was a
   reliability hazard. Validate every ep_* value:
     - Must round-trip through JSON.stringify (rejects functions, symbols,
       BigInt, circular refs).
     - Per-key serialized size capped at 64 KB.
     - Combined ep_* size capped at 256 KB per pad.
   Rejects drop the value with a console.warn line; the rest of the pad
   settings round-trip cleanly.

4. PadOption type — add `[k: \`ep_${string}\`]: unknown` index signature
   so the SocketIO message type matches runtime behavior; TS callers no
   longer need unsafe casts to read plugin-namespaced keys.

Also extends the backend test suite with cases covering the runtime flag
(off/on), JSON-serializability rejection, per-key cap, and total cap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(snap-tests): assert_grep — use here-string to dodge pipefail SIGPIPE

`assert_grep` ran `printf '%s' "$out" | grep -q -F -- "$needle"` under
`set -o pipefail`. When grep matched early it closed its stdin, printf
got SIGPIPE on its next write (exit 141), and pipefail propagated the
broken-pipe failure to the pipeline — making `if` see non-zero and
falling into the FAIL branch even though grep itself succeeded.

Failure was timing-dependent: it only fired when `$out` was large enough
that printf hadn't flushed before grep exited. CI ubuntu-latest tipped
into the racy path on PR #7698 once `settings.json.template` grew by 11
lines (the new `enablePluginPadOptions` flag); the symptom was the
`Wrapper unit tests` step reporting `dbType rewritten to sqlite ✗` with
"got: /*…" output even though the seeded file did contain the needle.

Replace the pipe with a here-string so grep gets its input in one shot
with no pipe between processes — no SIGPIPE possible. The fail-message
`head -3` is converted to a here-string for the same reason.

Repro on a runner whose pipe-buffer flush is slower than grep's first
match would have hit the same flake on any PR; the bug isn't about
this particular template change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:17:05 +01:00
John McLear
32d5d90c9d
chore: remove dead root files (.travis.yml, .lgtm.yml, *.bat) (#7531)
These files are stale: there's no CI/tooling left that reads them.

- .travis.yml — Etherpad moved to GitHub Actions years ago. The
  workflows in .github/workflows/ are the source of truth.
- .lgtm.yml — LGTM was sunset by GitHub in late 2022.
- start.bat — README only documents the PowerShell installer for
  Windows now (irm .../installer.ps1 | iex), no docs or scripts
  reference start.bat.
- bin/installOnWindows.bat — same; not referenced by README, docs
  or workflows.

Also drop the .travis.yml line from the plugin layout in
doc/plugins.md and replace it with a pointer at .github/workflows/.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 17:29:24 +01:00
David P
84e6619e03
correcting plugin install doc (#7104) 2025-08-29 15:48:35 +02:00
SamTV12345
d004d19dd7
Added vitepress for documentation. (#6270) 2024-03-23 20:58:05 +01:00
SamTV12345
dc0db68515
Added docs as asciidoctor with cross platform support. (#5733)
* Added docs as asciidoctor with cross platform support.

* Fixed release script with new doc building mechanism.
2023-06-21 13:13:31 +01:00
Richard Hansen
1e604add99 deps: Require Node.js 12.17.0 or later
This makes it possible to use dynamic `import()`.
2022-01-27 01:27:10 -05:00
Richard Hansen
ef1ba21104 deps: Drop support for Node.js < 12.13.0 2021-06-14 23:17:17 +02:00
Richard Hansen
6198e92706 tests: Pass --legacy-peer-deps flag to work around npm v7 bug
This flag is unknown to npm v6, but npm v6 silently ignores unknown
flags.
2021-02-22 03:36:12 -05:00
Richard Hansen
6163339c0d plugins: Always install plugins with --no-save
The npm CLI can get confused if `package.json` or `package-lock.json`
exist.
2021-02-18 19:18:59 +00:00
John McLear
0cc8405e9c Bump minimum required Node.js version to 10.17.0
This makes it possible to use fs.promises.
2021-01-30 17:00:40 -05:00
Richard Hansen
cedd27e4fe plugins: Default the module name to the plugin name 2020-11-13 20:30:27 +00:00
Richard Hansen
6c07229d38 docs: Revise plugin documentation 2020-11-13 20:30:27 +00:00
Richard Hansen
cc8dbb07fd docs: Wrap long lines
Also add blank lines around section headings and code blocks.
2020-11-13 20:30:27 +00:00
muxator
684f374ece runtime: require node >= 10.13.0 LTS
At the moment, NodeJS 10.x is the lowest supported LTS version. NodeJS 8.x is no
longer supported upstream.

Implements #3835.
Planned in #3650.
2020-04-09 04:43:37 +02:00
muxator
312c72c364 formatting: bulk remove trailing whitespaces
Do not touch vendorized files (e.g. libraries that were imported from external
projects).

No functional changes.

Command:
    find . -name '*.<EXTENSION>' -type f -print0 | xargs -0 sed -i 's/[[:space:]]*$//'
2019-10-20 02:09:22 +02:00
muxator
9d35d15ae3 node8: require nodejs >= 8.9.0, npm >= 6.4
Next version will be Etherpad 1.8. As planned in #3424, we are going to require
NodeJS >=8.9.0 and npm >= 6.4.

This commit implements that change and updates documentation and scripts.
Subsequent changes will get rid of old idioms, dating back to node < 0.7, that
still survive in the code.
Once migrated to NodeJS 8, we will be able to start working on migrating the
code base from callbacks to async/await, greatly simplifying legibility (see
#3540).

Closes #3557
2019-02-19 22:01:12 +01:00
HairyFotr
fce55df2b7 Fix typos 2019-01-16 11:14:04 +01:00
muxator
23eab79946 pad.html: for each client plugin, add a class to #editorcontainerbox
This commit implements the following behaviour:

1. adds a function clientPluginNames() to hooks.js (mimicking what is done in
   static.js), which returns an array containing the list of currently installed
   client side plugins. The array is eventually empty.

2. calls that function in pad.html at rendering time (thus server-side) to
   populate a class attribute.

Example results:
- with no client-side plugins installed:
  <div id="editorcontainerbox" class="">

- with some client-side plugins installed:
  <div id="editorcontainerbox" class="ep_author_neat ep_adminpads">

Looking at the existing code (src/node/hooks/express/static.js#L39-L57), a
client-side plugin is defined as a plugin that implements at least a client side
hook.

NOTE: there is currently no support for notifying plugin removal/installation
      to the connected clients: for now, in order to get an updated class list,
      the clients will have to refresh the page.

Fixes #3488
2018-10-02 21:22:13 +02:00
muxator
e9fb63f426 docs: "``js" -> "``json" in Markdown of some json blocks 2018-08-09 22:27:56 +02:00
muxator
7544585908 runtime: enforce minimal node version to 6.9.0
Etherpad 1.6.6 does not run on node <= 5 already.
Node 6.9 is the first LTS release in the 6 series, and comes with npm 3.10.8.

Declarations in package.json are advisory unless the user has set
`engine-strict` config flag.

Updated the docs accordingly.
2018-07-28 23:33:24 +02:00
HairyFotr
c7548450c0
Typos and minor fixes in bin, doc, and root 2017-09-14 13:33:27 +02:00
Eric Schrijver
b34224559d ‘Etherpad Lite’ -> ‘Etherpad’ 2013-09-29 13:57:37 +02:00
John McLear
280b3a404c doh, doc fix 2013-02-09 17:02:54 +00:00
John McLear
bb1d462612 plugin test docs 2013-02-09 15:45:00 +00:00
Marcel Klehr
e60f8de676 Expand plugin system docs with l10n info 2012-12-23 22:48:28 +01:00
Marcel Klehr
63e4aafae8 Add docs for plugins and plugin framework
@redhog please elaborate on / improve 'doc/api/pluginfw.md'!
2012-10-25 15:45:06 +02:00