mirror of
https://github.com/wekan/wekan.git
synced 2026-11-05 15:45:01 -05:00
models/lib/cardBoardConsistency.js and models/lib/restArrayParam.js are CommonJS (module.exports), but being under models/ they were eagerly bundled into the client by rspack, which classifies a no-import/require .js as an ES module and threw at load time: Uncaught Error: ES Modules may not assign module.exports or exports.* ... ./models/lib/cardBoardConsistency.js -> ./models/cards.js This aborted the client bundle on every page. (filenameSanitizer.js uses the same module.exports pattern without issue only because it is never imported into the client bundle.) Both helpers are server-only logic (a REST handler and a Cards.before.update hook), so they are moved to server/lib/ (excluded from the client rspack bundle, CommonJS is fine on the Node server) and enforceCardBoardConsistency is relocated from the isomorphic models/cards.js into server/models/cards.js. The isomorphic models/cards.js no longer imports either helper. Verified in a real headless Chromium against a running dev server: the page now loads with window.Meteor present and zero console/page errors (previously one PAGEERROR from cardBoardConsistency.js). Node unit tests updated to the new paths and pass (npm run test:unit:node, 11 passing). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
37 lines
1.6 KiB
JavaScript
37 lines
1.6 KiB
JavaScript
// Pure, dependency-free helper (no Meteor imports) so it can be unit tested
|
|
// directly with plain Node. Used by the REST API card update handler in
|
|
// server/models/cards.js.
|
|
//
|
|
// #3697: editing a card's `members` via the REST API and then trying to clear
|
|
// them left the field in a state the UI could not edit. Two problems:
|
|
// 1. The handler guarded with `if (req.body.members)`, which is falsy for the
|
|
// two natural "clear" payloads (`null` and `""`), so removing the last
|
|
// member via REST was a silent no-op.
|
|
// 2. Its string branch wrote `null` (not `[]`) for an empty value, and a card
|
|
// with `members: null` breaks UI code that treats it as an array
|
|
// (`members.indexOf(...)`, the members popup, etc.) — the schema declares
|
|
// `members` as an Array with defaultValue `[]`, never null.
|
|
//
|
|
// coerceRestArrayParam normalizes whatever the REST client sent into a clean
|
|
// String[] so the stored value is always an array: a single id becomes a
|
|
// one-element array, an empty string / null / any non-array becomes `[]` (an
|
|
// explicit clear), and an array is kept but filtered to strings (so a stray
|
|
// `[null]` / `[123]` cannot reach the document).
|
|
|
|
/**
|
|
* @param {*} value the raw REST body value for members / assignees
|
|
* @return {string[]} a normalized array of id strings (possibly empty)
|
|
*/
|
|
function coerceRestArrayParam(value) {
|
|
if (Array.isArray(value)) {
|
|
return value.filter(v => typeof v === 'string' && v !== '');
|
|
}
|
|
if (typeof value === 'string') {
|
|
return value === '' ? [] : [value];
|
|
}
|
|
// null / undefined / number / object → treat as an explicit clear.
|
|
return [];
|
|
}
|
|
|
|
module.exports = { coerceRestArrayParam };
|