tiptap-apcore 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +407 -0
- package/dist/builder/AnnotationCatalog.d.ts +22 -0
- package/dist/builder/AnnotationCatalog.d.ts.map +1 -0
- package/dist/builder/AnnotationCatalog.js +269 -0
- package/dist/builder/AnnotationCatalog.js.map +1 -0
- package/dist/builder/ModuleBuilder.d.ts +42 -0
- package/dist/builder/ModuleBuilder.d.ts.map +1 -0
- package/dist/builder/ModuleBuilder.js +106 -0
- package/dist/builder/ModuleBuilder.js.map +1 -0
- package/dist/builder/SchemaCatalog.d.ts +20 -0
- package/dist/builder/SchemaCatalog.d.ts.map +1 -0
- package/dist/builder/SchemaCatalog.js +352 -0
- package/dist/builder/SchemaCatalog.js.map +1 -0
- package/dist/builder/index.d.ts +4 -0
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +5 -0
- package/dist/builder/index.js.map +1 -0
- package/dist/discovery/ExtensionScanner.d.ts +25 -0
- package/dist/discovery/ExtensionScanner.d.ts.map +1 -0
- package/dist/discovery/ExtensionScanner.js +61 -0
- package/dist/discovery/ExtensionScanner.js.map +1 -0
- package/dist/discovery/index.d.ts +2 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +3 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/errors/TiptapModuleError.d.ts +18 -0
- package/dist/errors/TiptapModuleError.d.ts.map +1 -0
- package/dist/errors/TiptapModuleError.js +23 -0
- package/dist/errors/TiptapModuleError.js.map +1 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/TiptapExecutor.d.ts +20 -0
- package/dist/runtime/TiptapExecutor.d.ts.map +1 -0
- package/dist/runtime/TiptapExecutor.js +327 -0
- package/dist/runtime/TiptapExecutor.js.map +1 -0
- package/dist/runtime/TiptapRegistry.d.ts +35 -0
- package/dist/runtime/TiptapRegistry.d.ts.map +1 -0
- package/dist/runtime/TiptapRegistry.js +100 -0
- package/dist/runtime/TiptapRegistry.js.map +1 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/security/AclGuard.d.ts +10 -0
- package/dist/security/AclGuard.d.ts.map +1 -0
- package/dist/security/AclGuard.js +96 -0
- package/dist/security/AclGuard.js.map +1 -0
- package/dist/security/index.d.ts +2 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +2 -0
- package/dist/security/index.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +9 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +116 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/withApcore.d.ts +14 -0
- package/dist/withApcore.d.ts.map +1 -0
- package/dist/withApcore.js +81 -0
- package/dist/withApcore.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Executor, EditorLike } from "../types.js";
|
|
2
|
+
import type { TiptapRegistry } from "./TiptapRegistry.js";
|
|
3
|
+
import { AclGuard } from "../security/AclGuard.js";
|
|
4
|
+
export type { EditorLike, ChainLike } from "../types.js";
|
|
5
|
+
export declare class TiptapExecutor implements Executor {
|
|
6
|
+
readonly registry: TiptapRegistry;
|
|
7
|
+
private editor;
|
|
8
|
+
private aclGuard;
|
|
9
|
+
private sanitizeHtml;
|
|
10
|
+
constructor(editor: EditorLike, registry: TiptapRegistry, aclGuard: AclGuard, sanitizeHtml?: (html: string) => string);
|
|
11
|
+
call(moduleId: string, inputs: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
12
|
+
callAsync(moduleId: string, inputs: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
13
|
+
private extractCategory;
|
|
14
|
+
private extractCommandName;
|
|
15
|
+
private executeQuery;
|
|
16
|
+
private executeCommand;
|
|
17
|
+
private handleSelectText;
|
|
18
|
+
private buildArgs;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=TiptapExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TiptapExecutor.d.ts","sourceRoot":"","sources":["../../src/runtime/TiptapExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAa,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAInD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA4DzD,qBAAa,cAAe,YAAW,QAAQ;IAC7C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAyC;gBAG3D,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,EAClB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;IAQnC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAuBzF,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIpG,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,YAAY;IAmDpB,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,gBAAgB;IAsCxB,OAAO,CAAC,SAAS;CAiHlB"}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { TiptapModuleError, ErrorCodes } from "../errors/index.js";
|
|
2
|
+
// ── URL safety (C-1) ──────────────────────────────────────────────
|
|
3
|
+
const SAFE_PROTOCOLS = /^(https?|mailto|tel):/i;
|
|
4
|
+
const SAFE_RELATIVE = /^[/#?]/;
|
|
5
|
+
function isSafeUrl(url) {
|
|
6
|
+
if (typeof url !== "string")
|
|
7
|
+
return false;
|
|
8
|
+
const trimmed = url.trim();
|
|
9
|
+
return SAFE_PROTOCOLS.test(trimmed) || SAFE_RELATIVE.test(trimmed);
|
|
10
|
+
}
|
|
11
|
+
// ── Prototype pollution guard (C-2 + H-8) ─────────────────────────
|
|
12
|
+
const FORBIDDEN_PROPS = new Set([
|
|
13
|
+
"__proto__",
|
|
14
|
+
"constructor",
|
|
15
|
+
"prototype",
|
|
16
|
+
"toString",
|
|
17
|
+
"valueOf",
|
|
18
|
+
"hasOwnProperty",
|
|
19
|
+
]);
|
|
20
|
+
// ── Input validation helpers (H-2) ────────────────────────────────
|
|
21
|
+
function requireString(inputs, field, moduleId) {
|
|
22
|
+
const val = inputs[field];
|
|
23
|
+
if (typeof val !== "string" || val.length === 0) {
|
|
24
|
+
throw new TiptapModuleError(ErrorCodes.SCHEMA_VALIDATION_ERROR, `'${field}' must be a non-empty string`, { moduleId, field });
|
|
25
|
+
}
|
|
26
|
+
return val;
|
|
27
|
+
}
|
|
28
|
+
function requireNumber(inputs, field, moduleId) {
|
|
29
|
+
const val = inputs[field];
|
|
30
|
+
if (typeof val !== "number" || !Number.isFinite(val)) {
|
|
31
|
+
throw new TiptapModuleError(ErrorCodes.SCHEMA_VALIDATION_ERROR, `'${field}' must be a finite number`, { moduleId, field });
|
|
32
|
+
}
|
|
33
|
+
return val;
|
|
34
|
+
}
|
|
35
|
+
// ── Executor ──────────────────────────────────────────────────────
|
|
36
|
+
export class TiptapExecutor {
|
|
37
|
+
registry;
|
|
38
|
+
editor;
|
|
39
|
+
aclGuard;
|
|
40
|
+
sanitizeHtml;
|
|
41
|
+
constructor(editor, registry, aclGuard, sanitizeHtml) {
|
|
42
|
+
this.editor = editor;
|
|
43
|
+
this.registry = registry;
|
|
44
|
+
this.aclGuard = aclGuard;
|
|
45
|
+
this.sanitizeHtml = sanitizeHtml;
|
|
46
|
+
}
|
|
47
|
+
async call(moduleId, inputs) {
|
|
48
|
+
// 1. Check editor ready
|
|
49
|
+
if (this.editor.isDestroyed) {
|
|
50
|
+
throw new TiptapModuleError(ErrorCodes.EDITOR_NOT_READY, "Editor is not ready", { editorDestroyed: true });
|
|
51
|
+
}
|
|
52
|
+
// 2. Resolve descriptor
|
|
53
|
+
const descriptor = this.registry.getDefinition(moduleId);
|
|
54
|
+
if (!descriptor) {
|
|
55
|
+
throw new TiptapModuleError(ErrorCodes.MODULE_NOT_FOUND, `Module '${moduleId}' not found`, { moduleId });
|
|
56
|
+
}
|
|
57
|
+
// 3. ACL check (throws ACL_DENIED)
|
|
58
|
+
this.aclGuard.check(moduleId, descriptor);
|
|
59
|
+
// 4. Route to handler
|
|
60
|
+
const category = this.extractCategory(moduleId);
|
|
61
|
+
if (category === "query") {
|
|
62
|
+
return this.executeQuery(moduleId, inputs);
|
|
63
|
+
}
|
|
64
|
+
return this.executeCommand(moduleId, inputs);
|
|
65
|
+
}
|
|
66
|
+
async callAsync(moduleId, inputs) {
|
|
67
|
+
return this.call(moduleId, inputs);
|
|
68
|
+
}
|
|
69
|
+
extractCategory(moduleId) {
|
|
70
|
+
// "tiptap.format.toggleBold" → "format"
|
|
71
|
+
const parts = moduleId.split(".");
|
|
72
|
+
return parts.length >= 2 ? parts[1] : "unknown";
|
|
73
|
+
}
|
|
74
|
+
extractCommandName(moduleId) {
|
|
75
|
+
// "tiptap.format.toggleBold" → "toggleBold"
|
|
76
|
+
const parts = moduleId.split(".");
|
|
77
|
+
return parts.length >= 3 ? parts[2] : moduleId;
|
|
78
|
+
}
|
|
79
|
+
executeQuery(moduleId, inputs) {
|
|
80
|
+
const commandName = this.extractCommandName(moduleId);
|
|
81
|
+
switch (commandName) {
|
|
82
|
+
case "getHTML":
|
|
83
|
+
return { html: this.editor.getHTML() };
|
|
84
|
+
case "getJSON":
|
|
85
|
+
return { json: this.editor.getJSON() };
|
|
86
|
+
case "getText": {
|
|
87
|
+
const options = {};
|
|
88
|
+
if (typeof inputs.blockSeparator === "string") {
|
|
89
|
+
options.blockSeparator = inputs.blockSeparator;
|
|
90
|
+
}
|
|
91
|
+
return { text: this.editor.getText(options) };
|
|
92
|
+
}
|
|
93
|
+
case "isActive": {
|
|
94
|
+
const name = requireString(inputs, "name", moduleId);
|
|
95
|
+
return { active: this.editor.isActive(name, inputs.attrs ?? {}) };
|
|
96
|
+
}
|
|
97
|
+
case "getAttributes": {
|
|
98
|
+
const typeOrName = requireString(inputs, "typeOrName", moduleId);
|
|
99
|
+
return { attributes: this.editor.getAttributes(typeOrName) };
|
|
100
|
+
}
|
|
101
|
+
case "isEmpty":
|
|
102
|
+
return { value: this.editor.isEmpty };
|
|
103
|
+
case "isEditable":
|
|
104
|
+
return { value: this.editor.isEditable };
|
|
105
|
+
case "isFocused":
|
|
106
|
+
return { value: this.editor.isFocused };
|
|
107
|
+
case "getCharacterCount": {
|
|
108
|
+
const cc = this.editor.storage?.characterCount;
|
|
109
|
+
if (!cc || typeof cc.characters !== "function") {
|
|
110
|
+
throw new TiptapModuleError(ErrorCodes.COMMAND_NOT_FOUND, "Character count extension not available", { moduleId, commandName });
|
|
111
|
+
}
|
|
112
|
+
return { count: cc.characters() };
|
|
113
|
+
}
|
|
114
|
+
case "getWordCount": {
|
|
115
|
+
const cc = this.editor.storage?.characterCount;
|
|
116
|
+
if (!cc || typeof cc.words !== "function") {
|
|
117
|
+
throw new TiptapModuleError(ErrorCodes.COMMAND_NOT_FOUND, "Character count extension not available", { moduleId, commandName });
|
|
118
|
+
}
|
|
119
|
+
return { count: cc.words() };
|
|
120
|
+
}
|
|
121
|
+
default:
|
|
122
|
+
throw new TiptapModuleError(ErrorCodes.COMMAND_NOT_FOUND, `Command '${commandName}' not available on editor`, { moduleId, commandName });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
executeCommand(moduleId, inputs) {
|
|
126
|
+
const commandName = this.extractCommandName(moduleId);
|
|
127
|
+
// Built-in: selectText — find text content and set selection
|
|
128
|
+
if (commandName === "selectText") {
|
|
129
|
+
return this.handleSelectText(inputs, moduleId);
|
|
130
|
+
}
|
|
131
|
+
// C-2 + H-8: Prototype pollution / arbitrary command guard
|
|
132
|
+
if (FORBIDDEN_PROPS.has(commandName)) {
|
|
133
|
+
throw new TiptapModuleError(ErrorCodes.COMMAND_NOT_FOUND, `Command '${commandName}' is not allowed`, { moduleId, commandName });
|
|
134
|
+
}
|
|
135
|
+
// Build chain: editor.chain().focus().<commandName>(...args).run()
|
|
136
|
+
const chain = this.editor.chain().focus();
|
|
137
|
+
const commandFn = chain[commandName];
|
|
138
|
+
if (typeof commandFn !== "function") {
|
|
139
|
+
throw new TiptapModuleError(ErrorCodes.COMMAND_NOT_FOUND, `Command '${commandName}' not available on editor`, { moduleId, commandName });
|
|
140
|
+
}
|
|
141
|
+
// Spread input arguments into the command
|
|
142
|
+
const args = this.buildArgs(commandName, inputs, moduleId);
|
|
143
|
+
const resultChain = commandFn.call(chain, ...args);
|
|
144
|
+
const success = resultChain.run();
|
|
145
|
+
if (!success) {
|
|
146
|
+
// undo/redo return false when history stack is empty — this is a normal
|
|
147
|
+
// condition (editor is recreated per request), not an execution error.
|
|
148
|
+
if (commandName === "undo" || commandName === "redo") {
|
|
149
|
+
return { success: false, reason: `Nothing to ${commandName}` };
|
|
150
|
+
}
|
|
151
|
+
throw new TiptapModuleError(ErrorCodes.COMMAND_FAILED, `Command '${commandName}' failed`, { moduleId, commandName });
|
|
152
|
+
}
|
|
153
|
+
return { success: true };
|
|
154
|
+
}
|
|
155
|
+
handleSelectText(inputs, moduleId) {
|
|
156
|
+
const text = requireString(inputs, "text", moduleId);
|
|
157
|
+
const occurrence = typeof inputs.occurrence === "number" ? Math.max(1, inputs.occurrence) : 1;
|
|
158
|
+
const doc = this.editor.state.doc;
|
|
159
|
+
let count = 0;
|
|
160
|
+
let foundFrom = -1;
|
|
161
|
+
let foundTo = -1;
|
|
162
|
+
doc.descendants((node, pos) => {
|
|
163
|
+
if (foundFrom >= 0)
|
|
164
|
+
return false;
|
|
165
|
+
if (node.isText && node.text) {
|
|
166
|
+
let searchFrom = 0;
|
|
167
|
+
while (searchFrom < node.text.length) {
|
|
168
|
+
const idx = node.text.indexOf(text, searchFrom);
|
|
169
|
+
if (idx === -1)
|
|
170
|
+
break;
|
|
171
|
+
count++;
|
|
172
|
+
if (count === occurrence) {
|
|
173
|
+
foundFrom = pos + idx;
|
|
174
|
+
foundTo = foundFrom + text.length;
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
searchFrom = idx + 1;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
if (foundFrom < 0) {
|
|
182
|
+
return { found: false };
|
|
183
|
+
}
|
|
184
|
+
// Set text selection around the found text
|
|
185
|
+
const chain = this.editor.chain().focus();
|
|
186
|
+
chain.setTextSelection({ from: foundFrom, to: foundTo }).run();
|
|
187
|
+
return { found: true, from: foundFrom, to: foundTo };
|
|
188
|
+
}
|
|
189
|
+
buildArgs(commandName, inputs, moduleId) {
|
|
190
|
+
// Map input object fields to positional command arguments based on command name
|
|
191
|
+
// Most commands take 0 or 1 args
|
|
192
|
+
switch (commandName) {
|
|
193
|
+
// Commands with no args
|
|
194
|
+
case "toggleBold":
|
|
195
|
+
case "toggleItalic":
|
|
196
|
+
case "toggleStrike":
|
|
197
|
+
case "toggleCode":
|
|
198
|
+
case "toggleUnderline":
|
|
199
|
+
case "toggleSubscript":
|
|
200
|
+
case "toggleSuperscript":
|
|
201
|
+
case "toggleBulletList":
|
|
202
|
+
case "toggleOrderedList":
|
|
203
|
+
case "toggleTaskList":
|
|
204
|
+
case "toggleBlockquote":
|
|
205
|
+
case "unsetAllMarks":
|
|
206
|
+
case "clearNodes":
|
|
207
|
+
case "setHardBreak":
|
|
208
|
+
case "setHorizontalRule":
|
|
209
|
+
case "unsetLink":
|
|
210
|
+
case "selectAll":
|
|
211
|
+
case "selectParentNode":
|
|
212
|
+
case "selectTextblockStart":
|
|
213
|
+
case "selectTextblockEnd":
|
|
214
|
+
case "blur":
|
|
215
|
+
case "scrollIntoView":
|
|
216
|
+
case "undo":
|
|
217
|
+
case "redo":
|
|
218
|
+
case "deleteSelection":
|
|
219
|
+
case "deleteCurrentNode":
|
|
220
|
+
case "cut":
|
|
221
|
+
case "joinBackward":
|
|
222
|
+
case "joinForward":
|
|
223
|
+
case "setBold":
|
|
224
|
+
case "unsetBold":
|
|
225
|
+
case "setItalic":
|
|
226
|
+
case "unsetItalic":
|
|
227
|
+
case "setStrike":
|
|
228
|
+
case "unsetStrike":
|
|
229
|
+
case "setCode":
|
|
230
|
+
case "unsetCode":
|
|
231
|
+
case "setBlockquote":
|
|
232
|
+
case "unsetBlockquote":
|
|
233
|
+
case "setParagraph":
|
|
234
|
+
case "exitCode":
|
|
235
|
+
return [];
|
|
236
|
+
case "splitBlock":
|
|
237
|
+
return inputs.keepMarks !== undefined ? [{ keepMarks: inputs.keepMarks }] : [];
|
|
238
|
+
// Commands with single object arg
|
|
239
|
+
case "toggleHeading":
|
|
240
|
+
return [{ level: inputs.level }];
|
|
241
|
+
case "setHeading":
|
|
242
|
+
return [{ level: inputs.level }];
|
|
243
|
+
case "toggleHighlight":
|
|
244
|
+
return inputs.color ? [{ color: inputs.color }] : [];
|
|
245
|
+
case "toggleCodeBlock":
|
|
246
|
+
return inputs.language ? [{ language: inputs.language }] : [];
|
|
247
|
+
case "setTextAlign":
|
|
248
|
+
return [inputs.alignment];
|
|
249
|
+
case "setMark":
|
|
250
|
+
return [inputs.typeOrName, inputs.attrs ?? {}];
|
|
251
|
+
case "unsetMark":
|
|
252
|
+
return [inputs.typeOrName];
|
|
253
|
+
case "updateAttributes":
|
|
254
|
+
return [inputs.typeOrName, inputs.attrs];
|
|
255
|
+
case "setLink": {
|
|
256
|
+
// C-1: URL protocol validation
|
|
257
|
+
if (!isSafeUrl(inputs.href)) {
|
|
258
|
+
throw new TiptapModuleError(ErrorCodes.SCHEMA_VALIDATION_ERROR, "Invalid or unsafe URL protocol", { field: "href" });
|
|
259
|
+
}
|
|
260
|
+
const linkAttrs = { href: inputs.href };
|
|
261
|
+
if (inputs.target !== undefined)
|
|
262
|
+
linkAttrs.target = inputs.target;
|
|
263
|
+
if (inputs.rel !== undefined)
|
|
264
|
+
linkAttrs.rel = inputs.rel;
|
|
265
|
+
return [linkAttrs];
|
|
266
|
+
}
|
|
267
|
+
// Content commands — H-1: sanitize HTML
|
|
268
|
+
case "insertContent": {
|
|
269
|
+
let value = inputs.value;
|
|
270
|
+
if (typeof value === "string" && this.sanitizeHtml) {
|
|
271
|
+
value = this.sanitizeHtml(value);
|
|
272
|
+
}
|
|
273
|
+
return [value, inputs.options ?? {}];
|
|
274
|
+
}
|
|
275
|
+
case "insertContentAt": {
|
|
276
|
+
const position = requireNumber(inputs, "position", moduleId);
|
|
277
|
+
let value = inputs.value;
|
|
278
|
+
if (typeof value === "string" && this.sanitizeHtml) {
|
|
279
|
+
value = this.sanitizeHtml(value);
|
|
280
|
+
}
|
|
281
|
+
return [position, value, inputs.options ?? {}];
|
|
282
|
+
}
|
|
283
|
+
case "setNode":
|
|
284
|
+
return [inputs.typeOrName, inputs.attrs ?? {}];
|
|
285
|
+
case "liftListItem":
|
|
286
|
+
case "sinkListItem":
|
|
287
|
+
return [inputs.typeOrName];
|
|
288
|
+
case "wrapIn":
|
|
289
|
+
return [inputs.typeOrName, inputs.attrs ?? {}];
|
|
290
|
+
case "lift":
|
|
291
|
+
return [inputs.typeOrName, inputs.attrs ?? {}];
|
|
292
|
+
case "splitListItem":
|
|
293
|
+
return [inputs.typeOrName, inputs.overrideAttrs ?? {}];
|
|
294
|
+
case "wrapInList":
|
|
295
|
+
return [inputs.typeOrName, inputs.attributes ?? {}];
|
|
296
|
+
case "toggleList":
|
|
297
|
+
return [inputs.listTypeOrName, inputs.itemTypeOrName, inputs.keepMarks ?? false, inputs.attributes ?? {}];
|
|
298
|
+
case "deleteNode":
|
|
299
|
+
return [inputs.typeOrName];
|
|
300
|
+
// Destructive commands
|
|
301
|
+
case "clearContent":
|
|
302
|
+
return inputs.emitUpdate !== undefined ? [inputs.emitUpdate] : [];
|
|
303
|
+
case "setContent": {
|
|
304
|
+
let value = inputs.value;
|
|
305
|
+
if (typeof value === "string" && this.sanitizeHtml) {
|
|
306
|
+
value = this.sanitizeHtml(value);
|
|
307
|
+
}
|
|
308
|
+
return [value, inputs.emitUpdate ?? true, inputs.parseOptions ?? {}];
|
|
309
|
+
}
|
|
310
|
+
case "deleteRange":
|
|
311
|
+
return [{ from: inputs.from, to: inputs.to }];
|
|
312
|
+
// Selection commands
|
|
313
|
+
case "setTextSelection":
|
|
314
|
+
return [inputs.position];
|
|
315
|
+
case "setNodeSelection": {
|
|
316
|
+
const position = requireNumber(inputs, "position", moduleId);
|
|
317
|
+
return [position];
|
|
318
|
+
}
|
|
319
|
+
case "focus":
|
|
320
|
+
return inputs.position !== undefined ? [inputs.position] : [];
|
|
321
|
+
default:
|
|
322
|
+
// Unknown commands: pass all inputs as single object arg
|
|
323
|
+
return Object.keys(inputs).length > 0 ? [inputs] : [];
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=TiptapExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TiptapExecutor.js","sourceRoot":"","sources":["../../src/runtime/TiptapExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Registry, ModuleDescriptor } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* TiptapRegistry implements the APCore Registry interface.
|
|
4
|
+
*
|
|
5
|
+
* Manages module descriptors with event-driven registration/unregistration
|
|
6
|
+
* and supports filtering by tags (OR logic) and/or prefix (startsWith).
|
|
7
|
+
*/
|
|
8
|
+
export declare class TiptapRegistry implements Registry {
|
|
9
|
+
private modules;
|
|
10
|
+
private handlers;
|
|
11
|
+
private scanFn;
|
|
12
|
+
register(descriptor: ModuleDescriptor): void;
|
|
13
|
+
unregister(moduleId: string): void;
|
|
14
|
+
list(options?: {
|
|
15
|
+
tags?: string[] | null;
|
|
16
|
+
prefix?: string | null;
|
|
17
|
+
}): string[];
|
|
18
|
+
getDefinition(moduleId: string): ModuleDescriptor | null;
|
|
19
|
+
has(moduleId: string): boolean;
|
|
20
|
+
/** Returns an iterator over [moduleId, descriptor] pairs. */
|
|
21
|
+
iter(): IterableIterator<[string, ModuleDescriptor]>;
|
|
22
|
+
/** Number of registered modules. */
|
|
23
|
+
get count(): number;
|
|
24
|
+
/** Array of all registered module IDs. */
|
|
25
|
+
get moduleIds(): string[];
|
|
26
|
+
/** Clears any internal caches (no-op for now, reserved for future use). */
|
|
27
|
+
clearCache(): void;
|
|
28
|
+
on(event: string, callback: (...args: unknown[]) => void): () => void;
|
|
29
|
+
off(event: string, callback: (...args: unknown[]) => void): void;
|
|
30
|
+
removeAllListeners(event?: string): void;
|
|
31
|
+
discover(): Promise<number>;
|
|
32
|
+
setScanFunction(fn: () => number | Promise<number>): void;
|
|
33
|
+
private emit;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=TiptapRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TiptapRegistry.d.ts","sourceRoot":"","sources":["../../src/runtime/TiptapRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,QAAQ,CACJ;IACZ,OAAO,CAAC,MAAM,CAAiD;IAE/D,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAK5C,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKlC,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,MAAM,EAAE;IAyB5E,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAIxD,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI9B,6DAA6D;IAC7D,IAAI,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAIpD,oCAAoC;IACpC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,0CAA0C;IAC1C,IAAI,SAAS,IAAI,MAAM,EAAE,CAExB;IAED,2EAA2E;IAC3E,UAAU,IAAI,IAAI;IAKlB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAQrE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI;IAOhE,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAQlC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAOjC,eAAe,CAAC,EAAE,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAIzD,OAAO,CAAC,IAAI;CAMb"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TiptapRegistry implements the APCore Registry interface.
|
|
3
|
+
*
|
|
4
|
+
* Manages module descriptors with event-driven registration/unregistration
|
|
5
|
+
* and supports filtering by tags (OR logic) and/or prefix (startsWith).
|
|
6
|
+
*/
|
|
7
|
+
export class TiptapRegistry {
|
|
8
|
+
modules = new Map();
|
|
9
|
+
handlers = new Map();
|
|
10
|
+
scanFn = null;
|
|
11
|
+
register(descriptor) {
|
|
12
|
+
this.modules.set(descriptor.moduleId, descriptor);
|
|
13
|
+
this.emit("register", descriptor.moduleId, descriptor);
|
|
14
|
+
}
|
|
15
|
+
unregister(moduleId) {
|
|
16
|
+
this.modules.delete(moduleId);
|
|
17
|
+
this.emit("unregister", moduleId);
|
|
18
|
+
}
|
|
19
|
+
list(options) {
|
|
20
|
+
let ids = Array.from(this.modules.keys());
|
|
21
|
+
if (!options) {
|
|
22
|
+
return ids;
|
|
23
|
+
}
|
|
24
|
+
const { tags, prefix } = options;
|
|
25
|
+
if (tags && tags.length > 0) {
|
|
26
|
+
ids = ids.filter((id) => {
|
|
27
|
+
const descriptor = this.modules.get(id);
|
|
28
|
+
const moduleTags = descriptor.tags ?? [];
|
|
29
|
+
// OR logic: module matches if it has ANY of the requested tags
|
|
30
|
+
return tags.some((tag) => moduleTags.includes(tag));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (prefix) {
|
|
34
|
+
ids = ids.filter((id) => id.startsWith(prefix));
|
|
35
|
+
}
|
|
36
|
+
return ids;
|
|
37
|
+
}
|
|
38
|
+
getDefinition(moduleId) {
|
|
39
|
+
return this.modules.get(moduleId) ?? null;
|
|
40
|
+
}
|
|
41
|
+
has(moduleId) {
|
|
42
|
+
return this.modules.has(moduleId);
|
|
43
|
+
}
|
|
44
|
+
/** Returns an iterator over [moduleId, descriptor] pairs. */
|
|
45
|
+
iter() {
|
|
46
|
+
return this.modules.entries();
|
|
47
|
+
}
|
|
48
|
+
/** Number of registered modules. */
|
|
49
|
+
get count() {
|
|
50
|
+
return this.modules.size;
|
|
51
|
+
}
|
|
52
|
+
/** Array of all registered module IDs. */
|
|
53
|
+
get moduleIds() {
|
|
54
|
+
return Array.from(this.modules.keys());
|
|
55
|
+
}
|
|
56
|
+
/** Clears any internal caches (no-op for now, reserved for future use). */
|
|
57
|
+
clearCache() {
|
|
58
|
+
// TiptapRegistry has no caches currently; method provided for API parity
|
|
59
|
+
// with apcore-js Registry.
|
|
60
|
+
}
|
|
61
|
+
on(event, callback) {
|
|
62
|
+
if (!this.handlers.has(event)) {
|
|
63
|
+
this.handlers.set(event, []);
|
|
64
|
+
}
|
|
65
|
+
this.handlers.get(event).push(callback);
|
|
66
|
+
return () => this.off(event, callback);
|
|
67
|
+
}
|
|
68
|
+
off(event, callback) {
|
|
69
|
+
const callbacks = this.handlers.get(event);
|
|
70
|
+
if (!callbacks)
|
|
71
|
+
return;
|
|
72
|
+
const idx = callbacks.indexOf(callback);
|
|
73
|
+
if (idx !== -1)
|
|
74
|
+
callbacks.splice(idx, 1);
|
|
75
|
+
}
|
|
76
|
+
removeAllListeners(event) {
|
|
77
|
+
if (event) {
|
|
78
|
+
this.handlers.delete(event);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.handlers.clear();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async discover() {
|
|
85
|
+
if (this.scanFn) {
|
|
86
|
+
return this.scanFn();
|
|
87
|
+
}
|
|
88
|
+
return this.modules.size;
|
|
89
|
+
}
|
|
90
|
+
setScanFunction(fn) {
|
|
91
|
+
this.scanFn = fn;
|
|
92
|
+
}
|
|
93
|
+
emit(event, ...args) {
|
|
94
|
+
const callbacks = this.handlers.get(event);
|
|
95
|
+
if (callbacks) {
|
|
96
|
+
callbacks.forEach((cb) => cb(...args));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=TiptapRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TiptapRegistry.js","sourceRoot":"","sources":["../../src/runtime/TiptapRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AclConfig, Logger, ModuleDescriptor } from "../types.js";
|
|
2
|
+
export declare class AclGuard {
|
|
3
|
+
private config;
|
|
4
|
+
private logger;
|
|
5
|
+
constructor(config?: AclConfig, logger?: Logger);
|
|
6
|
+
check(moduleId: string, descriptor: ModuleDescriptor): void;
|
|
7
|
+
isAllowed(moduleId: string, descriptor: ModuleDescriptor): boolean;
|
|
8
|
+
private getDenialReason;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=AclGuard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AclGuard.d.ts","sourceRoot":"","sources":["../../src/security/AclGuard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASvE,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM;IAK/C,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAY3D,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,OAAO;IAwClE,OAAO,CAAC,eAAe;CAgDxB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { TiptapModuleError, ErrorCodes } from "../errors/index.js";
|
|
2
|
+
const ROLE_TAGS = {
|
|
3
|
+
readonly: ["query"],
|
|
4
|
+
editor: ["query", "format", "content", "history", "selection"],
|
|
5
|
+
admin: ["query", "format", "content", "destructive", "history", "selection"],
|
|
6
|
+
};
|
|
7
|
+
export class AclGuard {
|
|
8
|
+
config;
|
|
9
|
+
logger;
|
|
10
|
+
constructor(config, logger) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
}
|
|
14
|
+
check(moduleId, descriptor) {
|
|
15
|
+
if (!this.isAllowed(moduleId, descriptor)) {
|
|
16
|
+
const reason = this.getDenialReason(moduleId, descriptor);
|
|
17
|
+
this.logger?.warn(`ACL denied: ${moduleId}`, { reason });
|
|
18
|
+
throw new TiptapModuleError(ErrorCodes.ACL_DENIED, `Access denied: module '${moduleId}' is not permitted`, { moduleId });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
isAllowed(moduleId, descriptor) {
|
|
22
|
+
// No ACL config = all allowed (opt-in security)
|
|
23
|
+
if (!this.config)
|
|
24
|
+
return true;
|
|
25
|
+
const { denyModules, allowModules, denyTags, allowTags, role } = this.config;
|
|
26
|
+
const moduleTags = descriptor.tags ?? [];
|
|
27
|
+
// 1. denyModules (highest precedence)
|
|
28
|
+
if (denyModules?.includes(moduleId))
|
|
29
|
+
return false;
|
|
30
|
+
// 2. allowModules
|
|
31
|
+
if (allowModules && allowModules.length > 0) {
|
|
32
|
+
if (allowModules.includes(moduleId))
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
// 3. denyTags
|
|
36
|
+
if (denyTags && denyTags.length > 0) {
|
|
37
|
+
if (moduleTags.some((t) => denyTags.includes(t)))
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
// 4. allowTags
|
|
41
|
+
if (allowTags && allowTags.length > 0) {
|
|
42
|
+
if (moduleTags.some((t) => allowTags.includes(t)))
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
// 5. Role-based
|
|
46
|
+
if (role) {
|
|
47
|
+
const roleTags = ROLE_TAGS[role];
|
|
48
|
+
if (!roleTags)
|
|
49
|
+
return false;
|
|
50
|
+
return moduleTags.some((t) => roleTags.includes(t));
|
|
51
|
+
}
|
|
52
|
+
// 6. If any allow-list is present, default to deny; otherwise permissive
|
|
53
|
+
const hasAllowList = (allowModules && allowModules.length > 0) ||
|
|
54
|
+
(allowTags && allowTags.length > 0);
|
|
55
|
+
return !hasAllowList;
|
|
56
|
+
}
|
|
57
|
+
getDenialReason(moduleId, descriptor) {
|
|
58
|
+
if (!this.config)
|
|
59
|
+
return "No ACL config";
|
|
60
|
+
const { denyModules, denyTags, allowTags, allowModules, role } = this.config;
|
|
61
|
+
const moduleTags = descriptor.tags ?? [];
|
|
62
|
+
// 1. denyModules
|
|
63
|
+
if (denyModules?.includes(moduleId)) {
|
|
64
|
+
return `Module '${moduleId}' is in the denyModules list`;
|
|
65
|
+
}
|
|
66
|
+
// 2. allowModules set but module not in it
|
|
67
|
+
if (allowModules && allowModules.length > 0) {
|
|
68
|
+
if (!allowModules.includes(moduleId)) {
|
|
69
|
+
return `Module '${moduleId}' is not in the allowModules list`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// 3. denyTags
|
|
73
|
+
if (denyTags && denyTags.length > 0) {
|
|
74
|
+
const denied = moduleTags.filter((t) => denyTags.includes(t));
|
|
75
|
+
if (denied.length > 0) {
|
|
76
|
+
return `Module tags [${denied.join(", ")}] are in the denyTags list`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 4. allowTags set but no overlap
|
|
80
|
+
if (allowTags && allowTags.length > 0) {
|
|
81
|
+
if (!moduleTags.some((t) => allowTags.includes(t))) {
|
|
82
|
+
return `Module tags [${moduleTags.join(", ")}] are not in the allowTags list`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// 5. Role-based denial
|
|
86
|
+
if (role) {
|
|
87
|
+
const roleTags = ROLE_TAGS[role];
|
|
88
|
+
if (!roleTags) {
|
|
89
|
+
return `Unknown role '${role}'`;
|
|
90
|
+
}
|
|
91
|
+
return `Role '${role}' does not permit tags [${moduleTags.join(", ")}]`;
|
|
92
|
+
}
|
|
93
|
+
return "Access denied by policy";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=AclGuard.js.map
|