@tinycloud/cli 1.0.1-beta.5 → 1.1.0-beta.7
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/dist/index.js +2147 -1809
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +1868 -378
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +5 -5
- package/skills/tc-cli/AUTH.md +13 -0
- package/skills/tc-cli/REFERENCE.md +19 -6
- package/skills/tc-cli/SKILL.md +5 -1
package/dist/legacy-entry.js
CHANGED
|
@@ -14,11 +14,11 @@ var __export = (target, all) => {
|
|
|
14
14
|
for (var name in all)
|
|
15
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
16
|
};
|
|
17
|
-
var __copyProps = (to,
|
|
18
|
-
if (
|
|
19
|
-
for (let key of __getOwnPropNames(
|
|
17
|
+
var __copyProps = (to, from4, except, desc) => {
|
|
18
|
+
if (from4 && typeof from4 === "object" || typeof from4 === "function") {
|
|
19
|
+
for (let key of __getOwnPropNames(from4))
|
|
20
20
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
-
__defProp(to, key, { get: () =>
|
|
21
|
+
__defProp(to, key, { get: () => from4[key], enumerable: !(desc = __getOwnPropDesc(from4, key)) || desc.enumerable });
|
|
22
22
|
}
|
|
23
23
|
return to;
|
|
24
24
|
};
|
|
@@ -163,10 +163,10 @@ import ora from "ora";
|
|
|
163
163
|
function outputJson(data) {
|
|
164
164
|
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
165
165
|
}
|
|
166
|
-
function outputError(
|
|
166
|
+
function outputError(code3, message, hint) {
|
|
167
167
|
if (isInteractive()) {
|
|
168
168
|
process.stderr.write(
|
|
169
|
-
`${theme.error("\u2717")} ${theme.label(
|
|
169
|
+
`${theme.error("\u2717")} ${theme.label(code3)}: ${message}
|
|
170
170
|
`
|
|
171
171
|
);
|
|
172
172
|
if (hint) {
|
|
@@ -177,7 +177,7 @@ function outputError(code2, message, hint) {
|
|
|
177
177
|
}
|
|
178
178
|
} else {
|
|
179
179
|
const payload = {
|
|
180
|
-
error: { code:
|
|
180
|
+
error: { code: code3, message }
|
|
181
181
|
};
|
|
182
182
|
if (hint) payload.error.hint = hint;
|
|
183
183
|
process.stderr.write(JSON.stringify(payload, null, 2) + "\n");
|
|
@@ -380,9 +380,9 @@ var init_errors = __esm({
|
|
|
380
380
|
init_constants();
|
|
381
381
|
init_formatter();
|
|
382
382
|
CLIError = class extends Error {
|
|
383
|
-
constructor(
|
|
383
|
+
constructor(code3, message, exitCode = ExitCode.ERROR, metadata) {
|
|
384
384
|
super(message);
|
|
385
|
-
this.code =
|
|
385
|
+
this.code = code3;
|
|
386
386
|
this.exitCode = exitCode;
|
|
387
387
|
this.metadata = metadata;
|
|
388
388
|
this.name = "CLIError";
|
|
@@ -1325,12 +1325,12 @@ var init_md = __esm({
|
|
|
1325
1325
|
_cloneInto(to) {
|
|
1326
1326
|
to || (to = new this.constructor());
|
|
1327
1327
|
to.set(...this.get());
|
|
1328
|
-
const { blockLen, buffer, length:
|
|
1328
|
+
const { blockLen, buffer, length: length4, finished, destroyed, pos } = this;
|
|
1329
1329
|
to.destroyed = destroyed;
|
|
1330
1330
|
to.finished = finished;
|
|
1331
|
-
to.length =
|
|
1331
|
+
to.length = length4;
|
|
1332
1332
|
to.pos = pos;
|
|
1333
|
-
if (
|
|
1333
|
+
if (length4 % blockLen)
|
|
1334
1334
|
to.buffer.set(buffer);
|
|
1335
1335
|
return to;
|
|
1336
1336
|
}
|
|
@@ -1728,11 +1728,11 @@ var require_decrypt_transport_response_error = __commonJS({
|
|
|
1728
1728
|
for (var name in all)
|
|
1729
1729
|
__defProp3(target, name, { get: all[name], enumerable: true });
|
|
1730
1730
|
};
|
|
1731
|
-
var __copyProps2 = (to,
|
|
1732
|
-
if (
|
|
1733
|
-
for (let key of __getOwnPropNames2(
|
|
1731
|
+
var __copyProps2 = (to, from4, except, desc) => {
|
|
1732
|
+
if (from4 && typeof from4 === "object" || typeof from4 === "function") {
|
|
1733
|
+
for (let key of __getOwnPropNames2(from4))
|
|
1734
1734
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
1735
|
-
__defProp3(to, key, { get: () =>
|
|
1735
|
+
__defProp3(to, key, { get: () => from4[key], enumerable: !(desc = __getOwnPropDesc2(from4, key)) || desc.enumerable });
|
|
1736
1736
|
}
|
|
1737
1737
|
return to;
|
|
1738
1738
|
};
|
|
@@ -1779,7 +1779,7 @@ import {
|
|
|
1779
1779
|
profileStoreMetadataPath,
|
|
1780
1780
|
readAdditionalDelegations,
|
|
1781
1781
|
readAuthRequests,
|
|
1782
|
-
|
|
1782
|
+
updateProfileStore,
|
|
1783
1783
|
withProfileLock as withProfileLock2,
|
|
1784
1784
|
writeJsonAtomic
|
|
1785
1785
|
} from "@tinycloud/operations/state";
|
|
@@ -3322,8 +3322,8 @@ function isValidJWT(jwt, alg) {
|
|
|
3322
3322
|
const [header] = jwt.split(".");
|
|
3323
3323
|
if (!header)
|
|
3324
3324
|
return false;
|
|
3325
|
-
const
|
|
3326
|
-
const decoded = JSON.parse(atob(
|
|
3325
|
+
const base643 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
|
|
3326
|
+
const decoded = JSON.parse(atob(base643));
|
|
3327
3327
|
if (typeof decoded !== "object" || decoded === null)
|
|
3328
3328
|
return false;
|
|
3329
3329
|
if ("typ" in decoded && decoded?.typ !== "JWT")
|
|
@@ -5977,23 +5977,23 @@ var ZodEffects = class extends ZodType {
|
|
|
5977
5977
|
}
|
|
5978
5978
|
if (effect.type === "transform") {
|
|
5979
5979
|
if (ctx.common.async === false) {
|
|
5980
|
-
const
|
|
5980
|
+
const base4 = this._def.schema._parseSync({
|
|
5981
5981
|
data: ctx.data,
|
|
5982
5982
|
path: ctx.path,
|
|
5983
5983
|
parent: ctx
|
|
5984
5984
|
});
|
|
5985
|
-
if (!isValid(
|
|
5985
|
+
if (!isValid(base4))
|
|
5986
5986
|
return INVALID;
|
|
5987
|
-
const result = effect.transform(
|
|
5987
|
+
const result = effect.transform(base4.value, checkCtx);
|
|
5988
5988
|
if (result instanceof Promise) {
|
|
5989
5989
|
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
|
5990
5990
|
}
|
|
5991
5991
|
return { status: status.value, value: result };
|
|
5992
5992
|
} else {
|
|
5993
|
-
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((
|
|
5994
|
-
if (!isValid(
|
|
5993
|
+
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base4) => {
|
|
5994
|
+
if (!isValid(base4))
|
|
5995
5995
|
return INVALID;
|
|
5996
|
-
return Promise.resolve(effect.transform(
|
|
5996
|
+
return Promise.resolve(effect.transform(base4.value, checkCtx)).then((result) => ({
|
|
5997
5997
|
status: status.value,
|
|
5998
5998
|
value: result
|
|
5999
5999
|
}));
|
|
@@ -6432,9 +6432,9 @@ function ok(data) {
|
|
|
6432
6432
|
function err(error) {
|
|
6433
6433
|
return { ok: false, error };
|
|
6434
6434
|
}
|
|
6435
|
-
function serviceError(
|
|
6435
|
+
function serviceError(code3, message, service, options) {
|
|
6436
6436
|
return {
|
|
6437
|
-
code:
|
|
6437
|
+
code: code3,
|
|
6438
6438
|
message,
|
|
6439
6439
|
service,
|
|
6440
6440
|
cause: options?.cause,
|
|
@@ -7678,10 +7678,10 @@ var KVService = class extends BaseService {
|
|
|
7678
7678
|
errorText
|
|
7679
7679
|
);
|
|
7680
7680
|
}
|
|
7681
|
-
const
|
|
7681
|
+
const code3 = response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;
|
|
7682
7682
|
return err(
|
|
7683
7683
|
serviceError(
|
|
7684
|
-
|
|
7684
|
+
code3,
|
|
7685
7685
|
`Failed to create signed read URL for key ${JSON.stringify(key)}: ${response.status} - ${errorText}`,
|
|
7686
7686
|
"kv",
|
|
7687
7687
|
{ meta: { status: response.status, statusText: response.statusText } }
|
|
@@ -12896,18 +12896,18 @@ function expandVaultPermissionEntry(entry) {
|
|
|
12896
12896
|
const byBase = /* @__PURE__ */ new Map();
|
|
12897
12897
|
for (const action of entry.actions) {
|
|
12898
12898
|
const expansion = vaultActionExpansion(action);
|
|
12899
|
-
for (const
|
|
12900
|
-
const actions = byBase.get(
|
|
12899
|
+
for (const base4 of expansion.bases) {
|
|
12900
|
+
const actions = byBase.get(base4) ?? [];
|
|
12901
12901
|
if (!actions.includes(expansion.action)) {
|
|
12902
12902
|
actions.push(expansion.action);
|
|
12903
12903
|
}
|
|
12904
|
-
byBase.set(
|
|
12904
|
+
byBase.set(base4, actions);
|
|
12905
12905
|
}
|
|
12906
12906
|
}
|
|
12907
|
-
return [...byBase.entries()].map(([
|
|
12907
|
+
return [...byBase.entries()].map(([base4, actions]) => ({
|
|
12908
12908
|
...entry,
|
|
12909
12909
|
service: "tinycloud.kv",
|
|
12910
|
-
path: vaultKVPath(
|
|
12910
|
+
path: vaultKVPath(base4, entry.path),
|
|
12911
12911
|
actions,
|
|
12912
12912
|
skipPrefix: true
|
|
12913
12913
|
}));
|
|
@@ -12950,9 +12950,9 @@ function normalizeVaultAction(action) {
|
|
|
12950
12950
|
}
|
|
12951
12951
|
return action;
|
|
12952
12952
|
}
|
|
12953
|
-
function vaultKVPath(
|
|
12953
|
+
function vaultKVPath(base4, path) {
|
|
12954
12954
|
const normalized = path.startsWith("/") ? path.slice(1) : path;
|
|
12955
|
-
return `${
|
|
12955
|
+
return `${base4}/${normalized}`;
|
|
12956
12956
|
}
|
|
12957
12957
|
function cloneResourceCapability(entry) {
|
|
12958
12958
|
return {
|
|
@@ -13123,17 +13123,15 @@ function didWithoutFragment(did) {
|
|
|
13123
13123
|
async function loadAdditionalDelegations(profile) {
|
|
13124
13124
|
return readAdditionalDelegations(profile);
|
|
13125
13125
|
}
|
|
13126
|
-
async function
|
|
13127
|
-
await
|
|
13126
|
+
async function appendAdditionalDelegations(profile, entries) {
|
|
13127
|
+
const { mergeDelegationsWithoutRequest } = await import("@tinycloud/operations/delegation-binding");
|
|
13128
|
+
await updateProfileStore(profile, "additional-delegations", (stored) => ({
|
|
13129
|
+
records: mergeDelegationsWithoutRequest(stored, entries.map((entry) => ({ ...entry }))),
|
|
13130
|
+
result: void 0
|
|
13131
|
+
}));
|
|
13128
13132
|
}
|
|
13129
13133
|
async function appendAdditionalDelegation(profile, entry) {
|
|
13130
|
-
await
|
|
13131
|
-
profile,
|
|
13132
|
-
"additional-delegations",
|
|
13133
|
-
entry.delegation.cid,
|
|
13134
|
-
entry,
|
|
13135
|
-
(candidate) => candidate.delegation.cid
|
|
13136
|
-
);
|
|
13134
|
+
await appendAdditionalDelegations(profile, [entry]);
|
|
13137
13135
|
}
|
|
13138
13136
|
async function loadPermissionRequestArtifacts(profile) {
|
|
13139
13137
|
const raw = await readAuthRequests(profile);
|
|
@@ -13147,9 +13145,6 @@ async function appendPermissionRequestArtifact(profile, artifact) {
|
|
|
13147
13145
|
await writeSharedRecords(profile, "auth-requests", next);
|
|
13148
13146
|
});
|
|
13149
13147
|
}
|
|
13150
|
-
async function replaceSharedRecords(profile, store, entries) {
|
|
13151
|
-
await withProfileLock2(profile, () => writeSharedRecords(profile, store, entries));
|
|
13152
|
-
}
|
|
13153
13148
|
async function writeSharedRecords(profile, store, entries) {
|
|
13154
13149
|
const path = store === "additional-delegations" ? additionalDelegationsPath(profile) : permissionRequestsPath(profile);
|
|
13155
13150
|
await writeJsonAtomic(path, entries);
|
|
@@ -13163,13 +13158,48 @@ async function getLastPermissionRequestArtifact(profile) {
|
|
|
13163
13158
|
const existing = await loadPermissionRequestArtifacts(profile);
|
|
13164
13159
|
return existing.at(-1) ?? null;
|
|
13165
13160
|
}
|
|
13166
|
-
async function replayAdditionalDelegations(node, profile) {
|
|
13161
|
+
async function replayAdditionalDelegations(node, profile, options) {
|
|
13162
|
+
const {
|
|
13163
|
+
operationSpaceResolver,
|
|
13164
|
+
prepareStoredDelegationReplay,
|
|
13165
|
+
replayStoredDelegation,
|
|
13166
|
+
storedDelegationKind
|
|
13167
|
+
} = await import("@tinycloud/operations/delegation-binding");
|
|
13168
|
+
const activator = node;
|
|
13169
|
+
const migrated = await prepareStoredDelegationReplay(profile, activator, {
|
|
13170
|
+
host: options.host,
|
|
13171
|
+
migrate: options.migrate
|
|
13172
|
+
});
|
|
13173
|
+
const resolveSpace = operationSpaceResolver(node, options.ownerSpace);
|
|
13167
13174
|
const entries = await loadAdditionalDelegations(profile);
|
|
13168
|
-
for (const
|
|
13175
|
+
for (const stored of entries) {
|
|
13176
|
+
const kind = storedDelegationKind(stored);
|
|
13177
|
+
if (kind === "compact" || kind === "signed-login") {
|
|
13178
|
+
const installed = await replayStoredDelegation(activator, stored, {
|
|
13179
|
+
host: options.host,
|
|
13180
|
+
migrated,
|
|
13181
|
+
resolveSpace
|
|
13182
|
+
});
|
|
13183
|
+
if (installed === void 0 && process.env.TC_DEBUG_REPLAY === "1") {
|
|
13184
|
+
process.stderr.write("[replay] skipping a stored delegation refused by validation or its request binding\n");
|
|
13185
|
+
}
|
|
13186
|
+
continue;
|
|
13187
|
+
}
|
|
13188
|
+
if (kind === "refused") {
|
|
13189
|
+
if (process.env.TC_DEBUG_REPLAY === "1") {
|
|
13190
|
+
process.stderr.write("[replay] skipping a malformed stored record or one bound to a request it cannot be held to\n");
|
|
13191
|
+
}
|
|
13192
|
+
continue;
|
|
13193
|
+
}
|
|
13194
|
+
const entry = stored;
|
|
13169
13195
|
const expiry = entry.delegation.expiry instanceof Date ? entry.delegation.expiry : new Date(entry.delegation.expiry);
|
|
13170
13196
|
if (expiry.getTime() <= Date.now()) continue;
|
|
13171
13197
|
try {
|
|
13172
|
-
await node.useRuntimeDelegation({
|
|
13198
|
+
await node.useRuntimeDelegation({
|
|
13199
|
+
...entry.delegation,
|
|
13200
|
+
delegationHeader: { Authorization: entry.delegation.delegationHeader.Authorization },
|
|
13201
|
+
expiry
|
|
13202
|
+
});
|
|
13173
13203
|
} catch (err2) {
|
|
13174
13204
|
if (process.env.TC_DEBUG_REPLAY === "1") {
|
|
13175
13205
|
process.stderr.write(`[replay] skipping ${entry.delegation.cid}: ${err2.message}
|
|
@@ -13474,6 +13504,7 @@ async function createSDKInstance(ctx, options) {
|
|
|
13474
13504
|
host: ctx.host,
|
|
13475
13505
|
privateKey: effectivePrivateKey
|
|
13476
13506
|
});
|
|
13507
|
+
let restoredOwnSession2 = false;
|
|
13477
13508
|
if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
|
|
13478
13509
|
await node2.restoreSession({
|
|
13479
13510
|
delegationHeader: session.delegationHeader,
|
|
@@ -13486,16 +13517,22 @@ async function createSDKInstance(ctx, options) {
|
|
|
13486
13517
|
siwe: session.siwe,
|
|
13487
13518
|
signature: session.signature
|
|
13488
13519
|
});
|
|
13520
|
+
restoredOwnSession2 = true;
|
|
13489
13521
|
} else {
|
|
13490
13522
|
await node2.signIn();
|
|
13491
13523
|
}
|
|
13492
|
-
await replayAdditionalDelegations(node2, ctx.profile
|
|
13524
|
+
await replayAdditionalDelegations(node2, ctx.profile, {
|
|
13525
|
+
host: ctx.host,
|
|
13526
|
+
ownerSpace: profile.spaceId,
|
|
13527
|
+
migrate: restoredOwnSession2 && options?.privateKey === void 0
|
|
13528
|
+
});
|
|
13493
13529
|
return node2;
|
|
13494
13530
|
}
|
|
13495
13531
|
const node = new TinyCloudNode({
|
|
13496
13532
|
host: ctx.host,
|
|
13497
13533
|
privateKey: options?.privateKey
|
|
13498
13534
|
});
|
|
13535
|
+
let restoredOwnSession = false;
|
|
13499
13536
|
if (options?.privateKey) {
|
|
13500
13537
|
await node.signIn();
|
|
13501
13538
|
} else if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
|
|
@@ -13510,8 +13547,13 @@ async function createSDKInstance(ctx, options) {
|
|
|
13510
13547
|
siwe: session.siwe,
|
|
13511
13548
|
signature: session.signature
|
|
13512
13549
|
});
|
|
13550
|
+
restoredOwnSession = true;
|
|
13513
13551
|
}
|
|
13514
|
-
await replayAdditionalDelegations(node, ctx.profile
|
|
13552
|
+
await replayAdditionalDelegations(node, ctx.profile, {
|
|
13553
|
+
host: ctx.host,
|
|
13554
|
+
ownerSpace: profile?.spaceId,
|
|
13555
|
+
migrate: restoredOwnSession
|
|
13556
|
+
});
|
|
13515
13557
|
return node;
|
|
13516
13558
|
}
|
|
13517
13559
|
async function bootstrapDelegatedSession(ctx, delegation) {
|
|
@@ -13605,7 +13647,7 @@ async function ensureAuthenticated(ctx, options) {
|
|
|
13605
13647
|
}
|
|
13606
13648
|
const profile = await ProfileManager.getProfile(ctx.profile).catch(() => null);
|
|
13607
13649
|
if (profile?.authMethod === "local" && profile.privateKey) {
|
|
13608
|
-
return createSDKInstance(ctx
|
|
13650
|
+
return createSDKInstance(ctx);
|
|
13609
13651
|
}
|
|
13610
13652
|
const session = await ProfileManager.getSession(ctx.profile);
|
|
13611
13653
|
if (!session) {
|
|
@@ -14018,8 +14060,8 @@ function buildAuthUrl(did, options = {}) {
|
|
|
14018
14060
|
params.set("expiry", String(options.expiry));
|
|
14019
14061
|
}
|
|
14020
14062
|
params.set("protocolVersion", "1");
|
|
14021
|
-
const
|
|
14022
|
-
return `${
|
|
14063
|
+
const base4 = options.openkeyHost ?? DEFAULT_OPENKEY_HOST;
|
|
14064
|
+
return `${base4}/delegate?${params.toString()}`;
|
|
14023
14065
|
}
|
|
14024
14066
|
function validateDelegationCallbackPayload(value) {
|
|
14025
14067
|
if (!value || typeof value !== "object") return "expected an object";
|
|
@@ -14989,20 +15031,20 @@ async function acquireDeviceDelegation(input) {
|
|
|
14989
15031
|
}
|
|
14990
15032
|
const startValue = await responseJson(startResponse);
|
|
14991
15033
|
if (!startResponse.ok) {
|
|
14992
|
-
const
|
|
15034
|
+
const code3 = errorCode(startValue);
|
|
14993
15035
|
const description = errorDescription(startValue);
|
|
14994
|
-
if (startResponse.status === 429 &&
|
|
15036
|
+
if (startResponse.status === 429 && code3 === "rate_limited") {
|
|
14995
15037
|
throw deviceAuthRateLimit(startResponse);
|
|
14996
15038
|
}
|
|
14997
|
-
if (
|
|
15039
|
+
if (code3 === "invalid_scope") {
|
|
14998
15040
|
throw new CLIError(
|
|
14999
15041
|
"SCOPE_REJECTED",
|
|
15000
15042
|
`OpenKey rejected the requested scope${description ? `: ${description}` : "."} Remove that capability from the manifest or use another approval flow.`,
|
|
15001
15043
|
ExitCode.PERMISSION_DENIED,
|
|
15002
|
-
{ openkeyError:
|
|
15044
|
+
{ openkeyError: code3, ...description ? { capability: description } : {} }
|
|
15003
15045
|
);
|
|
15004
15046
|
}
|
|
15005
|
-
throw new CLIError("DEVICE_AUTH_FAILED", `OpenKey device authorization failed: ${
|
|
15047
|
+
throw new CLIError("DEVICE_AUTH_FAILED", `OpenKey device authorization failed: ${code3 ?? `HTTP ${startResponse.status}`}${description ? ` (${description})` : ""}`, ExitCode.ERROR);
|
|
15006
15048
|
}
|
|
15007
15049
|
const started = validateStart(startValue, openkeyHost);
|
|
15008
15050
|
const deadline = Date.now() + started.expiresIn * 1e3;
|
|
@@ -15030,20 +15072,20 @@ async function acquireDeviceDelegation(input) {
|
|
|
15030
15072
|
continue;
|
|
15031
15073
|
}
|
|
15032
15074
|
const value = await responseJson(response);
|
|
15033
|
-
const
|
|
15034
|
-
if (response.status >= 500 || response.status === 429 &&
|
|
15035
|
-
if (
|
|
15075
|
+
const code3 = errorCode(value);
|
|
15076
|
+
if (response.status >= 500 || response.status === 429 && code3 !== "slow_down") continue;
|
|
15077
|
+
if (code3 === "slow_down") {
|
|
15036
15078
|
interval += 5;
|
|
15037
15079
|
continue;
|
|
15038
15080
|
}
|
|
15039
|
-
if (
|
|
15040
|
-
if (
|
|
15081
|
+
if (code3 === "authorization_pending") continue;
|
|
15082
|
+
if (code3 === "access_denied") {
|
|
15041
15083
|
throw new CLIError("DEVICE_AUTH_DENIED", "The owner denied the OpenKey device authorization. No session was saved.", ExitCode.PERMISSION_DENIED);
|
|
15042
15084
|
}
|
|
15043
|
-
if (
|
|
15085
|
+
if (code3 === "expired_token") {
|
|
15044
15086
|
throw new CLIError("DEVICE_AUTH_EXPIRED", "OpenKey device authorization expired_token: the approval window closed. Run the command again.", ExitCode.AUTH_REQUIRED);
|
|
15045
15087
|
}
|
|
15046
|
-
if (!response.ok) throw new CLIError("DEVICE_AUTH_FAILED", `OpenKey device authorization failed: ${
|
|
15088
|
+
if (!response.ok) throw new CLIError("DEVICE_AUTH_FAILED", `OpenKey device authorization failed: ${code3 ?? `HTTP ${response.status}`}`, ExitCode.ERROR);
|
|
15047
15089
|
const result = value;
|
|
15048
15090
|
if (result?.status === "pending") {
|
|
15049
15091
|
interval = Math.max(interval, Number.isSafeInteger(result.interval) ? result.interval : interval);
|
|
@@ -15496,6 +15538,15 @@ function registerAuthCommand(program) {
|
|
|
15496
15538
|
return;
|
|
15497
15539
|
}
|
|
15498
15540
|
const imported = normalizeDelegationImport(parsed);
|
|
15541
|
+
const { activateUnboundCompactImport, storedDelegationKind } = await import("@tinycloud/operations/delegation-binding");
|
|
15542
|
+
const kind = storedDelegationKind({ delegation: imported.delegation });
|
|
15543
|
+
if (kind === "refused") {
|
|
15544
|
+
throw new CLIError(
|
|
15545
|
+
"INVALID_AUTH_IMPORT",
|
|
15546
|
+
"Imported delegation must carry exactly one string Authorization header.",
|
|
15547
|
+
ExitCode.USAGE_ERROR
|
|
15548
|
+
);
|
|
15549
|
+
}
|
|
15499
15550
|
let node;
|
|
15500
15551
|
try {
|
|
15501
15552
|
node = await ensureAuthenticated(ctx);
|
|
@@ -15505,18 +15556,33 @@ function registerAuthCommand(program) {
|
|
|
15505
15556
|
if (session || resolveProfilePosture(profile) !== "delegate-session") throw error;
|
|
15506
15557
|
node = (await bootstrapDelegatedSession(ctx, imported.delegation)).node;
|
|
15507
15558
|
}
|
|
15508
|
-
await appendAdditionalDelegation(ctx.profile, storedAdditionalDelegation(
|
|
15509
|
-
imported.delegation,
|
|
15510
|
-
imported.permissions
|
|
15511
|
-
));
|
|
15512
15559
|
const targetsSessionKey = typeof imported.delegation.delegateDID === "string" && principalDidEquals(imported.delegation.delegateDID, node.sessionDid);
|
|
15513
15560
|
let activated = false;
|
|
15514
|
-
|
|
15515
|
-
|
|
15561
|
+
let permissions = imported.permissions;
|
|
15562
|
+
if (targetsSessionKey && kind === "compact") {
|
|
15563
|
+
const record = await activateUnboundCompactImport(
|
|
15564
|
+
node,
|
|
15565
|
+
imported.delegation,
|
|
15566
|
+
ctx.host
|
|
15567
|
+
);
|
|
15568
|
+
await appendAdditionalDelegation(ctx.profile, record);
|
|
15569
|
+
permissions = record.permissions;
|
|
15516
15570
|
activated = true;
|
|
15571
|
+
} else {
|
|
15572
|
+
await appendAdditionalDelegation(ctx.profile, storedAdditionalDelegation(
|
|
15573
|
+
imported.delegation,
|
|
15574
|
+
imported.permissions
|
|
15575
|
+
));
|
|
15576
|
+
if (targetsSessionKey) {
|
|
15577
|
+
await node.useRuntimeDelegation({
|
|
15578
|
+
...imported.delegation,
|
|
15579
|
+
delegationHeader: { Authorization: imported.delegation.delegationHeader.Authorization }
|
|
15580
|
+
});
|
|
15581
|
+
activated = true;
|
|
15582
|
+
}
|
|
15517
15583
|
}
|
|
15518
15584
|
await appendGrantHistory(ctx.profile, {
|
|
15519
|
-
addedCaps:
|
|
15585
|
+
addedCaps: permissions,
|
|
15520
15586
|
source: "cli",
|
|
15521
15587
|
delegationCid: imported.delegation.cid,
|
|
15522
15588
|
expiry: imported.delegation.expiry.toISOString()
|
|
@@ -15527,7 +15593,7 @@ function registerAuthCommand(program) {
|
|
|
15527
15593
|
kind: "tinycloud.auth.delegation",
|
|
15528
15594
|
requestId: imported.requestId ?? null,
|
|
15529
15595
|
delegationCid: imported.delegation.cid,
|
|
15530
|
-
permissions
|
|
15596
|
+
permissions,
|
|
15531
15597
|
expiry: imported.delegation.expiry.toISOString()
|
|
15532
15598
|
});
|
|
15533
15599
|
} catch (error) {
|
|
@@ -15901,8 +15967,6 @@ async function activateAndStoreOpenKeyGrants(profileName, node, grants, source)
|
|
|
15901
15967
|
for (const { delegation } of grants) await node.useRuntimeDelegation(delegation);
|
|
15902
15968
|
if (grants.length === 0) return;
|
|
15903
15969
|
await ProfileManager.withLock(profileName, async () => {
|
|
15904
|
-
const existing = await loadAdditionalDelegations(profileName);
|
|
15905
|
-
const replacing = new Set(grants.map(({ delegation }) => delegation.cid));
|
|
15906
15970
|
for (const { delegation, effective } of grants) {
|
|
15907
15971
|
await appendGrantHistory(profileName, {
|
|
15908
15972
|
addedCaps: effective,
|
|
@@ -15911,10 +15975,10 @@ async function activateAndStoreOpenKeyGrants(profileName, node, grants, source)
|
|
|
15911
15975
|
expiry: delegation.expiry.toISOString()
|
|
15912
15976
|
});
|
|
15913
15977
|
}
|
|
15914
|
-
await
|
|
15915
|
-
|
|
15916
|
-
|
|
15917
|
-
|
|
15978
|
+
await appendAdditionalDelegations(
|
|
15979
|
+
profileName,
|
|
15980
|
+
grants.map(({ delegation, effective }) => storedAdditionalDelegation(delegation, effective))
|
|
15981
|
+
);
|
|
15918
15982
|
});
|
|
15919
15983
|
}
|
|
15920
15984
|
async function ensureDelegationAuthority(params) {
|
|
@@ -15996,7 +16060,7 @@ function execCapturedCommand(command) {
|
|
|
15996
16060
|
stdio: "inherit"
|
|
15997
16061
|
});
|
|
15998
16062
|
child.on("error", reject);
|
|
15999
|
-
child.on("exit", (
|
|
16063
|
+
child.on("exit", (code3, signal) => {
|
|
16000
16064
|
if (signal) {
|
|
16001
16065
|
reject(new CLIError(
|
|
16002
16066
|
"COMMAND_SIGNAL",
|
|
@@ -16005,8 +16069,8 @@ function execCapturedCommand(command) {
|
|
|
16005
16069
|
));
|
|
16006
16070
|
return;
|
|
16007
16071
|
}
|
|
16008
|
-
if (
|
|
16009
|
-
process.exitCode =
|
|
16072
|
+
if (code3 && code3 !== 0) {
|
|
16073
|
+
process.exitCode = code3;
|
|
16010
16074
|
}
|
|
16011
16075
|
resolve4();
|
|
16012
16076
|
});
|
|
@@ -17088,8 +17152,8 @@ function storageQuotaError(error) {
|
|
|
17088
17152
|
}
|
|
17089
17153
|
function assertAddressableKey(key) {
|
|
17090
17154
|
for (let i = 0; i < key.length; i++) {
|
|
17091
|
-
const
|
|
17092
|
-
if (
|
|
17155
|
+
const code3 = key.charCodeAt(i);
|
|
17156
|
+
if (code3 <= 32 || code3 === 127) {
|
|
17093
17157
|
throw new CLIError("USAGE_ERROR", "KV keys cannot contain spaces or control characters; use a URL-safe key", ExitCode.USAGE_ERROR);
|
|
17094
17158
|
}
|
|
17095
17159
|
}
|
|
@@ -17919,8 +17983,8 @@ async function writeSecretFile(path, value) {
|
|
|
17919
17983
|
if (created) {
|
|
17920
17984
|
await rm3(temp, { force: true }).catch(() => void 0);
|
|
17921
17985
|
}
|
|
17922
|
-
const
|
|
17923
|
-
throw new CLIError("ERROR", `Could not write secret output "${path}"${
|
|
17986
|
+
const code3 = error instanceof Error && "code" in error && typeof error.code === "string" ? ` (${error.code})` : "";
|
|
17987
|
+
throw new CLIError("ERROR", `Could not write secret output "${path}"${code3}.`, ExitCode.ERROR);
|
|
17924
17988
|
}
|
|
17925
17989
|
try {
|
|
17926
17990
|
const parent = await open2(parentPath, "r");
|
|
@@ -18058,8 +18122,8 @@ function shouldRequestSecretPermissions(error) {
|
|
|
18058
18122
|
function thrownPermissionError(error) {
|
|
18059
18123
|
const record = error;
|
|
18060
18124
|
const message = typeof record?.message === "string" ? record.message : String(error);
|
|
18061
|
-
const
|
|
18062
|
-
if (
|
|
18125
|
+
const code3 = typeof record?.code === "string" ? record.code : "PERMISSION_DENIED";
|
|
18126
|
+
if (code3 !== "PERMISSION_DENIED" && !/permission|session expired|autosign|capabilit/i.test(message)) {
|
|
18063
18127
|
return null;
|
|
18064
18128
|
}
|
|
18065
18129
|
return {
|
|
@@ -18267,9 +18331,9 @@ async function resolveDelegatedSecretSource(source, secretPath, space = SECRETS_
|
|
|
18267
18331
|
return { ...selected, source };
|
|
18268
18332
|
}
|
|
18269
18333
|
function mapEncryptionResultError(error) {
|
|
18270
|
-
const
|
|
18271
|
-
const exitCode =
|
|
18272
|
-
return new CLIError(
|
|
18334
|
+
const code3 = error.code || "DECRYPTION_FAILED";
|
|
18335
|
+
const exitCode = code3 === "PERMISSION_DENIED" ? ExitCode.PERMISSION_DENIED : code3 === "NOT_FOUND" ? ExitCode.NOT_FOUND : code3 === "NETWORK_ERROR" || code3 === "TRANSPORT_ERROR" ? ExitCode.NETWORK_ERROR : ExitCode.ERROR;
|
|
18336
|
+
return new CLIError(code3, error.message, exitCode);
|
|
18273
18337
|
}
|
|
18274
18338
|
function parseDecryptedSecretPayload(data, secretPath) {
|
|
18275
18339
|
const text = new TextDecoder().decode(data);
|
|
@@ -18803,13 +18867,13 @@ function _abool2(value, title = "") {
|
|
|
18803
18867
|
}
|
|
18804
18868
|
return value;
|
|
18805
18869
|
}
|
|
18806
|
-
function _abytes2(value,
|
|
18870
|
+
function _abytes2(value, length4, title = "") {
|
|
18807
18871
|
const bytes = isBytes(value);
|
|
18808
18872
|
const len = value?.length;
|
|
18809
|
-
const needsLen =
|
|
18810
|
-
if (!bytes || needsLen && len !==
|
|
18873
|
+
const needsLen = length4 !== void 0;
|
|
18874
|
+
if (!bytes || needsLen && len !== length4) {
|
|
18811
18875
|
const prefix = title && `"${title}" `;
|
|
18812
|
-
const ofLen = needsLen ? ` of length ${
|
|
18876
|
+
const ofLen = needsLen ? ` of length ${length4}` : "";
|
|
18813
18877
|
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
18814
18878
|
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
18815
18879
|
}
|
|
@@ -19332,15 +19396,15 @@ var wNAF = class {
|
|
|
19332
19396
|
const { windows, windowSize } = calcWOpts(W, this.bits);
|
|
19333
19397
|
const points = [];
|
|
19334
19398
|
let p = point;
|
|
19335
|
-
let
|
|
19399
|
+
let base4 = p;
|
|
19336
19400
|
for (let window = 0; window < windows; window++) {
|
|
19337
|
-
|
|
19338
|
-
points.push(
|
|
19401
|
+
base4 = p;
|
|
19402
|
+
points.push(base4);
|
|
19339
19403
|
for (let i = 1; i < windowSize; i++) {
|
|
19340
|
-
|
|
19341
|
-
points.push(
|
|
19404
|
+
base4 = base4.add(p);
|
|
19405
|
+
points.push(base4);
|
|
19342
19406
|
}
|
|
19343
|
-
p =
|
|
19407
|
+
p = base4.double();
|
|
19344
19408
|
}
|
|
19345
19409
|
return points;
|
|
19346
19410
|
}
|
|
@@ -20360,13 +20424,13 @@ var BLAKE2 = class extends Hash {
|
|
|
20360
20424
|
return res;
|
|
20361
20425
|
}
|
|
20362
20426
|
_cloneInto(to) {
|
|
20363
|
-
const { buffer, length:
|
|
20427
|
+
const { buffer, length: length4, finished, destroyed, outputLen, pos } = this;
|
|
20364
20428
|
to || (to = new this.constructor({ dkLen: outputLen }));
|
|
20365
20429
|
to.set(...this.get());
|
|
20366
20430
|
to.buffer.set(buffer);
|
|
20367
20431
|
to.destroyed = destroyed;
|
|
20368
20432
|
to.finished = finished;
|
|
20369
|
-
to.length =
|
|
20433
|
+
to.length = length4;
|
|
20370
20434
|
to.pos = pos;
|
|
20371
20435
|
to.outputLen = outputLen;
|
|
20372
20436
|
return to;
|
|
@@ -21600,8 +21664,8 @@ function isValidJWT2(jwt, alg) {
|
|
|
21600
21664
|
const [header] = jwt.split(".");
|
|
21601
21665
|
if (!header)
|
|
21602
21666
|
return false;
|
|
21603
|
-
const
|
|
21604
|
-
const decoded = JSON.parse(atob(
|
|
21667
|
+
const base6422 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
|
|
21668
|
+
const decoded = JSON.parse(atob(base6422));
|
|
21605
21669
|
if (typeof decoded !== "object" || decoded === null)
|
|
21606
21670
|
return false;
|
|
21607
21671
|
if ("typ" in decoded && decoded?.typ !== "JWT")
|
|
@@ -24255,23 +24319,23 @@ var ZodEffects2 = class extends ZodType2 {
|
|
|
24255
24319
|
}
|
|
24256
24320
|
if (effect.type === "transform") {
|
|
24257
24321
|
if (ctx.common.async === false) {
|
|
24258
|
-
const
|
|
24322
|
+
const base33 = this._def.schema._parseSync({
|
|
24259
24323
|
data: ctx.data,
|
|
24260
24324
|
path: ctx.path,
|
|
24261
24325
|
parent: ctx
|
|
24262
24326
|
});
|
|
24263
|
-
if (!isValid2(
|
|
24327
|
+
if (!isValid2(base33))
|
|
24264
24328
|
return INVALID2;
|
|
24265
|
-
const result = effect.transform(
|
|
24329
|
+
const result = effect.transform(base33.value, checkCtx);
|
|
24266
24330
|
if (result instanceof Promise) {
|
|
24267
24331
|
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
|
24268
24332
|
}
|
|
24269
24333
|
return { status: status.value, value: result };
|
|
24270
24334
|
} else {
|
|
24271
|
-
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((
|
|
24272
|
-
if (!isValid2(
|
|
24335
|
+
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base33) => {
|
|
24336
|
+
if (!isValid2(base33))
|
|
24273
24337
|
return INVALID2;
|
|
24274
|
-
return Promise.resolve(effect.transform(
|
|
24338
|
+
return Promise.resolve(effect.transform(base33.value, checkCtx)).then((result) => ({
|
|
24275
24339
|
status: status.value,
|
|
24276
24340
|
value: result
|
|
24277
24341
|
}));
|
|
@@ -25179,9 +25243,9 @@ var cache = /* @__PURE__ */ new WeakMap();
|
|
|
25179
25243
|
function baseCache(cid2) {
|
|
25180
25244
|
const baseCache22 = cache.get(cid2);
|
|
25181
25245
|
if (baseCache22 == null) {
|
|
25182
|
-
const
|
|
25183
|
-
cache.set(cid2,
|
|
25184
|
-
return
|
|
25246
|
+
const baseCache32 = /* @__PURE__ */ new Map();
|
|
25247
|
+
cache.set(cid2, baseCache32);
|
|
25248
|
+
return baseCache32;
|
|
25185
25249
|
}
|
|
25186
25250
|
return baseCache22;
|
|
25187
25251
|
}
|
|
@@ -26419,7 +26483,7 @@ function base2(ALPHABET, name) {
|
|
|
26419
26483
|
var LEADER = ALPHABET.charAt(0);
|
|
26420
26484
|
var FACTOR = Math.log(BASE) / Math.log(256);
|
|
26421
26485
|
var iFACTOR = Math.log(256) / Math.log(BASE);
|
|
26422
|
-
function
|
|
26486
|
+
function encode52(source) {
|
|
26423
26487
|
if (source instanceof Uint8Array)
|
|
26424
26488
|
;
|
|
26425
26489
|
else if (ArrayBuffer.isView(source)) {
|
|
@@ -26434,7 +26498,7 @@ function base2(ALPHABET, name) {
|
|
|
26434
26498
|
return "";
|
|
26435
26499
|
}
|
|
26436
26500
|
var zeroes = 0;
|
|
26437
|
-
var
|
|
26501
|
+
var length32 = 0;
|
|
26438
26502
|
var pbegin = 0;
|
|
26439
26503
|
var pend = source.length;
|
|
26440
26504
|
while (pbegin !== pend && source[pbegin] === 0) {
|
|
@@ -26446,7 +26510,7 @@ function base2(ALPHABET, name) {
|
|
|
26446
26510
|
while (pbegin !== pend) {
|
|
26447
26511
|
var carry = source[pbegin];
|
|
26448
26512
|
var i2 = 0;
|
|
26449
|
-
for (var it1 = size - 1; (carry !== 0 || i2 <
|
|
26513
|
+
for (var it1 = size - 1; (carry !== 0 || i2 < length32) && it1 !== -1; it1--, i2++) {
|
|
26450
26514
|
carry += 256 * b58[it1] >>> 0;
|
|
26451
26515
|
b58[it1] = carry % BASE >>> 0;
|
|
26452
26516
|
carry = carry / BASE >>> 0;
|
|
@@ -26454,10 +26518,10 @@ function base2(ALPHABET, name) {
|
|
|
26454
26518
|
if (carry !== 0) {
|
|
26455
26519
|
throw new Error("Non-zero carry");
|
|
26456
26520
|
}
|
|
26457
|
-
|
|
26521
|
+
length32 = i2;
|
|
26458
26522
|
pbegin++;
|
|
26459
26523
|
}
|
|
26460
|
-
var it2 = size -
|
|
26524
|
+
var it2 = size - length32;
|
|
26461
26525
|
while (it2 !== size && b58[it2] === 0) {
|
|
26462
26526
|
it2++;
|
|
26463
26527
|
}
|
|
@@ -26479,7 +26543,7 @@ function base2(ALPHABET, name) {
|
|
|
26479
26543
|
return;
|
|
26480
26544
|
}
|
|
26481
26545
|
var zeroes = 0;
|
|
26482
|
-
var
|
|
26546
|
+
var length32 = 0;
|
|
26483
26547
|
while (source[psz] === LEADER) {
|
|
26484
26548
|
zeroes++;
|
|
26485
26549
|
psz++;
|
|
@@ -26492,7 +26556,7 @@ function base2(ALPHABET, name) {
|
|
|
26492
26556
|
return;
|
|
26493
26557
|
}
|
|
26494
26558
|
var i2 = 0;
|
|
26495
|
-
for (var it3 = size - 1; (carry !== 0 || i2 <
|
|
26559
|
+
for (var it3 = size - 1; (carry !== 0 || i2 < length32) && it3 !== -1; it3--, i2++) {
|
|
26496
26560
|
carry += BASE * b256[it3] >>> 0;
|
|
26497
26561
|
b256[it3] = carry % 256 >>> 0;
|
|
26498
26562
|
carry = carry / 256 >>> 0;
|
|
@@ -26500,13 +26564,13 @@ function base2(ALPHABET, name) {
|
|
|
26500
26564
|
if (carry !== 0) {
|
|
26501
26565
|
throw new Error("Non-zero carry");
|
|
26502
26566
|
}
|
|
26503
|
-
|
|
26567
|
+
length32 = i2;
|
|
26504
26568
|
psz++;
|
|
26505
26569
|
}
|
|
26506
26570
|
if (source[psz] === " ") {
|
|
26507
26571
|
return;
|
|
26508
26572
|
}
|
|
26509
|
-
var it4 = size -
|
|
26573
|
+
var it4 = size - length32;
|
|
26510
26574
|
while (it4 !== size && b256[it4] === 0) {
|
|
26511
26575
|
it4++;
|
|
26512
26576
|
}
|
|
@@ -26517,7 +26581,7 @@ function base2(ALPHABET, name) {
|
|
|
26517
26581
|
}
|
|
26518
26582
|
return vch;
|
|
26519
26583
|
}
|
|
26520
|
-
function
|
|
26584
|
+
function decode92(string) {
|
|
26521
26585
|
var buffer = decodeUnsafe(string);
|
|
26522
26586
|
if (buffer) {
|
|
26523
26587
|
return buffer;
|
|
@@ -26525,9 +26589,9 @@ function base2(ALPHABET, name) {
|
|
|
26525
26589
|
throw new Error(`Non-${name} character`);
|
|
26526
26590
|
}
|
|
26527
26591
|
return {
|
|
26528
|
-
encode:
|
|
26592
|
+
encode: encode52,
|
|
26529
26593
|
decodeUnsafe,
|
|
26530
|
-
decode:
|
|
26594
|
+
decode: decode92
|
|
26531
26595
|
};
|
|
26532
26596
|
}
|
|
26533
26597
|
var src2 = base2;
|
|
@@ -26625,16 +26689,16 @@ var Codec2 = class {
|
|
|
26625
26689
|
return this.decoder.decode(input);
|
|
26626
26690
|
}
|
|
26627
26691
|
};
|
|
26628
|
-
function from2({ name, prefix, encode:
|
|
26629
|
-
return new Codec2(name, prefix,
|
|
26692
|
+
function from2({ name, prefix, encode: encode52, decode: decode92 }) {
|
|
26693
|
+
return new Codec2(name, prefix, encode52, decode92);
|
|
26630
26694
|
}
|
|
26631
26695
|
function baseX2({ name, prefix, alphabet }) {
|
|
26632
|
-
const { encode:
|
|
26696
|
+
const { encode: encode52, decode: decode92 } = base_x_default2(alphabet, name);
|
|
26633
26697
|
return from2({
|
|
26634
26698
|
prefix,
|
|
26635
26699
|
name,
|
|
26636
|
-
encode:
|
|
26637
|
-
decode: (text) => coerce3(
|
|
26700
|
+
encode: encode52,
|
|
26701
|
+
decode: (text) => coerce3(decode92(text))
|
|
26638
26702
|
});
|
|
26639
26703
|
}
|
|
26640
26704
|
function decode5(string, alphabetIdx, bitsPerChar, name) {
|
|
@@ -27004,24 +27068,24 @@ var Digest2 = class {
|
|
|
27004
27068
|
this.bytes = bytes3;
|
|
27005
27069
|
}
|
|
27006
27070
|
};
|
|
27007
|
-
function format2(link2,
|
|
27071
|
+
function format2(link2, base33) {
|
|
27008
27072
|
const { bytes: bytes3, version } = link2;
|
|
27009
27073
|
switch (version) {
|
|
27010
27074
|
case 0:
|
|
27011
|
-
return toStringV02(bytes3, baseCache2(link2),
|
|
27075
|
+
return toStringV02(bytes3, baseCache2(link2), base33 ?? base58btc2.encoder);
|
|
27012
27076
|
default:
|
|
27013
|
-
return toStringV12(bytes3, baseCache2(link2),
|
|
27077
|
+
return toStringV12(bytes3, baseCache2(link2), base33 ?? base322.encoder);
|
|
27014
27078
|
}
|
|
27015
27079
|
}
|
|
27016
27080
|
var cache2 = /* @__PURE__ */ new WeakMap();
|
|
27017
27081
|
function baseCache2(cid2) {
|
|
27018
|
-
const
|
|
27019
|
-
if (
|
|
27082
|
+
const baseCache32 = cache2.get(cid2);
|
|
27083
|
+
if (baseCache32 == null) {
|
|
27020
27084
|
const baseCache4 = /* @__PURE__ */ new Map();
|
|
27021
27085
|
cache2.set(cid2, baseCache4);
|
|
27022
27086
|
return baseCache4;
|
|
27023
27087
|
}
|
|
27024
|
-
return
|
|
27088
|
+
return baseCache32;
|
|
27025
27089
|
}
|
|
27026
27090
|
var CID2 = class _CID2 {
|
|
27027
27091
|
code;
|
|
@@ -27100,8 +27164,8 @@ var CID2 = class _CID2 {
|
|
|
27100
27164
|
const unknown = other;
|
|
27101
27165
|
return unknown != null && self.code === unknown.code && self.version === unknown.version && equals4(self.multihash, unknown.multihash);
|
|
27102
27166
|
}
|
|
27103
|
-
toString(
|
|
27104
|
-
return format2(this,
|
|
27167
|
+
toString(base33) {
|
|
27168
|
+
return format2(this, base33);
|
|
27105
27169
|
}
|
|
27106
27170
|
toJSON() {
|
|
27107
27171
|
return { "/": format2(this) };
|
|
@@ -27233,8 +27297,8 @@ var CID2 = class _CID2 {
|
|
|
27233
27297
|
static inspectBytes(initialBytes) {
|
|
27234
27298
|
let offset = 0;
|
|
27235
27299
|
const next = () => {
|
|
27236
|
-
const [i,
|
|
27237
|
-
offset +=
|
|
27300
|
+
const [i, length32] = decode7(initialBytes.subarray(offset));
|
|
27301
|
+
offset += length32;
|
|
27238
27302
|
return i;
|
|
27239
27303
|
};
|
|
27240
27304
|
let version = next();
|
|
@@ -27261,8 +27325,8 @@ var CID2 = class _CID2 {
|
|
|
27261
27325
|
* throw an error if encoding of the CID is not compatible with supplied (or
|
|
27262
27326
|
* a default decoder).
|
|
27263
27327
|
*/
|
|
27264
|
-
static parse(source,
|
|
27265
|
-
const [prefix, bytes3] = parseCIDtoBytes2(source,
|
|
27328
|
+
static parse(source, base33) {
|
|
27329
|
+
const [prefix, bytes3] = parseCIDtoBytes2(source, base33);
|
|
27266
27330
|
const cid2 = _CID2.decode(bytes3);
|
|
27267
27331
|
if (cid2.version === 0 && source[0] !== "Q") {
|
|
27268
27332
|
throw Error("Version 0 CID string must not include multibase prefix");
|
|
@@ -27271,56 +27335,56 @@ var CID2 = class _CID2 {
|
|
|
27271
27335
|
return cid2;
|
|
27272
27336
|
}
|
|
27273
27337
|
};
|
|
27274
|
-
function parseCIDtoBytes2(source,
|
|
27338
|
+
function parseCIDtoBytes2(source, base33) {
|
|
27275
27339
|
switch (source[0]) {
|
|
27276
27340
|
// CIDv0 is parsed differently
|
|
27277
27341
|
case "Q": {
|
|
27278
|
-
const decoder =
|
|
27342
|
+
const decoder = base33 ?? base58btc2;
|
|
27279
27343
|
return [
|
|
27280
27344
|
base58btc2.prefix,
|
|
27281
27345
|
decoder.decode(`${base58btc2.prefix}${source}`)
|
|
27282
27346
|
];
|
|
27283
27347
|
}
|
|
27284
27348
|
case base58btc2.prefix: {
|
|
27285
|
-
const decoder =
|
|
27349
|
+
const decoder = base33 ?? base58btc2;
|
|
27286
27350
|
return [base58btc2.prefix, decoder.decode(source)];
|
|
27287
27351
|
}
|
|
27288
27352
|
case base322.prefix: {
|
|
27289
|
-
const decoder =
|
|
27353
|
+
const decoder = base33 ?? base322;
|
|
27290
27354
|
return [base322.prefix, decoder.decode(source)];
|
|
27291
27355
|
}
|
|
27292
27356
|
case base362.prefix: {
|
|
27293
|
-
const decoder =
|
|
27357
|
+
const decoder = base33 ?? base362;
|
|
27294
27358
|
return [base362.prefix, decoder.decode(source)];
|
|
27295
27359
|
}
|
|
27296
27360
|
default: {
|
|
27297
|
-
if (
|
|
27361
|
+
if (base33 == null) {
|
|
27298
27362
|
throw Error("To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided");
|
|
27299
27363
|
}
|
|
27300
|
-
return [source[0],
|
|
27364
|
+
return [source[0], base33.decode(source)];
|
|
27301
27365
|
}
|
|
27302
27366
|
}
|
|
27303
27367
|
}
|
|
27304
|
-
function toStringV02(bytes3,
|
|
27305
|
-
const { prefix } =
|
|
27368
|
+
function toStringV02(bytes3, cache32, base33) {
|
|
27369
|
+
const { prefix } = base33;
|
|
27306
27370
|
if (prefix !== base58btc2.prefix) {
|
|
27307
|
-
throw Error(`Cannot string encode V0 in ${
|
|
27371
|
+
throw Error(`Cannot string encode V0 in ${base33.name} encoding`);
|
|
27308
27372
|
}
|
|
27309
|
-
const cid2 =
|
|
27373
|
+
const cid2 = cache32.get(prefix);
|
|
27310
27374
|
if (cid2 == null) {
|
|
27311
|
-
const cid3 =
|
|
27312
|
-
|
|
27375
|
+
const cid3 = base33.encode(bytes3).slice(1);
|
|
27376
|
+
cache32.set(prefix, cid3);
|
|
27313
27377
|
return cid3;
|
|
27314
27378
|
} else {
|
|
27315
27379
|
return cid2;
|
|
27316
27380
|
}
|
|
27317
27381
|
}
|
|
27318
|
-
function toStringV12(bytes3,
|
|
27319
|
-
const { prefix } =
|
|
27320
|
-
const cid2 =
|
|
27382
|
+
function toStringV12(bytes3, cache32, base33) {
|
|
27383
|
+
const { prefix } = base33;
|
|
27384
|
+
const cid2 = cache32.get(prefix);
|
|
27321
27385
|
if (cid2 == null) {
|
|
27322
|
-
const cid3 =
|
|
27323
|
-
|
|
27386
|
+
const cid3 = base33.encode(bytes3);
|
|
27387
|
+
cache32.set(prefix, cid3);
|
|
27324
27388
|
return cid3;
|
|
27325
27389
|
} else {
|
|
27326
27390
|
return cid2;
|
|
@@ -27374,11 +27438,12 @@ function historyRecordForPublishedShare(result, now = /* @__PURE__ */ new Date()
|
|
|
27374
27438
|
};
|
|
27375
27439
|
}
|
|
27376
27440
|
var ShareNotifyError = class extends Error {
|
|
27377
|
-
|
|
27378
|
-
constructor(message = "share delivery did not complete") {
|
|
27441
|
+
constructor(message = "share delivery did not complete", reason) {
|
|
27379
27442
|
super(message);
|
|
27443
|
+
this.reason = reason;
|
|
27380
27444
|
this.name = "ShareNotifyError";
|
|
27381
27445
|
}
|
|
27446
|
+
code = "delivery-failed";
|
|
27382
27447
|
};
|
|
27383
27448
|
function recipientMatchesShareRecord(record, recipient) {
|
|
27384
27449
|
const matcher = record.recipientMatcher;
|
|
@@ -27388,6 +27453,11 @@ function recipientMatchesShareRecord(record, recipient) {
|
|
|
27388
27453
|
if (matcher.kind === "emailDomain") return mailbox.domain === matcher.value;
|
|
27389
27454
|
return false;
|
|
27390
27455
|
}
|
|
27456
|
+
function shareDeliveryWindowExpiresAt(record) {
|
|
27457
|
+
const expiresAt = Math.min(Date.parse(record.expiresAt), Date.parse(record.registeredAt) + 5 * 60 * 1e3);
|
|
27458
|
+
if (!Number.isFinite(expiresAt)) throw new ShareNotifyError("share delivery history has invalid timestamps");
|
|
27459
|
+
return expiresAt;
|
|
27460
|
+
}
|
|
27391
27461
|
async function notifyShare(input) {
|
|
27392
27462
|
const mailbox = canonicalMailbox(input.recipient);
|
|
27393
27463
|
if (!input.shareId || mailbox === void 0) throw new ShareNotifyError("recipient is invalid");
|
|
@@ -27398,6 +27468,19 @@ async function notifyShare(input) {
|
|
|
27398
27468
|
const idempotencyKey = input.idempotencyKey ?? await defaultIdempotencyKey(input.shareId, recipient);
|
|
27399
27469
|
const attemptsLimit = input.maxAttempts ?? 3;
|
|
27400
27470
|
if (!Number.isSafeInteger(attemptsLimit) || attemptsLimit < 1 || attemptsLimit > 8) throw new ShareNotifyError("maxAttempts is invalid");
|
|
27471
|
+
if (input.signal?.aborted) throw new ShareNotifyError("share delivery was cancelled");
|
|
27472
|
+
if (input.checkDeliveryWindow && input.record !== void 0 && shareDeliveryWindowExpiresAt(input.record) <= Date.now()) {
|
|
27473
|
+
return {
|
|
27474
|
+
protocol: "tinycloud-share",
|
|
27475
|
+
version: 1,
|
|
27476
|
+
shareId: input.shareId,
|
|
27477
|
+
state: "partial-failure",
|
|
27478
|
+
idempotencyKey,
|
|
27479
|
+
attempts: 1,
|
|
27480
|
+
retryable: false,
|
|
27481
|
+
reason: "delivery-window-expired"
|
|
27482
|
+
};
|
|
27483
|
+
}
|
|
27401
27484
|
let attempts = 0;
|
|
27402
27485
|
let lastError;
|
|
27403
27486
|
while (attempts < attemptsLimit) {
|
|
@@ -27405,8 +27488,27 @@ async function notifyShare(input) {
|
|
|
27405
27488
|
attempts += 1;
|
|
27406
27489
|
try {
|
|
27407
27490
|
const state = await input.adapter.deliver({ shareId: input.shareId, recipient, idempotencyKey, ...input.record === void 0 ? {} : { record: input.record }, ...input.signal === void 0 ? {} : { signal: input.signal } });
|
|
27408
|
-
return {
|
|
27491
|
+
return {
|
|
27492
|
+
protocol: "tinycloud-share",
|
|
27493
|
+
version: 1,
|
|
27494
|
+
shareId: input.shareId,
|
|
27495
|
+
state: state === "delivered" && input.record?.deliveredRecipients?.includes(recipient) ? "already-delivered" : state,
|
|
27496
|
+
idempotencyKey,
|
|
27497
|
+
attempts
|
|
27498
|
+
};
|
|
27409
27499
|
} catch (error) {
|
|
27500
|
+
if (error instanceof ShareNotifyError && error.reason === "delivery-window-expired") {
|
|
27501
|
+
return {
|
|
27502
|
+
protocol: "tinycloud-share",
|
|
27503
|
+
version: 1,
|
|
27504
|
+
shareId: input.shareId,
|
|
27505
|
+
state: "partial-failure",
|
|
27506
|
+
idempotencyKey,
|
|
27507
|
+
attempts,
|
|
27508
|
+
retryable: false,
|
|
27509
|
+
reason: "delivery-window-expired"
|
|
27510
|
+
};
|
|
27511
|
+
}
|
|
27410
27512
|
lastError = error;
|
|
27411
27513
|
}
|
|
27412
27514
|
}
|
|
@@ -27454,7 +27556,11 @@ async function revokeShare(input) {
|
|
|
27454
27556
|
});
|
|
27455
27557
|
}
|
|
27456
27558
|
const revokedAt = (input.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
27457
|
-
if (input.records !== void 0)
|
|
27559
|
+
if (input.records?.update !== void 0) {
|
|
27560
|
+
await input.records.update(input.record.shareId, (record) => ({ ...record, revokedAt }));
|
|
27561
|
+
} else if (input.records !== void 0) {
|
|
27562
|
+
await input.records.put({ ...input.record, revokedAt });
|
|
27563
|
+
}
|
|
27458
27564
|
return { state: "revoked", target, delegationCid, revokedAt };
|
|
27459
27565
|
}
|
|
27460
27566
|
function redactRecord(record, revealLink, link2) {
|
|
@@ -27502,207 +27608,1530 @@ function parseNativeShareUrl(value) {
|
|
|
27502
27608
|
return token;
|
|
27503
27609
|
}
|
|
27504
27610
|
|
|
27505
|
-
//
|
|
27506
|
-
|
|
27507
|
-
|
|
27508
|
-
|
|
27509
|
-
|
|
27510
|
-
function writeJson2(value) {
|
|
27511
|
-
process.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
27512
|
-
`);
|
|
27513
|
-
}
|
|
27514
|
-
function authorizationRequiredJson(result) {
|
|
27515
|
-
return {
|
|
27516
|
-
state: "authorization-required",
|
|
27517
|
-
method: result.method,
|
|
27518
|
-
next: "complete authorization through the configured authority adapter, then retry with the required proof"
|
|
27519
|
-
};
|
|
27520
|
-
}
|
|
27521
|
-
function publishHuman(result) {
|
|
27522
|
-
process.stdout.write(`${result.url}
|
|
27523
|
-
`);
|
|
27524
|
-
}
|
|
27525
|
-
function inspectHuman(result) {
|
|
27526
|
-
const metadata = result.metadata;
|
|
27527
|
-
process.stdout.write([
|
|
27528
|
-
`Share ${metadata.shareId}`,
|
|
27529
|
-
`File: ${metadata.display.filename ?? "unnamed"}`,
|
|
27530
|
-
`Target: ${metadata.target.kind === "bearer" ? "bearer (anyone with the complete link can read)" : metadata.target.kind}`,
|
|
27531
|
-
`Expires: ${metadata.expiresAt}`,
|
|
27532
|
-
`Resource: ${metadata.resource.path}`,
|
|
27533
|
-
`Link format: ${result.link.kind}`
|
|
27534
|
-
].join("\n") + "\n");
|
|
27535
|
-
}
|
|
27536
|
-
function receiveHuman(path) {
|
|
27537
|
-
process.stdout.write(`${path}
|
|
27538
|
-
`);
|
|
27539
|
-
}
|
|
27540
|
-
function receiveJson(result, path) {
|
|
27541
|
-
writeJson2({ protocol: "tinycloud-share", version: 1, path, metadata: result.metadata });
|
|
27542
|
-
}
|
|
27543
|
-
|
|
27544
|
-
// src/share/io.ts
|
|
27545
|
-
import { constants } from "fs";
|
|
27546
|
-
import { lstat as lstat3, mkdir as mkdir3, mkdtemp, open as open4, readFile as readFile9, realpath, stat as stat2, link, rename as rename3, rm as rm4, unlink } from "fs/promises";
|
|
27547
|
-
import { randomBytes as randomBytes4 } from "crypto";
|
|
27548
|
-
import { basename as basename3, join as join6, resolve as resolve2, sep } from "path";
|
|
27549
|
-
init_errors();
|
|
27550
|
-
var MAX_SHARE_STDIN_BYTES = 100 * 1024 * 1024;
|
|
27551
|
-
var MAX_SHARE_URL_BYTES = 64 * 1024;
|
|
27552
|
-
async function readBoundedStdin(limit = MAX_SHARE_STDIN_BYTES) {
|
|
27553
|
-
if (!Number.isSafeInteger(limit) || limit <= 0) throw new Error("MAX_BYTES_EXCEEDED");
|
|
27554
|
-
const chunks = [];
|
|
27555
|
-
let total = 0;
|
|
27556
|
-
for await (const chunk of process.stdin) {
|
|
27557
|
-
const bytes = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
|
|
27558
|
-
total += bytes.byteLength;
|
|
27559
|
-
if (total > limit) throw new Error("MAX_BYTES_EXCEEDED");
|
|
27560
|
-
chunks.push(bytes);
|
|
27611
|
+
// ../share-envelope/dist/index.js
|
|
27612
|
+
var empty3 = new Uint8Array(0);
|
|
27613
|
+
function equals5(aa, bb) {
|
|
27614
|
+
if (aa === bb) {
|
|
27615
|
+
return true;
|
|
27561
27616
|
}
|
|
27562
|
-
|
|
27563
|
-
|
|
27564
|
-
async function readBoundedUrlStdin() {
|
|
27565
|
-
const bytes = await readBoundedStdin(MAX_SHARE_URL_BYTES);
|
|
27566
|
-
const value = new TextDecoder("utf-8", { fatal: true }).decode(bytes).trim();
|
|
27567
|
-
if (value.length === 0 || /\s/.test(value)) throw new Error("INVALID_ARGUMENT");
|
|
27568
|
-
return value;
|
|
27569
|
-
}
|
|
27570
|
-
function safeFilename(value) {
|
|
27571
|
-
return shareFilename(value);
|
|
27572
|
-
}
|
|
27573
|
-
function shareFilename(value) {
|
|
27574
|
-
try {
|
|
27575
|
-
return canonicalShareFilename(value);
|
|
27576
|
-
} catch {
|
|
27577
|
-
throw new CLIError(
|
|
27578
|
-
"UNSAFE_FILENAME",
|
|
27579
|
-
hasUnsafeFilenameCodePoint(value) ? "filename contains control or invisible characters" : "filename must be one safe path segment",
|
|
27580
|
-
8
|
|
27581
|
-
);
|
|
27617
|
+
if (aa.byteLength !== bb.byteLength) {
|
|
27618
|
+
return false;
|
|
27582
27619
|
}
|
|
27583
|
-
|
|
27584
|
-
|
|
27585
|
-
|
|
27586
|
-
}
|
|
27587
|
-
async function readShareInput(input, name, limit = MAX_SHARE_STDIN_BYTES) {
|
|
27588
|
-
const filename = shareInputFilename(input, name);
|
|
27589
|
-
if (input === "-") return { bytes: await readBoundedStdin(limit), filename };
|
|
27590
|
-
const path = resolve2(input);
|
|
27591
|
-
const info = await stat2(path);
|
|
27592
|
-
if (!info.isFile() || info.size > limit) throw new Error("MAX_BYTES_EXCEEDED");
|
|
27593
|
-
const bytes = new Uint8Array(await readFile9(path));
|
|
27594
|
-
if (bytes.byteLength > limit) throw new Error("MAX_BYTES_EXCEEDED");
|
|
27595
|
-
return { bytes, filename };
|
|
27596
|
-
}
|
|
27597
|
-
async function assertDirectory(path) {
|
|
27598
|
-
const absolute = resolve2(path);
|
|
27599
|
-
const segments = absolute.split(sep).filter(Boolean);
|
|
27600
|
-
let current = absolute.startsWith(sep) ? sep : "";
|
|
27601
|
-
for (const segment of segments) {
|
|
27602
|
-
current = current === sep ? join6(current, segment) : join6(current, segment);
|
|
27603
|
-
try {
|
|
27604
|
-
const info = await lstat3(current);
|
|
27605
|
-
if (info.isSymbolicLink()) {
|
|
27606
|
-
const canonical = await realpath(current);
|
|
27607
|
-
if (current !== "/tmp" && current !== "/var") throw new Error("OUTPUT_EXISTS");
|
|
27608
|
-
if (canonical !== `/private${current}`) throw new Error("OUTPUT_EXISTS");
|
|
27609
|
-
} else if (!info.isDirectory()) throw new Error("OUTPUT_EXISTS");
|
|
27610
|
-
} catch (error) {
|
|
27611
|
-
if (error.code !== "ENOENT") throw error;
|
|
27612
|
-
await mkdir3(current, { mode: 448 });
|
|
27613
|
-
const created = await lstat3(current);
|
|
27614
|
-
if (created.isSymbolicLink() || !created.isDirectory()) throw new Error("OUTPUT_EXISTS");
|
|
27620
|
+
for (let ii = 0; ii < aa.byteLength; ii++) {
|
|
27621
|
+
if (aa[ii] !== bb[ii]) {
|
|
27622
|
+
return false;
|
|
27615
27623
|
}
|
|
27616
27624
|
}
|
|
27625
|
+
return true;
|
|
27617
27626
|
}
|
|
27618
|
-
|
|
27619
|
-
|
|
27620
|
-
|
|
27621
|
-
const safeName = safeFilename(filename);
|
|
27622
|
-
const directoryHandle = await open4(outputDirectory, constants.O_RDONLY | (constants.O_DIRECTORY ?? 0) | (constants.O_NOFOLLOW ?? 0));
|
|
27623
|
-
const stableDirectory = await realpath(outputDirectory);
|
|
27624
|
-
const outputPath = join6(stableDirectory, safeName);
|
|
27625
|
-
const directoryIdentity = await directoryHandle.stat();
|
|
27626
|
-
const assertStableDirectory = async () => {
|
|
27627
|
-
const current = await stat2(stableDirectory);
|
|
27628
|
-
if (current.dev !== directoryIdentity.dev || current.ino !== directoryIdentity.ino) throw new Error("OUTPUT_EXISTS");
|
|
27629
|
-
};
|
|
27630
|
-
await assertStableDirectory();
|
|
27631
|
-
const stagingDirectory = await mkdtemp(join6(stableDirectory, ".tinycloud-share-stage-"));
|
|
27632
|
-
const stagingInfo = await lstat3(stagingDirectory);
|
|
27633
|
-
if (!stagingInfo.isDirectory() || (stagingInfo.mode & 511) !== 448) throw new Error("OUTPUT_EXISTS");
|
|
27634
|
-
const stagingPath = join6(stagingDirectory, `.tinycloud-share-${randomBytes4(16).toString("hex")}.tmp`);
|
|
27635
|
-
let temporaryPath;
|
|
27636
|
-
let handle;
|
|
27637
|
-
try {
|
|
27638
|
-
await assertStableDirectory();
|
|
27639
|
-
try {
|
|
27640
|
-
const existing = await lstat3(outputPath);
|
|
27641
|
-
if (existing.isSymbolicLink()) throw new Error("UNSAFE_FILENAME");
|
|
27642
|
-
} catch (error) {
|
|
27643
|
-
if (error.code !== "ENOENT") throw error;
|
|
27644
|
-
}
|
|
27645
|
-
temporaryPath = stagingPath;
|
|
27646
|
-
handle = await open4(temporaryPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | (constants.O_NOFOLLOW ?? 0), 384);
|
|
27647
|
-
await handle.writeFile(bytes);
|
|
27648
|
-
await handle.close();
|
|
27649
|
-
handle = void 0;
|
|
27650
|
-
await assertStableDirectory();
|
|
27651
|
-
if (force) {
|
|
27652
|
-
await rename3(temporaryPath, outputPath);
|
|
27653
|
-
} else {
|
|
27654
|
-
await link(temporaryPath, outputPath);
|
|
27655
|
-
await unlink(temporaryPath);
|
|
27656
|
-
}
|
|
27657
|
-
await assertStableDirectory();
|
|
27658
|
-
} catch (error) {
|
|
27659
|
-
if (error.code === "EEXIST") throw new Error("OUTPUT_EXISTS");
|
|
27660
|
-
if (error.code === "ELOOP") throw new Error("UNSAFE_FILENAME");
|
|
27661
|
-
throw error;
|
|
27662
|
-
} finally {
|
|
27663
|
-
await handle?.close();
|
|
27664
|
-
try {
|
|
27665
|
-
if (temporaryPath !== void 0) await unlink(temporaryPath);
|
|
27666
|
-
} catch {
|
|
27667
|
-
}
|
|
27668
|
-
await rm4(stagingDirectory, { recursive: true, force: true });
|
|
27669
|
-
await directoryHandle.close();
|
|
27627
|
+
function coerce4(o) {
|
|
27628
|
+
if (o instanceof Uint8Array && o.constructor.name === "Uint8Array") {
|
|
27629
|
+
return o;
|
|
27670
27630
|
}
|
|
27671
|
-
|
|
27672
|
-
|
|
27673
|
-
|
|
27674
|
-
// src/share/errors.ts
|
|
27675
|
-
var SharePublishAuthorityError = class extends Error {
|
|
27676
|
-
constructor(failure) {
|
|
27677
|
-
super(failure.kind);
|
|
27678
|
-
this.failure = failure;
|
|
27679
|
-
this.name = "SharePublishAuthorityError";
|
|
27631
|
+
if (o instanceof ArrayBuffer) {
|
|
27632
|
+
return new Uint8Array(o);
|
|
27680
27633
|
}
|
|
27681
|
-
|
|
27682
|
-
|
|
27683
|
-
// src/commands/share.ts
|
|
27684
|
-
var SHARE_ORIGIN = "https://share.tinycloud.xyz";
|
|
27685
|
-
var shareServices = {};
|
|
27686
|
-
function parseShareTarget(value) {
|
|
27687
|
-
if (value === "anyone" || value === "bearer") return { kind: "bearer" };
|
|
27688
|
-
if (value.startsWith("did:")) return { kind: "recipientDid", did: value };
|
|
27689
|
-
if (value.startsWith("domain:")) return canonicalMailboxTarget({ kind: "emailDomain", domain: value.slice("domain:".length) });
|
|
27690
|
-
if (value.startsWith("email:")) return canonicalMailboxTarget({ kind: "email", address: value.slice("email:".length) });
|
|
27691
|
-
if (value.includes("@")) return canonicalMailboxTarget({ kind: "email", address: value });
|
|
27692
|
-
throw new CLIError("INVALID_ARGUMENT", "--to must be anyone, a did:, an email address, or domain:example.com", 2);
|
|
27693
|
-
}
|
|
27694
|
-
function canonicalMailboxTarget(target) {
|
|
27695
|
-
try {
|
|
27696
|
-
return normalizeShareTarget(target);
|
|
27697
|
-
} catch (error) {
|
|
27698
|
-
throw new CLIError("INVALID_ARGUMENT", error instanceof TypeError ? error.message : "share recipient is invalid", 2);
|
|
27634
|
+
if (ArrayBuffer.isView(o)) {
|
|
27635
|
+
return new Uint8Array(o.buffer, o.byteOffset, o.byteLength);
|
|
27699
27636
|
}
|
|
27637
|
+
throw new Error("Unknown type, must be binary type");
|
|
27700
27638
|
}
|
|
27701
|
-
function
|
|
27702
|
-
if (
|
|
27703
|
-
|
|
27704
|
-
|
|
27705
|
-
|
|
27639
|
+
function base3(ALPHABET, name) {
|
|
27640
|
+
if (ALPHABET.length >= 255) {
|
|
27641
|
+
throw new TypeError("Alphabet too long");
|
|
27642
|
+
}
|
|
27643
|
+
var BASE_MAP = new Uint8Array(256);
|
|
27644
|
+
for (var j = 0; j < BASE_MAP.length; j++) {
|
|
27645
|
+
BASE_MAP[j] = 255;
|
|
27646
|
+
}
|
|
27647
|
+
for (var i = 0; i < ALPHABET.length; i++) {
|
|
27648
|
+
var x = ALPHABET.charAt(i);
|
|
27649
|
+
var xc = x.charCodeAt(0);
|
|
27650
|
+
if (BASE_MAP[xc] !== 255) {
|
|
27651
|
+
throw new TypeError(x + " is ambiguous");
|
|
27652
|
+
}
|
|
27653
|
+
BASE_MAP[xc] = i;
|
|
27654
|
+
}
|
|
27655
|
+
var BASE = ALPHABET.length;
|
|
27656
|
+
var LEADER = ALPHABET.charAt(0);
|
|
27657
|
+
var FACTOR = Math.log(BASE) / Math.log(256);
|
|
27658
|
+
var iFACTOR = Math.log(256) / Math.log(BASE);
|
|
27659
|
+
function encode32(source) {
|
|
27660
|
+
if (source instanceof Uint8Array)
|
|
27661
|
+
;
|
|
27662
|
+
else if (ArrayBuffer.isView(source)) {
|
|
27663
|
+
source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
|
|
27664
|
+
} else if (Array.isArray(source)) {
|
|
27665
|
+
source = Uint8Array.from(source);
|
|
27666
|
+
}
|
|
27667
|
+
if (!(source instanceof Uint8Array)) {
|
|
27668
|
+
throw new TypeError("Expected Uint8Array");
|
|
27669
|
+
}
|
|
27670
|
+
if (source.length === 0) {
|
|
27671
|
+
return "";
|
|
27672
|
+
}
|
|
27673
|
+
var zeroes = 0;
|
|
27674
|
+
var length22 = 0;
|
|
27675
|
+
var pbegin = 0;
|
|
27676
|
+
var pend = source.length;
|
|
27677
|
+
while (pbegin !== pend && source[pbegin] === 0) {
|
|
27678
|
+
pbegin++;
|
|
27679
|
+
zeroes++;
|
|
27680
|
+
}
|
|
27681
|
+
var size = (pend - pbegin) * iFACTOR + 1 >>> 0;
|
|
27682
|
+
var b58 = new Uint8Array(size);
|
|
27683
|
+
while (pbegin !== pend) {
|
|
27684
|
+
var carry = source[pbegin];
|
|
27685
|
+
var i2 = 0;
|
|
27686
|
+
for (var it1 = size - 1; (carry !== 0 || i2 < length22) && it1 !== -1; it1--, i2++) {
|
|
27687
|
+
carry += 256 * b58[it1] >>> 0;
|
|
27688
|
+
b58[it1] = carry % BASE >>> 0;
|
|
27689
|
+
carry = carry / BASE >>> 0;
|
|
27690
|
+
}
|
|
27691
|
+
if (carry !== 0) {
|
|
27692
|
+
throw new Error("Non-zero carry");
|
|
27693
|
+
}
|
|
27694
|
+
length22 = i2;
|
|
27695
|
+
pbegin++;
|
|
27696
|
+
}
|
|
27697
|
+
var it2 = size - length22;
|
|
27698
|
+
while (it2 !== size && b58[it2] === 0) {
|
|
27699
|
+
it2++;
|
|
27700
|
+
}
|
|
27701
|
+
var str = LEADER.repeat(zeroes);
|
|
27702
|
+
for (; it2 < size; ++it2) {
|
|
27703
|
+
str += ALPHABET.charAt(b58[it2]);
|
|
27704
|
+
}
|
|
27705
|
+
return str;
|
|
27706
|
+
}
|
|
27707
|
+
function decodeUnsafe(source) {
|
|
27708
|
+
if (typeof source !== "string") {
|
|
27709
|
+
throw new TypeError("Expected String");
|
|
27710
|
+
}
|
|
27711
|
+
if (source.length === 0) {
|
|
27712
|
+
return new Uint8Array();
|
|
27713
|
+
}
|
|
27714
|
+
var psz = 0;
|
|
27715
|
+
if (source[psz] === " ") {
|
|
27716
|
+
return;
|
|
27717
|
+
}
|
|
27718
|
+
var zeroes = 0;
|
|
27719
|
+
var length22 = 0;
|
|
27720
|
+
while (source[psz] === LEADER) {
|
|
27721
|
+
zeroes++;
|
|
27722
|
+
psz++;
|
|
27723
|
+
}
|
|
27724
|
+
var size = (source.length - psz) * FACTOR + 1 >>> 0;
|
|
27725
|
+
var b256 = new Uint8Array(size);
|
|
27726
|
+
while (source[psz]) {
|
|
27727
|
+
var carry = BASE_MAP[source.charCodeAt(psz)];
|
|
27728
|
+
if (carry === 255) {
|
|
27729
|
+
return;
|
|
27730
|
+
}
|
|
27731
|
+
var i2 = 0;
|
|
27732
|
+
for (var it3 = size - 1; (carry !== 0 || i2 < length22) && it3 !== -1; it3--, i2++) {
|
|
27733
|
+
carry += BASE * b256[it3] >>> 0;
|
|
27734
|
+
b256[it3] = carry % 256 >>> 0;
|
|
27735
|
+
carry = carry / 256 >>> 0;
|
|
27736
|
+
}
|
|
27737
|
+
if (carry !== 0) {
|
|
27738
|
+
throw new Error("Non-zero carry");
|
|
27739
|
+
}
|
|
27740
|
+
length22 = i2;
|
|
27741
|
+
psz++;
|
|
27742
|
+
}
|
|
27743
|
+
if (source[psz] === " ") {
|
|
27744
|
+
return;
|
|
27745
|
+
}
|
|
27746
|
+
var it4 = size - length22;
|
|
27747
|
+
while (it4 !== size && b256[it4] === 0) {
|
|
27748
|
+
it4++;
|
|
27749
|
+
}
|
|
27750
|
+
var vch = new Uint8Array(zeroes + (size - it4));
|
|
27751
|
+
var j2 = zeroes;
|
|
27752
|
+
while (it4 !== size) {
|
|
27753
|
+
vch[j2++] = b256[it4++];
|
|
27754
|
+
}
|
|
27755
|
+
return vch;
|
|
27756
|
+
}
|
|
27757
|
+
function decode52(string) {
|
|
27758
|
+
var buffer = decodeUnsafe(string);
|
|
27759
|
+
if (buffer) {
|
|
27760
|
+
return buffer;
|
|
27761
|
+
}
|
|
27762
|
+
throw new Error(`Non-${name} character`);
|
|
27763
|
+
}
|
|
27764
|
+
return {
|
|
27765
|
+
encode: encode32,
|
|
27766
|
+
decodeUnsafe,
|
|
27767
|
+
decode: decode52
|
|
27768
|
+
};
|
|
27769
|
+
}
|
|
27770
|
+
var src3 = base3;
|
|
27771
|
+
var _brrp__multiformats_scope_baseX3 = src3;
|
|
27772
|
+
var base_x_default3 = _brrp__multiformats_scope_baseX3;
|
|
27773
|
+
var Encoder3 = class {
|
|
27774
|
+
name;
|
|
27775
|
+
prefix;
|
|
27776
|
+
baseEncode;
|
|
27777
|
+
constructor(name, prefix, baseEncode) {
|
|
27778
|
+
this.name = name;
|
|
27779
|
+
this.prefix = prefix;
|
|
27780
|
+
this.baseEncode = baseEncode;
|
|
27781
|
+
}
|
|
27782
|
+
encode(bytes) {
|
|
27783
|
+
if (bytes instanceof Uint8Array) {
|
|
27784
|
+
return `${this.prefix}${this.baseEncode(bytes)}`;
|
|
27785
|
+
} else {
|
|
27786
|
+
throw Error("Unknown type, must be binary type");
|
|
27787
|
+
}
|
|
27788
|
+
}
|
|
27789
|
+
};
|
|
27790
|
+
var Decoder3 = class {
|
|
27791
|
+
name;
|
|
27792
|
+
prefix;
|
|
27793
|
+
baseDecode;
|
|
27794
|
+
prefixCodePoint;
|
|
27795
|
+
constructor(name, prefix, baseDecode) {
|
|
27796
|
+
this.name = name;
|
|
27797
|
+
this.prefix = prefix;
|
|
27798
|
+
const prefixCodePoint = prefix.codePointAt(0);
|
|
27799
|
+
if (prefixCodePoint === void 0) {
|
|
27800
|
+
throw new Error("Invalid prefix character");
|
|
27801
|
+
}
|
|
27802
|
+
this.prefixCodePoint = prefixCodePoint;
|
|
27803
|
+
this.baseDecode = baseDecode;
|
|
27804
|
+
}
|
|
27805
|
+
decode(text) {
|
|
27806
|
+
if (typeof text === "string") {
|
|
27807
|
+
if (text.codePointAt(0) !== this.prefixCodePoint) {
|
|
27808
|
+
throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);
|
|
27809
|
+
}
|
|
27810
|
+
return this.baseDecode(text.slice(this.prefix.length));
|
|
27811
|
+
} else {
|
|
27812
|
+
throw Error("Can only multibase decode strings");
|
|
27813
|
+
}
|
|
27814
|
+
}
|
|
27815
|
+
or(decoder) {
|
|
27816
|
+
return or3(this, decoder);
|
|
27817
|
+
}
|
|
27818
|
+
};
|
|
27819
|
+
var ComposedDecoder3 = class {
|
|
27820
|
+
decoders;
|
|
27821
|
+
constructor(decoders) {
|
|
27822
|
+
this.decoders = decoders;
|
|
27823
|
+
}
|
|
27824
|
+
or(decoder) {
|
|
27825
|
+
return or3(this, decoder);
|
|
27826
|
+
}
|
|
27827
|
+
decode(input) {
|
|
27828
|
+
const prefix = input[0];
|
|
27829
|
+
const decoder = this.decoders[prefix];
|
|
27830
|
+
if (decoder != null) {
|
|
27831
|
+
return decoder.decode(input);
|
|
27832
|
+
} else {
|
|
27833
|
+
throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`);
|
|
27834
|
+
}
|
|
27835
|
+
}
|
|
27836
|
+
};
|
|
27837
|
+
function or3(left, right) {
|
|
27838
|
+
return new ComposedDecoder3({
|
|
27839
|
+
...left.decoders ?? { [left.prefix]: left },
|
|
27840
|
+
...right.decoders ?? { [right.prefix]: right }
|
|
27841
|
+
});
|
|
27842
|
+
}
|
|
27843
|
+
var Codec3 = class {
|
|
27844
|
+
name;
|
|
27845
|
+
prefix;
|
|
27846
|
+
baseEncode;
|
|
27847
|
+
baseDecode;
|
|
27848
|
+
encoder;
|
|
27849
|
+
decoder;
|
|
27850
|
+
constructor(name, prefix, baseEncode, baseDecode) {
|
|
27851
|
+
this.name = name;
|
|
27852
|
+
this.prefix = prefix;
|
|
27853
|
+
this.baseEncode = baseEncode;
|
|
27854
|
+
this.baseDecode = baseDecode;
|
|
27855
|
+
this.encoder = new Encoder3(name, prefix, baseEncode);
|
|
27856
|
+
this.decoder = new Decoder3(name, prefix, baseDecode);
|
|
27857
|
+
}
|
|
27858
|
+
encode(input) {
|
|
27859
|
+
return this.encoder.encode(input);
|
|
27860
|
+
}
|
|
27861
|
+
decode(input) {
|
|
27862
|
+
return this.decoder.decode(input);
|
|
27863
|
+
}
|
|
27864
|
+
};
|
|
27865
|
+
function from3({ name, prefix, encode: encode32, decode: decode52 }) {
|
|
27866
|
+
return new Codec3(name, prefix, encode32, decode52);
|
|
27867
|
+
}
|
|
27868
|
+
function baseX3({ name, prefix, alphabet }) {
|
|
27869
|
+
const { encode: encode32, decode: decode52 } = base_x_default3(alphabet, name);
|
|
27870
|
+
return from3({
|
|
27871
|
+
prefix,
|
|
27872
|
+
name,
|
|
27873
|
+
encode: encode32,
|
|
27874
|
+
decode: (text) => coerce4(decode52(text))
|
|
27875
|
+
});
|
|
27876
|
+
}
|
|
27877
|
+
function decode9(string, alphabetIdx, bitsPerChar, name) {
|
|
27878
|
+
let end = string.length;
|
|
27879
|
+
while (string[end - 1] === "=") {
|
|
27880
|
+
--end;
|
|
27881
|
+
}
|
|
27882
|
+
const out = new Uint8Array(end * bitsPerChar / 8 | 0);
|
|
27883
|
+
let bits = 0;
|
|
27884
|
+
let buffer = 0;
|
|
27885
|
+
let written = 0;
|
|
27886
|
+
for (let i = 0; i < end; ++i) {
|
|
27887
|
+
const value = alphabetIdx[string[i]];
|
|
27888
|
+
if (value === void 0) {
|
|
27889
|
+
throw new SyntaxError(`Non-${name} character`);
|
|
27890
|
+
}
|
|
27891
|
+
buffer = buffer << bitsPerChar | value;
|
|
27892
|
+
bits += bitsPerChar;
|
|
27893
|
+
if (bits >= 8) {
|
|
27894
|
+
bits -= 8;
|
|
27895
|
+
out[written++] = 255 & buffer >> bits;
|
|
27896
|
+
}
|
|
27897
|
+
}
|
|
27898
|
+
if (bits >= bitsPerChar || (255 & buffer << 8 - bits) !== 0) {
|
|
27899
|
+
throw new SyntaxError("Unexpected end of data");
|
|
27900
|
+
}
|
|
27901
|
+
return out;
|
|
27902
|
+
}
|
|
27903
|
+
function encode5(data, alphabet, bitsPerChar) {
|
|
27904
|
+
const pad = alphabet[alphabet.length - 1] === "=";
|
|
27905
|
+
const mask = (1 << bitsPerChar) - 1;
|
|
27906
|
+
let out = "";
|
|
27907
|
+
let bits = 0;
|
|
27908
|
+
let buffer = 0;
|
|
27909
|
+
for (let i = 0; i < data.length; ++i) {
|
|
27910
|
+
buffer = buffer << 8 | data[i];
|
|
27911
|
+
bits += 8;
|
|
27912
|
+
while (bits > bitsPerChar) {
|
|
27913
|
+
bits -= bitsPerChar;
|
|
27914
|
+
out += alphabet[mask & buffer >> bits];
|
|
27915
|
+
}
|
|
27916
|
+
}
|
|
27917
|
+
if (bits !== 0) {
|
|
27918
|
+
out += alphabet[mask & buffer << bitsPerChar - bits];
|
|
27919
|
+
}
|
|
27920
|
+
if (pad) {
|
|
27921
|
+
while ((out.length * bitsPerChar & 7) !== 0) {
|
|
27922
|
+
out += "=";
|
|
27923
|
+
}
|
|
27924
|
+
}
|
|
27925
|
+
return out;
|
|
27926
|
+
}
|
|
27927
|
+
function createAlphabetIdx3(alphabet) {
|
|
27928
|
+
const alphabetIdx = {};
|
|
27929
|
+
for (let i = 0; i < alphabet.length; ++i) {
|
|
27930
|
+
alphabetIdx[alphabet[i]] = i;
|
|
27931
|
+
}
|
|
27932
|
+
return alphabetIdx;
|
|
27933
|
+
}
|
|
27934
|
+
function rfc46483({ name, prefix, bitsPerChar, alphabet }) {
|
|
27935
|
+
const alphabetIdx = createAlphabetIdx3(alphabet);
|
|
27936
|
+
return from3({
|
|
27937
|
+
prefix,
|
|
27938
|
+
name,
|
|
27939
|
+
encode(input) {
|
|
27940
|
+
return encode5(input, alphabet, bitsPerChar);
|
|
27941
|
+
},
|
|
27942
|
+
decode(input) {
|
|
27943
|
+
return decode9(input, alphabetIdx, bitsPerChar, name);
|
|
27944
|
+
}
|
|
27945
|
+
});
|
|
27946
|
+
}
|
|
27947
|
+
var base323 = rfc46483({
|
|
27948
|
+
prefix: "b",
|
|
27949
|
+
name: "base32",
|
|
27950
|
+
alphabet: "abcdefghijklmnopqrstuvwxyz234567",
|
|
27951
|
+
bitsPerChar: 5
|
|
27952
|
+
});
|
|
27953
|
+
var base32upper3 = rfc46483({
|
|
27954
|
+
prefix: "B",
|
|
27955
|
+
name: "base32upper",
|
|
27956
|
+
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
|
|
27957
|
+
bitsPerChar: 5
|
|
27958
|
+
});
|
|
27959
|
+
var base32pad3 = rfc46483({
|
|
27960
|
+
prefix: "c",
|
|
27961
|
+
name: "base32pad",
|
|
27962
|
+
alphabet: "abcdefghijklmnopqrstuvwxyz234567=",
|
|
27963
|
+
bitsPerChar: 5
|
|
27964
|
+
});
|
|
27965
|
+
var base32padupper3 = rfc46483({
|
|
27966
|
+
prefix: "C",
|
|
27967
|
+
name: "base32padupper",
|
|
27968
|
+
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
|
|
27969
|
+
bitsPerChar: 5
|
|
27970
|
+
});
|
|
27971
|
+
var base32hex3 = rfc46483({
|
|
27972
|
+
prefix: "v",
|
|
27973
|
+
name: "base32hex",
|
|
27974
|
+
alphabet: "0123456789abcdefghijklmnopqrstuv",
|
|
27975
|
+
bitsPerChar: 5
|
|
27976
|
+
});
|
|
27977
|
+
var base32hexupper3 = rfc46483({
|
|
27978
|
+
prefix: "V",
|
|
27979
|
+
name: "base32hexupper",
|
|
27980
|
+
alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
|
|
27981
|
+
bitsPerChar: 5
|
|
27982
|
+
});
|
|
27983
|
+
var base32hexpad3 = rfc46483({
|
|
27984
|
+
prefix: "t",
|
|
27985
|
+
name: "base32hexpad",
|
|
27986
|
+
alphabet: "0123456789abcdefghijklmnopqrstuv=",
|
|
27987
|
+
bitsPerChar: 5
|
|
27988
|
+
});
|
|
27989
|
+
var base32hexpadupper3 = rfc46483({
|
|
27990
|
+
prefix: "T",
|
|
27991
|
+
name: "base32hexpadupper",
|
|
27992
|
+
alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUV=",
|
|
27993
|
+
bitsPerChar: 5
|
|
27994
|
+
});
|
|
27995
|
+
var base32z3 = rfc46483({
|
|
27996
|
+
prefix: "h",
|
|
27997
|
+
name: "base32z",
|
|
27998
|
+
alphabet: "ybndrfg8ejkmcpqxot1uwisza345h769",
|
|
27999
|
+
bitsPerChar: 5
|
|
28000
|
+
});
|
|
28001
|
+
var base363 = baseX3({
|
|
28002
|
+
prefix: "k",
|
|
28003
|
+
name: "base36",
|
|
28004
|
+
alphabet: "0123456789abcdefghijklmnopqrstuvwxyz"
|
|
28005
|
+
});
|
|
28006
|
+
var base36upper3 = baseX3({
|
|
28007
|
+
prefix: "K",
|
|
28008
|
+
name: "base36upper",
|
|
28009
|
+
alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
28010
|
+
});
|
|
28011
|
+
var base58btc3 = baseX3({
|
|
28012
|
+
name: "base58btc",
|
|
28013
|
+
prefix: "z",
|
|
28014
|
+
alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
|
28015
|
+
});
|
|
28016
|
+
var base58flickr3 = baseX3({
|
|
28017
|
+
name: "base58flickr",
|
|
28018
|
+
prefix: "Z",
|
|
28019
|
+
alphabet: "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
|
|
28020
|
+
});
|
|
28021
|
+
var encode_13 = encode22;
|
|
28022
|
+
var MSB3 = 128;
|
|
28023
|
+
var REST3 = 127;
|
|
28024
|
+
var MSBALL3 = ~REST3;
|
|
28025
|
+
var INT3 = Math.pow(2, 31);
|
|
28026
|
+
function encode22(num, out, offset) {
|
|
28027
|
+
out = out || [];
|
|
28028
|
+
offset = offset || 0;
|
|
28029
|
+
var oldOffset = offset;
|
|
28030
|
+
while (num >= INT3) {
|
|
28031
|
+
out[offset++] = num & 255 | MSB3;
|
|
28032
|
+
num /= 128;
|
|
28033
|
+
}
|
|
28034
|
+
while (num & MSBALL3) {
|
|
28035
|
+
out[offset++] = num & 255 | MSB3;
|
|
28036
|
+
num >>>= 7;
|
|
28037
|
+
}
|
|
28038
|
+
out[offset] = num | 0;
|
|
28039
|
+
encode22.bytes = offset - oldOffset + 1;
|
|
28040
|
+
return out;
|
|
28041
|
+
}
|
|
28042
|
+
var decode22 = read3;
|
|
28043
|
+
var MSB$13 = 128;
|
|
28044
|
+
var REST$13 = 127;
|
|
28045
|
+
function read3(buf, offset) {
|
|
28046
|
+
var res = 0, offset = offset || 0, shift = 0, counter = offset, b, l = buf.length;
|
|
28047
|
+
do {
|
|
28048
|
+
if (counter >= l) {
|
|
28049
|
+
read3.bytes = 0;
|
|
28050
|
+
throw new RangeError("Could not decode varint");
|
|
28051
|
+
}
|
|
28052
|
+
b = buf[counter++];
|
|
28053
|
+
res += shift < 28 ? (b & REST$13) << shift : (b & REST$13) * Math.pow(2, shift);
|
|
28054
|
+
shift += 7;
|
|
28055
|
+
} while (b >= MSB$13);
|
|
28056
|
+
read3.bytes = counter - offset;
|
|
28057
|
+
return res;
|
|
28058
|
+
}
|
|
28059
|
+
var N13 = Math.pow(2, 7);
|
|
28060
|
+
var N23 = Math.pow(2, 14);
|
|
28061
|
+
var N33 = Math.pow(2, 21);
|
|
28062
|
+
var N43 = Math.pow(2, 28);
|
|
28063
|
+
var N53 = Math.pow(2, 35);
|
|
28064
|
+
var N63 = Math.pow(2, 42);
|
|
28065
|
+
var N73 = Math.pow(2, 49);
|
|
28066
|
+
var N83 = Math.pow(2, 56);
|
|
28067
|
+
var N93 = Math.pow(2, 63);
|
|
28068
|
+
var length3 = function(value) {
|
|
28069
|
+
return value < N13 ? 1 : value < N23 ? 2 : value < N33 ? 3 : value < N43 ? 4 : value < N53 ? 5 : value < N63 ? 6 : value < N73 ? 7 : value < N83 ? 8 : value < N93 ? 9 : 10;
|
|
28070
|
+
};
|
|
28071
|
+
var varint3 = {
|
|
28072
|
+
encode: encode_13,
|
|
28073
|
+
decode: decode22,
|
|
28074
|
+
encodingLength: length3
|
|
28075
|
+
};
|
|
28076
|
+
var _brrp_varint3 = varint3;
|
|
28077
|
+
var varint_default3 = _brrp_varint3;
|
|
28078
|
+
function decode32(data, offset = 0) {
|
|
28079
|
+
const code22 = varint_default3.decode(data, offset);
|
|
28080
|
+
return [code22, varint_default3.decode.bytes];
|
|
28081
|
+
}
|
|
28082
|
+
function encodeTo3(int, target, offset = 0) {
|
|
28083
|
+
varint_default3.encode(int, target, offset);
|
|
28084
|
+
return target;
|
|
28085
|
+
}
|
|
28086
|
+
function encodingLength3(int) {
|
|
28087
|
+
return varint_default3.encodingLength(int);
|
|
28088
|
+
}
|
|
28089
|
+
function create3(code22, digest2) {
|
|
28090
|
+
const size = digest2.byteLength;
|
|
28091
|
+
const sizeOffset = encodingLength3(code22);
|
|
28092
|
+
const digestOffset = sizeOffset + encodingLength3(size);
|
|
28093
|
+
const bytes = new Uint8Array(digestOffset + size);
|
|
28094
|
+
encodeTo3(code22, bytes, 0);
|
|
28095
|
+
encodeTo3(size, bytes, sizeOffset);
|
|
28096
|
+
bytes.set(digest2, digestOffset);
|
|
28097
|
+
return new Digest3(code22, size, digest2, bytes);
|
|
28098
|
+
}
|
|
28099
|
+
function decode42(multihash) {
|
|
28100
|
+
const bytes = coerce4(multihash);
|
|
28101
|
+
const [code22, sizeOffset] = decode32(bytes);
|
|
28102
|
+
const [size, digestOffset] = decode32(bytes.subarray(sizeOffset));
|
|
28103
|
+
const digest2 = bytes.subarray(sizeOffset + digestOffset);
|
|
28104
|
+
if (digest2.byteLength !== size) {
|
|
28105
|
+
throw new Error("Incorrect length");
|
|
28106
|
+
}
|
|
28107
|
+
return new Digest3(code22, size, digest2, bytes);
|
|
28108
|
+
}
|
|
28109
|
+
function equals22(a, b) {
|
|
28110
|
+
if (a === b) {
|
|
28111
|
+
return true;
|
|
28112
|
+
} else {
|
|
28113
|
+
const data = b;
|
|
28114
|
+
return a.code === data.code && a.size === data.size && data.bytes instanceof Uint8Array && equals5(a.bytes, data.bytes);
|
|
28115
|
+
}
|
|
28116
|
+
}
|
|
28117
|
+
var Digest3 = class {
|
|
28118
|
+
code;
|
|
28119
|
+
size;
|
|
28120
|
+
digest;
|
|
28121
|
+
bytes;
|
|
28122
|
+
/**
|
|
28123
|
+
* Creates a multihash digest.
|
|
28124
|
+
*/
|
|
28125
|
+
constructor(code22, size, digest2, bytes) {
|
|
28126
|
+
this.code = code22;
|
|
28127
|
+
this.size = size;
|
|
28128
|
+
this.digest = digest2;
|
|
28129
|
+
this.bytes = bytes;
|
|
28130
|
+
}
|
|
28131
|
+
};
|
|
28132
|
+
function format3(link2, base22) {
|
|
28133
|
+
const { bytes, version } = link2;
|
|
28134
|
+
switch (version) {
|
|
28135
|
+
case 0:
|
|
28136
|
+
return toStringV03(bytes, baseCache3(link2), base22 ?? base58btc3.encoder);
|
|
28137
|
+
default:
|
|
28138
|
+
return toStringV13(bytes, baseCache3(link2), base22 ?? base323.encoder);
|
|
28139
|
+
}
|
|
28140
|
+
}
|
|
28141
|
+
var cache3 = /* @__PURE__ */ new WeakMap();
|
|
28142
|
+
function baseCache3(cid) {
|
|
28143
|
+
const baseCache22 = cache3.get(cid);
|
|
28144
|
+
if (baseCache22 == null) {
|
|
28145
|
+
const baseCache32 = /* @__PURE__ */ new Map();
|
|
28146
|
+
cache3.set(cid, baseCache32);
|
|
28147
|
+
return baseCache32;
|
|
28148
|
+
}
|
|
28149
|
+
return baseCache22;
|
|
28150
|
+
}
|
|
28151
|
+
var CID3 = class _CID3 {
|
|
28152
|
+
code;
|
|
28153
|
+
version;
|
|
28154
|
+
multihash;
|
|
28155
|
+
bytes;
|
|
28156
|
+
"/";
|
|
28157
|
+
/**
|
|
28158
|
+
* @param version - Version of the CID
|
|
28159
|
+
* @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv
|
|
28160
|
+
* @param multihash - (Multi)hash of the of the content.
|
|
28161
|
+
*/
|
|
28162
|
+
constructor(version, code22, multihash, bytes) {
|
|
28163
|
+
this.code = code22;
|
|
28164
|
+
this.version = version;
|
|
28165
|
+
this.multihash = multihash;
|
|
28166
|
+
this.bytes = bytes;
|
|
28167
|
+
this["/"] = bytes;
|
|
28168
|
+
}
|
|
28169
|
+
/**
|
|
28170
|
+
* Signalling `cid.asCID === cid` has been replaced with `cid['/'] === cid.bytes`
|
|
28171
|
+
* please either use `CID.asCID(cid)` or switch to new signalling mechanism
|
|
28172
|
+
*
|
|
28173
|
+
* @deprecated
|
|
28174
|
+
*/
|
|
28175
|
+
get asCID() {
|
|
28176
|
+
return this;
|
|
28177
|
+
}
|
|
28178
|
+
// ArrayBufferView
|
|
28179
|
+
get byteOffset() {
|
|
28180
|
+
return this.bytes.byteOffset;
|
|
28181
|
+
}
|
|
28182
|
+
// ArrayBufferView
|
|
28183
|
+
get byteLength() {
|
|
28184
|
+
return this.bytes.byteLength;
|
|
28185
|
+
}
|
|
28186
|
+
toV0() {
|
|
28187
|
+
switch (this.version) {
|
|
28188
|
+
case 0: {
|
|
28189
|
+
return this;
|
|
28190
|
+
}
|
|
28191
|
+
case 1: {
|
|
28192
|
+
const { code: code22, multihash } = this;
|
|
28193
|
+
if (code22 !== DAG_PB_CODE3) {
|
|
28194
|
+
throw new Error("Cannot convert a non dag-pb CID to CIDv0");
|
|
28195
|
+
}
|
|
28196
|
+
if (multihash.code !== SHA_256_CODE3) {
|
|
28197
|
+
throw new Error("Cannot convert non sha2-256 multihash CID to CIDv0");
|
|
28198
|
+
}
|
|
28199
|
+
return _CID3.createV0(multihash);
|
|
28200
|
+
}
|
|
28201
|
+
default: {
|
|
28202
|
+
throw Error(`Can not convert CID version ${this.version} to version 0. This is a bug please report`);
|
|
28203
|
+
}
|
|
28204
|
+
}
|
|
28205
|
+
}
|
|
28206
|
+
toV1() {
|
|
28207
|
+
switch (this.version) {
|
|
28208
|
+
case 0: {
|
|
28209
|
+
const { code: code22, digest: digest2 } = this.multihash;
|
|
28210
|
+
const multihash = create3(code22, digest2);
|
|
28211
|
+
return _CID3.createV1(this.code, multihash);
|
|
28212
|
+
}
|
|
28213
|
+
case 1: {
|
|
28214
|
+
return this;
|
|
28215
|
+
}
|
|
28216
|
+
default: {
|
|
28217
|
+
throw Error(`Can not convert CID version ${this.version} to version 1. This is a bug please report`);
|
|
28218
|
+
}
|
|
28219
|
+
}
|
|
28220
|
+
}
|
|
28221
|
+
equals(other) {
|
|
28222
|
+
return _CID3.equals(this, other);
|
|
28223
|
+
}
|
|
28224
|
+
static equals(self, other) {
|
|
28225
|
+
const unknown = other;
|
|
28226
|
+
return unknown != null && self.code === unknown.code && self.version === unknown.version && equals22(self.multihash, unknown.multihash);
|
|
28227
|
+
}
|
|
28228
|
+
toString(base22) {
|
|
28229
|
+
return format3(this, base22);
|
|
28230
|
+
}
|
|
28231
|
+
toJSON() {
|
|
28232
|
+
return { "/": format3(this) };
|
|
28233
|
+
}
|
|
28234
|
+
link() {
|
|
28235
|
+
return this;
|
|
28236
|
+
}
|
|
28237
|
+
[Symbol.toStringTag] = "CID";
|
|
28238
|
+
// Legacy
|
|
28239
|
+
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
|
|
28240
|
+
return `CID(${this.toString()})`;
|
|
28241
|
+
}
|
|
28242
|
+
/**
|
|
28243
|
+
* Takes any input `value` and returns a `CID` instance if it was
|
|
28244
|
+
* a `CID` otherwise returns `null`. If `value` is instanceof `CID`
|
|
28245
|
+
* it will return value back. If `value` is not instance of this CID
|
|
28246
|
+
* class, but is compatible CID it will return new instance of this
|
|
28247
|
+
* `CID` class. Otherwise returns null.
|
|
28248
|
+
*
|
|
28249
|
+
* This allows two different incompatible versions of CID library to
|
|
28250
|
+
* co-exist and interop as long as binary interface is compatible.
|
|
28251
|
+
*/
|
|
28252
|
+
static asCID(input) {
|
|
28253
|
+
if (input == null) {
|
|
28254
|
+
return null;
|
|
28255
|
+
}
|
|
28256
|
+
const value = input;
|
|
28257
|
+
if (value instanceof _CID3) {
|
|
28258
|
+
return value;
|
|
28259
|
+
} else if (value["/"] != null && value["/"] === value.bytes || value.asCID === value) {
|
|
28260
|
+
const { version, code: code22, multihash, bytes } = value;
|
|
28261
|
+
return new _CID3(version, code22, multihash, bytes ?? encodeCID3(version, code22, multihash.bytes));
|
|
28262
|
+
} else if (value[cidSymbol3] === true) {
|
|
28263
|
+
const { version, multihash, code: code22 } = value;
|
|
28264
|
+
const digest2 = decode42(multihash);
|
|
28265
|
+
return _CID3.create(version, code22, digest2);
|
|
28266
|
+
} else {
|
|
28267
|
+
return null;
|
|
28268
|
+
}
|
|
28269
|
+
}
|
|
28270
|
+
/**
|
|
28271
|
+
* @param version - Version of the CID
|
|
28272
|
+
* @param code - Code of the codec content is encoded in, see https://github.com/multiformats/multicodec/blob/master/table.csv
|
|
28273
|
+
* @param digest - (Multi)hash of the of the content.
|
|
28274
|
+
*/
|
|
28275
|
+
static create(version, code22, digest2) {
|
|
28276
|
+
if (typeof code22 !== "number") {
|
|
28277
|
+
throw new Error("String codecs are no longer supported");
|
|
28278
|
+
}
|
|
28279
|
+
if (!(digest2.bytes instanceof Uint8Array)) {
|
|
28280
|
+
throw new Error("Invalid digest");
|
|
28281
|
+
}
|
|
28282
|
+
switch (version) {
|
|
28283
|
+
case 0: {
|
|
28284
|
+
if (code22 !== DAG_PB_CODE3) {
|
|
28285
|
+
throw new Error(`Version 0 CID must use dag-pb (code: ${DAG_PB_CODE3}) block encoding`);
|
|
28286
|
+
} else {
|
|
28287
|
+
return new _CID3(version, code22, digest2, digest2.bytes);
|
|
28288
|
+
}
|
|
28289
|
+
}
|
|
28290
|
+
case 1: {
|
|
28291
|
+
const bytes = encodeCID3(version, code22, digest2.bytes);
|
|
28292
|
+
return new _CID3(version, code22, digest2, bytes);
|
|
28293
|
+
}
|
|
28294
|
+
default: {
|
|
28295
|
+
throw new Error("Invalid version");
|
|
28296
|
+
}
|
|
28297
|
+
}
|
|
28298
|
+
}
|
|
28299
|
+
/**
|
|
28300
|
+
* Simplified version of `create` for CIDv0.
|
|
28301
|
+
*/
|
|
28302
|
+
static createV0(digest2) {
|
|
28303
|
+
return _CID3.create(0, DAG_PB_CODE3, digest2);
|
|
28304
|
+
}
|
|
28305
|
+
/**
|
|
28306
|
+
* Simplified version of `create` for CIDv1.
|
|
28307
|
+
*
|
|
28308
|
+
* @param code - Content encoding format code.
|
|
28309
|
+
* @param digest - Multihash of the content.
|
|
28310
|
+
*/
|
|
28311
|
+
static createV1(code22, digest2) {
|
|
28312
|
+
return _CID3.create(1, code22, digest2);
|
|
28313
|
+
}
|
|
28314
|
+
/**
|
|
28315
|
+
* Decoded a CID from its binary representation. The byte array must contain
|
|
28316
|
+
* only the CID with no additional bytes.
|
|
28317
|
+
*
|
|
28318
|
+
* An error will be thrown if the bytes provided do not contain a valid
|
|
28319
|
+
* binary representation of a CID.
|
|
28320
|
+
*/
|
|
28321
|
+
static decode(bytes) {
|
|
28322
|
+
const [cid, remainder] = _CID3.decodeFirst(bytes);
|
|
28323
|
+
if (remainder.length !== 0) {
|
|
28324
|
+
throw new Error("Incorrect length");
|
|
28325
|
+
}
|
|
28326
|
+
return cid;
|
|
28327
|
+
}
|
|
28328
|
+
/**
|
|
28329
|
+
* Decoded a CID from its binary representation at the beginning of a byte
|
|
28330
|
+
* array.
|
|
28331
|
+
*
|
|
28332
|
+
* Returns an array with the first element containing the CID and the second
|
|
28333
|
+
* element containing the remainder of the original byte array. The remainder
|
|
28334
|
+
* will be a zero-length byte array if the provided bytes only contained a
|
|
28335
|
+
* binary CID representation.
|
|
28336
|
+
*/
|
|
28337
|
+
static decodeFirst(bytes) {
|
|
28338
|
+
const specs = _CID3.inspectBytes(bytes);
|
|
28339
|
+
const prefixSize = specs.size - specs.multihashSize;
|
|
28340
|
+
const multihashBytes = coerce4(bytes.subarray(prefixSize, prefixSize + specs.multihashSize));
|
|
28341
|
+
if (multihashBytes.byteLength !== specs.multihashSize) {
|
|
28342
|
+
throw new Error("Incorrect length");
|
|
28343
|
+
}
|
|
28344
|
+
const digestBytes = multihashBytes.subarray(specs.multihashSize - specs.digestSize);
|
|
28345
|
+
const digest2 = new Digest3(specs.multihashCode, specs.digestSize, digestBytes, multihashBytes);
|
|
28346
|
+
const cid = specs.version === 0 ? _CID3.createV0(digest2) : _CID3.createV1(specs.codec, digest2);
|
|
28347
|
+
return [cid, bytes.subarray(specs.size)];
|
|
28348
|
+
}
|
|
28349
|
+
/**
|
|
28350
|
+
* Inspect the initial bytes of a CID to determine its properties.
|
|
28351
|
+
*
|
|
28352
|
+
* Involves decoding up to 4 varints. Typically this will require only 4 to 6
|
|
28353
|
+
* bytes but for larger multicodec code values and larger multihash digest
|
|
28354
|
+
* lengths these varints can be quite large. It is recommended that at least
|
|
28355
|
+
* 10 bytes be made available in the `initialBytes` argument for a complete
|
|
28356
|
+
* inspection.
|
|
28357
|
+
*/
|
|
28358
|
+
static inspectBytes(initialBytes) {
|
|
28359
|
+
let offset = 0;
|
|
28360
|
+
const next = () => {
|
|
28361
|
+
const [i, length22] = decode32(initialBytes.subarray(offset));
|
|
28362
|
+
offset += length22;
|
|
28363
|
+
return i;
|
|
28364
|
+
};
|
|
28365
|
+
let version = next();
|
|
28366
|
+
let codec = DAG_PB_CODE3;
|
|
28367
|
+
if (version === 18) {
|
|
28368
|
+
version = 0;
|
|
28369
|
+
offset = 0;
|
|
28370
|
+
} else {
|
|
28371
|
+
codec = next();
|
|
28372
|
+
}
|
|
28373
|
+
if (version !== 0 && version !== 1) {
|
|
28374
|
+
throw new RangeError(`Invalid CID version ${version}`);
|
|
28375
|
+
}
|
|
28376
|
+
const prefixSize = offset;
|
|
28377
|
+
const multihashCode = next();
|
|
28378
|
+
const digestSize = next();
|
|
28379
|
+
const size = offset + digestSize;
|
|
28380
|
+
const multihashSize = size - prefixSize;
|
|
28381
|
+
return { version, codec, multihashCode, digestSize, multihashSize, size };
|
|
28382
|
+
}
|
|
28383
|
+
/**
|
|
28384
|
+
* Takes cid in a string representation and creates an instance. If `base`
|
|
28385
|
+
* decoder is not provided will use a default from the configuration. It will
|
|
28386
|
+
* throw an error if encoding of the CID is not compatible with supplied (or
|
|
28387
|
+
* a default decoder).
|
|
28388
|
+
*/
|
|
28389
|
+
static parse(source, base22) {
|
|
28390
|
+
const [prefix, bytes] = parseCIDtoBytes3(source, base22);
|
|
28391
|
+
const cid = _CID3.decode(bytes);
|
|
28392
|
+
if (cid.version === 0 && source[0] !== "Q") {
|
|
28393
|
+
throw Error("Version 0 CID string must not include multibase prefix");
|
|
28394
|
+
}
|
|
28395
|
+
baseCache3(cid).set(prefix, source);
|
|
28396
|
+
return cid;
|
|
28397
|
+
}
|
|
28398
|
+
};
|
|
28399
|
+
function parseCIDtoBytes3(source, base22) {
|
|
28400
|
+
switch (source[0]) {
|
|
28401
|
+
// CIDv0 is parsed differently
|
|
28402
|
+
case "Q": {
|
|
28403
|
+
const decoder = base22 ?? base58btc3;
|
|
28404
|
+
return [
|
|
28405
|
+
base58btc3.prefix,
|
|
28406
|
+
decoder.decode(`${base58btc3.prefix}${source}`)
|
|
28407
|
+
];
|
|
28408
|
+
}
|
|
28409
|
+
case base58btc3.prefix: {
|
|
28410
|
+
const decoder = base22 ?? base58btc3;
|
|
28411
|
+
return [base58btc3.prefix, decoder.decode(source)];
|
|
28412
|
+
}
|
|
28413
|
+
case base323.prefix: {
|
|
28414
|
+
const decoder = base22 ?? base323;
|
|
28415
|
+
return [base323.prefix, decoder.decode(source)];
|
|
28416
|
+
}
|
|
28417
|
+
case base363.prefix: {
|
|
28418
|
+
const decoder = base22 ?? base363;
|
|
28419
|
+
return [base363.prefix, decoder.decode(source)];
|
|
28420
|
+
}
|
|
28421
|
+
default: {
|
|
28422
|
+
if (base22 == null) {
|
|
28423
|
+
throw Error("To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided");
|
|
28424
|
+
}
|
|
28425
|
+
return [source[0], base22.decode(source)];
|
|
28426
|
+
}
|
|
28427
|
+
}
|
|
28428
|
+
}
|
|
28429
|
+
function toStringV03(bytes, cache22, base22) {
|
|
28430
|
+
const { prefix } = base22;
|
|
28431
|
+
if (prefix !== base58btc3.prefix) {
|
|
28432
|
+
throw Error(`Cannot string encode V0 in ${base22.name} encoding`);
|
|
28433
|
+
}
|
|
28434
|
+
const cid = cache22.get(prefix);
|
|
28435
|
+
if (cid == null) {
|
|
28436
|
+
const cid2 = base22.encode(bytes).slice(1);
|
|
28437
|
+
cache22.set(prefix, cid2);
|
|
28438
|
+
return cid2;
|
|
28439
|
+
} else {
|
|
28440
|
+
return cid;
|
|
28441
|
+
}
|
|
28442
|
+
}
|
|
28443
|
+
function toStringV13(bytes, cache22, base22) {
|
|
28444
|
+
const { prefix } = base22;
|
|
28445
|
+
const cid = cache22.get(prefix);
|
|
28446
|
+
if (cid == null) {
|
|
28447
|
+
const cid2 = base22.encode(bytes);
|
|
28448
|
+
cache22.set(prefix, cid2);
|
|
28449
|
+
return cid2;
|
|
28450
|
+
} else {
|
|
28451
|
+
return cid;
|
|
28452
|
+
}
|
|
28453
|
+
}
|
|
28454
|
+
var DAG_PB_CODE3 = 112;
|
|
28455
|
+
var SHA_256_CODE3 = 18;
|
|
28456
|
+
function encodeCID3(version, code22, multihash) {
|
|
28457
|
+
const codeOffset = encodingLength3(version);
|
|
28458
|
+
const hashOffset = codeOffset + encodingLength3(code22);
|
|
28459
|
+
const bytes = new Uint8Array(hashOffset + multihash.byteLength);
|
|
28460
|
+
encodeTo3(version, bytes, 0);
|
|
28461
|
+
encodeTo3(code22, bytes, codeOffset);
|
|
28462
|
+
bytes.set(multihash, hashOffset);
|
|
28463
|
+
return bytes;
|
|
28464
|
+
}
|
|
28465
|
+
var cidSymbol3 = /* @__PURE__ */ Symbol.for("@ipld/js-cid/CID");
|
|
28466
|
+
var code2 = 85;
|
|
28467
|
+
var SHA256_CODE2 = 18;
|
|
28468
|
+
function isCanonicalRawCid2(cidString) {
|
|
28469
|
+
let cid;
|
|
28470
|
+
try {
|
|
28471
|
+
cid = CID3.parse(cidString);
|
|
28472
|
+
} catch {
|
|
28473
|
+
return false;
|
|
28474
|
+
}
|
|
28475
|
+
return cid.version === 1 && cid.code === code2 && cid.multihash.code === SHA256_CODE2 && cid.toString() === cidString;
|
|
28476
|
+
}
|
|
28477
|
+
var base642 = rfc46483({
|
|
28478
|
+
prefix: "m",
|
|
28479
|
+
name: "base64",
|
|
28480
|
+
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
|
|
28481
|
+
bitsPerChar: 6
|
|
28482
|
+
});
|
|
28483
|
+
var base64pad2 = rfc46483({
|
|
28484
|
+
prefix: "M",
|
|
28485
|
+
name: "base64pad",
|
|
28486
|
+
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
|
28487
|
+
bitsPerChar: 6
|
|
28488
|
+
});
|
|
28489
|
+
var base64url2 = rfc46483({
|
|
28490
|
+
prefix: "u",
|
|
28491
|
+
name: "base64url",
|
|
28492
|
+
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
|
|
28493
|
+
bitsPerChar: 6
|
|
28494
|
+
});
|
|
28495
|
+
var base64urlpad2 = rfc46483({
|
|
28496
|
+
prefix: "U",
|
|
28497
|
+
name: "base64urlpad",
|
|
28498
|
+
alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
|
|
28499
|
+
bitsPerChar: 6
|
|
28500
|
+
});
|
|
28501
|
+
function fromBase64Url2(text) {
|
|
28502
|
+
const bytes = base64url2.baseDecode(text);
|
|
28503
|
+
if (base64url2.baseEncode(bytes) !== text) {
|
|
28504
|
+
throw new TypeError("non-canonical base64url input");
|
|
28505
|
+
}
|
|
28506
|
+
return bytes;
|
|
28507
|
+
}
|
|
28508
|
+
function utf8Bytes2(text) {
|
|
28509
|
+
return new TextEncoder().encode(text);
|
|
28510
|
+
}
|
|
28511
|
+
var ED25519_MULTICODEC_PREFIX2 = Uint8Array.of(237, 1);
|
|
28512
|
+
function decodeBase64UrlOrNull2(value) {
|
|
28513
|
+
try {
|
|
28514
|
+
return fromBase64Url2(value);
|
|
28515
|
+
} catch {
|
|
28516
|
+
return null;
|
|
28517
|
+
}
|
|
28518
|
+
}
|
|
28519
|
+
var base64UrlString2 = () => external_exports.string().refine((value) => decodeBase64UrlOrNull2(value) !== null, {
|
|
28520
|
+
message: "expected strictly-decodable unpadded base64url"
|
|
28521
|
+
});
|
|
28522
|
+
function isCanonicalHttpsOrigin2(value) {
|
|
28523
|
+
let url;
|
|
28524
|
+
try {
|
|
28525
|
+
url = new URL(value);
|
|
28526
|
+
} catch {
|
|
28527
|
+
return false;
|
|
28528
|
+
}
|
|
28529
|
+
return url.protocol === "https:" && url.origin === value;
|
|
28530
|
+
}
|
|
28531
|
+
var sessionJwkCommonFields2 = {
|
|
28532
|
+
alg: external_exports.string().min(1).optional(),
|
|
28533
|
+
use: external_exports.string().min(1).optional(),
|
|
28534
|
+
key_ops: external_exports.array(external_exports.string().min(1)).optional(),
|
|
28535
|
+
kid: external_exports.string().min(1).optional(),
|
|
28536
|
+
ext: external_exports.boolean().optional()
|
|
28537
|
+
};
|
|
28538
|
+
var okpPrivateJwkSchema2 = external_exports.object({
|
|
28539
|
+
kty: external_exports.literal("OKP"),
|
|
28540
|
+
crv: external_exports.string().min(1),
|
|
28541
|
+
x: base64UrlString2(),
|
|
28542
|
+
d: base64UrlString2(),
|
|
28543
|
+
...sessionJwkCommonFields2
|
|
28544
|
+
}).strict();
|
|
28545
|
+
var ecPrivateJwkSchema2 = external_exports.object({
|
|
28546
|
+
kty: external_exports.literal("EC"),
|
|
28547
|
+
crv: external_exports.string().min(1),
|
|
28548
|
+
x: base64UrlString2(),
|
|
28549
|
+
y: base64UrlString2(),
|
|
28550
|
+
d: base64UrlString2(),
|
|
28551
|
+
...sessionJwkCommonFields2
|
|
28552
|
+
}).strict();
|
|
28553
|
+
var sessionJwkSchema2 = external_exports.discriminatedUnion("kty", [
|
|
28554
|
+
okpPrivateJwkSchema2,
|
|
28555
|
+
ecPrivateJwkSchema2
|
|
28556
|
+
]);
|
|
28557
|
+
var policyTargetSchema2 = external_exports.object({
|
|
28558
|
+
kind: external_exports.literal("policy"),
|
|
28559
|
+
policyCid: external_exports.string().min(1),
|
|
28560
|
+
/** Canonical policy bytes, base64url-encoded (bytes are not JSON). */
|
|
28561
|
+
policyBytes: base64UrlString2()
|
|
28562
|
+
}).strict();
|
|
28563
|
+
var bearerKeyTargetSchema2 = external_exports.object({
|
|
28564
|
+
kind: external_exports.literal("bearerKey"),
|
|
28565
|
+
sessionJwk: sessionJwkSchema2
|
|
28566
|
+
}).strict();
|
|
28567
|
+
var recipientDidTargetSchema2 = external_exports.object({
|
|
28568
|
+
kind: external_exports.literal("recipientDid"),
|
|
28569
|
+
did: external_exports.string().regex(/^did:[a-z0-9]+:.+$/, "expected a DID")
|
|
28570
|
+
}).strict();
|
|
28571
|
+
var authorizationTargetSchema2 = external_exports.discriminatedUnion("kind", [
|
|
28572
|
+
policyTargetSchema2,
|
|
28573
|
+
bearerKeyTargetSchema2,
|
|
28574
|
+
recipientDidTargetSchema2
|
|
28575
|
+
]);
|
|
28576
|
+
function isCanonicalResourcePath2(value) {
|
|
28577
|
+
if (value.length === 0) return false;
|
|
28578
|
+
if (/[\u0000-\u001f\u007f\\]/.test(value)) return false;
|
|
28579
|
+
if (/%2f|%5c|%2e/i.test(value)) return false;
|
|
28580
|
+
return value.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
28581
|
+
}
|
|
28582
|
+
function isCanonicalPathSegment2(value) {
|
|
28583
|
+
return isCanonicalResourcePath2(value) && !value.includes("/");
|
|
28584
|
+
}
|
|
28585
|
+
var resourceSelectorSchema2 = external_exports.object({
|
|
28586
|
+
kind: external_exports.union([external_exports.literal("exact"), external_exports.literal("prefix")]),
|
|
28587
|
+
path: external_exports.string().min(1)
|
|
28588
|
+
}).strict().superRefine((selector, ctx) => {
|
|
28589
|
+
const body = selector.kind === "prefix" && selector.path.endsWith("/") ? selector.path.slice(0, -1) : selector.path;
|
|
28590
|
+
if (!isCanonicalResourcePath2(body)) {
|
|
28591
|
+
ctx.addIssue({
|
|
28592
|
+
code: external_exports.ZodIssueCode.custom,
|
|
28593
|
+
path: ["path"],
|
|
28594
|
+
message: "expected a canonical resource path (non-empty segments, no . or .. segments, no //, no backslash, no %2f/%5c/%2e, no control chars)"
|
|
28595
|
+
});
|
|
28596
|
+
}
|
|
28597
|
+
});
|
|
28598
|
+
var targetSchema2 = external_exports.object({
|
|
28599
|
+
origin: external_exports.string().refine(isCanonicalHttpsOrigin2, {
|
|
28600
|
+
message: "expected a canonical https origin (https://host[:port], nothing else)"
|
|
28601
|
+
}),
|
|
28602
|
+
nodeAudience: external_exports.string().min(1),
|
|
28603
|
+
spaceId: external_exports.string().refine(isCanonicalPathSegment2, {
|
|
28604
|
+
message: "expected a single canonical path segment (spaceId joins the resource URI; separators/traversal would alias grants)"
|
|
28605
|
+
}),
|
|
28606
|
+
resource: resourceSelectorSchema2
|
|
28607
|
+
}).strict();
|
|
28608
|
+
var displaySchema2 = external_exports.object({
|
|
28609
|
+
senderName: external_exports.string().optional(),
|
|
28610
|
+
filename: external_exports.string().optional(),
|
|
28611
|
+
recipientHint: external_exports.string().optional(),
|
|
28612
|
+
/**
|
|
28613
|
+
* Presentation preference only (viewer spec §1): may narrow, never widen;
|
|
28614
|
+
* capabilities always win.
|
|
28615
|
+
*/
|
|
28616
|
+
mode: external_exports.union([external_exports.literal("document"), external_exports.literal("source"), external_exports.literal("folder")]).optional()
|
|
28617
|
+
}).strict();
|
|
28618
|
+
var contentPointerSchema2 = external_exports.object({
|
|
28619
|
+
cid: external_exports.string().refine(isCanonicalRawCid2, {
|
|
28620
|
+
message: "expected a canonical CIDv1 raw sha2-256 base32 CID"
|
|
28621
|
+
}),
|
|
28622
|
+
key: external_exports.string().refine((value) => decodeBase64UrlOrNull2(value)?.length === 32, {
|
|
28623
|
+
message: "expected base64url decoding to exactly 32 bytes"
|
|
28624
|
+
})
|
|
28625
|
+
}).strict();
|
|
28626
|
+
var signatureSchema2 = external_exports.object({
|
|
28627
|
+
/** did:key of the sender's ed25519 signing key. */
|
|
28628
|
+
signerDid: external_exports.string().regex(/^did:key:z[1-9A-HJ-NP-Za-km-z]+$/, "expected a did:key"),
|
|
28629
|
+
algorithm: external_exports.literal("Ed25519"),
|
|
28630
|
+
/** base64url-encoded ed25519 signature over the JCS bytes of all other fields. */
|
|
28631
|
+
value: external_exports.string().refine((value) => decodeBase64UrlOrNull2(value)?.length === 64, {
|
|
28632
|
+
message: "expected base64url decoding to exactly 64 bytes"
|
|
28633
|
+
})
|
|
28634
|
+
}).strict();
|
|
28635
|
+
var unsignedShareEnvelopeSchema2 = external_exports.object({
|
|
28636
|
+
version: external_exports.literal(1),
|
|
28637
|
+
shareId: external_exports.string().min(1),
|
|
28638
|
+
/** Full signed delegation chain, opaque serialized form. */
|
|
28639
|
+
delegation: external_exports.string().min(1),
|
|
28640
|
+
authorizationTarget: authorizationTargetSchema2,
|
|
28641
|
+
target: targetSchema2,
|
|
28642
|
+
display: displaySchema2,
|
|
28643
|
+
/** ISO 8601 UTC datetime. Advisory here; enforcement is the delegation's. */
|
|
28644
|
+
expiry: external_exports.string().datetime(),
|
|
28645
|
+
/** Bearer-slice sealed-content pointer (see contentPointerSchema). */
|
|
28646
|
+
content: contentPointerSchema2.optional()
|
|
28647
|
+
}).strict();
|
|
28648
|
+
var shareEnvelopeSchema2 = unsignedShareEnvelopeSchema2.extend({ signature: signatureSchema2 }).strict();
|
|
28649
|
+
var recipientMatcherSchema2 = external_exports.discriminatedUnion("kind", [
|
|
28650
|
+
external_exports.object({ kind: external_exports.literal("exactEmail"), value: external_exports.string().min(3).regex(/^[^@\s]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/) }).strict(),
|
|
28651
|
+
external_exports.object({ kind: external_exports.literal("emailDomain"), value: external_exports.string().regex(/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/) }).strict(),
|
|
28652
|
+
external_exports.object({ kind: external_exports.literal("recipientDid"), value: external_exports.string().regex(/^did:[a-z0-9]+:.+$/) }).strict(),
|
|
28653
|
+
external_exports.object({ kind: external_exports.literal("policyDigest"), value: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/) }).strict(),
|
|
28654
|
+
external_exports.object({ kind: external_exports.literal("bearer") }).strict()
|
|
28655
|
+
]);
|
|
28656
|
+
var shareActionSchema2 = external_exports.union([external_exports.literal("read"), external_exports.literal("list"), external_exports.literal("edit")]);
|
|
28657
|
+
var kvContentSourceSchema2 = external_exports.object({
|
|
28658
|
+
kind: external_exports.literal("kv"),
|
|
28659
|
+
space: external_exports.string().min(1),
|
|
28660
|
+
path: external_exports.string().min(1),
|
|
28661
|
+
action: external_exports.literal("tinycloud.kv/get")
|
|
28662
|
+
}).strict();
|
|
28663
|
+
var sqlContentSourceSchema2 = external_exports.object({
|
|
28664
|
+
kind: external_exports.literal("sql"),
|
|
28665
|
+
space: external_exports.string().min(1),
|
|
28666
|
+
database: external_exports.string().min(1),
|
|
28667
|
+
path: external_exports.string().min(1),
|
|
28668
|
+
statement: external_exports.string().min(1),
|
|
28669
|
+
arguments: external_exports.record(external_exports.string(), external_exports.number().int()),
|
|
28670
|
+
argumentsDigest: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
28671
|
+
action: external_exports.literal("tinycloud.sql/read")
|
|
28672
|
+
}).strict();
|
|
28673
|
+
var contentSourceSchema2 = external_exports.discriminatedUnion("kind", [kvContentSourceSchema2, sqlContentSourceSchema2]);
|
|
28674
|
+
var v2TargetSchema2 = external_exports.object({
|
|
28675
|
+
origin: external_exports.string().refine(isCanonicalHttpsOrigin2, { message: "expected a canonical https origin" }),
|
|
28676
|
+
nodeAudience: external_exports.string().min(1),
|
|
28677
|
+
spaceId: external_exports.string().refine(isCanonicalPathSegment2, { message: "expected a canonical space id" })
|
|
28678
|
+
}).strict();
|
|
28679
|
+
var shareDecryptionSchema2 = external_exports.object({
|
|
28680
|
+
networkId: external_exports.string().min(1),
|
|
28681
|
+
action: external_exports.literal("tinycloud.encryption/decrypt")
|
|
28682
|
+
}).strict();
|
|
28683
|
+
var ownerAuthoritySchema2 = external_exports.object({
|
|
28684
|
+
registrationCid: external_exports.string().min(1),
|
|
28685
|
+
shareCid: external_exports.string().min(1),
|
|
28686
|
+
envelopeCid: external_exports.string().min(1),
|
|
28687
|
+
enforcementDelegation: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
28688
|
+
outerEnvelope: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
28689
|
+
/** Node-signed registration evidence; required by trusted policy adapters. */
|
|
28690
|
+
registrationReceipt: external_exports.object({
|
|
28691
|
+
registration: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
28692
|
+
proof: external_exports.record(external_exports.string(), external_exports.unknown())
|
|
28693
|
+
}).strict().optional()
|
|
28694
|
+
}).strict();
|
|
28695
|
+
var contentMetadataSchema2 = external_exports.object({
|
|
28696
|
+
mediaType: external_exports.string().min(1).max(128).optional(),
|
|
28697
|
+
byteLength: external_exports.number().int().nonnegative().max(100 * 1024 * 1024).optional(),
|
|
28698
|
+
filename: external_exports.string().min(1).max(255).optional(),
|
|
28699
|
+
encoding: external_exports.literal("utf-8").optional(),
|
|
28700
|
+
/** Encrypted presentation discriminator. The fixed entry point is index.html. */
|
|
28701
|
+
artifact: external_exports.literal("html").optional()
|
|
28702
|
+
}).strict();
|
|
28703
|
+
var deliveryEmailSchema2 = external_exports.string().email();
|
|
28704
|
+
var unsignedShareEnvelopeV2BaseSchema2 = external_exports.object({
|
|
28705
|
+
version: external_exports.literal(2),
|
|
28706
|
+
shareId: external_exports.string().min(1),
|
|
28707
|
+
recipientMatcher: recipientMatcherSchema2,
|
|
28708
|
+
deliveryEmail: deliveryEmailSchema2.optional(),
|
|
28709
|
+
actions: external_exports.array(shareActionSchema2).min(1).max(3),
|
|
28710
|
+
resource: resourceSelectorSchema2,
|
|
28711
|
+
target: v2TargetSchema2,
|
|
28712
|
+
delegationCid: external_exports.string().min(1),
|
|
28713
|
+
authorityMaterialHandle: external_exports.string().min(1),
|
|
28714
|
+
authorityMaterialDigest: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
28715
|
+
decryption: shareDecryptionSchema2.optional(),
|
|
28716
|
+
contentSource: contentSourceSchema2,
|
|
28717
|
+
contentSourceDigest: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
28718
|
+
authorizationTarget: authorizationTargetSchema2,
|
|
28719
|
+
display: displaySchema2,
|
|
28720
|
+
expiry: external_exports.string().datetime(),
|
|
28721
|
+
encrypted: external_exports.boolean(),
|
|
28722
|
+
content: contentPointerSchema2.optional(),
|
|
28723
|
+
metadata: contentMetadataSchema2,
|
|
28724
|
+
ownerAuthority: ownerAuthoritySchema2.optional()
|
|
28725
|
+
}).strict();
|
|
28726
|
+
function validateV2Invariants2(value, ctx) {
|
|
28727
|
+
const actions = [...value.actions];
|
|
28728
|
+
if (new Set(actions).size !== actions.length) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["actions"], message: "actions must be unique" });
|
|
28729
|
+
if (actions.some((action, index) => action !== ["read", "list", "edit"].filter((candidate) => actions.includes(candidate))[index])) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["actions"], message: "actions must be canonically ordered" });
|
|
28730
|
+
if (!value.encrypted && value.recipientMatcher.kind !== "policyDigest") ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["recipientMatcher"], message: "safe plaintext must carry only a matcher digest" });
|
|
28731
|
+
if (!value.encrypted && value.authorizationTarget.kind !== "policy") ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["encrypted"], message: "unencrypted content requires a policy target" });
|
|
28732
|
+
if (!value.encrypted && value.content !== void 0) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["content"], message: "policy-only plaintext cannot carry content" });
|
|
28733
|
+
if (value.encrypted && (value.metadata.mediaType === void 0 || value.metadata.filename === void 0 || value.metadata.byteLength === void 0)) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["metadata"], message: "encrypted shares must describe their content" });
|
|
28734
|
+
if (!value.encrypted && Object.keys(value.metadata).length !== 0) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["metadata"], message: "policy-only plaintext cannot describe content" });
|
|
28735
|
+
if (!value.encrypted && value.metadata.encoding !== void 0) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["metadata", "encoding"], message: "policy-only plaintext cannot carry content encoding" });
|
|
28736
|
+
if (value.metadata.artifact === "html" && (!value.encrypted || value.resource.kind !== "prefix" || !value.actions.includes("read") || !value.actions.includes("list"))) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["metadata", "artifact"], message: "html artifacts require an encrypted readable prefix" });
|
|
28737
|
+
if (!value.encrypted && (value.display.senderName !== void 0 || value.display.filename !== void 0 || value.display.recipientHint !== void 0)) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["display"], message: "policy-only plaintext cannot carry display metadata" });
|
|
28738
|
+
if (!value.encrypted && value.deliveryEmail !== void 0) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["deliveryEmail"], message: "policy-only plaintext cannot carry delivery metadata" });
|
|
28739
|
+
if (value.recipientMatcher.kind === "exactEmail" && value.deliveryEmail !== void 0 && value.deliveryEmail !== value.recipientMatcher.value) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["deliveryEmail"], message: "delivery email must match the exact matcher" });
|
|
28740
|
+
if (value.recipientMatcher.kind === "emailDomain" && value.deliveryEmail !== void 0 && value.deliveryEmail.toLowerCase().endsWith(`@${value.recipientMatcher.value}`) === false) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["deliveryEmail"], message: "delivery email must belong to the matcher domain" });
|
|
28741
|
+
if (value.contentSource.kind === "kv" && value.contentSource.action !== "tinycloud.kv/get") ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["contentSource"], message: "source action mismatch" });
|
|
28742
|
+
if (value.contentSource.kind === "sql" && value.contentSource.action !== "tinycloud.sql/read") ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["contentSource"], message: "source action mismatch" });
|
|
28743
|
+
}
|
|
28744
|
+
var unsignedShareEnvelopeV2Schema2 = unsignedShareEnvelopeV2BaseSchema2.superRefine(validateV2Invariants2);
|
|
28745
|
+
var shareEnvelopeV2Schema2 = unsignedShareEnvelopeV2BaseSchema2.extend({ signature: signatureSchema2 }).strict().superRefine(validateV2Invariants2);
|
|
28746
|
+
var unifiedResourceSchema2 = external_exports.string().refine((value) => {
|
|
28747
|
+
const marker = value.indexOf("/kv/");
|
|
28748
|
+
if (marker < 1) return false;
|
|
28749
|
+
const space = value.slice(0, marker);
|
|
28750
|
+
const legacy = space.startsWith("tinycloud://");
|
|
28751
|
+
if (legacy ? /[:/?#%]/.test(space.slice("tinycloud://".length)) : !space.startsWith("tinycloud:") || /[/?#%]/.test(space)) return false;
|
|
28752
|
+
const path = value.slice(marker + 4);
|
|
28753
|
+
return !path.startsWith("/") && !path.endsWith("/") && !path.includes("//") && path.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
28754
|
+
}, { message: "expected canonical TinyCloud KV resource" });
|
|
28755
|
+
var unifiedEncryptionNetworkSchema2 = external_exports.string().refine((value) => {
|
|
28756
|
+
if (!value.startsWith("urn:tinycloud:encryption:")) return false;
|
|
28757
|
+
const rest = value.slice("urn:tinycloud:encryption:".length);
|
|
28758
|
+
const separator = rest.lastIndexOf(":");
|
|
28759
|
+
const owner = separator < 0 ? "" : rest.slice(0, separator);
|
|
28760
|
+
const network = separator < 0 ? "" : rest.slice(separator + 1);
|
|
28761
|
+
return owner.startsWith("did:") && owner.length > 4 && network.length > 0 && !/[:/%?#\s]/.test(network);
|
|
28762
|
+
}, { message: "expected canonical TinyCloud encryption network" });
|
|
28763
|
+
var unifiedKvCapabilitySchema2 = external_exports.object({
|
|
28764
|
+
kind: external_exports.literal("kv"),
|
|
28765
|
+
resource: unifiedResourceSchema2,
|
|
28766
|
+
selector: external_exports.union([external_exports.literal("exact"), external_exports.literal("prefix")]),
|
|
28767
|
+
actions: external_exports.array(external_exports.union([
|
|
28768
|
+
external_exports.literal("tinycloud.kv/get"),
|
|
28769
|
+
external_exports.literal("tinycloud.kv/list"),
|
|
28770
|
+
external_exports.literal("tinycloud.kv/metadata"),
|
|
28771
|
+
external_exports.literal("tinycloud.kv/put")
|
|
28772
|
+
])).min(1)
|
|
28773
|
+
}).strict();
|
|
28774
|
+
var unifiedEncryptionCapabilitySchema2 = external_exports.object({
|
|
28775
|
+
kind: external_exports.literal("encryption"),
|
|
28776
|
+
resource: unifiedEncryptionNetworkSchema2,
|
|
28777
|
+
action: external_exports.literal("tinycloud.encryption/decrypt")
|
|
28778
|
+
}).strict();
|
|
28779
|
+
var unifiedCapabilitySchema2 = external_exports.union([unifiedKvCapabilitySchema2, unifiedEncryptionCapabilitySchema2]);
|
|
28780
|
+
var unifiedContentSourceSchema2 = external_exports.object({
|
|
28781
|
+
shareId: external_exports.string().min(1),
|
|
28782
|
+
kvResource: unifiedResourceSchema2,
|
|
28783
|
+
selector: external_exports.union([external_exports.literal("exact"), external_exports.literal("prefix")]),
|
|
28784
|
+
encryptionNetwork: unifiedEncryptionNetworkSchema2,
|
|
28785
|
+
encryptedSymmetricKeyDigestHex: external_exports.string().regex(/^[0-9a-f]{64}$/),
|
|
28786
|
+
keyVersion: external_exports.number().int().positive(),
|
|
28787
|
+
mode: external_exports.union([external_exports.literal("mutable"), external_exports.literal("immutable")]),
|
|
28788
|
+
initialCiphertextDigestHex: external_exports.string().regex(/^[0-9a-f]{64}$/).optional()
|
|
28789
|
+
}).strict();
|
|
28790
|
+
var unifiedPolicyV1Schema2 = external_exports.object({
|
|
28791
|
+
schema: external_exports.literal("xyz.tinycloud.policy/policy/v1"),
|
|
28792
|
+
policyId: external_exports.string().regex(/^pol_[a-z2-7]+$/),
|
|
28793
|
+
ownerDid: external_exports.string().min(1),
|
|
28794
|
+
createdAt: external_exports.string().datetime({ offset: true }),
|
|
28795
|
+
expiresAt: external_exports.string().datetime({ offset: true }).optional(),
|
|
28796
|
+
contentSource: unifiedContentSourceSchema2,
|
|
28797
|
+
capabilityCeiling: external_exports.array(unifiedCapabilitySchema2).min(2),
|
|
28798
|
+
signature: external_exports.object({ suite: external_exports.string().min(1), signerDid: external_exports.string().min(1), value: external_exports.string().min(1) }).strict()
|
|
28799
|
+
}).strict();
|
|
28800
|
+
var policyCredentialRequirementV1Schema2 = external_exports.object({
|
|
28801
|
+
type: external_exports.literal("TinyCloudPolicyCredentialRequirement"),
|
|
28802
|
+
version: external_exports.literal(1),
|
|
28803
|
+
requirementDigest: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
28804
|
+
descriptorDigest: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
28805
|
+
issuerDid: external_exports.string().min(1),
|
|
28806
|
+
issuerKid: external_exports.string().min(1),
|
|
28807
|
+
profile: external_exports.object({ id: external_exports.string().min(1), version: external_exports.literal(1) }).strict(),
|
|
28808
|
+
credentialType: external_exports.object({ id: external_exports.string().min(1), version: external_exports.literal(1) }).strict()
|
|
28809
|
+
}).strict();
|
|
28810
|
+
var unifiedPolicyV2Schema2 = external_exports.object({
|
|
28811
|
+
schema: external_exports.literal("xyz.tinycloud.policy/policy/v2"),
|
|
28812
|
+
policyId: external_exports.string().regex(/^pol_[a-z2-7]+$/),
|
|
28813
|
+
ownerDid: external_exports.string().min(1),
|
|
28814
|
+
createdAt: external_exports.string().datetime({ offset: true }),
|
|
28815
|
+
expiresAt: external_exports.string().datetime({ offset: true }).optional(),
|
|
28816
|
+
contentSource: unifiedContentSourceSchema2,
|
|
28817
|
+
capabilityCeiling: external_exports.array(unifiedCapabilitySchema2).min(2),
|
|
28818
|
+
credentialRequirement: policyCredentialRequirementV1Schema2,
|
|
28819
|
+
signature: external_exports.object({ suite: external_exports.literal("Ed25519"), signerDid: external_exports.string().min(1), value: external_exports.string().min(1) }).strict()
|
|
28820
|
+
}).strict();
|
|
28821
|
+
var unifiedPolicySchema2 = external_exports.discriminatedUnion("schema", [
|
|
28822
|
+
unifiedPolicyV1Schema2,
|
|
28823
|
+
unifiedPolicyV2Schema2
|
|
28824
|
+
]);
|
|
28825
|
+
var unifiedRootSchema2 = external_exports.object({
|
|
28826
|
+
cid: external_exports.string().min(1),
|
|
28827
|
+
authorization: external_exports.string().regex(/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/),
|
|
28828
|
+
role: external_exports.union([external_exports.literal("policy-authority"), external_exports.literal("policy-enforcement")])
|
|
28829
|
+
}).strict();
|
|
28830
|
+
var attestedEnforcerBindingV2Schema2 = external_exports.object({
|
|
28831
|
+
schema: external_exports.literal("xyz.tinycloud.policy/attested-enforcer/v2"),
|
|
28832
|
+
enforcerDid: external_exports.string().regex(/^did:key:z[1-9A-HJ-NP-Za-km-z]+$/),
|
|
28833
|
+
nodeAudience: external_exports.string().min(1),
|
|
28834
|
+
attestationBindingDigestHex: external_exports.string().regex(/^[0-9a-f]{64}$/),
|
|
28835
|
+
issuedAt: external_exports.string().datetime({ offset: true }),
|
|
28836
|
+
expiresAt: external_exports.string().datetime({ offset: true }),
|
|
28837
|
+
signature: external_exports.object({ suite: external_exports.literal("Ed25519"), signerDid: external_exports.string().min(1), value: base64UrlString2() }).strict()
|
|
28838
|
+
}).strict();
|
|
28839
|
+
var v3TargetSchema2 = external_exports.object({
|
|
28840
|
+
origin: external_exports.string().refine(isCanonicalHttpsOrigin2, { message: "expected a canonical https origin" }),
|
|
28841
|
+
nodeAudience: external_exports.string().min(1),
|
|
28842
|
+
spaceId: external_exports.string().refine(isCanonicalPathSegment2, { message: "expected a canonical space id" })
|
|
28843
|
+
}).strict();
|
|
28844
|
+
var unsignedShareEnvelopeV3BaseSchema2 = external_exports.object({
|
|
28845
|
+
version: external_exports.literal(3),
|
|
28846
|
+
shareId: external_exports.string().min(1),
|
|
28847
|
+
recipientMatcher: recipientMatcherSchema2,
|
|
28848
|
+
deliveryEmail: deliveryEmailSchema2.optional(),
|
|
28849
|
+
actions: external_exports.array(shareActionSchema2).min(1).max(3),
|
|
28850
|
+
resource: resourceSelectorSchema2,
|
|
28851
|
+
target: v3TargetSchema2,
|
|
28852
|
+
policy: unifiedPolicySchema2,
|
|
28853
|
+
policyCid: external_exports.string().min(1),
|
|
28854
|
+
policyRoot: unifiedRootSchema2,
|
|
28855
|
+
enforcementRoot: unifiedRootSchema2,
|
|
28856
|
+
attestedEnforcerBinding: attestedEnforcerBindingV2Schema2,
|
|
28857
|
+
contentSource: unifiedContentSourceSchema2,
|
|
28858
|
+
contentSourceDigestHex: external_exports.string().regex(/^[0-9a-f]{64}$/),
|
|
28859
|
+
encryptionNetwork: unifiedEncryptionNetworkSchema2,
|
|
28860
|
+
expiry: external_exports.string().datetime({ offset: true }),
|
|
28861
|
+
display: displaySchema2,
|
|
28862
|
+
encrypted: external_exports.literal(true),
|
|
28863
|
+
metadata: contentMetadataSchema2
|
|
28864
|
+
}).strict();
|
|
28865
|
+
function validateV3Invariants2(value, ctx) {
|
|
28866
|
+
const actions = [...value.actions];
|
|
28867
|
+
if (new Set(actions).size !== actions.length || actions.some((action, index) => action !== ["read", "list", "edit"].filter((candidate) => actions.includes(candidate))[index])) {
|
|
28868
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["actions"], message: "actions must be unique and canonically ordered" });
|
|
28869
|
+
}
|
|
28870
|
+
if (value.policyRoot.role !== "policy-authority" || value.enforcementRoot.role !== "policy-enforcement") {
|
|
28871
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["policyRoot", "role"], message: "root roles are fixed" });
|
|
28872
|
+
}
|
|
28873
|
+
if (value.policyCid.length === 0 || value.policyCid === value.policyRoot.cid || value.policyCid === value.enforcementRoot.cid) {
|
|
28874
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["policyCid"], message: "policy CID must be distinct from both roots" });
|
|
28875
|
+
}
|
|
28876
|
+
if (value.contentSource.encryptionNetwork !== value.encryptionNetwork) {
|
|
28877
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["encryptionNetwork"], message: "encryption network is not bound to the source" });
|
|
28878
|
+
}
|
|
28879
|
+
if (value.attestedEnforcerBinding.nodeAudience !== value.target.nodeAudience || value.attestedEnforcerBinding.signature.signerDid !== value.attestedEnforcerBinding.nodeAudience || Date.parse(value.attestedEnforcerBinding.expiresAt) < Date.parse(value.expiry)) {
|
|
28880
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["attestedEnforcerBinding"], message: "enforcer binding does not cover the target and share lifetime" });
|
|
28881
|
+
}
|
|
28882
|
+
if (value.policy.contentSource.shareId !== value.contentSource.shareId || value.policy.contentSource.kvResource !== value.contentSource.kvResource || value.policy.contentSource.selector !== value.contentSource.selector || value.policy.contentSource.encryptionNetwork !== value.encryptionNetwork || value.policy.contentSource.encryptedSymmetricKeyDigestHex !== value.contentSource.encryptedSymmetricKeyDigestHex || value.policy.contentSource.keyVersion !== value.contentSource.keyVersion || value.policy.contentSource.mode !== value.contentSource.mode || value.policy.contentSource.initialCiphertextDigestHex !== value.contentSource.initialCiphertextDigestHex) {
|
|
28883
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["contentSource"], message: "content source is not bound to policy" });
|
|
28884
|
+
}
|
|
28885
|
+
if (value.policy.signature.suite !== "Ed25519" || value.policy.signature.signerDid !== value.policy.ownerDid) {
|
|
28886
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["policy", "signature"], message: "policy must be signed by its owner" });
|
|
28887
|
+
}
|
|
28888
|
+
const kvCapabilities = value.policy.capabilityCeiling.filter((capability) => capability.kind === "kv");
|
|
28889
|
+
const decryptCapabilities = value.policy.capabilityCeiling.filter((capability) => capability.kind === "encryption" && capability.resource === value.encryptionNetwork && capability.action === "tinycloud.encryption/decrypt");
|
|
28890
|
+
if (value.policy.capabilityCeiling.length !== 2 || kvCapabilities.length !== 1 || decryptCapabilities.length !== 1 || kvCapabilities[0]?.resource !== value.contentSource.kvResource || kvCapabilities[0]?.selector !== value.contentSource.selector) {
|
|
28891
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["policy", "capabilityCeiling"], message: "policy ceiling must contain exact decrypt network" });
|
|
28892
|
+
}
|
|
28893
|
+
}
|
|
28894
|
+
var unsignedShareEnvelopeV3Schema2 = unsignedShareEnvelopeV3BaseSchema2.superRefine(validateV3Invariants2);
|
|
28895
|
+
var shareEnvelopeV3Schema2 = unsignedShareEnvelopeV3BaseSchema2.extend({ signature: signatureSchema2 }).strict().superRefine(validateV3Invariants2);
|
|
28896
|
+
var ENVELOPE_AAD_LABEL2 = "tinycloud-share-envelope-v1";
|
|
28897
|
+
var AAD2 = utf8Bytes2(ENVELOPE_AAD_LABEL2);
|
|
28898
|
+
var LABEL2 = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
28899
|
+
function isCanonicalEmailDomain2(value) {
|
|
28900
|
+
if (value.length === 0 || value.length > 253) return false;
|
|
28901
|
+
const labels = value.split(".");
|
|
28902
|
+
return labels.length >= 2 && labels.every((label) => LABEL2.test(label)) && !/^[0-9]+$/.test(labels.at(-1));
|
|
28903
|
+
}
|
|
28904
|
+
function canonicalMailbox2(value) {
|
|
28905
|
+
const email = value.trim().toLowerCase();
|
|
28906
|
+
const at = email.indexOf("@");
|
|
28907
|
+
if (at <= 0 || at !== email.lastIndexOf("@")) return void 0;
|
|
28908
|
+
const local = email.slice(0, at);
|
|
28909
|
+
const domain = email.slice(at + 1);
|
|
28910
|
+
if (local.length > 64 || !/^[a-z0-9#$&'*+/=?^_`{|}~-]+(?:\.[a-z0-9#$&'*+/=?^_`{|}~-]+)*$/.test(local) || !isCanonicalEmailDomain2(domain)) return void 0;
|
|
28911
|
+
return Object.freeze({ email, domain });
|
|
28912
|
+
}
|
|
28913
|
+
var MAX_INLINE_BYTES2 = 256 * 1024;
|
|
28914
|
+
|
|
28915
|
+
// src/commands/share.ts
|
|
28916
|
+
import { ProfileLockTimeoutError as ProfileLockTimeoutError3 } from "@tinycloud/operations/state";
|
|
28917
|
+
init_formatter();
|
|
28918
|
+
init_errors();
|
|
28919
|
+
|
|
28920
|
+
// src/share/output.ts
|
|
28921
|
+
function writeJson2(value) {
|
|
28922
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
28923
|
+
`);
|
|
28924
|
+
}
|
|
28925
|
+
function authorizationRequiredJson(result) {
|
|
28926
|
+
return {
|
|
28927
|
+
state: "authorization-required",
|
|
28928
|
+
method: result.method,
|
|
28929
|
+
next: "complete authorization through the configured authority adapter, then retry with the required proof"
|
|
28930
|
+
};
|
|
28931
|
+
}
|
|
28932
|
+
function publishHuman(result) {
|
|
28933
|
+
process.stdout.write(`${result.url}
|
|
28934
|
+
`);
|
|
28935
|
+
}
|
|
28936
|
+
function inspectHuman(result) {
|
|
28937
|
+
const metadata = result.metadata;
|
|
28938
|
+
process.stdout.write([
|
|
28939
|
+
`Share ${metadata.shareId}`,
|
|
28940
|
+
`File: ${metadata.display.filename ?? "unnamed"}`,
|
|
28941
|
+
`Target: ${metadata.target.kind === "bearer" ? "bearer (anyone with the complete link can read)" : metadata.target.kind}`,
|
|
28942
|
+
`Expires: ${metadata.expiresAt}`,
|
|
28943
|
+
`Resource: ${metadata.resource.path}`,
|
|
28944
|
+
`Link format: ${result.link.kind}`
|
|
28945
|
+
].join("\n") + "\n");
|
|
28946
|
+
}
|
|
28947
|
+
function receiveHuman(path) {
|
|
28948
|
+
process.stdout.write(`${path}
|
|
28949
|
+
`);
|
|
28950
|
+
}
|
|
28951
|
+
function receiveJson(result, path) {
|
|
28952
|
+
writeJson2({ protocol: "tinycloud-share", version: 1, path, metadata: result.metadata });
|
|
28953
|
+
}
|
|
28954
|
+
|
|
28955
|
+
// src/share/io.ts
|
|
28956
|
+
import { constants } from "fs";
|
|
28957
|
+
import { lstat as lstat3, mkdir as mkdir3, mkdtemp, open as open4, readFile as readFile9, realpath, stat as stat2, link, rename as rename3, rm as rm4, unlink } from "fs/promises";
|
|
28958
|
+
import { randomBytes as randomBytes4 } from "crypto";
|
|
28959
|
+
import { basename as basename3, join as join6, resolve as resolve2, sep } from "path";
|
|
28960
|
+
init_errors();
|
|
28961
|
+
var MAX_SHARE_STDIN_BYTES = 100 * 1024 * 1024;
|
|
28962
|
+
var MAX_SHARE_URL_BYTES = 64 * 1024;
|
|
28963
|
+
async function readBoundedStdin(limit = MAX_SHARE_STDIN_BYTES) {
|
|
28964
|
+
if (!Number.isSafeInteger(limit) || limit <= 0) throw new Error("MAX_BYTES_EXCEEDED");
|
|
28965
|
+
const chunks = [];
|
|
28966
|
+
let total = 0;
|
|
28967
|
+
for await (const chunk of process.stdin) {
|
|
28968
|
+
const bytes = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
|
|
28969
|
+
total += bytes.byteLength;
|
|
28970
|
+
if (total > limit) throw new Error("MAX_BYTES_EXCEEDED");
|
|
28971
|
+
chunks.push(bytes);
|
|
28972
|
+
}
|
|
28973
|
+
return new Uint8Array(Buffer.concat(chunks, total));
|
|
28974
|
+
}
|
|
28975
|
+
async function readBoundedUrlStdin() {
|
|
28976
|
+
const bytes = await readBoundedStdin(MAX_SHARE_URL_BYTES);
|
|
28977
|
+
const value = new TextDecoder("utf-8", { fatal: true }).decode(bytes).trim();
|
|
28978
|
+
if (value.length === 0 || /\s/.test(value)) throw new Error("INVALID_ARGUMENT");
|
|
28979
|
+
return value;
|
|
28980
|
+
}
|
|
28981
|
+
function safeFilename(value) {
|
|
28982
|
+
return shareFilename(value);
|
|
28983
|
+
}
|
|
28984
|
+
function shareFilename(value) {
|
|
28985
|
+
try {
|
|
28986
|
+
return canonicalShareFilename(value);
|
|
28987
|
+
} catch {
|
|
28988
|
+
throw new CLIError(
|
|
28989
|
+
"UNSAFE_FILENAME",
|
|
28990
|
+
hasUnsafeFilenameCodePoint(value) ? "filename contains control or invisible characters" : "filename must be one safe path segment",
|
|
28991
|
+
8
|
|
28992
|
+
);
|
|
28993
|
+
}
|
|
28994
|
+
}
|
|
28995
|
+
function shareInputFilename(input, name) {
|
|
28996
|
+
return shareFilename(name ?? (input === "-" ? "stdin.md" : basename3(resolve2(input))));
|
|
28997
|
+
}
|
|
28998
|
+
async function readShareInput(input, name, limit = MAX_SHARE_STDIN_BYTES) {
|
|
28999
|
+
const filename = shareInputFilename(input, name);
|
|
29000
|
+
if (input === "-") return { bytes: await readBoundedStdin(limit), filename };
|
|
29001
|
+
const path = resolve2(input);
|
|
29002
|
+
const info = await stat2(path);
|
|
29003
|
+
if (!info.isFile() || info.size > limit) throw new Error("MAX_BYTES_EXCEEDED");
|
|
29004
|
+
const bytes = new Uint8Array(await readFile9(path));
|
|
29005
|
+
if (bytes.byteLength > limit) throw new Error("MAX_BYTES_EXCEEDED");
|
|
29006
|
+
return { bytes, filename };
|
|
29007
|
+
}
|
|
29008
|
+
async function assertDirectory(path) {
|
|
29009
|
+
const absolute = resolve2(path);
|
|
29010
|
+
const segments = absolute.split(sep).filter(Boolean);
|
|
29011
|
+
let current = absolute.startsWith(sep) ? sep : "";
|
|
29012
|
+
for (const segment of segments) {
|
|
29013
|
+
current = current === sep ? join6(current, segment) : join6(current, segment);
|
|
29014
|
+
try {
|
|
29015
|
+
const info = await lstat3(current);
|
|
29016
|
+
if (info.isSymbolicLink()) {
|
|
29017
|
+
const canonical = await realpath(current);
|
|
29018
|
+
if (current !== "/tmp" && current !== "/var") throw new Error("OUTPUT_EXISTS");
|
|
29019
|
+
if (canonical !== `/private${current}`) throw new Error("OUTPUT_EXISTS");
|
|
29020
|
+
} else if (!info.isDirectory()) throw new Error("OUTPUT_EXISTS");
|
|
29021
|
+
} catch (error) {
|
|
29022
|
+
if (error.code !== "ENOENT") throw error;
|
|
29023
|
+
await mkdir3(current, { mode: 448 });
|
|
29024
|
+
const created = await lstat3(current);
|
|
29025
|
+
if (created.isSymbolicLink() || !created.isDirectory()) throw new Error("OUTPUT_EXISTS");
|
|
29026
|
+
}
|
|
29027
|
+
}
|
|
29028
|
+
}
|
|
29029
|
+
async function writeShareOutput(directory, filename, bytes, force) {
|
|
29030
|
+
const outputDirectory = resolve2(directory);
|
|
29031
|
+
await assertDirectory(outputDirectory);
|
|
29032
|
+
const safeName = safeFilename(filename);
|
|
29033
|
+
const directoryHandle = await open4(outputDirectory, constants.O_RDONLY | (constants.O_DIRECTORY ?? 0) | (constants.O_NOFOLLOW ?? 0));
|
|
29034
|
+
const stableDirectory = await realpath(outputDirectory);
|
|
29035
|
+
const outputPath = join6(stableDirectory, safeName);
|
|
29036
|
+
const directoryIdentity = await directoryHandle.stat();
|
|
29037
|
+
const assertStableDirectory = async () => {
|
|
29038
|
+
const current = await stat2(stableDirectory);
|
|
29039
|
+
if (current.dev !== directoryIdentity.dev || current.ino !== directoryIdentity.ino) throw new Error("OUTPUT_EXISTS");
|
|
29040
|
+
};
|
|
29041
|
+
await assertStableDirectory();
|
|
29042
|
+
const stagingDirectory = await mkdtemp(join6(stableDirectory, ".tinycloud-share-stage-"));
|
|
29043
|
+
const stagingInfo = await lstat3(stagingDirectory);
|
|
29044
|
+
if (!stagingInfo.isDirectory() || (stagingInfo.mode & 511) !== 448) throw new Error("OUTPUT_EXISTS");
|
|
29045
|
+
const stagingPath = join6(stagingDirectory, `.tinycloud-share-${randomBytes4(16).toString("hex")}.tmp`);
|
|
29046
|
+
let temporaryPath;
|
|
29047
|
+
let handle;
|
|
29048
|
+
try {
|
|
29049
|
+
await assertStableDirectory();
|
|
29050
|
+
try {
|
|
29051
|
+
const existing = await lstat3(outputPath);
|
|
29052
|
+
if (existing.isSymbolicLink()) throw new Error("UNSAFE_FILENAME");
|
|
29053
|
+
} catch (error) {
|
|
29054
|
+
if (error.code !== "ENOENT") throw error;
|
|
29055
|
+
}
|
|
29056
|
+
temporaryPath = stagingPath;
|
|
29057
|
+
handle = await open4(temporaryPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | (constants.O_NOFOLLOW ?? 0), 384);
|
|
29058
|
+
await handle.writeFile(bytes);
|
|
29059
|
+
await handle.close();
|
|
29060
|
+
handle = void 0;
|
|
29061
|
+
await assertStableDirectory();
|
|
29062
|
+
if (force) {
|
|
29063
|
+
await rename3(temporaryPath, outputPath);
|
|
29064
|
+
} else {
|
|
29065
|
+
await link(temporaryPath, outputPath);
|
|
29066
|
+
await unlink(temporaryPath);
|
|
29067
|
+
}
|
|
29068
|
+
await assertStableDirectory();
|
|
29069
|
+
} catch (error) {
|
|
29070
|
+
if (error.code === "EEXIST") throw new Error("OUTPUT_EXISTS");
|
|
29071
|
+
if (error.code === "ELOOP") throw new Error("UNSAFE_FILENAME");
|
|
29072
|
+
throw error;
|
|
29073
|
+
} finally {
|
|
29074
|
+
await handle?.close();
|
|
29075
|
+
try {
|
|
29076
|
+
if (temporaryPath !== void 0) await unlink(temporaryPath);
|
|
29077
|
+
} catch {
|
|
29078
|
+
}
|
|
29079
|
+
await rm4(stagingDirectory, { recursive: true, force: true });
|
|
29080
|
+
await directoryHandle.close();
|
|
29081
|
+
}
|
|
29082
|
+
return join6(outputDirectory, safeName);
|
|
29083
|
+
}
|
|
29084
|
+
|
|
29085
|
+
// src/share/errors.ts
|
|
29086
|
+
var SharePublishAuthorityError = class extends Error {
|
|
29087
|
+
constructor(failure) {
|
|
29088
|
+
super(failure.kind);
|
|
29089
|
+
this.failure = failure;
|
|
29090
|
+
this.name = "SharePublishAuthorityError";
|
|
29091
|
+
}
|
|
29092
|
+
};
|
|
29093
|
+
var ShareHistoryRetryError = class extends Error {
|
|
29094
|
+
constructor(profile) {
|
|
29095
|
+
super("sender history changed during the operation");
|
|
29096
|
+
this.profile = profile;
|
|
29097
|
+
this.name = "ShareHistoryRetryError";
|
|
29098
|
+
}
|
|
29099
|
+
code = "SHARE_HISTORY_RETRY";
|
|
29100
|
+
};
|
|
29101
|
+
|
|
29102
|
+
// src/commands/share.ts
|
|
29103
|
+
var SHARE_ORIGIN = "https://share.tinycloud.xyz";
|
|
29104
|
+
var NOTIFY_WINDOW_MESSAGE = "Share notification authorization expired (at share expiry or 5 minutes after publication); publish a new share and invite the recipient then.\n";
|
|
29105
|
+
var shareServices = {};
|
|
29106
|
+
function parseShareTarget(value) {
|
|
29107
|
+
if (value === "anyone" || value === "bearer") return { kind: "bearer" };
|
|
29108
|
+
if (value.startsWith("did:")) return { kind: "recipientDid", did: value };
|
|
29109
|
+
if (value.startsWith("domain:")) return canonicalMailboxTarget({ kind: "emailDomain", domain: value.slice("domain:".length) });
|
|
29110
|
+
if (value.startsWith("email:")) return canonicalMailboxTarget({ kind: "email", address: value.slice("email:".length) });
|
|
29111
|
+
if (value.includes("@")) return canonicalMailboxTarget({ kind: "email", address: value });
|
|
29112
|
+
throw new CLIError("INVALID_ARGUMENT", "--to must be anyone, a did:, an email address, or domain:example.com", 2);
|
|
29113
|
+
}
|
|
29114
|
+
function canonicalMailboxTarget(target) {
|
|
29115
|
+
try {
|
|
29116
|
+
return normalizeShareTarget(target);
|
|
29117
|
+
} catch (error) {
|
|
29118
|
+
throw new CLIError("INVALID_ARGUMENT", error instanceof TypeError ? error.message : "share recipient is invalid", 2);
|
|
29119
|
+
}
|
|
29120
|
+
}
|
|
29121
|
+
function shareCliError(error, operation = "publish") {
|
|
29122
|
+
if (error instanceof CLIError) return error;
|
|
29123
|
+
if (error instanceof ProfileLockTimeoutError3) return wrapError(error);
|
|
29124
|
+
if (error instanceof ShareHistoryRetryError) {
|
|
29125
|
+
return new CLIError(
|
|
29126
|
+
"SHARE_HISTORY_RETRY",
|
|
29127
|
+
`sender history for profile ${JSON.stringify(error.profile)} changed or disappeared during this command`,
|
|
29128
|
+
1,
|
|
29129
|
+
{ hint: `Retry this command with --profile ${JSON.stringify(error.profile)}. If this was a revoke, check its node state first: revocation may already have succeeded.` }
|
|
29130
|
+
);
|
|
29131
|
+
}
|
|
29132
|
+
if (error instanceof SharePublishAuthorityError) {
|
|
29133
|
+
const failure = error.failure;
|
|
29134
|
+
const profileName = "profileName" in failure ? failure.profileName : void 0;
|
|
27706
29135
|
const localKey = "localKey" in failure && failure.localKey === true;
|
|
27707
29136
|
const profileHint = profileName === void 0 ? "" : `--profile ${profileName} `;
|
|
27708
29137
|
const loginHint = localKey ? `\`tc ${profileHint}auth login --method local\`` : `\`tc ${profileHint}auth login --device --manifest builtin:share-publishing\` (or \`tc ${profileHint}enable share\`)`;
|
|
@@ -27741,6 +29170,10 @@ function shareCliError(error) {
|
|
|
27741
29170
|
if (failure.kind === "registry-unavailable") {
|
|
27742
29171
|
return new CLIError("UNAVAILABLE", "the TinyCloud location registry could not be reached, so nothing was shared; try again shortly", 4);
|
|
27743
29172
|
}
|
|
29173
|
+
if (failure.kind === "node-info-unavailable") {
|
|
29174
|
+
const outcome = operation === "publish" ? "nothing was shared and no invitation was sent" : "no invitation was sent";
|
|
29175
|
+
return new CLIError("UNAVAILABLE", `could not verify TinyCloud node 1.17.3 domain delivery support; ${outcome}. Check the node and retry`, 4);
|
|
29176
|
+
}
|
|
27744
29177
|
if (failure.kind === "registry-rejected") {
|
|
27745
29178
|
return new CLIError("REGISTRY_REJECTED", "the TinyCloud location registry rejected this session's location record, so nothing was shared; retrying will not help. Log in again, and report the problem if it persists", 6);
|
|
27746
29179
|
}
|
|
@@ -27757,14 +29190,14 @@ function shareCliError(error) {
|
|
|
27757
29190
|
}
|
|
27758
29191
|
if (error instanceof SharePublishError) {
|
|
27759
29192
|
const exit = error.code === "authority-required" ? 3 : error.code === "max-bytes-exceeded" ? 7 : 2;
|
|
27760
|
-
const
|
|
27761
|
-
return new CLIError(
|
|
29193
|
+
const code3 = error.code === "authority-required" ? "AUTH_REQUIRED" : error.code === "max-bytes-exceeded" ? "MAX_BYTES_EXCEEDED" : "INVALID_ARGUMENT";
|
|
29194
|
+
return new CLIError(code3, error.message, exit);
|
|
27762
29195
|
}
|
|
27763
29196
|
if (error instanceof ShareReceiveError) {
|
|
27764
29197
|
const verification = /* @__PURE__ */ new Set(["cid-mismatch", "decrypt-failed", "envelope-invalid", "origin-mismatch", "signature-invalid", "capability-invalid", "content-integrity-failed"]);
|
|
27765
29198
|
const exit = error.code === "max-bytes-exceeded" ? 7 : verification.has(error.code) ? 5 : error.code === "expired" || error.code === "fetch-failed" ? 4 : error.code === "invalid-link" || error.code === "unsupported-target" ? 2 : 2;
|
|
27766
|
-
const
|
|
27767
|
-
return new CLIError(
|
|
29199
|
+
const code3 = error.code === "fetch-failed" ? "NOT_FOUND" : error.code.replaceAll("-", "_").toUpperCase();
|
|
29200
|
+
return new CLIError(code3, error.message, exit);
|
|
27768
29201
|
}
|
|
27769
29202
|
const message = error instanceof Error ? error.message : String(error);
|
|
27770
29203
|
const nodeCode = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
|
|
@@ -27809,8 +29242,33 @@ function expires(value) {
|
|
|
27809
29242
|
}
|
|
27810
29243
|
async function rememberPublishedShare(result) {
|
|
27811
29244
|
const record = historyRecordForPublishedShare(result);
|
|
27812
|
-
if (shareServices.records
|
|
27813
|
-
|
|
29245
|
+
if (shareServices.records === void 0) return { record, recorded: false };
|
|
29246
|
+
try {
|
|
29247
|
+
await shareServices.records.put(record);
|
|
29248
|
+
return { record, recorded: true };
|
|
29249
|
+
} catch {
|
|
29250
|
+
process.stderr.write("Warning: share was published but not recorded in sender history; future share list, share notify, and share revoke by ID will not find it.\n");
|
|
29251
|
+
return { record, recorded: false };
|
|
29252
|
+
}
|
|
29253
|
+
}
|
|
29254
|
+
async function notifyRecordedShare(record, recipient, adapter, storage) {
|
|
29255
|
+
const result = await notifyShare({ shareId: record.shareId, recipient, record, adapter, checkDeliveryWindow: true });
|
|
29256
|
+
if (result.state !== "partial-failure" && storage !== void 0) {
|
|
29257
|
+
const mailbox = canonicalMailbox2(recipient).email;
|
|
29258
|
+
if (!record.deliveredRecipients?.includes(mailbox)) {
|
|
29259
|
+
try {
|
|
29260
|
+
if (storage.update === void 0) throw new Error("atomic sender history update is unavailable");
|
|
29261
|
+
const updated = await storage.update(record.shareId, (current) => ({
|
|
29262
|
+
...current,
|
|
29263
|
+
deliveredRecipients: current.deliveredRecipients?.includes(mailbox) ? current.deliveredRecipients : [...current.deliveredRecipients ?? [], mailbox]
|
|
29264
|
+
}));
|
|
29265
|
+
if (updated === void 0) throw new Error("sender history record was removed");
|
|
29266
|
+
} catch {
|
|
29267
|
+
process.stderr.write("Warning: delivery succeeded, but could not record its confirmation in sender history.\n");
|
|
29268
|
+
}
|
|
29269
|
+
}
|
|
29270
|
+
}
|
|
29271
|
+
return result;
|
|
27814
29272
|
}
|
|
27815
29273
|
function byteLimit(value) {
|
|
27816
29274
|
if (value === void 0) return void 0;
|
|
@@ -27837,7 +29295,7 @@ function assertAggregateInputLimit(inputs, maxBytes) {
|
|
|
27837
29295
|
}
|
|
27838
29296
|
function registerShareCommand(program) {
|
|
27839
29297
|
const share = program.command("share").description("Publish and consume TinyCloud Share links");
|
|
27840
|
-
share.command("publish <files...>").description("Publish one or more bounded files as a Share").option("--name <filename>", "Filename for stdin input").option("--to <target>", "Share target", "anyone").option("--notify", "
|
|
29298
|
+
share.command("publish <files...>").description("Publish one or more bounded files as a Share").option("--name <filename>", "Filename for stdin input").option("--to <target>", "Share target", "anyone").option("--notify", "Email an exact-email recipient, or a domain mailbox on node 1.17.3+").option("--notify-to <address>", "Mailbox to invite for --to domain:<name> --notify (node 1.17.3+)").option("--expires <duration>", "Share lifetime").option("--max-bytes <bytes>", "Bound input bytes").option("--media-type <type>", "Media type for a single input").option("--action <actions...>", "Addressed permission: read, list, or edit").option("--prefix", "Publish multiple inputs beneath one addressed prefix").option("--binary", "Allow non-UTF-8 bearer content").option("--json", "Print versioned redacted JSON").option("--viewer-origin <origin>", "Canonical HTTPS viewer origin", SHARE_ORIGIN).action(async (files, options, command) => {
|
|
27841
29299
|
try {
|
|
27842
29300
|
const json = jsonOutput(options, command);
|
|
27843
29301
|
const maxBytes = byteLimit(options.maxBytes);
|
|
@@ -27851,7 +29309,21 @@ function registerShareCommand(program) {
|
|
|
27851
29309
|
if (options.prefix && target.kind === "bearer") throw new CLIError("INVALID_ARGUMENT", "--prefix requires an addressed target", 2);
|
|
27852
29310
|
if (inputs.length > 1 && target.kind === "bearer") throw new CLIError("UNSUPPORTED_LINK", "multiple files require an addressed target", 2);
|
|
27853
29311
|
if (inputs.length > 1 && !options.prefix) throw new CLIError("INVALID_ARGUMENT", "multiple files require --prefix", 2);
|
|
27854
|
-
if (options.notify === true &&
|
|
29312
|
+
if (options.notify === true && !actions.includes("read")) throw new CLIError("INVALID_ARGUMENT", "--notify requires the read action; nothing was shared", 2);
|
|
29313
|
+
if (options.notifyTo !== void 0 && (options.notify !== true || target.kind !== "emailDomain")) {
|
|
29314
|
+
throw new CLIError("INVALID_ARGUMENT", "--notify-to requires --to domain:<name> --notify", 2);
|
|
29315
|
+
}
|
|
29316
|
+
let notifyRecipient;
|
|
29317
|
+
if (options.notify === true && target.kind === "email") notifyRecipient = target.address;
|
|
29318
|
+
else if (options.notify === true && target.kind === "emailDomain") {
|
|
29319
|
+
const mailbox = options.notifyTo === void 0 ? void 0 : canonicalMailbox2(options.notifyTo);
|
|
29320
|
+
if (mailbox === void 0 || mailbox.domain !== target.domain) {
|
|
29321
|
+
throw new CLIError("INVALID_ARGUMENT", "--to domain:<name> --notify requires --notify-to <email> at that exact domain (node 1.17.3+)", 2);
|
|
29322
|
+
}
|
|
29323
|
+
notifyRecipient = mailbox.email;
|
|
29324
|
+
} else if (options.notify === true) {
|
|
29325
|
+
throw new CLIError("INVALID_ARGUMENT", "--notify requires an email target, or a domain target with --notify-to on node 1.17.3+", 2);
|
|
29326
|
+
}
|
|
27855
29327
|
const result = await publishTargetShare({
|
|
27856
29328
|
source: inputs[0].bytes,
|
|
27857
29329
|
filename: inputs[0].filename,
|
|
@@ -27876,16 +29348,17 @@ function registerShareCommand(program) {
|
|
|
27876
29348
|
}
|
|
27877
29349
|
throw new CLIError(result.method === "openkey-device" ? "DEVICE_AUTH_REQUIRED" : "CLAIM_REQUIRED", "recipient authorization is required; continue through the configured authority adapter", 6);
|
|
27878
29350
|
}
|
|
27879
|
-
const record = await rememberPublishedShare(result);
|
|
27880
|
-
|
|
29351
|
+
const { record, recorded } = await rememberPublishedShare(result);
|
|
29352
|
+
let notification;
|
|
29353
|
+
if (notifyRecipient !== void 0) {
|
|
27881
29354
|
if (shareServices.delivery === void 0) throw new CLIError("AUTH_REQUIRED", "delivery authority is not configured", 3);
|
|
27882
|
-
|
|
27883
|
-
|
|
27884
|
-
if (
|
|
29355
|
+
notification = await notifyRecordedShare(record, notifyRecipient, shareServices.delivery, recorded ? shareServices.records : void 0);
|
|
29356
|
+
if (notification.state === "partial-failure") process.exitCode = 9;
|
|
29357
|
+
if (notification.reason === "delivery-window-expired") process.stderr.write(NOTIFY_WINDOW_MESSAGE);
|
|
27885
29358
|
}
|
|
27886
29359
|
if (result.metadata.expiryClamped === true) process.stderr.write(`Share expiry clamped to session expiry (${result.metadata.expiresAt}).
|
|
27887
29360
|
`);
|
|
27888
|
-
if (json) writeJson2({ ...redactPublishedShare(result), expiryClamped: result.metadata.expiryClamped === true });
|
|
29361
|
+
if (json) writeJson2({ ...redactPublishedShare(result), expiryClamped: result.metadata.expiryClamped === true, ...notification === void 0 ? {} : { notification } });
|
|
27889
29362
|
else publishHuman(result);
|
|
27890
29363
|
} catch (error) {
|
|
27891
29364
|
handleError(shareCliError(error));
|
|
@@ -27972,20 +29445,31 @@ function registerShareCommand(program) {
|
|
|
27972
29445
|
handleError(shareCliError(error));
|
|
27973
29446
|
}
|
|
27974
29447
|
});
|
|
27975
|
-
share.command("notify <id>").description("Retry idempotent delivery
|
|
29448
|
+
share.command("notify <id>").description("Retry idempotent delivery within 5 minutes of publication; after that publish a new share").requiredOption("--to <address>", "Recipient email").option("--json", "Print versioned JSON").action(async (id, options, command) => {
|
|
27976
29449
|
try {
|
|
27977
29450
|
const json = jsonOutput(options, command);
|
|
27978
29451
|
if (shareServices.delivery === void 0) throw new CLIError("AUTH_REQUIRED", "delivery authority is not configured", 3);
|
|
27979
29452
|
if (shareServices.records === void 0) throw new CLIError("AUTH_REQUIRED", "sender history storage is not configured", 3);
|
|
27980
29453
|
const record = await shareServices.records.get(id);
|
|
27981
29454
|
if (record === void 0) throw new CLIError("NOT_FOUND", "share not found", 4);
|
|
27982
|
-
|
|
29455
|
+
if (!record.actions.includes("tinycloud.kv/get")) {
|
|
29456
|
+
throw new CLIError("INVALID_ARGUMENT", "share notify requires a stored share with the read action; no invitation was sent", 2);
|
|
29457
|
+
}
|
|
29458
|
+
const mailbox = canonicalMailbox2(options.to);
|
|
29459
|
+
if (mailbox === void 0) throw new ShareNotifyError("recipient is invalid");
|
|
29460
|
+
if (!recipientMatchesShareRecord(record, mailbox.email)) throw new ShareNotifyError("recipient does not match the stored share target");
|
|
29461
|
+
if (record.recipientMatcher.kind === "emailDomain" && shareDeliveryWindowExpiresAt(record) > Date.now()) {
|
|
29462
|
+
if (shareServices.assertDomainDelivery === void 0) throw new CLIError("UNAVAILABLE", "could not verify TinyCloud node 1.17.3 domain delivery support; no invitation was sent", 4);
|
|
29463
|
+
await shareServices.assertDomainDelivery();
|
|
29464
|
+
}
|
|
29465
|
+
const result = await notifyRecordedShare(record, options.to, shareServices.delivery, shareServices.records);
|
|
27983
29466
|
if (json) writeJson2(result);
|
|
27984
29467
|
else process.stdout.write(`${result.state}
|
|
27985
29468
|
`);
|
|
29469
|
+
if (result.reason === "delivery-window-expired") process.stderr.write(NOTIFY_WINDOW_MESSAGE);
|
|
27986
29470
|
if (result.state === "partial-failure") process.exitCode = 9;
|
|
27987
29471
|
} catch (error) {
|
|
27988
|
-
handleError(shareCliError(error));
|
|
29472
|
+
handleError(shareCliError(error, "notify"));
|
|
27989
29473
|
}
|
|
27990
29474
|
});
|
|
27991
29475
|
share.command("revoke <id>").description("Revoke addressed shares; report bearer retention honestly").option("--ancestor", "Revoke the owner delegation ancestry").option("--json", "Print versioned JSON").action(async (id, options, command) => {
|
|
@@ -28561,7 +30045,13 @@ async function readHasKey(name, issues) {
|
|
|
28561
30045
|
}
|
|
28562
30046
|
async function readDelegations(name, issues) {
|
|
28563
30047
|
try {
|
|
28564
|
-
|
|
30048
|
+
const entries = await loadAdditionalDelegations(name);
|
|
30049
|
+
const { storedDelegationKind } = await import("@tinycloud/operations/delegation-binding");
|
|
30050
|
+
const readable = entries.filter((entry) => storedDelegationKind(entry) !== "refused");
|
|
30051
|
+
if (readable.length < entries.length) {
|
|
30052
|
+
issues.push(`delegations: ${entries.length - readable.length} unreadable stored record(s) skipped`);
|
|
30053
|
+
}
|
|
30054
|
+
return readable;
|
|
28565
30055
|
} catch (error) {
|
|
28566
30056
|
issues.push(`delegations: ${messageFromError(error)}`);
|
|
28567
30057
|
return [];
|