@yadsh/dsh-qa-surface 0.6.1 → 0.7.1
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 +163 -7
- package/capability-policy.json +1 -1
- package/lib/access/capability-catalog.js +144 -0
- package/lib/access/capability-catalog.js.map +1 -0
- package/lib/access/model.js +379 -0
- package/lib/access/model.js.map +1 -0
- package/lib/access/role-repository.js +195 -0
- package/lib/access/role-repository.js.map +1 -0
- package/lib/access/service.js +380 -0
- package/lib/access/service.js.map +1 -0
- package/lib/access/skill-metadata.js +234 -0
- package/lib/access/skill-metadata.js.map +1 -0
- package/lib/account-remotes.js +20 -10
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/file.js.map +1 -1
- package/lib/accounts/store.js +202 -3
- package/lib/accounts/store.js.map +1 -1
- package/lib/admin/conversation-log.js +256 -0
- package/lib/admin/conversation-log.js.map +1 -0
- package/lib/admin/index.js +17 -0
- package/lib/admin/index.js.map +1 -0
- package/lib/admin/metrics.js +103 -0
- package/lib/admin/metrics.js.map +1 -0
- package/lib/admin/paging.js +23 -0
- package/lib/admin/paging.js.map +1 -0
- package/lib/admin/permissions.js +50 -0
- package/lib/admin/permissions.js.map +1 -0
- package/lib/admin/quality-store.js +485 -0
- package/lib/admin/quality-store.js.map +1 -0
- package/lib/admin/queue.js +107 -0
- package/lib/admin/queue.js.map +1 -0
- package/lib/admin/redaction.js +45 -0
- package/lib/admin/redaction.js.map +1 -0
- package/lib/admin/service.js +897 -0
- package/lib/admin/service.js.map +1 -0
- package/lib/admin/session-log.js +142 -0
- package/lib/admin/session-log.js.map +1 -0
- package/lib/cli.js +9 -6
- package/lib/cli.js.map +1 -1
- package/lib/client/QaSessionController.js +28 -2
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +143 -5
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaTranscriptAdapter.js +1 -0
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/admin/QaAdmin.js +458 -0
- package/lib/client/admin/QaAdmin.js.map +1 -0
- package/lib/client/admin/format.js +177 -0
- package/lib/client/admin/format.js.map +1 -0
- package/lib/client/admin/pages/Conversations.js +114 -0
- package/lib/client/admin/pages/Conversations.js.map +1 -0
- package/lib/client/admin/pages/Overview.js +24 -0
- package/lib/client/admin/pages/Overview.js.map +1 -0
- package/lib/client/admin/pages/Quality.js +71 -0
- package/lib/client/admin/pages/Quality.js.map +1 -0
- package/lib/client/admin/pages/Review.js +93 -0
- package/lib/client/admin/pages/Review.js.map +1 -0
- package/lib/client/admin/pages/Users.js +95 -0
- package/lib/client/admin/pages/Users.js.map +1 -0
- package/lib/client/admin/routes.js +143 -0
- package/lib/client/admin/routes.js.map +1 -0
- package/lib/client/admin/shared.js +91 -0
- package/lib/client/admin/shared.js.map +1 -0
- package/lib/client/admin/styles.js +111 -0
- package/lib/client/admin/styles.js.map +1 -0
- package/lib/client/components/QaChangelog.js +53 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaHeader.js +3 -3
- package/lib/client/components/QaHeader.js.map +1 -1
- package/lib/client/components/QaMessage.js +61 -2
- package/lib/client/components/QaMessage.js.map +1 -1
- package/lib/client/create-session.js +1 -1
- package/lib/client/create-session.js.map +1 -1
- package/lib/client/index.js +48 -1
- package/lib/client/index.js.map +1 -1
- package/lib/client/role/RoleSelector.js +31 -0
- package/lib/client/role/RoleSelector.js.map +1 -0
- package/lib/client/session-sources.js +37 -1
- package/lib/client/session-sources.js.map +1 -1
- package/lib/client/settings/card.js +2 -2
- package/lib/client/settings/card.js.map +1 -1
- package/lib/client/settings/sections.js +0 -1
- package/lib/client/settings/sections.js.map +1 -1
- package/lib/client/settings-extensions/index.js +1 -0
- package/lib/client/settings-extensions/index.js.map +1 -1
- package/lib/client/settings-extensions/user-session.js +62 -0
- package/lib/client/settings-extensions/user-session.js.map +1 -0
- package/lib/client/styles.js +31 -0
- package/lib/client/styles.js.map +1 -1
- package/lib/client/types.js.map +1 -1
- package/lib/client.js +9993 -4848
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/defaults.js +0 -2
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config.js +0 -249
- package/lib/config.js.map +1 -1
- package/lib/enforcement/skill-policy.js +172 -0
- package/lib/enforcement/skill-policy.js.map +1 -0
- package/lib/enforcement/tool-grants.js +151 -0
- package/lib/enforcement/tool-grants.js.map +1 -0
- package/lib/index.js +224 -42
- package/lib/index.js.map +1 -1
- package/lib/personal-skills/service.js +10 -3
- package/lib/personal-skills/service.js.map +1 -1
- package/lib/qa-tools/index.js +4 -0
- package/lib/qa-tools/index.js.map +1 -1
- package/lib/resolve-config.js +0 -2
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +71 -17
- package/lib/secure-session.js.map +1 -1
- package/lib/typert.host.js +2237 -202
- package/lib/typert.remote-client.d.ts +49 -3
- package/lib/typert.remote-client.js +1863 -183
- package/lib/types/access/capability-catalog.d.ts +37 -0
- package/lib/types/access/model.d.ts +60 -0
- package/lib/types/access/role-repository.d.ts +32 -0
- package/lib/types/access/service.d.ts +57 -0
- package/lib/types/access/skill-metadata.d.ts +53 -0
- package/lib/types/account-remotes.d.ts +6 -0
- package/lib/types/accounts/errors.d.ts +1 -1
- package/lib/types/accounts/file.d.ts +16 -5
- package/lib/types/accounts/store.d.ts +83 -3
- package/lib/types/admin/conversation-log.d.ts +39 -0
- package/lib/types/admin/index.d.ts +24 -0
- package/lib/types/admin/metrics.d.ts +29 -0
- package/lib/types/admin/paging.d.ts +33 -0
- package/lib/types/admin/permissions.d.ts +10 -0
- package/lib/types/admin/quality-store.d.ts +82 -0
- package/lib/types/admin/queue.d.ts +21 -0
- package/lib/types/admin/redaction.d.ts +29 -0
- package/lib/types/admin/service.d.ts +105 -0
- package/lib/types/admin/session-log.d.ts +53 -0
- package/lib/types/client/QaSessionController.d.ts +12 -1
- package/lib/types/client/QaSurface.d.ts +7 -1
- package/lib/types/client/admin/QaAdmin.d.ts +17 -0
- package/lib/types/client/admin/format.d.ts +43 -0
- package/lib/types/client/admin/pages/Conversations.d.ts +21 -0
- package/lib/types/client/admin/pages/Overview.d.ts +13 -0
- package/lib/types/client/admin/pages/Quality.d.ts +18 -0
- package/lib/types/client/admin/pages/Review.d.ts +15 -0
- package/lib/types/client/admin/pages/Users.d.ts +22 -0
- package/lib/types/client/admin/routes.d.ts +60 -0
- package/lib/types/client/admin/shared.d.ts +53 -0
- package/lib/types/client/admin/styles.d.ts +11 -0
- package/lib/types/client/components/QaHeader.d.ts +5 -1
- package/lib/types/client/components/QaMessage.d.ts +14 -1
- package/lib/types/client/create-session.d.ts +2 -0
- package/lib/types/client/role/RoleSelector.d.ts +14 -0
- package/lib/types/client/session-sources.d.ts +9 -0
- package/lib/types/client/settings/sections.d.ts +0 -1
- package/lib/types/client/settings-extensions/index.d.ts +2 -0
- package/lib/types/client/settings-extensions/user-session.d.ts +59 -0
- package/lib/types/client/types.d.ts +39 -2
- package/lib/types/enforcement/skill-policy.d.ts +29 -0
- package/lib/types/enforcement/tool-grants.d.ts +84 -0
- package/lib/types/index.d.ts +62 -14
- package/lib/types/qa-tools/index.d.ts +2 -0
- package/lib/types/secure-session.d.ts +10 -1
- package/lib/types/types.d.ts +568 -5
- package/package.json +2 -2
- package/lib/client/settings/sections/documents.js +0 -88
- package/lib/client/settings/sections/documents.js.map +0 -1
- package/lib/documents/artifacts/ids.js +0 -43
- package/lib/documents/artifacts/ids.js.map +0 -1
- package/lib/documents/artifacts/manifest.js +0 -66
- package/lib/documents/artifacts/manifest.js.map +0 -1
- package/lib/documents/artifacts/store.js +0 -169
- package/lib/documents/artifacts/store.js.map +0 -1
- package/lib/documents/capabilities.js +0 -93
- package/lib/documents/capabilities.js.map +0 -1
- package/lib/documents/config.js +0 -302
- package/lib/documents/config.js.map +0 -1
- package/lib/documents/defaults.js +0 -78
- package/lib/documents/defaults.js.map +0 -1
- package/lib/documents/errors.js +0 -101
- package/lib/documents/errors.js.map +0 -1
- package/lib/documents/index.js +0 -80
- package/lib/documents/index.js.map +0 -1
- package/lib/documents/inspect/facts.js +0 -161
- package/lib/documents/inspect/facts.js.map +0 -1
- package/lib/documents/inspect/zip.js +0 -108
- package/lib/documents/inspect/zip.js.map +0 -1
- package/lib/documents/markdown/directives.js +0 -135
- package/lib/documents/markdown/directives.js.map +0 -1
- package/lib/documents/markdown/frontmatter.js +0 -35
- package/lib/documents/markdown/frontmatter.js.map +0 -1
- package/lib/documents/markdown/normalize.js +0 -113
- package/lib/documents/markdown/normalize.js.map +0 -1
- package/lib/documents/orchestrator/assets.js +0 -243
- package/lib/documents/orchestrator/assets.js.map +0 -1
- package/lib/documents/orchestrator/convert-document.js +0 -186
- package/lib/documents/orchestrator/convert-document.js.map +0 -1
- package/lib/documents/orchestrator/create-document.js +0 -292
- package/lib/documents/orchestrator/create-document.js.map +0 -1
- package/lib/documents/orchestrator/extract-document.js +0 -162
- package/lib/documents/orchestrator/extract-document.js.map +0 -1
- package/lib/documents/orchestrator/inspect-document.js +0 -89
- package/lib/documents/orchestrator/inspect-document.js.map +0 -1
- package/lib/documents/orchestrator/runtime-deps.js +0 -59
- package/lib/documents/orchestrator/runtime-deps.js.map +0 -1
- package/lib/documents/orchestrator/scope.js +0 -132
- package/lib/documents/orchestrator/scope.js.map +0 -1
- package/lib/documents/providers/docling.js +0 -247
- package/lib/documents/providers/docling.js.map +0 -1
- package/lib/documents/providers/libreoffice.js +0 -130
- package/lib/documents/providers/libreoffice.js.map +0 -1
- package/lib/documents/providers/markitdown.js +0 -89
- package/lib/documents/providers/markitdown.js.map +0 -1
- package/lib/documents/providers/pandoc.js +0 -161
- package/lib/documents/providers/pandoc.js.map +0 -1
- package/lib/documents/providers/process.js +0 -164
- package/lib/documents/providers/process.js.map +0 -1
- package/lib/documents/providers/registry.js +0 -152
- package/lib/documents/providers/registry.js.map +0 -1
- package/lib/documents/providers/shared.js +0 -75
- package/lib/documents/providers/shared.js.map +0 -1
- package/lib/documents/runtime.js +0 -114
- package/lib/documents/runtime.js.map +0 -1
- package/lib/documents/security/file-types.js +0 -188
- package/lib/documents/security/file-types.js.map +0 -1
- package/lib/documents/security/limits.js +0 -78
- package/lib/documents/security/limits.js.map +0 -1
- package/lib/documents/security/mime.js +0 -43
- package/lib/documents/security/mime.js.map +0 -1
- package/lib/documents/security/paths.js +0 -133
- package/lib/documents/security/paths.js.map +0 -1
- package/lib/documents/templates/registry.js +0 -147
- package/lib/documents/templates/registry.js.map +0 -1
- package/lib/documents/templates/resolver.js +0 -59
- package/lib/documents/templates/resolver.js.map +0 -1
- package/lib/documents/tools/convert.js +0 -125
- package/lib/documents/tools/convert.js.map +0 -1
- package/lib/documents/tools/create.js +0 -187
- package/lib/documents/tools/create.js.map +0 -1
- package/lib/documents/tools/index.js +0 -41
- package/lib/documents/tools/index.js.map +0 -1
- package/lib/documents/tools/inspect.js +0 -135
- package/lib/documents/tools/inspect.js.map +0 -1
- package/lib/documents/tools/shared.js +0 -88
- package/lib/documents/tools/shared.js.map +0 -1
- package/lib/documents/tools/to-markdown.js +0 -125
- package/lib/documents/tools/to-markdown.js.map +0 -1
- package/lib/documents/types.js +0 -12
- package/lib/documents/types.js.map +0 -1
- package/lib/types/client/settings/sections/documents.d.ts +0 -13
- package/lib/types/documents/artifacts/ids.d.ts +0 -14
- package/lib/types/documents/artifacts/manifest.d.ts +0 -32
- package/lib/types/documents/artifacts/store.d.ts +0 -67
- package/lib/types/documents/capabilities.d.ts +0 -32
- package/lib/types/documents/config.d.ts +0 -27
- package/lib/types/documents/defaults.d.ts +0 -161
- package/lib/types/documents/errors.d.ts +0 -42
- package/lib/types/documents/index.d.ts +0 -63
- package/lib/types/documents/inspect/facts.d.ts +0 -43
- package/lib/types/documents/inspect/zip.d.ts +0 -28
- package/lib/types/documents/markdown/directives.d.ts +0 -39
- package/lib/types/documents/markdown/frontmatter.d.ts +0 -15
- package/lib/types/documents/markdown/normalize.d.ts +0 -30
- package/lib/types/documents/orchestrator/assets.d.ts +0 -55
- package/lib/types/documents/orchestrator/convert-document.d.ts +0 -25
- package/lib/types/documents/orchestrator/create-document.d.ts +0 -18
- package/lib/types/documents/orchestrator/extract-document.d.ts +0 -24
- package/lib/types/documents/orchestrator/inspect-document.d.ts +0 -12
- package/lib/types/documents/orchestrator/runtime-deps.d.ts +0 -43
- package/lib/types/documents/orchestrator/scope.d.ts +0 -52
- package/lib/types/documents/providers/docling.d.ts +0 -54
- package/lib/types/documents/providers/libreoffice.d.ts +0 -40
- package/lib/types/documents/providers/markitdown.d.ts +0 -28
- package/lib/types/documents/providers/pandoc.d.ts +0 -42
- package/lib/types/documents/providers/process.d.ts +0 -54
- package/lib/types/documents/providers/registry.d.ts +0 -68
- package/lib/types/documents/providers/shared.d.ts +0 -27
- package/lib/types/documents/runtime.d.ts +0 -59
- package/lib/types/documents/security/file-types.d.ts +0 -39
- package/lib/types/documents/security/limits.d.ts +0 -24
- package/lib/types/documents/security/mime.d.ts +0 -13
- package/lib/types/documents/security/paths.d.ts +0 -38
- package/lib/types/documents/templates/registry.d.ts +0 -50
- package/lib/types/documents/templates/resolver.d.ts +0 -30
- package/lib/types/documents/tools/convert.d.ts +0 -9
- package/lib/types/documents/tools/create.d.ts +0 -14
- package/lib/types/documents/tools/index.d.ts +0 -33
- package/lib/types/documents/tools/inspect.d.ts +0 -9
- package/lib/types/documents/tools/shared.d.ts +0 -77
- package/lib/types/documents/tools/to-markdown.d.ts +0 -12
- package/lib/types/documents/types.d.ts +0 -294
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Asset preparation and reference auditing (§17.1).
|
|
3
|
-
*
|
|
4
|
-
* Assets reach a document two ways: the caller names a file in the workspace,
|
|
5
|
-
* or it inlines bytes as a data URI. Both are copied into the bundle's
|
|
6
|
-
* `assets/` directory under a name the pipeline chooses, so the rendered
|
|
7
|
-
* document never depends on a path outside the artifact, and the Markdown
|
|
8
|
-
* references are rewritten to match.
|
|
9
|
-
*
|
|
10
|
-
* Before a renderer runs, every image reference in the source is accounted
|
|
11
|
-
* for: a missing local file, a reference that leaves the assets directory, or
|
|
12
|
-
* a remote URL (which the renderer would fetch from the network) is an error,
|
|
13
|
-
* not a silent drop.
|
|
14
|
-
*/
|
|
15
|
-
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
16
|
-
import path from "node:path";
|
|
17
|
-
import { DocumentError, asDocumentError } from "../errors.js";
|
|
18
|
-
import { assertBytesWithinBudget } from "../security/limits.js";
|
|
19
|
-
import { assertRelativeAssetReference, resolveInsideRoot, sanitizeFilename, } from "../security/paths.js";
|
|
20
|
-
import { describeBytes, isAllowedAssetMimeType, mimeTypeForFilename, mimeTypeOfBytes, } from "../security/file-types.js";
|
|
21
|
-
import { allowedInputRoots } from "./scope.js";
|
|
22
|
-
const DATA_URI = /^data:([A-Za-z0-9.+/-]+);base64,([\s\S]*)$/u;
|
|
23
|
-
const EXTENSION_BY_MIME = {
|
|
24
|
-
"image/png": "png",
|
|
25
|
-
"image/jpeg": "jpg",
|
|
26
|
-
"image/gif": "gif",
|
|
27
|
-
"image/webp": "webp",
|
|
28
|
-
"image/bmp": "bmp",
|
|
29
|
-
"image/tiff": "tif",
|
|
30
|
-
};
|
|
31
|
-
function extensionFor(mediaType, fallbackName) {
|
|
32
|
-
const mapped = EXTENSION_BY_MIME[mediaType];
|
|
33
|
-
if (mapped !== undefined)
|
|
34
|
-
return mapped;
|
|
35
|
-
const fromName = fallbackName === undefined ? undefined : path.extname(fallbackName);
|
|
36
|
-
return fromName === undefined || fromName === "" ? "bin" : fromName.slice(1);
|
|
37
|
-
}
|
|
38
|
-
function decodeBase64(payload, id) {
|
|
39
|
-
const compact = payload.replace(/\s+/gu, "");
|
|
40
|
-
try {
|
|
41
|
-
const buffer = Buffer.from(compact, "base64");
|
|
42
|
-
if (buffer.length === 0)
|
|
43
|
-
throw new Error("empty payload");
|
|
44
|
-
return buffer;
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
throw new DocumentError("INVALID_ASSET", `asset "${id}" is not valid base64`, {
|
|
48
|
-
cause: error,
|
|
49
|
-
details: { asset: id },
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
export async function prepareAssets(assets, options) {
|
|
54
|
-
if (assets === undefined || assets.length === 0) {
|
|
55
|
-
return { assets: [], warnings: [] };
|
|
56
|
-
}
|
|
57
|
-
await mkdir(options.assetsDir, { recursive: true });
|
|
58
|
-
const seenIds = new Set();
|
|
59
|
-
const prepared = [];
|
|
60
|
-
const warnings = [];
|
|
61
|
-
const maxBytes = options.config.limits.maxAssetBytes;
|
|
62
|
-
for (const asset of assets) {
|
|
63
|
-
const id = asset.id?.trim() ?? "";
|
|
64
|
-
if (id === "") {
|
|
65
|
-
throw new DocumentError("INVALID_ASSET", "every asset needs a non-empty id");
|
|
66
|
-
}
|
|
67
|
-
if (seenIds.has(id)) {
|
|
68
|
-
throw new DocumentError("INVALID_ASSET", `asset id "${id}" is used twice`, {
|
|
69
|
-
details: { asset: id },
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
seenIds.add(id);
|
|
73
|
-
if ((asset.path === undefined) === (asset.dataRef === undefined)) {
|
|
74
|
-
throw new DocumentError("INVALID_ASSET", `asset "${id}" must carry exactly one of path or dataRef`, { details: { asset: id } });
|
|
75
|
-
}
|
|
76
|
-
let bytes;
|
|
77
|
-
let references = [];
|
|
78
|
-
if (asset.path !== undefined) {
|
|
79
|
-
const declared = asset.path.trim();
|
|
80
|
-
let resolved;
|
|
81
|
-
for (const root of allowedInputRoots(options.config, options.scope)) {
|
|
82
|
-
try {
|
|
83
|
-
resolved = await resolveInsideRoot(root, declared, `asset "${id}"`);
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
if (error instanceof DocumentError &&
|
|
88
|
-
error.code === "PATH_NOT_ALLOWED")
|
|
89
|
-
continue;
|
|
90
|
-
throw error;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (resolved === undefined) {
|
|
94
|
-
throw new DocumentError("PATH_NOT_ALLOWED", `asset "${id}" is outside the session workspace and configured document roots`, { details: { asset: id } });
|
|
95
|
-
}
|
|
96
|
-
const details = await stat(resolved).catch(() => undefined);
|
|
97
|
-
if (details === undefined || !details.isFile()) {
|
|
98
|
-
throw new DocumentError("INVALID_ASSET", `asset "${id}" does not exist`, {
|
|
99
|
-
details: { asset: id },
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
assertBytesWithinBudget(details.size, maxBytes, `asset "${id}"`);
|
|
103
|
-
bytes = await readFile(resolved).catch((error) => {
|
|
104
|
-
throw asDocumentError(error, "INVALID_ASSET", id);
|
|
105
|
-
});
|
|
106
|
-
// Both separators: a source authored on one platform may spell the path
|
|
107
|
-
// the other way, and the rewrite has to catch it either way.
|
|
108
|
-
references = [declared, resolved, resolved.replace(/\\/gu, "/")];
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
const match = DATA_URI.exec((asset.dataRef ?? "").trim());
|
|
112
|
-
if (match === null) {
|
|
113
|
-
throw new DocumentError("INVALID_ASSET", `asset "${id}" must be a base64 data URI`, { details: { asset: id } });
|
|
114
|
-
}
|
|
115
|
-
bytes = decodeBase64(match[2] ?? "", id);
|
|
116
|
-
assertBytesWithinBudget(bytes.length, maxBytes, `asset "${id}"`);
|
|
117
|
-
if (asset.mimeType === undefined) {
|
|
118
|
-
const declaredMime = match[1] ?? "";
|
|
119
|
-
if (declaredMime.startsWith("image/")) {
|
|
120
|
-
warnings.push({
|
|
121
|
-
code: "METADATA_PARTIALLY_EXTRACTED",
|
|
122
|
-
message: `asset "${id}" carries no mimeType; the data URI's type was used`,
|
|
123
|
-
details: { asset: id },
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
assertBytesWithinBudget(bytes.length, maxBytes, `asset "${id}"`);
|
|
129
|
-
const declaredMime = asset.mimeType?.trim();
|
|
130
|
-
const dataUriMime = asset.dataRef === undefined
|
|
131
|
-
? undefined
|
|
132
|
-
: DATA_URI.exec(asset.dataRef.trim())?.[1];
|
|
133
|
-
const mediaType = (declaredMime === undefined || declaredMime === ""
|
|
134
|
-
? undefined
|
|
135
|
-
: declaredMime) ??
|
|
136
|
-
(dataUriMime === undefined || dataUriMime === ""
|
|
137
|
-
? undefined
|
|
138
|
-
: dataUriMime) ??
|
|
139
|
-
mimeTypeOfBytes(bytes) ??
|
|
140
|
-
(asset.filename === undefined
|
|
141
|
-
? undefined
|
|
142
|
-
: mimeTypeForFilename(asset.filename)) ??
|
|
143
|
-
"";
|
|
144
|
-
if (mediaType === "") {
|
|
145
|
-
throw new DocumentError("INVALID_ASSET", `asset "${id}" has no recognizable media type`, { details: { asset: id, bytes: describeBytes(bytes) } });
|
|
146
|
-
}
|
|
147
|
-
if (!isAllowedAssetMimeType(mediaType, options.config.limits.allowedAssetMimeTypes)) {
|
|
148
|
-
throw new DocumentError("INVALID_ASSET", `asset "${id}" has media type ${mediaType}, which this deployment does not accept`, { details: { asset: id, mediaType } });
|
|
149
|
-
}
|
|
150
|
-
const fileName = sanitizeFilename(asset.filename ??
|
|
151
|
-
(asset.path === undefined ? id : path.basename(asset.path)), id, `.${extensionFor(mediaType, asset.filename)}`);
|
|
152
|
-
await writeFile(path.join(options.assetsDir, fileName), bytes);
|
|
153
|
-
// Two spellings reach the stored file: the declared path (rewritten to the
|
|
154
|
-
// stored name) and the asset id, so a source that references
|
|
155
|
-
// `assets/<id>.<ext>` lands on the same file as one that references the
|
|
156
|
-
// final name.
|
|
157
|
-
const idReference = `assets/${id}${path.extname(fileName)}`;
|
|
158
|
-
if (!references.includes(idReference))
|
|
159
|
-
references.push(idReference);
|
|
160
|
-
prepared.push({ id, fileName, mediaType, bytes: bytes.length, references });
|
|
161
|
-
}
|
|
162
|
-
return { assets: prepared, warnings };
|
|
163
|
-
}
|
|
164
|
-
const IMAGE_REFERENCE = /!\[[^\]]*\]\(\s*([^)\s]+)(?:\s+"[^"]*")?\s*\)/gu;
|
|
165
|
-
function normalizeReference(value) {
|
|
166
|
-
return value.trim().replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
167
|
-
}
|
|
168
|
-
/** Any spelling of a provided asset's location, mapped to its stored name. */
|
|
169
|
-
function referenceIndex(assets, roots) {
|
|
170
|
-
const index = new Map();
|
|
171
|
-
const remember = (raw, fileName) => {
|
|
172
|
-
const candidates = [normalizeReference(raw)];
|
|
173
|
-
for (const root of roots) {
|
|
174
|
-
candidates.push(normalizeReference(path.isAbsolute(raw) ? path.resolve(raw) : path.resolve(root, raw)));
|
|
175
|
-
}
|
|
176
|
-
for (const candidate of candidates) {
|
|
177
|
-
if (candidate !== "" && !index.has(candidate))
|
|
178
|
-
index.set(candidate, fileName);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
for (const asset of assets) {
|
|
182
|
-
for (const reference of asset.references)
|
|
183
|
-
remember(reference, asset.fileName);
|
|
184
|
-
}
|
|
185
|
-
return index;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Rewrite the image references that point at a provided asset to the bundle's
|
|
189
|
-
* own `assets/<name>`, keeping every other reference untouched. Matching is
|
|
190
|
-
* whole-reference (never a substring) and resolves relative spellings against
|
|
191
|
-
* the workspace, so an absolute path and a workspace-relative path to the same
|
|
192
|
-
* file both land on the same asset.
|
|
193
|
-
*/
|
|
194
|
-
export function rewriteAssetReferences(markdown, assets, options) {
|
|
195
|
-
if (assets.length === 0)
|
|
196
|
-
return markdown;
|
|
197
|
-
const index = referenceIndex(assets, options.roots);
|
|
198
|
-
return markdown.replace(IMAGE_REFERENCE, (full, reference) => {
|
|
199
|
-
const direct = index.get(normalizeReference(reference));
|
|
200
|
-
if (direct !== undefined)
|
|
201
|
-
return full.replace(reference, `assets/${direct}`);
|
|
202
|
-
for (const root of options.roots) {
|
|
203
|
-
const resolved = index.get(normalizeReference(path.resolve(root, reference)));
|
|
204
|
-
if (resolved !== undefined)
|
|
205
|
-
return full.replace(reference, `assets/${resolved}`);
|
|
206
|
-
}
|
|
207
|
-
return full;
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Verify every image reference in the Markdown before a renderer can act on
|
|
212
|
-
* it: local files must exist inside the assets directory, and remote URLs are
|
|
213
|
-
* refused because the renderer would fetch them (§26.5).
|
|
214
|
-
*/
|
|
215
|
-
export async function auditAssetReferences(markdown, options) {
|
|
216
|
-
const warnings = [];
|
|
217
|
-
const prepared = new Set(options.assets.map((asset) => asset.fileName));
|
|
218
|
-
for (const match of markdown.matchAll(IMAGE_REFERENCE)) {
|
|
219
|
-
const rawReference = match[1] ?? "";
|
|
220
|
-
// A scheme with an authority is a remote fetch; an absolute path (which on
|
|
221
|
-
// Windows starts with a drive letter and therefore looks like a scheme) is
|
|
222
|
-
// not, and is caught by the containment check below.
|
|
223
|
-
if (/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(rawReference) ||
|
|
224
|
-
rawReference.startsWith("//")) {
|
|
225
|
-
throw new DocumentError("INVALID_ASSET", `the source references the remote image "${rawReference}"; remote images are never fetched — add it through assets instead`, { details: { reference: rawReference } });
|
|
226
|
-
}
|
|
227
|
-
const reference = assertRelativeAssetReference(rawReference.replace(/^\.\//u, ""));
|
|
228
|
-
const fileName = path.basename(reference);
|
|
229
|
-
const target = path.resolve(options.assetsDir, reference);
|
|
230
|
-
const insideAssets = path.relative(options.assetsDir, target).split(path.sep)[0] !== "..";
|
|
231
|
-
if (!insideAssets) {
|
|
232
|
-
throw new DocumentError("INVALID_ASSET", `the source references "${rawReference}", which leaves the assets directory`, { details: { reference: rawReference } });
|
|
233
|
-
}
|
|
234
|
-
if (prepared.has(fileName))
|
|
235
|
-
continue;
|
|
236
|
-
const details = await stat(target).catch(() => undefined);
|
|
237
|
-
if (details?.isFile() === true)
|
|
238
|
-
continue;
|
|
239
|
-
throw new DocumentError("INVALID_ASSET", `the source references "${rawReference}", but no such asset was provided`, { details: { reference: rawReference } });
|
|
240
|
-
}
|
|
241
|
-
return warnings;
|
|
242
|
-
}
|
|
243
|
-
//# sourceMappingURL=assets.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/documents/orchestrator/assets.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `document_convert` orchestration (§10).
|
|
3
|
-
*
|
|
4
|
-
* The route table is explicit and closed:
|
|
5
|
-
*
|
|
6
|
-
* ```text
|
|
7
|
-
* MD → DOCX, PDF
|
|
8
|
-
* DOCX → PDF, MD
|
|
9
|
-
* PDF → MD
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
|
-
* Anything else answers `UNSUPPORTED_CONVERSION` — the pipeline never falls
|
|
13
|
-
* back to "run some shell pipeline and hope", because a conversion the service
|
|
14
|
-
* does not model is a conversion it cannot bound, observe or secure.
|
|
15
|
-
*/
|
|
16
|
-
import { stat } from "node:fs/promises";
|
|
17
|
-
import path from "node:path";
|
|
18
|
-
import { sha256Hex, sha256OfFile } from "../artifacts/store.js";
|
|
19
|
-
import { buildManifest, outputRecord, writeManifest, } from "../artifacts/manifest.js";
|
|
20
|
-
import { DocumentError, asDocumentError } from "../errors.js";
|
|
21
|
-
import { describeUnsupported, mediaTypeFor, sniffDocument, supportedFormatOf, } from "../security/file-types.js";
|
|
22
|
-
import { createDocument } from "./create-document.js";
|
|
23
|
-
import { extractToMarkdown } from "./extract-document.js";
|
|
24
|
-
import { ensureArtifactRoot, readInputBytes, resolveDocumentScope, resolveInputPath, } from "./scope.js";
|
|
25
|
-
import { withRenderSlot } from "./runtime-deps.js";
|
|
26
|
-
/** Routes this pipeline implements (source → target). */
|
|
27
|
-
export const CONVERSION_ROUTES = [
|
|
28
|
-
["md", "docx"],
|
|
29
|
-
["md", "pdf"],
|
|
30
|
-
["docx", "pdf"],
|
|
31
|
-
["docx", "md"],
|
|
32
|
-
["pdf", "md"],
|
|
33
|
-
];
|
|
34
|
-
function routeIsSupported(source, target) {
|
|
35
|
-
return CONVERSION_ROUTES.some(([from, to]) => from === source && to === target);
|
|
36
|
-
}
|
|
37
|
-
export async function convertDocument(deps, input, scopeInput) {
|
|
38
|
-
const config = deps.config;
|
|
39
|
-
if (input.targetFormat !== "docx" &&
|
|
40
|
-
input.targetFormat !== "pdf" &&
|
|
41
|
-
input.targetFormat !== "md") {
|
|
42
|
-
throw new DocumentError("UNSUPPORTED_FORMAT", `"${String(input.targetFormat)}" is not a convertible target format`);
|
|
43
|
-
}
|
|
44
|
-
const scope = await resolveDocumentScope(config, scopeInput);
|
|
45
|
-
const inputPath = await resolveInputPath(config, scope, input.file, "file");
|
|
46
|
-
const bytes = await readInputBytes(inputPath, config, "file");
|
|
47
|
-
const sniffed = sniffDocument(bytes, inputPath);
|
|
48
|
-
const sourceFormat = supportedFormatOf(sniffed);
|
|
49
|
-
if (sourceFormat === undefined) {
|
|
50
|
-
throw new DocumentError(sniffed.format === "docm"
|
|
51
|
-
? "MACRO_ENABLED_DOCUMENT"
|
|
52
|
-
: "UNSUPPORTED_FORMAT", describeUnsupported(sniffed, inputPath));
|
|
53
|
-
}
|
|
54
|
-
if (!routeIsSupported(sourceFormat, input.targetFormat)) {
|
|
55
|
-
throw new DocumentError("UNSUPPORTED_CONVERSION", `${sourceFormat} → ${input.targetFormat} is not a supported conversion (supported: ${CONVERSION_ROUTES.map(([from, to]) => `${from} → ${to}`).join(", ")})`, { details: { source: sourceFormat, target: input.targetFormat } });
|
|
56
|
-
}
|
|
57
|
-
// Extraction first: it also covers `md` sources, and it narrows
|
|
58
|
-
// `targetFormat` to a creatable format for the branch below.
|
|
59
|
-
if (input.targetFormat === "md") {
|
|
60
|
-
const extracted = await extractToMarkdown(deps, {
|
|
61
|
-
file: inputPath,
|
|
62
|
-
...(input.options?.ocr === undefined ? {} : { ocr: input.options.ocr }),
|
|
63
|
-
...(input.outputFilename === undefined
|
|
64
|
-
? {}
|
|
65
|
-
: { outputFilename: input.outputFilename }),
|
|
66
|
-
}, {
|
|
67
|
-
...scope,
|
|
68
|
-
...(scope.signal === undefined ? {} : { signal: scope.signal }),
|
|
69
|
-
}, "document_convert");
|
|
70
|
-
return {
|
|
71
|
-
artifactId: extracted.artifactId,
|
|
72
|
-
files: [
|
|
73
|
-
{
|
|
74
|
-
format: "md",
|
|
75
|
-
path: extracted.markdownPath,
|
|
76
|
-
mediaType: mediaTypeFor("md"),
|
|
77
|
-
size: (await stat(extracted.markdownPath)).size,
|
|
78
|
-
sha256: await sha256OfFile(extracted.markdownPath),
|
|
79
|
-
status: "created",
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
source: { path: inputPath, format: sourceFormat },
|
|
83
|
-
warnings: extracted.warnings,
|
|
84
|
-
manifestPath: extracted.manifestPath,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
if (sourceFormat === "md") {
|
|
88
|
-
return await convertMarkdown(deps, input, scope, inputPath, bytes, input.targetFormat);
|
|
89
|
-
}
|
|
90
|
-
return await convertDocxToPdf(deps, input, scope, inputPath, bytes);
|
|
91
|
-
}
|
|
92
|
-
/** Markdown input: the create pipeline is the route, so nothing is duplicated. */
|
|
93
|
-
async function convertMarkdown(deps, input, scope, inputPath, bytes, target) {
|
|
94
|
-
const content = bytes.toString("utf8");
|
|
95
|
-
const created = await createDocument(deps, {
|
|
96
|
-
content,
|
|
97
|
-
formats: [target],
|
|
98
|
-
...(input.template === undefined ? {} : { template: input.template }),
|
|
99
|
-
filename: input.filename ?? path.basename(inputPath).replace(/\.[^.]+$/u, ""),
|
|
100
|
-
...(input.options?.pdfMode === undefined
|
|
101
|
-
? {}
|
|
102
|
-
: { options: { pdfMode: input.options.pdfMode } }),
|
|
103
|
-
}, { ...scope });
|
|
104
|
-
return {
|
|
105
|
-
artifactId: created.artifactId,
|
|
106
|
-
files: created.files,
|
|
107
|
-
source: { path: inputPath, format: "md" },
|
|
108
|
-
warnings: created.warnings,
|
|
109
|
-
manifestPath: created.manifestPath,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/** DOCX input, PDF output: render nothing, convert the document as it is. */
|
|
113
|
-
async function convertDocxToPdf(deps, input, scope, inputPath, bytes) {
|
|
114
|
-
const config = deps.config;
|
|
115
|
-
await ensureArtifactRoot(scope);
|
|
116
|
-
const { artifactId, dir: artifactDir } = await scope.store.create(deps.now().getTime());
|
|
117
|
-
const workDir = await scope.store.createWorkDir(artifactId);
|
|
118
|
-
const warnings = [];
|
|
119
|
-
try {
|
|
120
|
-
if (config.storage.retainInputs) {
|
|
121
|
-
await scope.store.write(path.join(artifactId, "input", path.basename(inputPath)), bytes);
|
|
122
|
-
}
|
|
123
|
-
const stem = (input.filename ?? path.basename(inputPath).replace(/\.[^.]+$/u, ""))
|
|
124
|
-
.replace(/[^A-Za-z0-9._-]+/gu, "-")
|
|
125
|
-
.replace(/^-+|-+$/gu, "");
|
|
126
|
-
const outputPath = path.join(artifactDir, `${stem === "" ? "document" : stem}.pdf`);
|
|
127
|
-
const converted = await withRenderSlot(deps, scope.signal, async () => await deps.providers.converter.convert({
|
|
128
|
-
inputPath,
|
|
129
|
-
outputPath,
|
|
130
|
-
workDir,
|
|
131
|
-
...(scope.signal === undefined ? {} : { signal: scope.signal }),
|
|
132
|
-
}));
|
|
133
|
-
warnings.push(...converted.warnings);
|
|
134
|
-
const file = {
|
|
135
|
-
format: "pdf",
|
|
136
|
-
path: converted.path,
|
|
137
|
-
mediaType: mediaTypeFor("pdf"),
|
|
138
|
-
size: converted.size,
|
|
139
|
-
sha256: converted.sha256,
|
|
140
|
-
status: "created",
|
|
141
|
-
};
|
|
142
|
-
const manifest = buildManifest({
|
|
143
|
-
artifactId,
|
|
144
|
-
operation: "document_convert",
|
|
145
|
-
createdAt: deps.now().toISOString(),
|
|
146
|
-
input: {
|
|
147
|
-
format: "docx",
|
|
148
|
-
sha256: sha256Hex(bytes),
|
|
149
|
-
filename: path.basename(inputPath),
|
|
150
|
-
bytes: bytes.length,
|
|
151
|
-
},
|
|
152
|
-
outputs: [outputRecord(file)],
|
|
153
|
-
backends: { convert: converted.backend },
|
|
154
|
-
warnings,
|
|
155
|
-
scope: {
|
|
156
|
-
...(scope.sessionId === undefined
|
|
157
|
-
? {}
|
|
158
|
-
: { sessionId: scope.sessionId }),
|
|
159
|
-
workspace: scope.workspaceRoot,
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
const manifestPath = await writeManifest(scope.store, artifactId, manifest);
|
|
163
|
-
await scope.store.removeWorkDir(workDir);
|
|
164
|
-
deps.logger.info("documents.convert", {
|
|
165
|
-
artifactId,
|
|
166
|
-
from: "docx",
|
|
167
|
-
to: "pdf",
|
|
168
|
-
backend: converted.backend.provider,
|
|
169
|
-
bytes: bytes.length,
|
|
170
|
-
outBytes: converted.size,
|
|
171
|
-
status: "ok",
|
|
172
|
-
});
|
|
173
|
-
return {
|
|
174
|
-
artifactId,
|
|
175
|
-
files: [file],
|
|
176
|
-
source: { path: inputPath, format: "docx" },
|
|
177
|
-
warnings,
|
|
178
|
-
manifestPath,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
await scope.store.removeWorkDir(workDir);
|
|
183
|
-
throw asDocumentError(error, "CONVERSION_FAILED");
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
//# sourceMappingURL=convert-document.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convert-document.js","sourceRoot":"","sources":["../../../src/documents/orchestrator/convert-document.ts"],"names":[],"mappings":"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"}
|