UNPKG

forest-cli

Version:

The Lumberjacks' toolbelt is the Forest CLI which makes easy to manage your back office application directly from the terminal.

434 lines 29.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.matchesWhitelist = exports.NUM_OR_UUID = exports.DOMAIN_RULES = void 0; const scalar = (prop, extra = {}) => ({ kind: 'scalar', prop, ...extra, }); const opaque = (prop, extra = {}) => ({ kind: 'opaque', prop, ...extra, }); /** Return an addDefaults fn that fills the given keys only when absent. */ const withDefaults = (defaults) => (value) => { const out = { ...value }; Object.entries(defaults).forEach(([key, fallback]) => { if (out[key] === undefined) out[key] = fallback; }); return out; }; /** * Segment write-shape: the rendering read omits `defaultSortingFieldName` and * `columns` (both required by the server's segment validator), and manual * segments require `filter`/`query` keys to be present (null allowed) while * smart segments forbid them. */ function segmentAddDefaults(value) { const out = withDefaults({ columns: [], defaultSortingFieldName: null, defaultSortingFieldOrder: null, hasColumnsConfiguration: false, icon: null, isVisible: true, position: 0, type: 'manual', })(value); if (out.type !== 'smart') { if (out.filter === undefined) out.filter = null; if (out.query === undefined) out.query = null; } return out; } /** Chart properties (viewEdit and dashboards) — editable scalars; clear one by setting it to `null`. */ const CHART_PROPS = [ 'name', 'type', 'aggregator', 'aggregateFieldName', 'filter', 'query', 'apiVersion', 'sourceCollectionId', 'groupByFieldName', 'timeRange', 'limit', 'labelFieldName', 'relationshipFieldName', 'numeratorChartId', 'denominatorChartId', 'objective', 'displaySettings', 'description', 'subTitle', ].map(prop => scalar(prop)); const SEGMENT_RULE = { addable: true, children: [ scalar('name'), scalar('position'), scalar('isVisible'), opaque('filter'), { children: [scalar('position'), scalar('isVisible')], fallbackReplaceWhole: true, kind: 'keyedArray', prop: 'columns', segment: 'columns', }, ], addDefaults: segmentAddDefaults, kind: 'keyedArray', premiumPack: 'scopes', prop: 'segments', removable: true, segment: 'segments', }; /** Children of a collection's `layout` object (canonical: collection.layout.*). */ const COLLECTION_LAYOUT_RULE = { children: [ { children: [scalar('position'), scalar('isVisible')], kind: 'keyedArray', prop: 'columns', segment: 'columns', }, { children: [ scalar('displayName'), scalar('description'), scalar('isReadOnly'), scalar('isFilterDisplayed'), scalar('isDissociateDisplayed'), opaque('widgetEdit'), opaque('widgetDisplay'), opaque('mappingValues'), opaque('conditionalFormatting'), ], kind: 'keyedArray', prop: 'fields', segment: 'fields', }, SEGMENT_RULE, { children: [ scalar('position'), scalar('isVisible'), scalar('displayName'), opaque('confirmation'), opaque('segments'), scalar('buttonType'), ], kind: 'keyedArray', prop: 'actions', segment: 'actions', }, { children: [ opaque('summaryView'), { addable: true, children: CHART_PROPS, kind: 'keyedArray', prop: 'charts', removable: true, segment: 'charts', stripOnAdd: [], }, ], kind: 'object', prop: 'viewEdit', segment: 'viewEdit', }, ], kind: 'object', prop: 'layout', segment: 'layout', }; const COLLECTION_RULES = [ scalar('displayName'), scalar('displayNamePlural'), scalar('icon'), scalar('restrictedToSegments'), scalar('defaultSortingOrder'), scalar('defaultSortingFieldName'), scalar('displayFieldName'), COLLECTION_LAYOUT_RULE, ]; /** * Workspaces (and their components) — addressed by id (the route's * `:collectionId` param receives the workspace/component id). Component `type` is * add-only (set on creation); `name`, `displaySettings`, `visibility` and * `options` are editable, matching the server whitelist. `options` is deep and * polymorphic (filter, visibleColumns, collectionId…), so it is kept opaque and * replaced as a whole when it changes. */ const WORKSPACE_RULE = { addable: true, addDefaults: withDefaults({ collectionId: null, components: [], icon: '🗂️', position: 0 }), children: [ scalar('name'), scalar('icon'), scalar('position'), { addable: true, children: [ scalar('name'), opaque('displaySettings'), opaque('visibility'), opaque('options'), ], kind: 'keyedArray', prop: 'components', removable: true, segment: 'components', }, ], kind: 'keyedArray', prop: 'workspaces', removable: true, segment: 'workspaces', }; /** * Inboxes — premium-gated. `type`, `dispatchRule`, `sortingFields`, * `collectionId` and `segmentId` are add-only (set on creation, not * replaceable); the rest are editable scalars. */ const INBOX_RULE = { addable: true, addDefaults: withDefaults({ canUsersReassign: false, position: 0 }), children: [ scalar('name'), scalar('icon'), scalar('position'), scalar('folder'), scalar('tasksLimit'), scalar('canUsersReassign'), opaque('unassignAfter'), ], kind: 'keyedArray', premiumPack: 'inbox', prop: 'inboxes', removable: true, segment: 'inboxes', }; exports.DOMAIN_RULES = { folders: { root: [ { addable: true, children: [ scalar('name'), scalar('icon'), { addable: true, children: [ scalar('position'), scalar('isVisible'), { addable: true, children: [scalar('position'), scalar('isVisible')], kind: 'keyedArray', prop: 'subChildren', removable: true, segment: 'subChildren', }, ], kind: 'keyedArray', prop: 'children', removable: true, segment: 'children', }, ], kind: 'keyedArray', prop: '', removable: true, segment: 'folders', singletonFlag: 'isMain', }, ], }, layout: { root: [ { children: COLLECTION_RULES, kind: 'keyedArray', prop: 'collections', segment: 'collections', }, { addable: true, children: [ scalar('name'), scalar('icon'), scalar('position'), { addable: true, children: CHART_PROPS, kind: 'keyedArray', prop: 'charts', removable: true, segment: 'charts', stripOnAdd: [], }, ], addDefaults: withDefaults({ charts: [], icon: null, position: 0 }), kind: 'keyedArray', premiumPack: 'multipleDashboards', prop: 'dashboards', removable: true, segment: 'dashboards', }, WORKSPACE_RULE, INBOX_RULE, opaque('sections'), ], }, workflows: { root: [ { addable: true, // `collectionId` is required on add but is not a replaceable path, so it is // carried in the add value (passed through) rather than declared as a child. addDefaults: withDefaults({ isVisible: true, position: 0, segmentIds: [] }), children: [ scalar('name'), scalar('position'), scalar('isVisible'), opaque('segmentIds'), scalar('bpmnAwsS3Identifier'), ], kind: 'keyedArray', prop: '', removable: true, segment: 'workflows', // `steps` is authoring input compiled to BPMN out-of-band, never sent in the shell patch. stripOnAdd: ['steps'], }, ], }, }; /* --------------------------- whitelist mirror ---------------------------- */ // Same id classes as the server's patch-handler. NUM_OR_UUID is exported so the // sidecar prune (`workflow-sidecar.ts`) only ever deletes files named after a // real server id — never a user's own hand-named BPMN files. const ID = String.raw `[^/\s:]+`; exports.NUM_OR_UUID = String.raw `([0-9]+|[0-9a-fA-F-]{36})`; function entry(ops, path) { return { ops, pattern: new RegExp(`^${path}$`) }; } const COLLECTION_SCALARS = [ 'displayName', 'displayNamePlural', 'icon', 'restrictedToSegments', 'defaultSortingOrder', 'defaultSortingFieldName', 'displayFieldName', ].join('|'); const FIELD_PROPS = [ 'displayName', 'description', 'isReadOnly', 'isFilterDisplayed', 'isDissociateDisplayed', 'widgetEdit', 'widgetDisplay', 'mappingValues', 'conditionalFormatting', ].join('|'); const ACTION_PROPS = [ 'position', 'isVisible', 'displayName', 'confirmation', 'segments', 'buttonType', ].join('|'); const CHART_PROP_NAMES = [ 'name', 'type', 'aggregator', 'aggregateFieldName', 'filter', 'query', 'apiVersion', 'sourceCollectionId', 'groupByFieldName', 'timeRange', 'limit', 'labelFieldName', 'relationshipFieldName', 'numeratorChartId', 'denominatorChartId', 'objective', 'displaySettings', 'description', 'subTitle', ].join('|'); const WHITELIST = { folders: [ entry(['add'], `/folders/-`), entry(['remove'], `/folders/${exports.NUM_OR_UUID}`), entry(['replace'], `/folders/${exports.NUM_OR_UUID}/(name|icon)`), entry(['add'], `/folders/${exports.NUM_OR_UUID}/children/-`), entry(['remove'], `/folders/${exports.NUM_OR_UUID}/children/${ID}`), entry(['replace'], `/folders/${exports.NUM_OR_UUID}/children/${ID}/(position|isVisible)`), entry(['add'], `/folders/${exports.NUM_OR_UUID}/children/${ID}/subChildren/-`), entry(['remove'], `/folders/${exports.NUM_OR_UUID}/children/${ID}/subChildren/${ID}`), entry(['replace'], `/folders/${exports.NUM_OR_UUID}/children/${ID}/subChildren/${ID}/(position|isVisible)`), ], layout: [ entry(['replace'], `/collections/${ID}/(${COLLECTION_SCALARS})`), entry(['replace'], `/collections/${ID}/layout/columns/${ID}/(position|isVisible)`), entry(['replace'], `/collections/${ID}/layout/fields/${ID}/(${FIELD_PROPS})`), entry(['add'], `/collections/${ID}/layout/segments/-`), entry(['remove'], `/collections/${ID}/layout/segments/${ID}`), entry(['replace'], `/collections/${ID}/layout/segments/${ID}/(name|position|isVisible|filter|columns)`), entry(['replace'], `/collections/${ID}/layout/segments/${ID}/columns/${ID}/(position|isVisible)`), entry(['replace'], `/collections/${ID}/layout/actions/${ID}/(${ACTION_PROPS})`), entry(['replace'], `/collections/${ID}/layout/viewEdit/summaryView`), entry(['add'], `/collections/${ID}/layout/viewEdit/charts/-`), entry(['remove', 'replace'], `/collections/${ID}/layout/viewEdit/charts/${exports.NUM_OR_UUID}`), entry(['remove', 'replace'], `/collections/${ID}/layout/viewEdit/charts/${exports.NUM_OR_UUID}/(${CHART_PROP_NAMES})`), entry(['replace'], `/collections/${ID}/layout/viewEdit/rows/${ID}/(position|isVisible|explorerConfiguration)`), entry(['replace'], `/collections/${ID}/layout/viewCreate/rows/${ID}/(position|isVisible)`), entry(['add'], `/collections/${ID}/layout/viewLists/-`), entry(['remove'], `/collections/${ID}/layout/viewLists/${ID}`), entry(['replace'], `/collections/${ID}/layout/viewLists/${ID}/(name|position|recordsPerPage|allowJavascript)`), entry(['replace'], `/collections/${ID}/layout/scope`), entry(['add'], `/dashboards/-`), entry(['remove'], `/dashboards/${exports.NUM_OR_UUID}`), entry(['replace'], `/dashboards/${exports.NUM_OR_UUID}/(name|icon|position)`), entry(['add'], `/dashboards/${exports.NUM_OR_UUID}/charts/-`), entry(['remove', 'replace'], `/dashboards/${exports.NUM_OR_UUID}/charts/${exports.NUM_OR_UUID}`), entry(['remove', 'replace'], `/dashboards/${exports.NUM_OR_UUID}/charts/${exports.NUM_OR_UUID}/(${CHART_PROP_NAMES})`), entry(['add'], `/workspaces/-`), entry(['remove'], `/workspaces/${ID}`), entry(['replace'], `/workspaces/${ID}/(name|icon|position)`), entry(['add'], `/workspaces/${ID}/components/-`), entry(['remove'], `/workspaces/${ID}/components/${exports.NUM_OR_UUID}`), entry(['replace'], `/workspaces/${ID}/components/${exports.NUM_OR_UUID}/(name|displaySettings|visibility|options)`), entry(['add'], `/inboxes/-`), entry(['remove'], `/inboxes/${exports.NUM_OR_UUID}`), entry(['replace'], `/inboxes/${exports.NUM_OR_UUID}/${ID}`), entry(['replace'], `/sections`), ], workflows: [ entry(['add'], `/workflows/-`), entry(['remove'], `/workflows/${exports.NUM_OR_UUID}`), entry(['replace'], `/workflows/${exports.NUM_OR_UUID}/(name|position|isVisible|segmentIds|bpmnAwsS3Identifier)`), ], }; /** True when an op matches the mirrored server whitelist for this domain. */ function matchesWhitelist(domain, op) { return WHITELIST[domain].some(candidate => candidate.ops.includes(op.op) && candidate.pattern.test(op.path)); } exports.matchesWhitelist = matchesWhitelist; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0Y2gtcnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvbGF5b3V0L3BhdGNoLXJ1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTREQSxNQUFNLE1BQU0sR0FBRyxDQUFDLElBQVksRUFBRSxRQUE2QixFQUFFLEVBQWMsRUFBRSxDQUFDLENBQUM7SUFDN0UsSUFBSSxFQUFFLFFBQVE7SUFDZCxJQUFJO0lBQ0osR0FBRyxLQUFLO0NBQ1QsQ0FBQyxDQUFDO0FBQ0gsTUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFZLEVBQUUsUUFBNkIsRUFBRSxFQUFjLEVBQUUsQ0FBQyxDQUFDO0lBQzdFLElBQUksRUFBRSxRQUFRO0lBQ2QsSUFBSTtJQUNKLEdBQUcsS0FBSztDQUNULENBQUMsQ0FBQztBQUVILDJFQUEyRTtBQUMzRSxNQUFNLFlBQVksR0FDaEIsQ0FBQyxRQUFpQyxFQUFFLEVBQUUsQ0FDdEMsQ0FBQyxLQUE4QixFQUEyQixFQUFFO0lBQzFELE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxLQUFLLEVBQUUsQ0FBQztJQUN6QixNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxFQUFFLEVBQUU7UUFDbkQsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssU0FBUztZQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMsQ0FBQztBQUVKOzs7OztHQUtHO0FBQ0gsU0FBUyxrQkFBa0IsQ0FBQyxLQUE4QjtJQUN4RCxNQUFNLEdBQUcsR0FBRyxZQUFZLENBQUM7UUFDdkIsT0FBTyxFQUFFLEVBQUU7UUFDWCx1QkFBdUIsRUFBRSxJQUFJO1FBQzdCLHdCQUF3QixFQUFFLElBQUk7UUFDOUIsdUJBQXVC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