@opengeni/artifact-tool 0.2.2
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/LICENSE +190 -0
- package/README.md +104 -0
- package/dist/bounded-zip.d.ts +28 -0
- package/dist/chunk-4BSENMAE.js +39 -0
- package/dist/chunk-4BSENMAE.js.map +1 -0
- package/dist/chunk-4FRFNNBM.js +276 -0
- package/dist/chunk-4FRFNNBM.js.map +1 -0
- package/dist/chunk-5XIA6KHZ.js +49 -0
- package/dist/chunk-5XIA6KHZ.js.map +1 -0
- package/dist/chunk-66CT2ZRP.js +2229 -0
- package/dist/chunk-66CT2ZRP.js.map +1 -0
- package/dist/chunk-72SYDU4O.js +319 -0
- package/dist/chunk-72SYDU4O.js.map +1 -0
- package/dist/chunk-B2ZJRZDA.js +279 -0
- package/dist/chunk-B2ZJRZDA.js.map +1 -0
- package/dist/chunk-DCTLTNPW.js +2458 -0
- package/dist/chunk-DCTLTNPW.js.map +1 -0
- package/dist/chunk-FGZM4FQ6.js +473 -0
- package/dist/chunk-FGZM4FQ6.js.map +1 -0
- package/dist/chunk-HTJBLBDE.js +591 -0
- package/dist/chunk-HTJBLBDE.js.map +1 -0
- package/dist/chunk-IYFXZQ34.js +5306 -0
- package/dist/chunk-IYFXZQ34.js.map +1 -0
- package/dist/chunk-J6N7IR44.js +172 -0
- package/dist/chunk-J6N7IR44.js.map +1 -0
- package/dist/chunk-N2IHNWBS.js +1002 -0
- package/dist/chunk-N2IHNWBS.js.map +1 -0
- package/dist/chunk-NAG44K67.js +549 -0
- package/dist/chunk-NAG44K67.js.map +1 -0
- package/dist/chunk-O24KTEGP.js +33 -0
- package/dist/chunk-O24KTEGP.js.map +1 -0
- package/dist/chunk-PI2AZVGK.js +2074 -0
- package/dist/chunk-PI2AZVGK.js.map +1 -0
- package/dist/chunk-Q2FFHEY7.js +40 -0
- package/dist/chunk-Q2FFHEY7.js.map +1 -0
- package/dist/chunk-RBGQADXA.js +57 -0
- package/dist/chunk-RBGQADXA.js.map +1 -0
- package/dist/chunk-U5G2BKM2.js +613 -0
- package/dist/chunk-U5G2BKM2.js.map +1 -0
- package/dist/chunk-VOJHMSM3.js +39 -0
- package/dist/chunk-VOJHMSM3.js.map +1 -0
- package/dist/chunk-VUNV25KB.js +16 -0
- package/dist/chunk-VUNV25KB.js.map +1 -0
- package/dist/chunk-XIFUNVBO.js +101 -0
- package/dist/chunk-XIFUNVBO.js.map +1 -0
- package/dist/chunk-ZCJYRJGB.js +489 -0
- package/dist/chunk-ZCJYRJGB.js.map +1 -0
- package/dist/chunk-ZZXPEE4S.js +2260 -0
- package/dist/chunk-ZZXPEE4S.js.map +1 -0
- package/dist/document-docx-api.d.ts +49 -0
- package/dist/document-docx-codec.d.ts +9 -0
- package/dist/document-docx-codec.js +4765 -0
- package/dist/document-docx-codec.js.map +1 -0
- package/dist/document-docx-import.d.ts +261 -0
- package/dist/document-docx-packer.d.ts +18 -0
- package/dist/document-docx-state.d.ts +12 -0
- package/dist/document-render.d.ts +3 -0
- package/dist/document-render.js +492 -0
- package/dist/document-render.js.map +1 -0
- package/dist/document.d.ts +432 -0
- package/dist/document.js +37 -0
- package/dist/document.js.map +1 -0
- package/dist/errors.d.ts +23 -0
- package/dist/file-blob.d.ts +11 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/inspection.d.ts +12 -0
- package/dist/kernel.d.ts +101 -0
- package/dist/lib-GQLPACFK.js +9746 -0
- package/dist/lib-GQLPACFK.js.map +1 -0
- package/dist/materializer-cli-entry.d.ts +2 -0
- package/dist/materializer-cli-entry.js +29 -0
- package/dist/materializer-cli-entry.js.map +1 -0
- package/dist/materializer-cli.d.ts +24 -0
- package/dist/materializer-cli.js +24 -0
- package/dist/materializer-cli.js.map +1 -0
- package/dist/native-raster.d.ts +10 -0
- package/dist/native.d.ts +129 -0
- package/dist/native.js +31 -0
- package/dist/native.js.map +1 -0
- package/dist/office-import.d.ts +48 -0
- package/dist/office-import.js +154 -0
- package/dist/office-import.js.map +1 -0
- package/dist/presentation-pptx-api.d.ts +60 -0
- package/dist/presentation-pptx-import.d.ts +5 -0
- package/dist/presentation-pptx-state-digest-765CZZED.js +10 -0
- package/dist/presentation-pptx-state-digest-765CZZED.js.map +1 -0
- package/dist/presentation-pptx-state-digest.d.ts +3 -0
- package/dist/presentation-pptx-state.d.ts +4 -0
- package/dist/presentation-pptx-xml.d.ts +29 -0
- package/dist/presentation-pptx.d.ts +5 -0
- package/dist/presentation-pptx.js +2365 -0
- package/dist/presentation-pptx.js.map +1 -0
- package/dist/presentation-render.d.ts +29 -0
- package/dist/presentation-render.js +375 -0
- package/dist/presentation-render.js.map +1 -0
- package/dist/presentation.d.ts +565 -0
- package/dist/presentation.js +71 -0
- package/dist/presentation.js.map +1 -0
- package/dist/production-composite.d.ts +68 -0
- package/dist/production-document.d.ts +2 -0
- package/dist/production-document.js +176 -0
- package/dist/production-document.js.map +1 -0
- package/dist/production-native-codecs.d.ts +94 -0
- package/dist/production-presentation.d.ts +2 -0
- package/dist/production-presentation.js +176 -0
- package/dist/production-presentation.js.map +1 -0
- package/dist/production-sha256.d.ts +2 -0
- package/dist/production-spreadsheet-native.d.ts +12 -0
- package/dist/production-spreadsheet.d.ts +2 -0
- package/dist/production-spreadsheet.js +176 -0
- package/dist/production-spreadsheet.js.map +1 -0
- package/dist/production.d.ts +96 -0
- package/dist/raster-image.d.ts +34 -0
- package/dist/reference.d.ts +17 -0
- package/dist/reference.js +574 -0
- package/dist/reference.js.map +1 -0
- package/dist/runtime-cli-entry.d.ts +2 -0
- package/dist/runtime-cli-entry.js +21 -0
- package/dist/runtime-cli-entry.js.map +1 -0
- package/dist/runtime-cli.d.ts +76 -0
- package/dist/runtime-cli.js +26 -0
- package/dist/runtime-cli.js.map +1 -0
- package/dist/runtime-development.d.ts +73 -0
- package/dist/runtime-development.js +30 -0
- package/dist/runtime-development.js.map +1 -0
- package/dist/runtime-receipt.d.ts +19 -0
- package/dist/runtime.d.ts +355 -0
- package/dist/runtime.js +42 -0
- package/dist/runtime.js.map +1 -0
- package/dist/snapshot.d.ts +26 -0
- package/dist/snapshot.js +61 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/spreadsheet-address.d.ts +18 -0
- package/dist/spreadsheet-file.d.ts +17 -0
- package/dist/spreadsheet-formula.d.ts +67 -0
- package/dist/spreadsheet-image.d.ts +17 -0
- package/dist/spreadsheet-render.d.ts +5 -0
- package/dist/spreadsheet-render.js +752 -0
- package/dist/spreadsheet-render.js.map +1 -0
- package/dist/spreadsheet-types.d.ts +155 -0
- package/dist/spreadsheet-xlsx-api.d.ts +88 -0
- package/dist/spreadsheet-xlsx-codec.d.ts +16 -0
- package/dist/spreadsheet-xlsx-codec.js +16 -0
- package/dist/spreadsheet-xlsx-codec.js.map +1 -0
- package/dist/spreadsheet-xlsx-state.d.ts +16 -0
- package/dist/spreadsheet.d.ts +724 -0
- package/dist/spreadsheet.js +67 -0
- package/dist/spreadsheet.js.map +1 -0
- package/package.json +129 -0
- package/src/bounded-zip.ts +450 -0
- package/src/document-docx-api.ts +64 -0
- package/src/document-docx-codec.ts +2253 -0
- package/src/document-docx-import.ts +3814 -0
- package/src/document-docx-packer.ts +72 -0
- package/src/document-docx-state.ts +59 -0
- package/src/document-render.ts +615 -0
- package/src/document.ts +2800 -0
- package/src/errors.ts +45 -0
- package/src/file-blob.ts +43 -0
- package/src/index.ts +4 -0
- package/src/inspection.ts +50 -0
- package/src/kernel.ts +525 -0
- package/src/materializer-cli-entry.ts +11 -0
- package/src/materializer-cli.ts +743 -0
- package/src/native-raster.ts +141 -0
- package/src/native.ts +390 -0
- package/src/office-import.ts +243 -0
- package/src/presentation-pptx-api.ts +107 -0
- package/src/presentation-pptx-import.ts +2065 -0
- package/src/presentation-pptx-state-digest.ts +46 -0
- package/src/presentation-pptx-state.ts +18 -0
- package/src/presentation-pptx-xml.ts +473 -0
- package/src/presentation-pptx.ts +447 -0
- package/src/presentation-render.ts +532 -0
- package/src/presentation.ts +2599 -0
- package/src/production-composite.ts +805 -0
- package/src/production-document.ts +2 -0
- package/src/production-native-codecs.ts +1141 -0
- package/src/production-presentation.ts +2 -0
- package/src/production-sha256.ts +150 -0
- package/src/production-spreadsheet-native.ts +686 -0
- package/src/production-spreadsheet.ts +2 -0
- package/src/production.ts +1022 -0
- package/src/raster-image.ts +586 -0
- package/src/reference.ts +17 -0
- package/src/runtime-cli-entry.ts +13 -0
- package/src/runtime-cli.ts +670 -0
- package/src/runtime-development.ts +689 -0
- package/src/runtime-receipt.ts +169 -0
- package/src/runtime.ts +1463 -0
- package/src/snapshot.ts +88 -0
- package/src/spreadsheet-address.ts +90 -0
- package/src/spreadsheet-file.ts +71 -0
- package/src/spreadsheet-formula.ts +1212 -0
- package/src/spreadsheet-image.ts +242 -0
- package/src/spreadsheet-render.ts +985 -0
- package/src/spreadsheet-types.ts +171 -0
- package/src/spreadsheet-xlsx-api.ts +123 -0
- package/src/spreadsheet-xlsx-codec.ts +3063 -0
- package/src/spreadsheet-xlsx-state.ts +191 -0
- package/src/spreadsheet.ts +5195 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { decodeEditableArtifactCausalFrontier } from "@opengeni/contracts/editable-artifact-causal-frontier";
|
|
3
|
+
import { EDITABLE_ARTIFACT_PRODUCT_MAX_SNAPSHOT_BYTES } from "@opengeni/contracts/editable-artifacts";
|
|
4
|
+
import type { ArtifactSnapshot } from "./snapshot";
|
|
5
|
+
|
|
6
|
+
export type ArtifactOfficeModality = "spreadsheet" | "document" | "presentation";
|
|
7
|
+
export type ArtifactOfficeMimeType =
|
|
8
|
+
| "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
9
|
+
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
10
|
+
| "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
|
11
|
+
|
|
12
|
+
export type PreparedArtifactOfficeImport = Readonly<{
|
|
13
|
+
source: Readonly<{
|
|
14
|
+
filename: string;
|
|
15
|
+
byteSize: number;
|
|
16
|
+
contentHash: `sha256:${string}`;
|
|
17
|
+
mimeType: ArtifactOfficeMimeType;
|
|
18
|
+
}>;
|
|
19
|
+
snapshot:
|
|
20
|
+
| Readonly<{
|
|
21
|
+
modality: "spreadsheet";
|
|
22
|
+
bytes: Uint8Array;
|
|
23
|
+
byteSize: number;
|
|
24
|
+
contentHash: `sha256:${string}`;
|
|
25
|
+
stateHash: `sha256:${string}`;
|
|
26
|
+
modelSchemaVersion: 1;
|
|
27
|
+
kernelVersion: string;
|
|
28
|
+
coveredCausalFrontier: readonly Readonly<{ replicaId: string; counter: number }>[];
|
|
29
|
+
operationProtocolVersion: 1;
|
|
30
|
+
crdtStateVersion: 1;
|
|
31
|
+
}>
|
|
32
|
+
| Readonly<{
|
|
33
|
+
modality: "document" | "presentation";
|
|
34
|
+
bytes: Uint8Array;
|
|
35
|
+
byteSize: number;
|
|
36
|
+
contentHash: `sha256:${string}`;
|
|
37
|
+
stateHash: `sha256:${string}`;
|
|
38
|
+
modelSchemaVersion: 1;
|
|
39
|
+
kernelVersion: string;
|
|
40
|
+
nativeRevision: number;
|
|
41
|
+
}>;
|
|
42
|
+
}>;
|
|
43
|
+
|
|
44
|
+
/** The Office container is valid input bytes but cannot be modeled safely. */
|
|
45
|
+
export class ArtifactOfficeSourceUnsupportedError extends Error {
|
|
46
|
+
constructor(extension: ".xlsx" | ".docx" | ".pptx", options: ErrorOptions) {
|
|
47
|
+
super(`The ${extension} source could not be imported`, options);
|
|
48
|
+
this.name = "ArtifactOfficeSourceUnsupportedError";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Import bounded Office bytes through the exact verified facade, without a local path. */
|
|
53
|
+
export async function prepareArtifactOfficeImport(
|
|
54
|
+
input: Readonly<{
|
|
55
|
+
facade: unknown;
|
|
56
|
+
modality: ArtifactOfficeModality;
|
|
57
|
+
filename: string;
|
|
58
|
+
mimeType: ArtifactOfficeMimeType;
|
|
59
|
+
bytes: Uint8Array;
|
|
60
|
+
expectedRuntimeTarget: string;
|
|
61
|
+
expectedKernelVersion: string;
|
|
62
|
+
}>,
|
|
63
|
+
): Promise<PreparedArtifactOfficeImport> {
|
|
64
|
+
const expected = officeFormat(input.modality);
|
|
65
|
+
if (input.mimeType !== expected.mimeType) {
|
|
66
|
+
throw new TypeError("Office MIME type does not match artifact modality");
|
|
67
|
+
}
|
|
68
|
+
if (!input.filename.toLowerCase().endsWith(expected.extension)) {
|
|
69
|
+
throw new TypeError(`Office filename must end with ${expected.extension}`);
|
|
70
|
+
}
|
|
71
|
+
if (!(input.bytes instanceof Uint8Array) || input.bytes.byteLength < 1) {
|
|
72
|
+
throw new TypeError("Office source bytes must be a nonempty Uint8Array");
|
|
73
|
+
}
|
|
74
|
+
if (input.bytes.byteLength > EDITABLE_ARTIFACT_PRODUCT_MAX_SNAPSHOT_BYTES) {
|
|
75
|
+
throw new RangeError("Office source exceeds the editable artifact product limit");
|
|
76
|
+
}
|
|
77
|
+
const sourceBytes = Uint8Array.from(input.bytes);
|
|
78
|
+
const module = exactModule(input.facade);
|
|
79
|
+
const fileBlob = exactNamespace(module.FileBlob, "FileBlob");
|
|
80
|
+
const fromBytes = exactFunction(fileBlob.fromBytes, "FileBlob.fromBytes");
|
|
81
|
+
const createSnapshot = exactFunction(module.createArtifactSnapshot, "createArtifactSnapshot");
|
|
82
|
+
const disposeArtifact = exactFunction(module.disposeArtifact, "disposeArtifact");
|
|
83
|
+
const importer = officeImporter(module, input.modality);
|
|
84
|
+
const blob = Reflect.apply(fromBytes, fileBlob, [
|
|
85
|
+
sourceBytes,
|
|
86
|
+
{ name: input.filename, type: input.mimeType },
|
|
87
|
+
]);
|
|
88
|
+
let artifact: unknown;
|
|
89
|
+
try {
|
|
90
|
+
artifact = await importer(blob);
|
|
91
|
+
} catch (cause) {
|
|
92
|
+
throw new ArtifactOfficeSourceUnsupportedError(expected.extension, { cause });
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const snapshot = validateSnapshot(
|
|
96
|
+
Reflect.apply(createSnapshot, module, [artifact]),
|
|
97
|
+
input.modality,
|
|
98
|
+
input.expectedRuntimeTarget,
|
|
99
|
+
input.expectedKernelVersion,
|
|
100
|
+
);
|
|
101
|
+
return Object.freeze({
|
|
102
|
+
source: Object.freeze({
|
|
103
|
+
filename: input.filename,
|
|
104
|
+
byteSize: sourceBytes.byteLength,
|
|
105
|
+
contentHash: sha256(sourceBytes),
|
|
106
|
+
mimeType: input.mimeType,
|
|
107
|
+
}),
|
|
108
|
+
snapshot,
|
|
109
|
+
});
|
|
110
|
+
} finally {
|
|
111
|
+
Reflect.apply(disposeArtifact, module, [artifact]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function validateSnapshot(
|
|
116
|
+
value: unknown,
|
|
117
|
+
modality: ArtifactOfficeModality,
|
|
118
|
+
expectedRuntimeTarget: string,
|
|
119
|
+
expectedKernelVersion: string,
|
|
120
|
+
): PreparedArtifactOfficeImport["snapshot"] {
|
|
121
|
+
const snapshot = exactNamespace(value, "artifact snapshot") as unknown as ArtifactSnapshot;
|
|
122
|
+
if (
|
|
123
|
+
snapshot.schemaVersion !== 1 ||
|
|
124
|
+
snapshot.modality !== modality ||
|
|
125
|
+
snapshot.runtimeTarget !== expectedRuntimeTarget ||
|
|
126
|
+
snapshot.kernelVersion !== expectedKernelVersion ||
|
|
127
|
+
snapshot.modelSchemaVersion !== 1 ||
|
|
128
|
+
snapshot.snapshotVersion !== 1 ||
|
|
129
|
+
!/^sha256:[0-9a-f]{64}$/u.test(snapshot.stateHash)
|
|
130
|
+
) {
|
|
131
|
+
throw new TypeError("Imported snapshot differs from the verified native runtime boundary");
|
|
132
|
+
}
|
|
133
|
+
if (
|
|
134
|
+
!(snapshot.snapshotBytes instanceof Uint8Array) ||
|
|
135
|
+
snapshot.snapshotBytes.byteLength < 1 ||
|
|
136
|
+
snapshot.snapshotBytes.byteLength > EDITABLE_ARTIFACT_PRODUCT_MAX_SNAPSHOT_BYTES
|
|
137
|
+
) {
|
|
138
|
+
throw new TypeError("Imported snapshot bytes are outside the product limit");
|
|
139
|
+
}
|
|
140
|
+
const bytes = Uint8Array.from(snapshot.snapshotBytes);
|
|
141
|
+
const common = {
|
|
142
|
+
bytes,
|
|
143
|
+
byteSize: bytes.byteLength,
|
|
144
|
+
contentHash: sha256(bytes),
|
|
145
|
+
stateHash: snapshot.stateHash as `sha256:${string}`,
|
|
146
|
+
modelSchemaVersion: 1 as const,
|
|
147
|
+
kernelVersion: snapshot.kernelVersion,
|
|
148
|
+
};
|
|
149
|
+
if (snapshot.modality === "spreadsheet") {
|
|
150
|
+
if (
|
|
151
|
+
!(snapshot.coveredCausalFrontierBytes instanceof Uint8Array) ||
|
|
152
|
+
snapshot.operationProtocolVersion !== 1 ||
|
|
153
|
+
snapshot.crdtStateVersion !== 1
|
|
154
|
+
) {
|
|
155
|
+
throw new TypeError("Imported spreadsheet snapshot coverage is invalid");
|
|
156
|
+
}
|
|
157
|
+
return Object.freeze({
|
|
158
|
+
...common,
|
|
159
|
+
modality: "spreadsheet" as const,
|
|
160
|
+
coveredCausalFrontier: decodeEditableArtifactCausalFrontier(
|
|
161
|
+
snapshot.coveredCausalFrontierBytes,
|
|
162
|
+
),
|
|
163
|
+
operationProtocolVersion: 1 as const,
|
|
164
|
+
crdtStateVersion: 1 as const,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
if (!Number.isSafeInteger(snapshot.nativeRevision) || snapshot.nativeRevision < 0) {
|
|
168
|
+
throw new TypeError("Imported serialized snapshot revision is invalid");
|
|
169
|
+
}
|
|
170
|
+
return Object.freeze({
|
|
171
|
+
...common,
|
|
172
|
+
modality: snapshot.modality,
|
|
173
|
+
nativeRevision: snapshot.nativeRevision,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function officeImporter(
|
|
178
|
+
module: Record<string, unknown>,
|
|
179
|
+
modality: ArtifactOfficeModality,
|
|
180
|
+
): (input: unknown) => Promise<unknown> {
|
|
181
|
+
const namespaceName =
|
|
182
|
+
modality === "spreadsheet"
|
|
183
|
+
? "SpreadsheetFile"
|
|
184
|
+
: modality === "document"
|
|
185
|
+
? "DocumentFile"
|
|
186
|
+
: "PresentationFile";
|
|
187
|
+
const methodName =
|
|
188
|
+
modality === "spreadsheet"
|
|
189
|
+
? "importXlsx"
|
|
190
|
+
: modality === "document"
|
|
191
|
+
? "importDocx"
|
|
192
|
+
: "importPptx";
|
|
193
|
+
const namespace = exactNamespace(module[namespaceName], namespaceName);
|
|
194
|
+
const method = exactFunction(namespace[methodName], `${namespaceName}.${methodName}`);
|
|
195
|
+
return async (blob) => await Reflect.apply(method, namespace, [blob]);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function officeFormat(modality: ArtifactOfficeModality): Readonly<{
|
|
199
|
+
extension: ".xlsx" | ".docx" | ".pptx";
|
|
200
|
+
mimeType: ArtifactOfficeMimeType;
|
|
201
|
+
}> {
|
|
202
|
+
if (modality === "spreadsheet") {
|
|
203
|
+
return {
|
|
204
|
+
extension: ".xlsx",
|
|
205
|
+
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
if (modality === "document") {
|
|
209
|
+
return {
|
|
210
|
+
extension: ".docx",
|
|
211
|
+
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
extension: ".pptx",
|
|
216
|
+
mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function exactModule(value: unknown): Record<string, unknown> {
|
|
221
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
222
|
+
throw new TypeError("Verified artifact facade must be a module namespace");
|
|
223
|
+
}
|
|
224
|
+
return value as Record<string, unknown>;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function exactNamespace(value: unknown, label: string): Record<string, unknown> {
|
|
228
|
+
if ((typeof value !== "object" && typeof value !== "function") || value === null) {
|
|
229
|
+
throw new TypeError(`Verified artifact facade is missing ${label}`);
|
|
230
|
+
}
|
|
231
|
+
return value as Record<string, unknown>;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function exactFunction(value: unknown, label: string): (...args: unknown[]) => unknown {
|
|
235
|
+
if (typeof value !== "function") {
|
|
236
|
+
throw new TypeError(`Verified artifact facade is missing ${label}()`);
|
|
237
|
+
}
|
|
238
|
+
return value as (...args: unknown[]) => unknown;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function sha256(bytes: Uint8Array): `sha256:${string}` {
|
|
242
|
+
return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
243
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export const PPTX_MEDIA_TYPE =
|
|
2
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation" as const;
|
|
3
|
+
|
|
4
|
+
export type PresentationPptxFeature =
|
|
5
|
+
| "animation"
|
|
6
|
+
| "audio"
|
|
7
|
+
| "custom-geometry"
|
|
8
|
+
| "connector"
|
|
9
|
+
| "embedded-object"
|
|
10
|
+
| "group"
|
|
11
|
+
| "hyperlink"
|
|
12
|
+
| "master"
|
|
13
|
+
| "layout"
|
|
14
|
+
| "media"
|
|
15
|
+
| "placeholder"
|
|
16
|
+
| "source-only"
|
|
17
|
+
| "smart-art"
|
|
18
|
+
| "table-style"
|
|
19
|
+
| "theme"
|
|
20
|
+
| "transition"
|
|
21
|
+
| "unsupported-chart"
|
|
22
|
+
| "video";
|
|
23
|
+
|
|
24
|
+
export type PresentationFidelityIssue = {
|
|
25
|
+
code:
|
|
26
|
+
| "content-preserved-in-source"
|
|
27
|
+
| "content-will-be-discarded"
|
|
28
|
+
| "group-will-be-flattened"
|
|
29
|
+
| "style-approximated";
|
|
30
|
+
severity: "warning" | "error";
|
|
31
|
+
feature: PresentationPptxFeature;
|
|
32
|
+
message: string;
|
|
33
|
+
parts?: readonly string[];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type PresentationPptxImportLimits = {
|
|
37
|
+
compressedBytes: number;
|
|
38
|
+
expandedBytes: number;
|
|
39
|
+
entryBytes: number;
|
|
40
|
+
entries: number;
|
|
41
|
+
compressionRatio: number;
|
|
42
|
+
totalXmlBytes: number;
|
|
43
|
+
xmlBytes: number;
|
|
44
|
+
xmlDepth: number;
|
|
45
|
+
xmlNodes: number;
|
|
46
|
+
xmlAttributesPerElement: number;
|
|
47
|
+
relationshipsPerPart: number;
|
|
48
|
+
relationships: number;
|
|
49
|
+
slides: number;
|
|
50
|
+
elements: number;
|
|
51
|
+
textCharacters: number;
|
|
52
|
+
imageBytes: number;
|
|
53
|
+
chartPoints: number;
|
|
54
|
+
nestedPackageBytes: number;
|
|
55
|
+
nestedExpandedBytes: number;
|
|
56
|
+
nestedEntries: number;
|
|
57
|
+
retainedBytes: number;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export type PresentationPptxImportOptions = {
|
|
61
|
+
/** Preserve unsupported, inert content in the original package or reject it. */
|
|
62
|
+
unsupportedContent?: "preserve" | "error";
|
|
63
|
+
/** Every limit is applied before or while allocating decoded package state. */
|
|
64
|
+
limits?: Partial<PresentationPptxImportLimits>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type PresentationPptxExportOptions = {
|
|
68
|
+
fileName?: string;
|
|
69
|
+
/** Explicitly acknowledge content the editable model cannot regenerate. */
|
|
70
|
+
unsupportedContent?: "error" | "discard";
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type PresentationLossPreservationEnvelope = {
|
|
74
|
+
version: 1;
|
|
75
|
+
mediaType: typeof PPTX_MEDIA_TYPE;
|
|
76
|
+
sourceBytes: Uint8Array;
|
|
77
|
+
sourceDigest: string;
|
|
78
|
+
unsupportedParts: readonly string[];
|
|
79
|
+
modelDigest: string;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export class PresentationFidelityError extends Error {
|
|
83
|
+
readonly issues: readonly PresentationFidelityIssue[];
|
|
84
|
+
|
|
85
|
+
constructor(message: string, issues: readonly PresentationFidelityIssue[]) {
|
|
86
|
+
super(message);
|
|
87
|
+
this.name = "PresentationFidelityError";
|
|
88
|
+
this.issues = issues;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export class PresentationSecurityError extends Error {
|
|
93
|
+
constructor(
|
|
94
|
+
message: string,
|
|
95
|
+
readonly code:
|
|
96
|
+
| "active-content"
|
|
97
|
+
| "encrypted-content"
|
|
98
|
+
| "external-relationship"
|
|
99
|
+
| "invalid-package"
|
|
100
|
+
| "limit-exceeded"
|
|
101
|
+
| "unsafe-xml",
|
|
102
|
+
readonly entryName?: string,
|
|
103
|
+
) {
|
|
104
|
+
super(message);
|
|
105
|
+
this.name = "PresentationSecurityError";
|
|
106
|
+
}
|
|
107
|
+
}
|