@oddington/sdk 0.1.30 → 0.1.32
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 +0 -20
- package/dist/browser.js +150 -195
- package/dist/index.js +3 -62
- package/dist/types/packages/sdk/src/public.d.ts +1 -13
- package/dist/types/shared/files-contract.d.ts +6 -36
- package/dist/types/shared/inbox-contract.d.ts +0 -13
- package/dist/types/shared/inbox-files.d.ts +5 -10
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -15,22 +15,7 @@ function parseFileDescriptor(value) {
|
|
|
15
15
|
};
|
|
16
16
|
if (!value || typeof value != "object" || Array.isArray(value)) return invalid9();
|
|
17
17
|
let f = value;
|
|
18
|
-
if (Object.keys(f).sort().join(",") !== "
|
|
19
|
-
let d = f.details;
|
|
20
|
-
if (d.kind === "other") {
|
|
21
|
-
if (Object.keys(d).length !== 1 || ![
|
|
22
|
-
"application/octet-stream",
|
|
23
|
-
"text/plain",
|
|
24
|
-
"text/markdown",
|
|
25
|
-
"application/json",
|
|
26
|
-
"image/png",
|
|
27
|
-
"image/jpeg"
|
|
28
|
-
].includes(f.mediaType)) return invalid9();
|
|
29
|
-
} else if (d.kind === "csv") {
|
|
30
|
-
if (Object.keys(d).sort().join(",") !== "dataRows,delimiter,encoding,headerRow,kind" || f.mediaType !== "text/csv" || !["utf-8", "windows-1252"].includes(d.encoding) || ![",", ";", " "].includes(d.delimiter) || !Number.isSafeInteger(d.headerRow) || d.headerRow < 1 || !Number.isSafeInteger(d.dataRows) || d.dataRows < 0) return invalid9();
|
|
31
|
-
} else if (d.kind === "pdf") {
|
|
32
|
-
if (f.mediaType !== "application/pdf" || Object.keys(d).some((key) => !["kind", "pages"].includes(key)) || "pages" in d && (!Number.isSafeInteger(d.pages) || d.pages < 1)) return invalid9();
|
|
33
|
-
} else return invalid9();
|
|
18
|
+
if (Object.keys(f).sort().join(",") !== "enrichments,id,mediaType,name,path,sha256,size" || typeof f.id != "string" || !FILE_ID_PATTERN.test(f.id) || !safeFileName(f.name) || !safeFilePath(f.path) || !Number.isSafeInteger(f.size) || f.size < 0 || f.size > FILE_ORIGINAL_MAX_BYTES || typeof f.sha256 != "string" || !/^[0-9a-f]{64}$/.test(f.sha256) || !f.enrichments || typeof f.enrichments != "object" || Array.isArray(f.enrichments) || !isCanonicalOriginalMediaType(f.mediaType)) return invalid9();
|
|
34
19
|
for (let [name2, descriptor] of Object.entries(f.enrichments)) {
|
|
35
20
|
if (!safeEnrichmentName(name2)) return invalid9();
|
|
36
21
|
parseEnrichmentDescriptor(descriptor);
|
|
@@ -67,10 +52,19 @@ function safeFilePath(value) {
|
|
|
67
52
|
function safeManagedFilePath(value) {
|
|
68
53
|
return safeFilePath(value) && value.split("/")[0].toLowerCase() !== ".os";
|
|
69
54
|
}
|
|
70
|
-
var ORIGINAL_MEDIA_TYPES = ["application/pdf", "text/plain", "text/markdown", "application/json", "image/png", "image/jpeg"];
|
|
71
55
|
function declaredOriginalMediaType(value) {
|
|
72
|
-
|
|
73
|
-
|
|
56
|
+
if (typeof value != "string" || value.length > 255 || /[\u0000-\u001f\u007f-\u009f]/.test(value))
|
|
57
|
+
throw new FileOperationError("invalid_input", 400);
|
|
58
|
+
let normalized = value.split(";", 1)[0].trim().toLowerCase(), token = "[a-z0-9!#$%&'+.^_`|~-]+";
|
|
59
|
+
if (!new RegExp(`^${token}/${token}$`).test(normalized)) throw new FileOperationError("invalid_input", 400);
|
|
60
|
+
return normalized;
|
|
61
|
+
}
|
|
62
|
+
function isCanonicalOriginalMediaType(value) {
|
|
63
|
+
try {
|
|
64
|
+
return declaredOriginalMediaType(value) === value;
|
|
65
|
+
} catch {
|
|
66
|
+
return !1;
|
|
67
|
+
}
|
|
74
68
|
}
|
|
75
69
|
function parseFileCreateMetadata(value, maxBytes) {
|
|
76
70
|
let invalid9 = () => {
|
|
@@ -78,26 +72,17 @@ function parseFileCreateMetadata(value, maxBytes) {
|
|
|
78
72
|
};
|
|
79
73
|
if (!value || typeof value != "object" || Array.isArray(value)) return invalid9();
|
|
80
74
|
let input = value;
|
|
81
|
-
if (Object.keys(input).some((key) => !["name", "path", "storage", "
|
|
75
|
+
if (Object.keys(input).some((key) => !["name", "path", "storage", "mediaType", "size", "requestKey"].includes(key))) return invalid9();
|
|
82
76
|
let path = input.path === void 0 ? "Files" : input.path;
|
|
83
|
-
if (!safeFileName(input.name) || !safeManagedFilePath(path) || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local"
|
|
77
|
+
if (!safeFileName(input.name) || !safeManagedFilePath(path) || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local") return invalid9();
|
|
78
|
+
let mediaType = input.mediaType === void 0 ? "application/octet-stream" : declaredOriginalMediaType(input.mediaType);
|
|
79
|
+
if (!Number.isSafeInteger(input.size) || input.size < 0) return invalid9();
|
|
84
80
|
if (input.size > maxBytes) throw new FileOperationError("request_too_large", 413);
|
|
85
|
-
|
|
86
|
-
let csv;
|
|
87
|
-
if (input.csv !== void 0) {
|
|
88
|
-
if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return invalid9();
|
|
89
|
-
let hints = input.csv;
|
|
90
|
-
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return invalid9();
|
|
91
|
-
let encoding = hints.encoding === void 0 ? "utf-8" : hints.encoding, delimiter = hints.delimiter === void 0 ? "," : hints.delimiter, headerRow = hints.headerRow === void 0 ? 1 : hints.headerRow;
|
|
92
|
-
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return invalid9();
|
|
93
|
-
csv = { encoding, delimiter, headerRow };
|
|
94
|
-
}
|
|
95
|
-
return {
|
|
81
|
+
return typeof input.requestKey != "string" || input.requestKey.length < 1 || input.requestKey.length > 256 || input.requestKey !== input.requestKey.trim() || /[\u0000-\u001f\u007f]/.test(input.requestKey) ? invalid9() : {
|
|
96
82
|
name: input.name,
|
|
97
83
|
path,
|
|
98
84
|
...input.storage ? { storage: input.storage } : {},
|
|
99
|
-
|
|
100
|
-
...csv ? { csv } : {},
|
|
85
|
+
mediaType,
|
|
101
86
|
size: input.size,
|
|
102
87
|
requestKey: input.requestKey
|
|
103
88
|
};
|
|
@@ -166,32 +151,11 @@ function natural(value, label, minimum = 0) {
|
|
|
166
151
|
}
|
|
167
152
|
function validateInboxFile(value) {
|
|
168
153
|
let v = object(serializable(value), "Inbox file");
|
|
169
|
-
keys(v, ["id", "name", "mediaType", "size", "sha256"
|
|
154
|
+
keys(v, ["id", "name", "mediaType", "size", "sha256"], "Inbox file");
|
|
170
155
|
let fileId = id(v.id, "Inbox file ID"), name2 = id(v.name, "filename"), mediaType = id(v.mediaType, "media type");
|
|
171
|
-
(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(fileId) || /[\x00-\x1f\x7f/\\]/.test(name2) ||
|
|
156
|
+
(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(fileId) || /[\x00-\x1f\x7f/\\]/.test(name2) || !isCanonicalOriginalMediaType(mediaType) || typeof v.sha256 != "string" || !/^[0-9a-f]{64}$/.test(v.sha256)) && fail("Invalid Inbox file identity or metadata");
|
|
172
157
|
let size = natural(v.size, "file size");
|
|
173
|
-
size > FILE_ORIGINAL_MAX_BYTES && fail("File exceeds supported size");
|
|
174
|
-
let d = object(v.details, "file details"), details;
|
|
175
|
-
switch (d.kind) {
|
|
176
|
-
case "csv":
|
|
177
|
-
keys(d, ["kind", "encoding", "delimiter", "headerRow", "dataRows"], "CSV details"), (mediaType !== "text/csv" || !["utf-8", "windows-1252"].includes(d.encoding) || ![",", ";", " "].includes(d.delimiter)) && fail("Invalid CSV details"), details = {
|
|
178
|
-
kind: "csv",
|
|
179
|
-
encoding: d.encoding,
|
|
180
|
-
delimiter: d.delimiter,
|
|
181
|
-
headerRow: natural(d.headerRow, "header row"),
|
|
182
|
-
dataRows: natural(d.dataRows, "data rows")
|
|
183
|
-
};
|
|
184
|
-
break;
|
|
185
|
-
case "pdf":
|
|
186
|
-
keys(d, ["kind", "pages"], "PDF details"), mediaType !== "application/pdf" && fail("Invalid PDF media type"), details = { kind: "pdf", ...d.pages === void 0 ? {} : { pages: natural(d.pages, "PDF pages", 1) } };
|
|
187
|
-
break;
|
|
188
|
-
case "other":
|
|
189
|
-
keys(d, ["kind"], "other file details"), ["text/csv", "application/pdf"].includes(mediaType) && fail("File type and details differ"), details = { kind: "other" };
|
|
190
|
-
break;
|
|
191
|
-
default:
|
|
192
|
-
return fail("Unknown file details kind");
|
|
193
|
-
}
|
|
194
|
-
return { id: fileId, name: name2, mediaType, size, sha256: v.sha256, details };
|
|
158
|
+
return size > FILE_ORIGINAL_MAX_BYTES && fail("File exceeds supported size"), { id: fileId, name: name2, mediaType, size, sha256: v.sha256 };
|
|
195
159
|
}
|
|
196
160
|
function fields(value) {
|
|
197
161
|
let result2 = array(value, "selected fields").map((entry) => {
|
|
@@ -258,8 +222,8 @@ function fileBlock(value) {
|
|
|
258
222
|
} catch {
|
|
259
223
|
return fail("Invalid shared File descriptor");
|
|
260
224
|
}
|
|
261
|
-
let { id: id3, name: name2, mediaType, size, sha256
|
|
262
|
-
return { id: id3, name: name2, mediaType, size, sha256
|
|
225
|
+
let { id: id3, name: name2, mediaType, size, sha256 } = file2;
|
|
226
|
+
return { id: id3, name: name2, mediaType, size, sha256 };
|
|
263
227
|
});
|
|
264
228
|
return validateBlock({ ...input, kind: "files", files: files3 });
|
|
265
229
|
}
|
|
@@ -1179,20 +1143,20 @@ function installMemberContext(resolve, retained = resolve) {
|
|
|
1179
1143
|
async function resolveAppContext(retained = !1) {
|
|
1180
1144
|
let host = memberContext;
|
|
1181
1145
|
if (!host) throw new Error("App context unavailable.");
|
|
1182
|
-
let
|
|
1183
|
-
if (host !== memberContext || !
|
|
1146
|
+
let context = await (retained ? retainedContext : host)();
|
|
1147
|
+
if (host !== memberContext || !context.isCurrent() || context.expiresAt <= Date.now() || context.kind !== "local" && (typeof context.accessToken != "string" || !/^[^\s]{1,8192}$/.test(context.accessToken)))
|
|
1184
1148
|
throw new Error("App context unavailable.");
|
|
1185
|
-
return
|
|
1149
|
+
return context;
|
|
1186
1150
|
}
|
|
1187
1151
|
async function resolveDataContext() {
|
|
1188
1152
|
try {
|
|
1189
1153
|
let host = memberContext;
|
|
1190
1154
|
if (host !== void 0) {
|
|
1191
|
-
let
|
|
1192
|
-
if (host !== memberContext || !
|
|
1193
|
-
if (
|
|
1194
|
-
if (!
|
|
1195
|
-
return checked(
|
|
1155
|
+
let context = await host();
|
|
1156
|
+
if (host !== memberContext || !context.isCurrent() || context.expiresAt <= Date.now()) throw new Error();
|
|
1157
|
+
if (context.kind === "local") return { local: context.requestData };
|
|
1158
|
+
if (!context || !Number.isFinite(context.expiresAt) || context.expiresAt <= Date.now() || typeof context.accessToken != "string" || !/^[^\s]{1,8192}$/.test(context.accessToken)) throw new Error();
|
|
1159
|
+
return checked(context.workspace, context.endpoint, { authorization: `Bearer ${context.accessToken}` });
|
|
1196
1160
|
}
|
|
1197
1161
|
throw new Error();
|
|
1198
1162
|
} catch {
|
|
@@ -1203,20 +1167,20 @@ async function resolveFilesContext() {
|
|
|
1203
1167
|
try {
|
|
1204
1168
|
let environment = {}, host = memberContext;
|
|
1205
1169
|
if (host) {
|
|
1206
|
-
let
|
|
1207
|
-
if (host !== memberContext || !
|
|
1208
|
-
if (
|
|
1209
|
-
url: `private:app:${
|
|
1170
|
+
let context = await host();
|
|
1171
|
+
if (host !== memberContext || !context.isCurrent() || context.expiresAt <= Date.now()) throw new Error();
|
|
1172
|
+
if (context.kind === "local") return {
|
|
1173
|
+
url: `private:app:${context.workspace}/${context.memberId}`,
|
|
1210
1174
|
headers: {},
|
|
1211
|
-
isCurrent:
|
|
1212
|
-
signal:
|
|
1175
|
+
isCurrent: context.isCurrent,
|
|
1176
|
+
signal: context.signal,
|
|
1213
1177
|
local: void 0,
|
|
1214
|
-
localFiles:
|
|
1178
|
+
localFiles: context.requestFiles
|
|
1215
1179
|
};
|
|
1216
|
-
if (!Number.isFinite(
|
|
1180
|
+
if (!Number.isFinite(context.expiresAt) || context.expiresAt <= Date.now() || typeof context.accessToken != "string" || !/^[^\s]{1,8192}$/.test(context.accessToken)) throw new Error();
|
|
1217
1181
|
return {
|
|
1218
|
-
...filesContext(
|
|
1219
|
-
isCurrent:
|
|
1182
|
+
...filesContext(context.workspace, context.endpoint, { authorization: `Bearer ${context.accessToken}` }),
|
|
1183
|
+
isCurrent: context.isCurrent,
|
|
1220
1184
|
local: void 0,
|
|
1221
1185
|
localFiles: void 0,
|
|
1222
1186
|
signal: void 0
|
|
@@ -1330,14 +1294,14 @@ function recordPagination(select) {
|
|
|
1330
1294
|
var genericData = {
|
|
1331
1295
|
repository(repository) {
|
|
1332
1296
|
async function send3(input) {
|
|
1333
|
-
let
|
|
1334
|
-
if (checkDataRequestSize(envelope), "local" in
|
|
1297
|
+
let context = await resolveDataContext(), envelope = { repository, ...input };
|
|
1298
|
+
if (checkDataRequestSize(envelope), "local" in context) return await context.local("data/query", envelope);
|
|
1335
1299
|
try {
|
|
1336
|
-
let response2 = await fetch(
|
|
1300
|
+
let response2 = await fetch(context.url, {
|
|
1337
1301
|
method: "POST",
|
|
1338
1302
|
redirect: "error",
|
|
1339
1303
|
cache: "no-store",
|
|
1340
|
-
headers: { "content-type": "application/json", ...
|
|
1304
|
+
headers: { "content-type": "application/json", ...context.headers },
|
|
1341
1305
|
body: JSON.stringify(envelope)
|
|
1342
1306
|
}), result2 = await response2.json();
|
|
1343
1307
|
if (!response2.ok)
|
|
@@ -1539,20 +1503,20 @@ async function result(response2, maximum = RESULT_BYTES) {
|
|
|
1539
1503
|
}
|
|
1540
1504
|
}
|
|
1541
1505
|
async function send(suffix, init2, descriptor, initial, parent) {
|
|
1542
|
-
let original = initial, checkCurrent = (
|
|
1506
|
+
let original = initial, checkCurrent = (context = original) => {
|
|
1543
1507
|
if (parent?.aborted) throw unavailable2();
|
|
1544
|
-
if (!original.isCurrent() ||
|
|
1508
|
+
if (!original.isCurrent() || context.url !== original.url) throw new FileOperationError("unsupported_context", 400);
|
|
1545
1509
|
};
|
|
1546
1510
|
for (let attempt = 0; attempt < ATTEMPTS; attempt++) {
|
|
1547
1511
|
checkCurrent();
|
|
1548
|
-
let
|
|
1549
|
-
checkCurrent(
|
|
1512
|
+
let context = await resolveFilesContext();
|
|
1513
|
+
checkCurrent(context);
|
|
1550
1514
|
try {
|
|
1551
|
-
let response2 =
|
|
1552
|
-
let url = `${
|
|
1515
|
+
let response2 = context.localFiles ? await context.localFiles(suffix, init2, parent) : await (async () => {
|
|
1516
|
+
let url = `${context.url}${suffix}`, request2 = {
|
|
1553
1517
|
...init2,
|
|
1554
1518
|
signal: parent,
|
|
1555
|
-
headers: { ...
|
|
1519
|
+
headers: { ...context.headers, ...init2.headers },
|
|
1556
1520
|
redirect: "error",
|
|
1557
1521
|
cache: "no-store"
|
|
1558
1522
|
};
|
|
@@ -1683,17 +1647,17 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1683
1647
|
}
|
|
1684
1648
|
}
|
|
1685
1649
|
async function operation(work, initial, parent) {
|
|
1686
|
-
let
|
|
1650
|
+
let context = initial ?? await resolveFilesContext();
|
|
1687
1651
|
if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
|
|
1688
1652
|
active++;
|
|
1689
1653
|
let execute = async (signal2) => {
|
|
1690
1654
|
try {
|
|
1691
|
-
return await work(
|
|
1655
|
+
return await work(context, signal2);
|
|
1692
1656
|
} finally {
|
|
1693
1657
|
active--;
|
|
1694
1658
|
}
|
|
1695
|
-
}, signal =
|
|
1696
|
-
return
|
|
1659
|
+
}, signal = context.signal && parent ? AbortSignal.any([context.signal, parent]) : context.signal ?? parent;
|
|
1660
|
+
return context.localFiles ? execute(signal ?? new AbortController().signal) : timed(execute, signal).catch((error) => {
|
|
1697
1661
|
throw error instanceof FileOperationError ? error : unavailable2();
|
|
1698
1662
|
});
|
|
1699
1663
|
}
|
|
@@ -1704,10 +1668,10 @@ function contentPath(id3, name2) {
|
|
|
1704
1668
|
return `${path}/enrichments/${encodeURIComponent(name2)}/content`;
|
|
1705
1669
|
}
|
|
1706
1670
|
async function read(id3, names) {
|
|
1707
|
-
let
|
|
1671
|
+
let context = await resolveFilesContext();
|
|
1708
1672
|
if (idPath(id3), names === void 0 || typeof names == "string") {
|
|
1709
1673
|
let path = contentPath(id3, names);
|
|
1710
|
-
return operation((
|
|
1674
|
+
return operation((context2, signal) => send(path, { method: "GET" }, !1, context2, signal), context);
|
|
1711
1675
|
}
|
|
1712
1676
|
if (!Array.isArray(names)) throw invalid7();
|
|
1713
1677
|
let distinct = [], seen = /* @__PURE__ */ new Set();
|
|
@@ -1723,10 +1687,10 @@ async function read(id3, names) {
|
|
|
1723
1687
|
let responses = {};
|
|
1724
1688
|
try {
|
|
1725
1689
|
for (let i = 0; i < paths.length; i++) {
|
|
1726
|
-
let response2 = await operation((
|
|
1690
|
+
let response2 = await operation((context2, signal) => send(paths[i], { method: "GET" }, !1, context2, signal), context, parent);
|
|
1727
1691
|
Object.defineProperty(responses, distinct[i], { value: response2, enumerable: !0 });
|
|
1728
1692
|
}
|
|
1729
|
-
if (!
|
|
1693
|
+
if (!context.isCurrent()) throw new FileOperationError("unsupported_context", 400);
|
|
1730
1694
|
return responses;
|
|
1731
1695
|
} catch (error) {
|
|
1732
1696
|
for (let response2 of Object.values(responses)) response2.body?.cancel().catch(() => {
|
|
@@ -1737,18 +1701,18 @@ async function read(id3, names) {
|
|
|
1737
1701
|
}
|
|
1738
1702
|
var files = {
|
|
1739
1703
|
delete(id3) {
|
|
1740
|
-
return operation((
|
|
1704
|
+
return operation((context, signal) => send(idPath(id3), { method: "DELETE" }, 204, context, signal));
|
|
1741
1705
|
},
|
|
1742
1706
|
async upload(id3) {
|
|
1743
|
-
return operation(async (
|
|
1744
|
-
let file2 = await send(`${idPath(id3)}/upload`, { method: "POST" }, !0,
|
|
1707
|
+
return operation(async (context, signal) => {
|
|
1708
|
+
let file2 = await send(`${idPath(id3)}/upload`, { method: "POST" }, !0, context, signal);
|
|
1745
1709
|
if (file2.id !== id3) throw unavailable2();
|
|
1746
1710
|
return file2;
|
|
1747
1711
|
});
|
|
1748
1712
|
},
|
|
1749
1713
|
async create(input, options) {
|
|
1750
|
-
let
|
|
1751
|
-
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "size", "path", "name", "storage", "
|
|
1714
|
+
let context = await resolveFilesContext();
|
|
1715
|
+
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "size", "path", "name", "storage", "mediaType"].includes(key)) || options !== void 0 && (!options || typeof options != "object" || Array.isArray(options) || Object.keys(options).some((key) => key !== "requestKey")))
|
|
1752
1716
|
throw invalid7();
|
|
1753
1717
|
let blob = input.file instanceof Blob, array3 = input.file instanceof Uint8Array, stream = input.file instanceof ReadableStream;
|
|
1754
1718
|
if (!blob && !array3 && !stream) throw invalid7();
|
|
@@ -1756,21 +1720,20 @@ var files = {
|
|
|
1756
1720
|
if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid7();
|
|
1757
1721
|
let name2 = input.name;
|
|
1758
1722
|
name2 === void 0 && blob && "name" in input.file && typeof input.file.name == "string" && (name2 = typeof globalThis.File < "u" && input.file instanceof globalThis.File ? input.file.name : input.file.name.split(/[\\/]/).at(-1));
|
|
1759
|
-
let
|
|
1723
|
+
let mediaType = declaredOriginalMediaType(input.mediaType === void 0 ? blob && input.file.type ? input.file.type : "application/octet-stream" : input.mediaType), metadata = parseFileCreateMetadata({
|
|
1760
1724
|
name: name2,
|
|
1761
1725
|
size: intrinsic ?? input.size,
|
|
1762
1726
|
path: input.path,
|
|
1763
1727
|
storage: input.storage,
|
|
1764
|
-
|
|
1765
|
-
...inputMediaType === void 0 ? {} : { inputMediaType },
|
|
1728
|
+
mediaType,
|
|
1766
1729
|
requestKey: options?.requestKey === void 0 ? routineTransport()?.key("files") ?? crypto.randomUUID() : options.requestKey
|
|
1767
1730
|
}, FILE_ORIGINAL_MAX_BYTES);
|
|
1768
|
-
if (!
|
|
1731
|
+
if (!context.local && !context.localFiles && metadata.storage === "local") throw new FileOperationError("unsupported_context", 400);
|
|
1769
1732
|
let header = encodeURIComponent(JSON.stringify(metadata));
|
|
1770
1733
|
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid7();
|
|
1771
1734
|
if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
|
|
1772
|
-
if (active++,
|
|
1773
|
-
let signal =
|
|
1735
|
+
if (active++, context.localFiles && !routineTransport() && metadata.size > MAX_BYTES) {
|
|
1736
|
+
let signal = context.signal ?? new AbortController().signal, file2 = input.file, offset = 0, body = file2 instanceof Blob ? context.signal ? file2 : file2.stream() : file2 instanceof ReadableStream ? file2 : new ReadableStream({
|
|
1774
1737
|
pull(controller) {
|
|
1775
1738
|
if (offset === file2.byteLength) {
|
|
1776
1739
|
controller.close();
|
|
@@ -1784,12 +1747,12 @@ var files = {
|
|
|
1784
1747
|
return await send("", { method: "POST", headers: {
|
|
1785
1748
|
"content-type": "application/octet-stream",
|
|
1786
1749
|
"x-os-file": header
|
|
1787
|
-
}, body }, !0,
|
|
1750
|
+
}, body }, !0, context, signal);
|
|
1788
1751
|
} finally {
|
|
1789
1752
|
active--;
|
|
1790
1753
|
}
|
|
1791
1754
|
}
|
|
1792
|
-
return metadata.size > MAX_BYTES ? multipartCreate(input, metadata, (suffix, init2, kind, signal) => kind === !0 ? send(suffix, init2, !0,
|
|
1755
|
+
return metadata.size > MAX_BYTES ? multipartCreate(input, metadata, (suffix, init2, kind, signal) => kind === !0 ? send(suffix, init2, !0, context, signal) : send(suffix, init2, "control", context, signal)) : timed(async (signal) => {
|
|
1793
1756
|
try {
|
|
1794
1757
|
let bytes = array3 ? input.file.slice() : await boundedBytes(
|
|
1795
1758
|
blob ? input.file.stream() : input.file,
|
|
@@ -1802,21 +1765,21 @@ var files = {
|
|
|
1802
1765
|
method: "POST",
|
|
1803
1766
|
headers: { "content-type": "application/octet-stream", "x-os-file": header },
|
|
1804
1767
|
body: bytes.buffer
|
|
1805
|
-
}, !0,
|
|
1768
|
+
}, !0, context, signal);
|
|
1806
1769
|
} finally {
|
|
1807
1770
|
active--;
|
|
1808
1771
|
}
|
|
1809
|
-
},
|
|
1772
|
+
}, context.signal).catch((error) => {
|
|
1810
1773
|
throw error instanceof FileOperationError ? error : unavailable2();
|
|
1811
1774
|
});
|
|
1812
1775
|
},
|
|
1813
1776
|
async enrich(input) {
|
|
1814
|
-
let
|
|
1777
|
+
let context = await resolveFilesContext();
|
|
1815
1778
|
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "name", "content", "mediaType", "replace"].includes(key)) || typeof input.content != "string" && !(input.content instanceof Uint8Array)) throw invalid7();
|
|
1816
1779
|
let path = `${idPath(input.file)}/enrichments`;
|
|
1817
1780
|
if (typeof input.content == "string" ? input.content.length > MAX_BYTES : input.content.byteLength > MAX_BYTES)
|
|
1818
1781
|
throw new FileOperationError("request_too_large", 413);
|
|
1819
|
-
return operation(async (
|
|
1782
|
+
return operation(async (context2, signal) => {
|
|
1820
1783
|
let bytes;
|
|
1821
1784
|
if (typeof input.content == "string") {
|
|
1822
1785
|
let buffer = new Uint8Array(Math.min(MAX_BYTES, input.content.length * 3)), encoded = new TextEncoder().encodeInto(input.content, buffer);
|
|
@@ -1833,13 +1796,13 @@ var files = {
|
|
|
1833
1796
|
let result2 = await send(path, { method: "POST", headers: {
|
|
1834
1797
|
"content-type": "application/octet-stream",
|
|
1835
1798
|
"x-os-enrichment": header
|
|
1836
|
-
}, body: bytes.buffer }, "enrichment",
|
|
1799
|
+
}, body: bytes.buffer }, "enrichment", context2, signal);
|
|
1837
1800
|
if (result2.name !== metadata.name) throw unavailable2();
|
|
1838
1801
|
return result2;
|
|
1839
|
-
},
|
|
1802
|
+
}, context);
|
|
1840
1803
|
},
|
|
1841
1804
|
async get(id3) {
|
|
1842
|
-
return operation((
|
|
1805
|
+
return operation((context, signal) => send(idPath(id3), { method: "GET" }, !0, context, signal));
|
|
1843
1806
|
},
|
|
1844
1807
|
read
|
|
1845
1808
|
};
|
|
@@ -2143,6 +2106,15 @@ async function reportLocalRoutineEffect(value) {
|
|
|
2143
2106
|
}
|
|
2144
2107
|
|
|
2145
2108
|
var local;
|
|
2109
|
+
async function localLease(identity, reportUse = !0) {
|
|
2110
|
+
let current2 = local;
|
|
2111
|
+
if (!current2 || !current2.declared.includes(identity)) throw new Error("Connection unavailable");
|
|
2112
|
+
reportUse && await current2.recheck(identity);
|
|
2113
|
+
let lease = current2.acquire ? parseConnectionLease(await current2.acquire(identity)) : current2.leases.find((lease2) => `${lease2.provider}/${lease2.name}` === identity);
|
|
2114
|
+
if (local !== current2 || !lease || lease.runId !== current2.runId || `${lease.provider}/${lease.name}` !== identity)
|
|
2115
|
+
throw new Error("Connection unavailable");
|
|
2116
|
+
return parseConnectionLease(lease);
|
|
2117
|
+
}
|
|
2146
2118
|
var airtable = /* @__PURE__ */ createConnections(async (name2, operation2, input) => {
|
|
2147
2119
|
throw new AirtableOperationError("Airtable connection unavailable");
|
|
2148
2120
|
});
|
|
@@ -2335,10 +2307,7 @@ function responseDefinition(value) {
|
|
|
2335
2307
|
assert(suggestions.length <= 8 && new Set(refs).size === refs.length);
|
|
2336
2308
|
}
|
|
2337
2309
|
function inboxFile(value) {
|
|
2338
|
-
|
|
2339
|
-
keys3(file2, ["id", "name", "mediaType", "size", "sha256", "details"]), assert(id2(file2.id) && text4(file2.name) && !/[\x00-\x1f\x7f/\\]/.test(file2.name) && text4(file2.mediaType) && /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(file2.mediaType) && integer(file2.size, 0) && file2.size <= 25 * 1024 * 1024 && typeof file2.sha256 == "string" && /^[0-9a-f]{64}$/.test(file2.sha256));
|
|
2340
|
-
let details = object4(file2.details);
|
|
2341
|
-
details.kind === "csv" ? (keys3(details, ["kind", "encoding", "delimiter", "headerRow", "dataRows"]), assert(file2.mediaType === "text/csv" && ["utf-8", "windows-1252"].includes(String(details.encoding)) && [",", ";", " "].includes(String(details.delimiter)) && integer(details.headerRow, 0) && integer(details.dataRows, 0))) : details.kind === "pdf" ? (keys3(details, ["kind", "pages"], ["kind"]), assert(file2.mediaType === "application/pdf" && (!("pages" in details) || integer(details.pages)))) : (keys3(details, ["kind"]), assert(details.kind === "other" && !["text/csv", "application/pdf"].includes(file2.mediaType)));
|
|
2310
|
+
validateInboxFile(value);
|
|
2342
2311
|
}
|
|
2343
2312
|
function fields4(value) {
|
|
2344
2313
|
let labels = array2(value).map((value2) => {
|
|
@@ -2583,15 +2552,15 @@ function hostedInboxContext() {
|
|
|
2583
2552
|
if (check(), (response2.status === 401 || response2.status === 403) && (installed2 = void 0, revision++, settled = Math.max(settled, started)), !response2.ok || response2.status !== 200) throw new InboxContextError(response2.status);
|
|
2584
2553
|
let bytes = await limitedBody(response2, 4096);
|
|
2585
2554
|
if (check(), !bytes) throw new Error("Inbox context unavailable");
|
|
2586
|
-
let
|
|
2587
|
-
if (
|
|
2588
|
-
if (JSON.stringify(installed2) !== JSON.stringify(
|
|
2555
|
+
let context = parseInboxHostContext(JSON.parse(new TextDecoder("utf-8", { fatal: !0 }).decode(bytes)));
|
|
2556
|
+
if (context.memberId !== host.memberId) throw new Error("Inbox context unavailable");
|
|
2557
|
+
if (JSON.stringify(installed2) !== JSON.stringify(context)) {
|
|
2589
2558
|
if (started < settled) throw new Error("Inbox context unavailable");
|
|
2590
|
-
installed2 =
|
|
2559
|
+
installed2 = context, revision++;
|
|
2591
2560
|
}
|
|
2592
2561
|
settled = Math.max(settled, started);
|
|
2593
2562
|
let current2 = revision;
|
|
2594
|
-
return Object.freeze({ context
|
|
2563
|
+
return Object.freeze({ context, isCurrent: () => host.isCurrent() && host.expiresAt > Date.now() && current2 === revision });
|
|
2595
2564
|
} finally {
|
|
2596
2565
|
response2.body?.cancel().catch(() => {
|
|
2597
2566
|
});
|
|
@@ -2895,7 +2864,7 @@ function appContext(origin, active2) {
|
|
|
2895
2864
|
await check(), admitted === credential && current2() && value && typeof value == "object" && "error" in value && value.error === "authority_unavailable" && invalidate();
|
|
2896
2865
|
}), response2;
|
|
2897
2866
|
}
|
|
2898
|
-
function
|
|
2867
|
+
function context() {
|
|
2899
2868
|
let issued = credential, signal = access.signal;
|
|
2900
2869
|
return {
|
|
2901
2870
|
kind: "local",
|
|
@@ -2926,24 +2895,24 @@ function appContext(origin, active2) {
|
|
|
2926
2895
|
}
|
|
2927
2896
|
if (expireAccess(), binding.expiresAt <= Date.now()) {
|
|
2928
2897
|
if (await renew(), !current2()) throw new AppRenewalUnavailable();
|
|
2929
|
-
return
|
|
2898
|
+
return context();
|
|
2930
2899
|
}
|
|
2931
2900
|
await synchronize();
|
|
2932
2901
|
let candidate = stored(), retained2 = readPair(candidate);
|
|
2933
2902
|
if (attempted = candidate ?? void 0, !current2()) throw new AppRenewalUnavailable();
|
|
2934
2903
|
let value = await proof(retained2.credential);
|
|
2935
2904
|
if (stored() !== candidate || serialized !== candidate)
|
|
2936
|
-
return await synchronize(),
|
|
2905
|
+
return await synchronize(), context();
|
|
2937
2906
|
if (!current2()) throw new Error();
|
|
2938
2907
|
if (expiry && binding && value.expiresAt > binding.expiresAt) throw new Error();
|
|
2939
|
-
return (!expiry || value.expiresAt !== binding.expiresAt) && install(value, retained2, candidate),
|
|
2908
|
+
return (!expiry || value.expiresAt !== binding.expiresAt) && install(value, retained2, candidate), context();
|
|
2940
2909
|
} catch (error) {
|
|
2941
2910
|
if (alive() && error instanceof AppRenewalUnavailable)
|
|
2942
2911
|
throw new Error();
|
|
2943
2912
|
try {
|
|
2944
|
-
if (binding && current2() && attempted && attempted !== serialized) return
|
|
2913
|
+
if (binding && current2() && attempted && attempted !== serialized) return context();
|
|
2945
2914
|
if (binding && alive() && stored() && stored() !== serialized)
|
|
2946
|
-
return await synchronize(),
|
|
2915
|
+
return await synchronize(), context();
|
|
2947
2916
|
} catch {
|
|
2948
2917
|
}
|
|
2949
2918
|
throw error instanceof AppContextDenied && binding && alive() && renewal ? new Error() : alive() && (error instanceof AppResponseReadError || pair && stored() === serialized && !current2()) ? new Error() : (invalidate(), new Error());
|
|
@@ -2955,7 +2924,7 @@ function appContext(origin, active2) {
|
|
|
2955
2924
|
if (!expiry && alive() && (binding ? current2() && resolution2 : readPair(stored()).context.expiresAt > Date.now()))
|
|
2956
2925
|
return resolve();
|
|
2957
2926
|
if (!expiry || !current2()) throw new Error("Local app context unavailable.");
|
|
2958
|
-
return
|
|
2927
|
+
return context();
|
|
2959
2928
|
}, start: () => {
|
|
2960
2929
|
startup = setTimeout(() => {
|
|
2961
2930
|
alive() && !resolution2 && !binding && resolve().catch(() => {
|
|
@@ -2978,23 +2947,23 @@ function validPair(value) {
|
|
|
2978
2947
|
}
|
|
2979
2948
|
|
|
2980
2949
|
var unavailable3 = () => new InboxOperationError(503, "unavailable"), stale = () => new InboxOperationError(401, "authority_unavailable");
|
|
2981
|
-
function hostFailure(error,
|
|
2982
|
-
return !
|
|
2950
|
+
function hostFailure(error, context) {
|
|
2951
|
+
return !context.isCurrent() || context.expiresAt <= Date.now() || error instanceof InboxContextError && error.status === 401 ? stale() : error instanceof InboxContextError && error.status === 403 ? new InboxOperationError(403, "access_denied") : unavailable3();
|
|
2983
2952
|
}
|
|
2984
2953
|
async function send2(operation2, input, admitted) {
|
|
2985
|
-
let envelope = parseInboxRequest({ operation: operation2, input }),
|
|
2954
|
+
let envelope = parseInboxRequest({ operation: operation2, input }), context;
|
|
2986
2955
|
try {
|
|
2987
|
-
|
|
2956
|
+
context = admitted ?? await resolveAppContext();
|
|
2988
2957
|
} catch {
|
|
2989
2958
|
throw stale();
|
|
2990
2959
|
}
|
|
2991
|
-
if (
|
|
2960
|
+
if (context.kind === "local") {
|
|
2992
2961
|
if (!isAppQuestionOperation(operation2)) throw new InboxOperationError(403, "access_denied");
|
|
2993
2962
|
let check2 = () => {
|
|
2994
|
-
if (!
|
|
2963
|
+
if (!context.isCurrent() || context.signal.aborted || context.expiresAt <= Date.now()) throw stale();
|
|
2995
2964
|
};
|
|
2996
2965
|
try {
|
|
2997
|
-
let response2 = await
|
|
2966
|
+
let response2 = await context.requestInbox(operation2, envelope.input), value = await appResponse(response2, INBOX_RESULT_BYTES, context.signal);
|
|
2998
2967
|
if (check2(), !response2.ok) throw new InboxOperationError(
|
|
2999
2968
|
[400, 401, 403, 409].includes(response2.status) ? response2.status : 503,
|
|
3000
2969
|
response2.status === 400 ? "invalid_input" : response2.status === 401 ? "authority_unavailable" : response2.status === 403 ? "access_denied" : response2.status === 409 ? "conflict" : "unavailable"
|
|
@@ -3007,25 +2976,25 @@ async function send2(operation2, input, admitted) {
|
|
|
3007
2976
|
throw check2(), error instanceof InboxOperationError ? error : unavailable3();
|
|
3008
2977
|
}
|
|
3009
2978
|
}
|
|
3010
|
-
if (
|
|
2979
|
+
if (context.endpoint !== `https://${context.workspace}.oddington.ai` || ["auth", "www", "api", "os"].includes(context.workspace)) throw stale();
|
|
3011
2980
|
let host;
|
|
3012
2981
|
if (!isAppQuestionOperation(operation2)) {
|
|
3013
2982
|
try {
|
|
3014
|
-
host = await resolveHostedInboxContext(
|
|
2983
|
+
host = await resolveHostedInboxContext(context);
|
|
3015
2984
|
} catch (error) {
|
|
3016
|
-
throw hostFailure(error,
|
|
2985
|
+
throw hostFailure(error, context);
|
|
3017
2986
|
}
|
|
3018
2987
|
if (!host) throw unavailable3();
|
|
3019
2988
|
}
|
|
3020
2989
|
let check = () => {
|
|
3021
|
-
if (!
|
|
2990
|
+
if (!context.isCurrent() || host && !host.isCurrent() || !Number.isFinite(context.expiresAt) || context.expiresAt <= Date.now()) throw stale();
|
|
3022
2991
|
};
|
|
3023
2992
|
if (check(), host?.context.kind === "focused")
|
|
3024
2993
|
throw new InboxOperationError(403, "access_denied");
|
|
3025
2994
|
try {
|
|
3026
|
-
let response2 = await fetch(`${
|
|
2995
|
+
let response2 = await fetch(`${context.endpoint}/api/inbox`, {
|
|
3027
2996
|
method: "POST",
|
|
3028
|
-
headers: { authorization: `Bearer ${
|
|
2997
|
+
headers: { authorization: `Bearer ${context.accessToken}`, "content-type": "application/json" },
|
|
3029
2998
|
body: JSON.stringify(envelope),
|
|
3030
2999
|
redirect: "error",
|
|
3031
3000
|
cache: "no-store",
|
|
@@ -3077,7 +3046,7 @@ async function send2(operation2, input, admitted) {
|
|
|
3077
3046
|
let bytes = await limitedBody(response2, INBOX_RESULT_BYTES);
|
|
3078
3047
|
if (check(), !bytes) throw unavailable3();
|
|
3079
3048
|
let value = JSON.parse(new TextDecoder("utf-8", { fatal: !0 }).decode(bytes)), parsed = parseInboxResult(operation2, value);
|
|
3080
|
-
if (check(), operation2 === "current" && parsed.workspace.slug !==
|
|
3049
|
+
if (check(), operation2 === "current" && parsed.workspace.slug !== context.workspace) throw unavailable3();
|
|
3081
3050
|
if ("itemId" in envelope.input) {
|
|
3082
3051
|
let item = operation2 === "items.read" ? parsed : operation2 === "items.rename" || operation2 === "items.setLifecycle" || operation2 === "items.addRecipient" ? parsed.item : void 0;
|
|
3083
3052
|
if (item && (item.id !== envelope.input.itemId || "revision" in envelope.input && item.revision !== envelope.input.revision) || operation2 === "items.addRecipient" && parsed.addedPersonId !== envelope.input.personId || operation2 === "questions.answer" && typeof envelope.input.response.selection == "object" && !parsed.label?.trim()) throw unavailable3();
|
|
@@ -3700,56 +3669,56 @@ var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/, uuid2 = /^[0-9a-f]{8}-[0
|
|
|
3700
3669
|
}, fail3 = (reason) => {
|
|
3701
3670
|
throw new AppRoutineError(reason);
|
|
3702
3671
|
};
|
|
3703
|
-
function current(
|
|
3704
|
-
(!
|
|
3672
|
+
function current(context) {
|
|
3673
|
+
(!context.isCurrent() || context.kind === "local" && context.signal.aborted) && fail3("authority_unavailable");
|
|
3705
3674
|
}
|
|
3706
3675
|
function appDescriptors() {
|
|
3707
3676
|
return globalThis[/* @__PURE__ */ Symbol.for("oddington.app.descriptor")]?.routines ?? [];
|
|
3708
3677
|
}
|
|
3709
3678
|
async function authority(retained = !1) {
|
|
3710
|
-
let
|
|
3711
|
-
return current(
|
|
3679
|
+
let context = await resolveAppContext(retained).catch(() => fail3("authority_unavailable"));
|
|
3680
|
+
return current(context), context.kind !== "local" && (!context.binding || !context.memberId || !identifier.test(context.workspace) || context.workspace.length > 63 || ["auth", "api", "os", "www"].includes(context.workspace) || context.endpoint !== `https://${context.workspace}.oddington.ai`) && fail3("authority_unavailable"), context;
|
|
3712
3681
|
}
|
|
3713
|
-
async function live(
|
|
3714
|
-
if (current(
|
|
3682
|
+
async function live(context, read2) {
|
|
3683
|
+
if (current(context), context.kind === "local") return context;
|
|
3715
3684
|
let resolved = await authority(read2);
|
|
3716
|
-
return current(
|
|
3685
|
+
return current(context), (resolved.kind === "local" || resolved.binding !== context.binding || resolved.memberId !== context.memberId || resolved.workspace !== context.workspace || resolved.endpoint !== context.endpoint) && fail3("authority_unavailable"), resolved;
|
|
3717
3686
|
}
|
|
3718
3687
|
async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained, read2 = !1) {
|
|
3719
3688
|
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable");
|
|
3720
|
-
let
|
|
3721
|
-
current(
|
|
3722
|
-
let deadline = new AbortController(), timeout =
|
|
3689
|
+
let context = retained ? await live(retained, read2) : await authority(read2);
|
|
3690
|
+
current(context);
|
|
3691
|
+
let deadline = new AbortController(), timeout = context.kind === "local" ? void 0 : setTimeout(() => deadline.abort(), 2e4);
|
|
3723
3692
|
try {
|
|
3724
|
-
let response2 = await (
|
|
3693
|
+
let response2 = await (context.kind === "local" ? read2 ? context.requestRetainedRoutine(key, suffix) : context.requestRoutine(key, suffix, init2) : fetch(`${context.endpoint}/api/routines/${key}/${suffix}`, {
|
|
3725
3694
|
...init2,
|
|
3726
3695
|
credentials: "omit",
|
|
3727
3696
|
redirect: "error",
|
|
3728
3697
|
signal: deadline.signal,
|
|
3729
|
-
headers: { authorization: `Bearer ${
|
|
3698
|
+
headers: { authorization: `Bearer ${context.accessToken}`, ...init2?.body ? { "content-type": "application/json" } : {} }
|
|
3730
3699
|
}));
|
|
3731
3700
|
response2.redirected && fail3("execution_unavailable");
|
|
3732
|
-
let value = await appResponse(response2, maximum,
|
|
3733
|
-
if (current(
|
|
3734
|
-
if (
|
|
3701
|
+
let value = await appResponse(response2, maximum, context.kind === "local" ? context.signal : deadline.signal);
|
|
3702
|
+
if (current(context), context.kind !== "local" && await live(context, read2), !response2.ok) {
|
|
3703
|
+
if (context.kind !== "local") {
|
|
3735
3704
|
let code = value?.code;
|
|
3736
3705
|
if ((code === "authentication_required" || code === "access_denied") && fail3("authority_unavailable"), (code === "input_invalid" || code === "file_not_remote") && fail3("invalid_input"), suffix === "describe" && (code === "current_deployment_unavailable" || code === "capability_unavailable"))
|
|
3737
3706
|
return unavailable4(key, code === "current_deployment_unavailable" ? "not_deployed" : "capability_unavailable");
|
|
3738
3707
|
fail3("execution_unavailable");
|
|
3739
3708
|
}
|
|
3740
3709
|
let reason = value?.error;
|
|
3741
|
-
reason === "authority_unavailable" && (
|
|
3710
|
+
reason === "authority_unavailable" && (context.kind === "local" && context.invalidate(), fail3(reason)), (reason === "invalid_input" || reason === "execution_unavailable") && fail3(reason), fail3("execution_unavailable");
|
|
3742
3711
|
}
|
|
3743
3712
|
return value;
|
|
3744
3713
|
} catch (error) {
|
|
3745
|
-
if (current(
|
|
3714
|
+
if (current(context), error instanceof AppRoutineError) throw error;
|
|
3746
3715
|
fail3("execution_unavailable");
|
|
3747
3716
|
} finally {
|
|
3748
3717
|
clearTimeout(timeout);
|
|
3749
3718
|
}
|
|
3750
3719
|
}
|
|
3751
|
-
function summary(value, key,
|
|
3752
|
-
if (
|
|
3720
|
+
function summary(value, key, context, id3) {
|
|
3721
|
+
if (context.kind !== "local")
|
|
3753
3722
|
try {
|
|
3754
3723
|
return (!only(value, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure") || !Array.isArray(value.steps) || value.steps.some((step) => !only(step, "id,title,status,startedAt,finishedAt,summary,detailAvailable")) || value.failure !== void 0 && !only(value.failure, "message")) && fail3("execution_unavailable"), parseRemoteRun(value, { routine: key, id: id3 });
|
|
3755
3724
|
} catch {
|
|
@@ -3788,17 +3757,17 @@ function jsonInput(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
|
3788
3757
|
function structure(value) {
|
|
3789
3758
|
return JSON.stringify(value, (_key, item) => item && typeof item == "object" && !Array.isArray(item) ? Object.fromEntries(Object.keys(item).sort().map((key) => [key, item[key]])) : item);
|
|
3790
3759
|
}
|
|
3791
|
-
function handle(key, id3,
|
|
3760
|
+
function handle(key, id3, context) {
|
|
3792
3761
|
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable"), (typeof id3 != "string" || !uuid2.test(id3)) && fail3("invalid_input");
|
|
3793
|
-
let read2 = async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES,
|
|
3762
|
+
let read2 = async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES, context, !0), key, context, id3);
|
|
3794
3763
|
return routineRunHandle({
|
|
3795
3764
|
async current() {
|
|
3796
|
-
return current(
|
|
3765
|
+
return current(context), read2();
|
|
3797
3766
|
},
|
|
3798
3767
|
async step(step) {
|
|
3799
3768
|
(typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
|
|
3800
|
-
let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024,
|
|
3801
|
-
if (
|
|
3769
|
+
let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024, context, !0);
|
|
3770
|
+
if (context.kind !== "local")
|
|
3802
3771
|
try {
|
|
3803
3772
|
return only(value, "id,title,status,startedAt,finishedAt,summary,data") || fail3("execution_unavailable"), parseRunStep(value, step);
|
|
3804
3773
|
} catch {
|
|
@@ -3807,7 +3776,7 @@ function handle(key, id3, context2) {
|
|
|
3807
3776
|
return (!only(value, "id,title,status,startedAt,finishedAt,summary,data") || value.id !== step || !validStep(value)) && fail3("execution_unavailable"), value;
|
|
3808
3777
|
},
|
|
3809
3778
|
async publish() {
|
|
3810
|
-
return
|
|
3779
|
+
return context.kind !== "local" && fail3("execution_unavailable"), summary(await request(key, `runs/${id3}/publish`, { method: "POST" }, SUMMARY_BYTES, context), key, context, id3);
|
|
3811
3780
|
}
|
|
3812
3781
|
});
|
|
3813
3782
|
}
|
|
@@ -3832,8 +3801,8 @@ async function describeAppRoutine(key) {
|
|
|
3832
3801
|
let descriptor = appDescriptors().find((item) => item.id === key);
|
|
3833
3802
|
if (!descriptor) return fail3("authority_unavailable");
|
|
3834
3803
|
try {
|
|
3835
|
-
let
|
|
3836
|
-
return
|
|
3804
|
+
let context = await authority(), value = await request(key, "describe", void 0, 1024 * 1024, context);
|
|
3805
|
+
return context.kind !== "local" && deployedDescription(value, key), (!only(value, "id,title,input,connections,steps,readiness") || !value.readiness || !Array.isArray(value.connections) || context.kind === "local" && structure({ ...value, readiness: void 0, connections: value.connections.map(({ available, ...item }) => item) }) !== structure(descriptor) || value.connections.some((item) => typeof item.available != "boolean") || !(value.readiness.state === "ready" && only(value.readiness, "state,placement") && value.readiness.placement === (context.kind === "local" ? "local" : "remote") || value.readiness.state === "unavailable" && only(value.readiness, "state,reason,message") && ["not_deployed", "definition_invalid", "capability_unavailable"].includes(value.readiness.reason) && message(value.readiness.message))) && fail3("execution_unavailable"), value;
|
|
3837
3806
|
} catch {
|
|
3838
3807
|
return unavailable4(key, "capability_unavailable");
|
|
3839
3808
|
}
|
|
@@ -3854,16 +3823,16 @@ function appRoutineBinding(key) {
|
|
|
3854
3823
|
} catch {
|
|
3855
3824
|
return fail3("invalid_input");
|
|
3856
3825
|
}
|
|
3857
|
-
let
|
|
3858
|
-
|
|
3859
|
-
let run = summary(await request(key, "runs", { method: "POST", body: encoded }, SUMMARY_BYTES,
|
|
3860
|
-
return handle(key, run.id,
|
|
3826
|
+
let context = await authority();
|
|
3827
|
+
context.kind !== "local" && (encoded = JSON.stringify({ ...JSON.parse(encoded), startKey: crypto.randomUUID() }));
|
|
3828
|
+
let run = summary(await request(key, "runs", { method: "POST", body: encoded }, SUMMARY_BYTES, context), key, context);
|
|
3829
|
+
return handle(key, run.id, context);
|
|
3861
3830
|
},
|
|
3862
3831
|
runs: Object.freeze({
|
|
3863
3832
|
async list() {
|
|
3864
|
-
let
|
|
3833
|
+
let context = await authority(!0), value = await request(key, "runs", void 0, 20 * SUMMARY_BYTES, context, !0);
|
|
3865
3834
|
if (!Array.isArray(value) || value.length > 20) return fail3("execution_unavailable");
|
|
3866
|
-
let runs = value.map((run) => summary(run, key,
|
|
3835
|
+
let runs = value.map((run) => summary(run, key, context));
|
|
3867
3836
|
return new Set(runs.map((run) => run.id)).size !== runs.length && fail3("execution_unavailable"), runs;
|
|
3868
3837
|
},
|
|
3869
3838
|
async get(id3) {
|
|
@@ -3887,24 +3856,11 @@ var app = /* @__PURE__ */ Object.freeze({
|
|
|
3887
3856
|
})
|
|
3888
3857
|
});
|
|
3889
3858
|
|
|
3890
|
-
var LIMIT2 = 16 * 1024, context;
|
|
3891
|
-
var appRun = {
|
|
3892
|
-
current() {
|
|
3893
|
-
return context;
|
|
3894
|
-
}
|
|
3895
|
-
};
|
|
3896
|
-
|
|
3897
3859
|
function validateFileAddOptions(value) {
|
|
3898
3860
|
let v = serializable(value);
|
|
3899
|
-
if (!v || typeof v != "object" || Array.isArray(v) || Object.keys(v).some((k) => !["path", "name"
|
|
3861
|
+
if (!v || typeof v != "object" || Array.isArray(v) || Object.keys(v).some((k) => !["path", "name"].includes(k)) || typeof v.path != "string" || !v.path || v.path !== v.path.trim() || /[\\\x00-\x1f]/.test(v.path) || v.path.split("/").some((part) => !part || part === "." || part === "..") || /^[A-Za-z]:/.test(v.path))
|
|
3900
3862
|
throw new InboxContractError("File path must be relative to the configured working root");
|
|
3901
3863
|
if (v.name !== void 0 && (typeof v.name != "string" || !v.name || v.name !== v.name.trim() || v.name.length > 255 || /[\x00-\x1f\x7f/\\]/.test(v.name))) throw new InboxContractError("File name must be a safe filename");
|
|
3902
|
-
return v.csv !== void 0 && validateCsvHints(v.csv), v;
|
|
3903
|
-
}
|
|
3904
|
-
function validateCsvHints(value) {
|
|
3905
|
-
let v = serializable(value);
|
|
3906
|
-
if (!v || typeof v != "object" || Array.isArray(v) || Object.keys(v).some((k) => !["encoding", "delimiter", "headerRow"].includes(k)) || v.encoding !== void 0 && !["utf-8", "windows-1252"].includes(v.encoding) || v.delimiter !== void 0 && ![",", ";", " "].includes(v.delimiter) || v.headerRow !== void 0 && (!Number.isSafeInteger(v.headerRow) || v.headerRow < 0))
|
|
3907
|
-
throw new InboxContractError("Invalid CSV parsing hints");
|
|
3908
3864
|
return v;
|
|
3909
3865
|
}
|
|
3910
3866
|
|
|
@@ -3994,7 +3950,6 @@ export {
|
|
|
3994
3950
|
InboxOperationError,
|
|
3995
3951
|
RoutineRecordWriteError,
|
|
3996
3952
|
app,
|
|
3997
|
-
appRun,
|
|
3998
3953
|
asksBlock,
|
|
3999
3954
|
auth,
|
|
4000
3955
|
connections,
|