tenjin-cli 0.1.0-alpha.1 → 0.1.0-alpha.3
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/NOTICE.md +33 -0
- package/README.md +167 -16
- package/dist/{_esm-ZH2J4QEH.js → _esm-C5CRWCYU.js} +2 -2
- package/dist/_esm-FEASBWRP.js +881 -0
- package/dist/buy-EE6SEXP6.js +1598 -0
- package/dist/buy-EE6SEXP6.js.map +1 -0
- package/dist/candidate-ERMSYYQZ.js +127 -0
- package/dist/candidate-ERMSYYQZ.js.map +1 -0
- package/dist/{ccip-UCLT5VOW.js → ccip-NQXCEK2U.js} +6 -5
- package/dist/ccip-XR5NE5QK.js +19 -0
- package/dist/chunk-2I4QTOLB.js +11 -0
- package/dist/chunk-2I4QTOLB.js.map +1 -0
- package/dist/chunk-3OV7E5G5.js +18 -0
- package/dist/chunk-3OV7E5G5.js.map +1 -0
- package/dist/chunk-4ONXEEQL.js +152 -0
- package/dist/chunk-4ONXEEQL.js.map +1 -0
- package/dist/chunk-5CLSD5YN.js +209 -0
- package/dist/chunk-5CLSD5YN.js.map +1 -0
- package/dist/chunk-662MSGZB.js +286 -0
- package/dist/chunk-662MSGZB.js.map +1 -0
- package/dist/chunk-7KUW4MJD.js +59 -0
- package/dist/chunk-7KUW4MJD.js.map +1 -0
- package/dist/{doctor-3QBYN46N.js → chunk-AWPAWHNX.js} +88 -93
- package/dist/chunk-AWPAWHNX.js.map +1 -0
- package/dist/chunk-CYOF7ROH.js +70 -0
- package/dist/chunk-CYOF7ROH.js.map +1 -0
- package/dist/chunk-DXTQ3CSI.js +171 -0
- package/dist/chunk-DXTQ3CSI.js.map +1 -0
- package/dist/{chunk-EZROUI5U.js → chunk-ESPNTPQ2.js} +80 -8
- package/dist/chunk-ESPNTPQ2.js.map +1 -0
- package/dist/chunk-FJPLRISB.js +79 -0
- package/dist/chunk-FJPLRISB.js.map +1 -0
- package/dist/chunk-GO75V3NZ.js +160 -0
- package/dist/chunk-GO75V3NZ.js.map +1 -0
- package/dist/chunk-HIVZG55D.js +204 -0
- package/dist/chunk-HIVZG55D.js.map +1 -0
- package/dist/chunk-HSDCI7OV.js +7806 -0
- package/dist/chunk-HSDCI7OV.js.map +1 -0
- package/dist/chunk-JPHG2JW3.js +96 -0
- package/dist/chunk-JPHG2JW3.js.map +1 -0
- package/dist/{chunk-ZPZFPVDN.js → chunk-MUBUQVC3.js} +1 -1
- package/dist/chunk-MUBUQVC3.js.map +1 -0
- package/dist/{chunk-T4LKNY7T.js → chunk-NCE5NSN6.js} +166 -11
- package/dist/chunk-NCE5NSN6.js.map +1 -0
- package/dist/{chunk-YG2DO46P.js → chunk-OYMYCW7J.js} +18 -3
- package/dist/{chunk-YG2DO46P.js.map → chunk-OYMYCW7J.js.map} +1 -1
- package/dist/{chunk-Q53IYV2G.js → chunk-QVX5MWJZ.js} +20 -17
- package/dist/{chunk-Q53IYV2G.js.map → chunk-QVX5MWJZ.js.map} +1 -1
- package/dist/{chunk-CUWUHTIL.js → chunk-RBJPAZFI.js} +16 -202
- package/dist/chunk-RBJPAZFI.js.map +1 -0
- package/dist/chunk-RRN3YTK7.js +6199 -0
- package/dist/chunk-RRN3YTK7.js.map +1 -0
- package/dist/chunk-RY4XKNV3.js +140 -0
- package/dist/chunk-RY4XKNV3.js.map +1 -0
- package/dist/chunk-S3IGX57D.js +14682 -0
- package/dist/chunk-S3IGX57D.js.map +1 -0
- package/dist/chunk-TLCMMYLY.js +126 -0
- package/dist/chunk-TLCMMYLY.js.map +1 -0
- package/dist/{chunk-IPOWB3G3.js → chunk-UGX7YPX2.js} +3314 -306
- package/dist/chunk-UGX7YPX2.js.map +1 -0
- package/dist/chunk-UO22YNY4.js +69 -0
- package/dist/chunk-UO22YNY4.js.map +1 -0
- package/dist/{config-CEFTL5ZL.js → chunk-XHC6FCGZ.js} +115 -18
- package/dist/chunk-XHC6FCGZ.js.map +1 -0
- package/dist/chunk-XJIW7USF.js +217 -0
- package/dist/chunk-XJIW7USF.js.map +1 -0
- package/dist/{chunk-BRJHUQSY.js → chunk-YALGASEU.js} +1548 -1452
- package/dist/chunk-YALGASEU.js.map +1 -0
- package/dist/{chunk-DXPYFVKG.js → chunk-YN5SHIXQ.js} +6 -6
- package/dist/chunk-YN5SHIXQ.js.map +1 -0
- package/dist/chunk-Z52RA3NC.js +137 -0
- package/dist/chunk-Z52RA3NC.js.map +1 -0
- package/dist/{chunk-EXBMF5X7.js → chunk-Z6MFJV5Z.js} +151 -19
- package/dist/chunk-Z6MFJV5Z.js.map +1 -0
- package/dist/chunk-ZABPQJ3M.js +83 -0
- package/dist/chunk-ZABPQJ3M.js.map +1 -0
- package/dist/{chunk-LPRVHM7P.js → chunk-ZMHYXMO6.js} +1655 -114
- package/dist/chunk-ZMHYXMO6.js.map +1 -0
- package/dist/{chunk-3IMLRUZE.js → chunk-ZXTAQYNA.js} +6 -2
- package/dist/{cli-WA65NP4Y.js → cli-SBXI5AMS.js} +177 -177
- package/dist/cli-SBXI5AMS.js.map +1 -0
- package/dist/config-VELDKLHY.js +21 -0
- package/dist/doctor-T3KWNNP2.js +20 -0
- package/dist/doctor-T3KWNNP2.js.map +1 -0
- package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js +18 -0
- package/dist/ethersCompat-Df4a6QIZ-3YZIAXDK.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/inspect-LMKOXE4Y.js +96 -0
- package/dist/inspect-LMKOXE4Y.js.map +1 -0
- package/dist/install-LEX3ENQ6.js +387 -0
- package/dist/install-LEX3ENQ6.js.map +1 -0
- package/dist/lookup-ZPN2Q67N.js +129 -0
- package/dist/lookup-ZPN2Q67N.js.map +1 -0
- package/dist/{mine.wasm-GQECMSGN.js → mine.wasm-6PIT3DK6.js} +2 -2
- package/dist/outcome-N7TAK6WR.js +66 -0
- package/dist/outcome-N7TAK6WR.js.map +1 -0
- package/dist/publish-BKBQQAW4.js +1478 -0
- package/dist/publish-BKBQQAW4.js.map +1 -0
- package/dist/{secp256k1-BEZS642W.js → secp256k1-N3ZHU7LB.js} +5 -4
- package/dist/secp256k1-N3ZHU7LB.js.map +1 -0
- package/dist/usdc-JIAJW4SV.js +22 -0
- package/dist/usdc-JIAJW4SV.js.map +1 -0
- package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js +14 -0
- package/dist/viemAdapter-By13KInL-ZZE6UV4Y.js.map +1 -0
- package/dist/{wallet-XD576HF3.js → wallet-CWEMYVIH.js} +28 -22
- package/dist/{wallet-XD576HF3.js.map → wallet-CWEMYVIH.js.map} +1 -1
- package/dist/wallet-PA54CRBL.js +30 -0
- package/dist/wallet-PA54CRBL.js.map +1 -0
- package/package.json +19 -16
- package/skills/tenjin/SKILL.md +199 -0
- package/skills/tenjin-publish/SKILL.md +111 -0
- package/skills/tenjin-search/SKILL.md +133 -0
- package/dist/chunk-BRJHUQSY.js.map +0 -1
- package/dist/chunk-CUWUHTIL.js.map +0 -1
- package/dist/chunk-DXPYFVKG.js.map +0 -1
- package/dist/chunk-EXBMF5X7.js.map +0 -1
- package/dist/chunk-EZROUI5U.js.map +0 -1
- package/dist/chunk-IPOWB3G3.js.map +0 -1
- package/dist/chunk-LPRVHM7P.js.map +0 -1
- package/dist/chunk-T4LKNY7T.js.map +0 -1
- package/dist/chunk-ZPZFPVDN.js.map +0 -1
- package/dist/cli-WA65NP4Y.js.map +0 -1
- package/dist/config-CEFTL5ZL.js.map +0 -1
- package/dist/doctor-3QBYN46N.js.map +0 -1
- package/dist/usdc-44R6XZF2.js +0 -18
- package/dist/wallet-ELBTBMXO.js +0 -20
- /package/dist/{_esm-ZH2J4QEH.js.map → _esm-C5CRWCYU.js.map} +0 -0
- /package/dist/{ccip-UCLT5VOW.js.map → _esm-FEASBWRP.js.map} +0 -0
- /package/dist/{chunk-3IMLRUZE.js.map → ccip-NQXCEK2U.js.map} +0 -0
- /package/dist/{secp256k1-BEZS642W.js.map → ccip-XR5NE5QK.js.map} +0 -0
- /package/dist/{usdc-44R6XZF2.js.map → chunk-ZXTAQYNA.js.map} +0 -0
- /package/dist/{wallet-ELBTBMXO.js.map → config-VELDKLHY.js.map} +0 -0
- /package/dist/{mine.wasm-GQECMSGN.js.map → mine.wasm-6PIT3DK6.js.map} +0 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
createCandidate,
|
|
4
|
+
dropCandidate,
|
|
5
|
+
listCandidates
|
|
6
|
+
} from "./chunk-TLCMMYLY.js";
|
|
7
|
+
import {
|
|
8
|
+
UUID_RE
|
|
9
|
+
} from "./chunk-3OV7E5G5.js";
|
|
10
|
+
import {
|
|
11
|
+
sanitizeForTerminal
|
|
12
|
+
} from "./chunk-Z52RA3NC.js";
|
|
13
|
+
import {
|
|
14
|
+
pathExists
|
|
15
|
+
} from "./chunk-GO75V3NZ.js";
|
|
16
|
+
import "./chunk-ESPNTPQ2.js";
|
|
17
|
+
import "./chunk-2I4QTOLB.js";
|
|
18
|
+
import "./chunk-UO22YNY4.js";
|
|
19
|
+
import "./chunk-MUBUQVC3.js";
|
|
20
|
+
import {
|
|
21
|
+
CliError
|
|
22
|
+
} from "./chunk-OYMYCW7J.js";
|
|
23
|
+
import "./chunk-ZXTAQYNA.js";
|
|
24
|
+
|
|
25
|
+
// src/commands/candidate.ts
|
|
26
|
+
import { readFile } from "fs/promises";
|
|
27
|
+
import { dirname, join, resolve } from "path";
|
|
28
|
+
async function runCandidateAdd(args, ctx, deps = {}) {
|
|
29
|
+
if (!UUID_RE.test(args.lookupId)) {
|
|
30
|
+
throw new CliError("USAGE", `Invalid --lookup-id: ${JSON.stringify(args.lookupId)}.`, {
|
|
31
|
+
fix: "Pass the lookupId from a prior `tenjin lookup` (a uuid)."
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (args.question !== void 0 && args.question.length > 200) {
|
|
35
|
+
throw new CliError("USAGE", "A candidate --question is at most 200 characters.", {
|
|
36
|
+
fix: "Shorten the question to 200 characters or fewer."
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
let draft;
|
|
40
|
+
try {
|
|
41
|
+
draft = await readFile(args.file, "utf8");
|
|
42
|
+
} catch (err) {
|
|
43
|
+
throw new CliError("USAGE", `Cannot read draft file ${JSON.stringify(args.file)}.`, {
|
|
44
|
+
fix: "Pass a path to a readable Markdown file.",
|
|
45
|
+
cause: err
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
49
|
+
const sourceProject = await repoRootOrCwd(cwd);
|
|
50
|
+
const created = (deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
51
|
+
const record = await createCandidate(ctx.dataDir, {
|
|
52
|
+
draft,
|
|
53
|
+
lookupId: args.lookupId,
|
|
54
|
+
...args.question !== void 0 ? { question: args.question } : {},
|
|
55
|
+
created,
|
|
56
|
+
sourceProject
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
data: {
|
|
60
|
+
id: record.id,
|
|
61
|
+
path: record.dir,
|
|
62
|
+
lookupId: record.meta.lookupId,
|
|
63
|
+
...record.meta.question !== void 0 ? { question: record.meta.question } : {},
|
|
64
|
+
created: record.meta.created,
|
|
65
|
+
sourceProject: record.meta.sourceProject
|
|
66
|
+
},
|
|
67
|
+
humanLines: [`Parked candidate ${record.id}`, ` ${record.dir}`]
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async function runCandidateList(ctx, deps = {}) {
|
|
71
|
+
const now = deps.now?.() ?? /* @__PURE__ */ new Date();
|
|
72
|
+
const records = await listCandidates(ctx.dataDir);
|
|
73
|
+
const candidates = records.map((r) => ({
|
|
74
|
+
id: r.id,
|
|
75
|
+
lookupId: r.meta.lookupId,
|
|
76
|
+
...r.meta.question !== void 0 ? { question: r.meta.question } : {},
|
|
77
|
+
created: r.meta.created,
|
|
78
|
+
sourceProject: r.meta.sourceProject,
|
|
79
|
+
path: r.dir
|
|
80
|
+
}));
|
|
81
|
+
const humanLines = records.length === 0 ? ["No pending candidates."] : records.map((r) => {
|
|
82
|
+
const q = r.meta.question !== void 0 ? sanitizeForTerminal(r.meta.question) : "(no question)";
|
|
83
|
+
return `${r.id} ${humanizeAge(r.meta.created, now)} ${q} [${sanitizeForTerminal(
|
|
84
|
+
r.meta.sourceProject
|
|
85
|
+
)}]`;
|
|
86
|
+
});
|
|
87
|
+
return { data: { candidates }, humanLines };
|
|
88
|
+
}
|
|
89
|
+
async function runCandidateDrop(args, ctx) {
|
|
90
|
+
const dropped = await dropCandidate(ctx.dataDir, args.id);
|
|
91
|
+
if (!dropped) {
|
|
92
|
+
throw new CliError("USAGE", `No candidate with id ${JSON.stringify(args.id)}.`, {
|
|
93
|
+
fix: "Run `tenjin candidate list` to see pending candidate ids."
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
data: { id: args.id, dropped: true },
|
|
98
|
+
humanLines: [`Dropped candidate ${args.id}.`]
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function repoRootOrCwd(cwd) {
|
|
102
|
+
let dir = resolve(cwd);
|
|
103
|
+
for (; ; ) {
|
|
104
|
+
if (await pathExists(join(dir, ".git"))) return dir;
|
|
105
|
+
const parent = dirname(dir);
|
|
106
|
+
if (parent === dir) return resolve(cwd);
|
|
107
|
+
dir = parent;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
var MINUTE = 6e4;
|
|
111
|
+
var HOUR = 60 * MINUTE;
|
|
112
|
+
var DAY = 24 * HOUR;
|
|
113
|
+
function humanizeAge(iso, now) {
|
|
114
|
+
const then = Date.parse(iso);
|
|
115
|
+
if (Number.isNaN(then)) return "just now";
|
|
116
|
+
const ms = now.getTime() - then;
|
|
117
|
+
if (ms < MINUTE) return "just now";
|
|
118
|
+
if (ms < HOUR) return `${Math.floor(ms / MINUTE)}m ago`;
|
|
119
|
+
if (ms < DAY) return `${Math.floor(ms / HOUR)}h ago`;
|
|
120
|
+
return `${Math.floor(ms / DAY)}d ago`;
|
|
121
|
+
}
|
|
122
|
+
export {
|
|
123
|
+
runCandidateAdd,
|
|
124
|
+
runCandidateDrop,
|
|
125
|
+
runCandidateList
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=candidate-ERMSYYQZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/candidate.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { CliError } from '../lib/errors';\nimport { createCandidate, dropCandidate, listCandidates } from '../lib/candidate-store';\nimport { UUID_RE } from '../lib/ids';\nimport { sanitizeForTerminal } from '../lib/output';\nimport { pathExists } from '../lib/settings';\nimport type { CommandContext, CommandResult } from '../context';\n\n/**\n * `tenjin candidate [add|list|drop]`: the D40 local store of parked publish\n * drafts. Entirely offline — a candidate never touches the network and never\n * uploads; only a later `tenjin publish --candidate <id>` sends it, under the\n * D38 consent scan. This module owns the command surface; lib/candidate-store.ts\n * owns the on-disk custody (0700 dirs, 0600 files, atomic meta commit).\n */\n\nexport interface CandidateAddArgs {\n file: string;\n lookupId: string;\n question?: string;\n}\n\nexport interface CandidateDeps {\n /** Clock seam so list ordering / age tests are deterministic. */\n now?: () => Date;\n /** cwd seam so sourceProject discovery is testable against a temp tree. */\n cwd?: string;\n}\n\nexport async function runCandidateAdd(\n args: CandidateAddArgs,\n ctx: CommandContext,\n deps: CandidateDeps = {},\n): Promise<CommandResult> {\n if (!UUID_RE.test(args.lookupId)) {\n throw new CliError('USAGE', `Invalid --lookup-id: ${JSON.stringify(args.lookupId)}.`, {\n fix: 'Pass the lookupId from a prior `tenjin lookup` (a uuid).',\n });\n }\n // Cap the question at the server's questionsAnswered item bound (200) at PARK\n // time, so a candidate can never be born unpublishable — it prefills the card's\n // questionsAnswered, which publish would otherwise reject only at write time.\n if (args.question !== undefined && args.question.length > 200) {\n throw new CliError('USAGE', 'A candidate --question is at most 200 characters.', {\n fix: 'Shorten the question to 200 characters or fewer.',\n });\n }\n\n let draft: string;\n try {\n draft = await readFile(args.file, 'utf8');\n } catch (err) {\n throw new CliError('USAGE', `Cannot read draft file ${JSON.stringify(args.file)}.`, {\n fix: 'Pass a path to a readable Markdown file.',\n cause: err,\n });\n }\n\n const cwd = deps.cwd ?? process.cwd();\n const sourceProject = await repoRootOrCwd(cwd);\n const created = (deps.now?.() ?? new Date()).toISOString();\n\n const record = await createCandidate(ctx.dataDir, {\n draft,\n lookupId: args.lookupId,\n ...(args.question !== undefined ? { question: args.question } : {}),\n created,\n sourceProject,\n });\n\n return {\n data: {\n id: record.id,\n path: record.dir,\n lookupId: record.meta.lookupId,\n ...(record.meta.question !== undefined ? { question: record.meta.question } : {}),\n created: record.meta.created,\n sourceProject: record.meta.sourceProject,\n },\n humanLines: [`Parked candidate ${record.id}`, ` ${record.dir}`],\n };\n}\n\nexport async function runCandidateList(\n ctx: CommandContext,\n deps: CandidateDeps = {},\n): Promise<CommandResult> {\n const now = deps.now?.() ?? new Date();\n const records = await listCandidates(ctx.dataDir);\n\n const candidates = records.map((r) => ({\n id: r.id,\n lookupId: r.meta.lookupId,\n ...(r.meta.question !== undefined ? { question: r.meta.question } : {}),\n created: r.meta.created,\n sourceProject: r.meta.sourceProject,\n path: r.dir,\n }));\n\n const humanLines =\n records.length === 0\n ? ['No pending candidates.']\n : records.map((r) => {\n const q =\n r.meta.question !== undefined ? sanitizeForTerminal(r.meta.question) : '(no question)';\n return `${r.id} ${humanizeAge(r.meta.created, now)} ${q} [${sanitizeForTerminal(\n r.meta.sourceProject,\n )}]`;\n });\n\n return { data: { candidates }, humanLines };\n}\n\nexport async function runCandidateDrop(\n args: { id: string },\n ctx: CommandContext,\n): Promise<CommandResult> {\n const dropped = await dropCandidate(ctx.dataDir, args.id);\n if (!dropped) {\n throw new CliError('USAGE', `No candidate with id ${JSON.stringify(args.id)}.`, {\n fix: 'Run `tenjin candidate list` to see pending candidate ids.',\n });\n }\n return {\n data: { id: args.id, dropped: true },\n humanLines: [`Dropped candidate ${args.id}.`],\n };\n}\n\n/**\n * The project a candidate was parked from: the nearest ancestor holding a `.git`\n * (inclusive), or the cwd when the add did not run inside a repo. Mirrors the\n * repo-root walk settings.ts uses to bound the `.tenjin.json` search.\n */\nasync function repoRootOrCwd(cwd: string): Promise<string> {\n let dir = resolve(cwd);\n for (;;) {\n if (await pathExists(join(dir, '.git'))) return dir;\n const parent = dirname(dir);\n if (parent === dir) return resolve(cwd);\n dir = parent;\n }\n}\n\nconst MINUTE = 60_000;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\n\n/**\n * Compact relative age for the human list (\"just now\", \"5m ago\", \"3d ago\"). A\n * future or unparseable timestamp degrades to \"just now\" rather than throwing;\n * the ISO value is always carried verbatim in the JSON data for machines.\n */\nfunction humanizeAge(iso: string, now: Date): string {\n const then = Date.parse(iso);\n if (Number.isNaN(then)) return 'just now';\n const ms = now.getTime() - then;\n if (ms < MINUTE) return 'just now';\n if (ms < HOUR) return `${Math.floor(ms / MINUTE)}m ago`;\n if (ms < DAY) return `${Math.floor(ms / HOUR)}h ago`;\n return `${Math.floor(ms / DAY)}d ago`;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,14 +4,15 @@ import {
|
|
|
4
4
|
offchainLookup,
|
|
5
5
|
offchainLookupAbiItem,
|
|
6
6
|
offchainLookupSignature
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-RRN3YTK7.js";
|
|
8
|
+
import "./chunk-HIVZG55D.js";
|
|
9
|
+
import "./chunk-RBJPAZFI.js";
|
|
10
|
+
import "./chunk-5CLSD5YN.js";
|
|
11
|
+
import "./chunk-ZXTAQYNA.js";
|
|
11
12
|
export {
|
|
12
13
|
ccipRequest,
|
|
13
14
|
offchainLookup,
|
|
14
15
|
offchainLookupAbiItem,
|
|
15
16
|
offchainLookupSignature
|
|
16
17
|
};
|
|
17
|
-
//# sourceMappingURL=ccip-
|
|
18
|
+
//# sourceMappingURL=ccip-NQXCEK2U.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ccipRequest,
|
|
4
|
+
offchainLookup,
|
|
5
|
+
offchainLookupAbiItem,
|
|
6
|
+
offchainLookupSignature
|
|
7
|
+
} from "./chunk-ZMHYXMO6.js";
|
|
8
|
+
import "./chunk-YALGASEU.js";
|
|
9
|
+
import "./chunk-HIVZG55D.js";
|
|
10
|
+
import "./chunk-RBJPAZFI.js";
|
|
11
|
+
import "./chunk-5CLSD5YN.js";
|
|
12
|
+
import "./chunk-ZXTAQYNA.js";
|
|
13
|
+
export {
|
|
14
|
+
ccipRequest,
|
|
15
|
+
offchainLookup,
|
|
16
|
+
offchainLookupAbiItem,
|
|
17
|
+
offchainLookupSignature
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=ccip-XR5NE5QK.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/lib/errno.ts
|
|
4
|
+
function hasCode(err, code) {
|
|
5
|
+
return typeof err === "object" && err !== null && "code" in err && err.code === code;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
hasCode
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=chunk-2I4QTOLB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/errno.ts"],"sourcesContent":["/**\n * True when `err` is a Node system error carrying the given `code` (ENOENT,\n * EEXIST, …). One definition so the fs-error checks scattered across the wallet\n * store, config loader, and session cache stay identical.\n */\nexport function hasCode(err: unknown, code: string): boolean {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as { code?: unknown }).code === code\n );\n}\n"],"mappings":";;;AAKO,SAAS,QAAQ,KAAc,MAAuB;AAC3D,SACE,OAAO,QAAQ,YACf,QAAQ,QACR,UAAU,OACT,IAA2B,SAAS;AAEzC;","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/lib/ids.ts
|
|
4
|
+
import { randomUUID } from "crypto";
|
|
5
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
6
|
+
var SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
7
|
+
var ATOMIC_RE = /^\d{1,39}$/;
|
|
8
|
+
function newId() {
|
|
9
|
+
return randomUUID();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
UUID_RE,
|
|
14
|
+
SLUG_RE,
|
|
15
|
+
ATOMIC_RE,
|
|
16
|
+
newId
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=chunk-3OV7E5G5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/ids.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\n/**\n * The shared identity patterns for server-controlled values that become file\n * paths, URL segments, or terminal output. One definition so a future change\n * (e.g. accepting uppercase ids) cannot be applied in one command and missed in\n * another. SLUG_RE must match the server's slugify charset (lib/posts.ts:\n * lowercase a-z0-9 groups joined by single hyphens, no leading/trailing hyphen).\n */\nexport const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nexport const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n/** A non-negative atomic USDC integer string (6-decimal base units). */\nexport const ATOMIC_RE = /^\\d{1,39}$/;\n\n/**\n * Mint a fresh opaque id for a locally-created entity (a parked candidate). A v4\n * uuid: the same shape a lookupId takes, so UUID_RE validates it and a `drop\n * <id>` argument that reaches a filesystem path can't traverse out of the store.\n */\nexport function newId(): string {\n return randomUUID();\n}\n"],"mappings":";;;AAAA,SAAS,kBAAkB;AASpB,IAAM,UAAU;AAChB,IAAM,UAAU;AAEhB,IAAM,YAAY;AAOlB,SAAS,QAAgB;AAC9B,SAAO,WAAW;AACpB;","names":[]}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
package_default
|
|
4
|
+
} from "./chunk-FJPLRISB.js";
|
|
5
|
+
|
|
6
|
+
// src/lib/http.ts
|
|
7
|
+
async function fetchJson(url, opts) {
|
|
8
|
+
const doFetch = opts.fetchImpl ?? fetch;
|
|
9
|
+
const controller = new AbortController();
|
|
10
|
+
let timedOut = false;
|
|
11
|
+
const timer = setTimeout(() => {
|
|
12
|
+
timedOut = true;
|
|
13
|
+
controller.abort();
|
|
14
|
+
}, opts.timeoutMs);
|
|
15
|
+
try {
|
|
16
|
+
let res;
|
|
17
|
+
try {
|
|
18
|
+
res = await doFetch(url, {
|
|
19
|
+
signal: controller.signal,
|
|
20
|
+
...opts.headers !== void 0 ? { headers: opts.headers } : {}
|
|
21
|
+
});
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return timedOut ? timeoutFailure(url, opts.timeoutMs) : { ok: false, kind: "network", message: `Request to ${url} failed: ${errorMessage(err)}` };
|
|
24
|
+
}
|
|
25
|
+
const requestId = res.headers.get("x-request-id") ?? void 0;
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
kind: "http",
|
|
30
|
+
status: res.status,
|
|
31
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
32
|
+
message: `Request to ${url} failed with status ${res.status}`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
let json;
|
|
36
|
+
try {
|
|
37
|
+
json = await res.json();
|
|
38
|
+
} catch (err) {
|
|
39
|
+
if (timedOut) return timeoutFailure(url, opts.timeoutMs);
|
|
40
|
+
if (err instanceof SyntaxError) {
|
|
41
|
+
return {
|
|
42
|
+
ok: false,
|
|
43
|
+
kind: "invalid-json",
|
|
44
|
+
status: res.status,
|
|
45
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
46
|
+
message: `Response from ${url} was not valid JSON`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
kind: "network",
|
|
52
|
+
status: res.status,
|
|
53
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
54
|
+
message: `Request to ${url} failed while reading the response body: ${errorMessage(err)}`
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
ok: true,
|
|
59
|
+
status: res.status,
|
|
60
|
+
json,
|
|
61
|
+
...requestId !== void 0 ? { requestId } : {}
|
|
62
|
+
};
|
|
63
|
+
} finally {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function timeoutFailure(url, timeoutMs) {
|
|
68
|
+
return {
|
|
69
|
+
ok: false,
|
|
70
|
+
kind: "timeout",
|
|
71
|
+
message: `Request to ${url} timed out after ${timeoutMs}ms`
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function httpRequest(url, opts) {
|
|
75
|
+
const doFetch = opts.fetchImpl ?? fetch;
|
|
76
|
+
const controller = new AbortController();
|
|
77
|
+
let timedOut = false;
|
|
78
|
+
const timer = setTimeout(() => {
|
|
79
|
+
timedOut = true;
|
|
80
|
+
controller.abort();
|
|
81
|
+
}, opts.timeoutMs);
|
|
82
|
+
try {
|
|
83
|
+
const headers = { ...opts.headers ?? {} };
|
|
84
|
+
let body;
|
|
85
|
+
if (opts.jsonBody !== void 0) {
|
|
86
|
+
body = JSON.stringify(opts.jsonBody);
|
|
87
|
+
headers["content-type"] = "application/json";
|
|
88
|
+
}
|
|
89
|
+
if (opts.method === "POST" || body !== void 0) headers["accept"] ??= "application/json";
|
|
90
|
+
let res;
|
|
91
|
+
try {
|
|
92
|
+
res = await doFetch(url, {
|
|
93
|
+
method: opts.method ?? "GET",
|
|
94
|
+
headers,
|
|
95
|
+
body,
|
|
96
|
+
signal: controller.signal
|
|
97
|
+
});
|
|
98
|
+
} catch (err) {
|
|
99
|
+
return timedOut ? timeoutFailure(url, opts.timeoutMs) : { ok: false, kind: "network", message: `Request to ${url} failed: ${errorMessage(err)}` };
|
|
100
|
+
}
|
|
101
|
+
const requestId = res.headers.get("x-request-id") ?? void 0;
|
|
102
|
+
let text;
|
|
103
|
+
try {
|
|
104
|
+
text = await res.text();
|
|
105
|
+
} catch (err) {
|
|
106
|
+
if (timedOut) return timeoutFailure(url, opts.timeoutMs);
|
|
107
|
+
return {
|
|
108
|
+
ok: false,
|
|
109
|
+
kind: "network",
|
|
110
|
+
status: res.status,
|
|
111
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
112
|
+
message: `Request to ${url} failed while reading the response body: ${errorMessage(err)}`
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
let json;
|
|
116
|
+
if (text.length > 0) {
|
|
117
|
+
try {
|
|
118
|
+
json = JSON.parse(text);
|
|
119
|
+
} catch {
|
|
120
|
+
json = void 0;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
ok: true,
|
|
125
|
+
status: res.status,
|
|
126
|
+
header: (name) => res.headers.get(name) ?? void 0,
|
|
127
|
+
json,
|
|
128
|
+
...requestId !== void 0 ? { requestId } : {}
|
|
129
|
+
};
|
|
130
|
+
} finally {
|
|
131
|
+
clearTimeout(timer);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function errorMessage(err) {
|
|
135
|
+
return err instanceof Error ? err.message : String(err);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/lib/client-meta.ts
|
|
139
|
+
var CLIENT_HEADER = `tenjin-cli/${package_default.version}`;
|
|
140
|
+
|
|
141
|
+
// src/lib/url.ts
|
|
142
|
+
function trimSlash(url) {
|
|
143
|
+
return url.replace(/\/+$/, "");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export {
|
|
147
|
+
fetchJson,
|
|
148
|
+
httpRequest,
|
|
149
|
+
CLIENT_HEADER,
|
|
150
|
+
trimSlash
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=chunk-4ONXEEQL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/http.ts","../src/lib/client-meta.ts","../src/lib/url.ts"],"sourcesContent":["import { CliError } from './errors';\n\n/**\n * The single JSON client the whole CLI grows on: `doctor` uses it in B1, `lookup`\n * reuses it in B2. It never throws on a transport/protocol failure — it returns a\n * discriminated result so callers decide how each failure class maps to a check\n * or an error. `fetchImpl` is injectable so tests never touch the network.\n */\nexport interface FetchJsonOptions {\n /** Abort the request after this many milliseconds. */\n timeoutMs: number;\n /** Override global fetch (tests inject a stub returning canned Responses). */\n fetchImpl?: typeof fetch;\n /** Optional request headers (doctor sends the X-Tenjin-Client label). */\n headers?: Record<string, string>;\n}\n\n/** A successful 2xx whose body parsed as JSON. */\nexport interface FetchJsonSuccess {\n ok: true;\n status: number;\n json: unknown;\n /** The server's `x-request-id`, when it sent one — useful in error reports. */\n requestId?: string;\n}\n\n/**\n * A failed request, tagged by class so the caller maps it deliberately:\n * `network`/`timeout` (never reached the server or no answer), `http` (a non-2xx\n * status), `invalid-json` (2xx but the body was not JSON).\n */\nexport interface FetchJsonFailure {\n ok: false;\n kind: 'network' | 'timeout' | 'http' | 'invalid-json';\n status?: number;\n requestId?: string;\n message: string;\n}\n\nexport type FetchJsonResult = FetchJsonSuccess | FetchJsonFailure;\n\nexport async function fetchJson(url: string, opts: FetchJsonOptions): Promise<FetchJsonResult> {\n const doFetch = opts.fetchImpl ?? fetch;\n const controller = new AbortController();\n let timedOut = false;\n // The timer stays armed until the body is fully consumed (cleared in the outer\n // finally), so a server that sends headers then stalls the body still trips the\n // deadline instead of hanging forever on res.json().\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, opts.timeoutMs);\n\n try {\n let res: Response;\n try {\n res = await doFetch(url, {\n signal: controller.signal,\n ...(opts.headers !== undefined ? { headers: opts.headers } : {}),\n });\n } catch (err) {\n // A timeout is a network failure the AbortController induced; distinguish it\n // from an organic one so the caller can say \"timed out\" rather than a raw\n // AbortError message.\n return timedOut\n ? timeoutFailure(url, opts.timeoutMs)\n : { ok: false, kind: 'network', message: `Request to ${url} failed: ${errorMessage(err)}` };\n }\n\n const requestId = res.headers.get('x-request-id') ?? undefined;\n\n if (!res.ok) {\n return {\n ok: false,\n kind: 'http',\n status: res.status,\n ...(requestId !== undefined ? { requestId } : {}),\n message: `Request to ${url} failed with status ${res.status}`,\n };\n }\n\n let json: unknown;\n try {\n json = await res.json();\n } catch (err) {\n // The body read can fail three ways. A timeout wins first: the abort fires\n // synchronously with `timedOut`, so any abort-induced rejection here is our\n // deadline. Otherwise a SyntaxError is a genuine parse failure (invalid\n // JSON); anything else is a transport failure mid-body (network).\n if (timedOut) return timeoutFailure(url, opts.timeoutMs);\n if (err instanceof SyntaxError) {\n return {\n ok: false,\n kind: 'invalid-json',\n status: res.status,\n ...(requestId !== undefined ? { requestId } : {}),\n message: `Response from ${url} was not valid JSON`,\n };\n }\n return {\n ok: false,\n kind: 'network',\n status: res.status,\n ...(requestId !== undefined ? { requestId } : {}),\n message: `Request to ${url} failed while reading the response body: ${errorMessage(err)}`,\n };\n }\n\n return {\n ok: true,\n status: res.status,\n json,\n ...(requestId !== undefined ? { requestId } : {}),\n };\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction timeoutFailure(url: string, timeoutMs: number): FetchJsonFailure {\n return {\n ok: false,\n kind: 'timeout',\n message: `Request to ${url} timed out after ${timeoutMs}ms`,\n };\n}\n\n/**\n * A full HTTP round trip that surfaces the STATUS, headers, and best-effort JSON\n * body for ANY status. Unlike fetchJson (2xx-only), the B2 read/pay flow needs\n * the body on a 402 (the leak-safe preview) and a 409 (the owned-re-pay gate),\n * and lookup/outcome need a 4xx validation envelope. A transport/timeout failure\n * still returns the discriminated FetchJsonFailure so callers map it uniformly.\n */\nexport interface HttpRequestOptions {\n method?: 'GET' | 'POST';\n timeoutMs: number;\n headers?: Record<string, string>;\n /** A JSON body (POST); serialized with a content-type header set automatically. */\n jsonBody?: unknown;\n fetchImpl?: typeof fetch;\n}\n\nexport interface HttpResponse {\n ok: true;\n status: number;\n /** Case-insensitive header lookup over the response. */\n header(name: string): string | undefined;\n /** Parsed JSON body, or undefined when the body was empty or not JSON. */\n json: unknown;\n requestId?: string;\n}\n\nexport type HttpResult = HttpResponse | FetchJsonFailure;\n\nexport async function httpRequest(url: string, opts: HttpRequestOptions): Promise<HttpResult> {\n const doFetch = opts.fetchImpl ?? fetch;\n const controller = new AbortController();\n let timedOut = false;\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, opts.timeoutMs);\n\n try {\n const headers: Record<string, string> = { ...(opts.headers ?? {}) };\n let body: string | undefined;\n if (opts.jsonBody !== undefined) {\n body = JSON.stringify(opts.jsonBody);\n headers['content-type'] = 'application/json';\n }\n if (opts.method === 'POST' || body !== undefined) headers['accept'] ??= 'application/json';\n\n let res: Response;\n try {\n res = await doFetch(url, {\n method: opts.method ?? 'GET',\n headers,\n body,\n signal: controller.signal,\n });\n } catch (err) {\n return timedOut\n ? timeoutFailure(url, opts.timeoutMs)\n : { ok: false, kind: 'network', message: `Request to ${url} failed: ${errorMessage(err)}` };\n }\n\n const requestId = res.headers.get('x-request-id') ?? undefined;\n // Read the raw text once; parse best-effort. A non-JSON body (empty 202, an\n // HTML error page) yields `undefined` rather than a thrown parse, because a\n // 402/409 caller keys off the STATUS and only some statuses carry JSON.\n let text: string;\n try {\n text = await res.text();\n } catch (err) {\n if (timedOut) return timeoutFailure(url, opts.timeoutMs);\n return {\n ok: false,\n kind: 'network',\n status: res.status,\n ...(requestId !== undefined ? { requestId } : {}),\n message: `Request to ${url} failed while reading the response body: ${errorMessage(err)}`,\n };\n }\n let json: unknown;\n if (text.length > 0) {\n try {\n json = JSON.parse(text);\n } catch {\n json = undefined;\n }\n }\n return {\n ok: true,\n status: res.status,\n header: (name) => res.headers.get(name) ?? undefined,\n json,\n ...(requestId !== undefined ? { requestId } : {}),\n };\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport interface FailureToCliErrorOptions {\n fix?: string;\n details?: unknown;\n}\n\n/**\n * Normalize a fetch failure into the CLI error contract: network/timeout are a\n * NETWORK_ERROR, an `http` status (server reachable but errored — commonly 5xx)\n * is API_UNREACHABLE, and a 2xx that failed to parse when JSON was required is a\n * CONTRACT_MISMATCH. Callers that need a check-specific code (doctor) build their\n * own CliError; this is the default B2's passthrough leans on.\n */\nexport function fetchFailureToCliError(\n failure: FetchJsonFailure,\n opts: FailureToCliErrorOptions = {},\n): CliError {\n const code =\n failure.kind === 'network' || failure.kind === 'timeout'\n ? 'NETWORK_ERROR'\n : failure.kind === 'invalid-json'\n ? 'CONTRACT_MISMATCH'\n : 'API_UNREACHABLE';\n return new CliError(code, failure.message, {\n ...(opts.fix !== undefined ? { fix: opts.fix } : {}),\n ...(opts.details !== undefined ? { details: opts.details } : {}),\n });\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import pkg from '../../package.json';\n\n/**\n * The `X-Tenjin-Client` value on every B2 request (spec 09 §purchase-attribution):\n * the server classifies views/payments by this label, so a CLI lookup-flow\n * purchase is never mixed with a web checkout. Format `tenjin-cli/<version>`.\n */\nexport const CLIENT_HEADER = `tenjin-cli/${pkg.version}`;\n","/** Drop trailing slashes from a base URL so `${base}/path` never doubles a slash. */\nexport function trimSlash(url: string): string {\n return url.replace(/\\/+$/, '');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { createRequire as __tenjinCreateRequire } from 'node:module'; const require = __tenjinCreateRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/cryptoNode.js
|
|
4
|
+
import * as nc from "crypto";
|
|
5
|
+
var crypto = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : nc && typeof nc === "object" && "randomBytes" in nc ? nc : void 0;
|
|
6
|
+
|
|
7
|
+
// node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js
|
|
8
|
+
function isBytes(a) {
|
|
9
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
10
|
+
}
|
|
11
|
+
function anumber(n) {
|
|
12
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
13
|
+
throw new Error("positive integer expected, got " + n);
|
|
14
|
+
}
|
|
15
|
+
function abytes(b, ...lengths) {
|
|
16
|
+
if (!isBytes(b))
|
|
17
|
+
throw new Error("Uint8Array expected");
|
|
18
|
+
if (lengths.length > 0 && !lengths.includes(b.length))
|
|
19
|
+
throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
|
|
20
|
+
}
|
|
21
|
+
function ahash(h) {
|
|
22
|
+
if (typeof h !== "function" || typeof h.create !== "function")
|
|
23
|
+
throw new Error("Hash should be wrapped by utils.createHasher");
|
|
24
|
+
anumber(h.outputLen);
|
|
25
|
+
anumber(h.blockLen);
|
|
26
|
+
}
|
|
27
|
+
function aexists(instance, checkFinished = true) {
|
|
28
|
+
if (instance.destroyed)
|
|
29
|
+
throw new Error("Hash instance has been destroyed");
|
|
30
|
+
if (checkFinished && instance.finished)
|
|
31
|
+
throw new Error("Hash#digest() has already been called");
|
|
32
|
+
}
|
|
33
|
+
function aoutput(out, instance) {
|
|
34
|
+
abytes(out);
|
|
35
|
+
const min = instance.outputLen;
|
|
36
|
+
if (out.length < min) {
|
|
37
|
+
throw new Error("digestInto() expects output buffer of length at least " + min);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function u32(arr) {
|
|
41
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
42
|
+
}
|
|
43
|
+
function clean(...arrays) {
|
|
44
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
45
|
+
arrays[i].fill(0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function createView(arr) {
|
|
49
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
50
|
+
}
|
|
51
|
+
function rotr(word, shift) {
|
|
52
|
+
return word << 32 - shift | word >>> shift;
|
|
53
|
+
}
|
|
54
|
+
function rotl(word, shift) {
|
|
55
|
+
return word << shift | word >>> 32 - shift >>> 0;
|
|
56
|
+
}
|
|
57
|
+
var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
58
|
+
function byteSwap(word) {
|
|
59
|
+
return word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
|
|
60
|
+
}
|
|
61
|
+
function byteSwap32(arr) {
|
|
62
|
+
for (let i = 0; i < arr.length; i++) {
|
|
63
|
+
arr[i] = byteSwap(arr[i]);
|
|
64
|
+
}
|
|
65
|
+
return arr;
|
|
66
|
+
}
|
|
67
|
+
var swap32IfBE = isLE ? (u) => u : byteSwap32;
|
|
68
|
+
var hasHexBuiltin = /* @__PURE__ */ (() => (
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function"
|
|
71
|
+
))();
|
|
72
|
+
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
73
|
+
function bytesToHex(bytes) {
|
|
74
|
+
abytes(bytes);
|
|
75
|
+
if (hasHexBuiltin)
|
|
76
|
+
return bytes.toHex();
|
|
77
|
+
let hex = "";
|
|
78
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
79
|
+
hex += hexes[bytes[i]];
|
|
80
|
+
}
|
|
81
|
+
return hex;
|
|
82
|
+
}
|
|
83
|
+
var nextTick = async () => {
|
|
84
|
+
};
|
|
85
|
+
async function asyncLoop(iters, tick, cb) {
|
|
86
|
+
let ts = Date.now();
|
|
87
|
+
for (let i = 0; i < iters; i++) {
|
|
88
|
+
cb(i);
|
|
89
|
+
const diff = Date.now() - ts;
|
|
90
|
+
if (diff >= 0 && diff < tick)
|
|
91
|
+
continue;
|
|
92
|
+
await nextTick();
|
|
93
|
+
ts += diff;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function utf8ToBytes(str) {
|
|
97
|
+
if (typeof str !== "string")
|
|
98
|
+
throw new Error("string expected");
|
|
99
|
+
return new Uint8Array(new TextEncoder().encode(str));
|
|
100
|
+
}
|
|
101
|
+
function toBytes(data) {
|
|
102
|
+
if (typeof data === "string")
|
|
103
|
+
data = utf8ToBytes(data);
|
|
104
|
+
abytes(data);
|
|
105
|
+
return data;
|
|
106
|
+
}
|
|
107
|
+
function kdfInputToBytes(data) {
|
|
108
|
+
if (typeof data === "string")
|
|
109
|
+
data = utf8ToBytes(data);
|
|
110
|
+
abytes(data);
|
|
111
|
+
return data;
|
|
112
|
+
}
|
|
113
|
+
function concatBytes(...arrays) {
|
|
114
|
+
let sum = 0;
|
|
115
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
116
|
+
const a = arrays[i];
|
|
117
|
+
abytes(a);
|
|
118
|
+
sum += a.length;
|
|
119
|
+
}
|
|
120
|
+
const res = new Uint8Array(sum);
|
|
121
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
122
|
+
const a = arrays[i];
|
|
123
|
+
res.set(a, pad);
|
|
124
|
+
pad += a.length;
|
|
125
|
+
}
|
|
126
|
+
return res;
|
|
127
|
+
}
|
|
128
|
+
function checkOpts(defaults, opts) {
|
|
129
|
+
if (opts !== void 0 && {}.toString.call(opts) !== "[object Object]")
|
|
130
|
+
throw new Error("options should be object or undefined");
|
|
131
|
+
const merged = Object.assign(defaults, opts);
|
|
132
|
+
return merged;
|
|
133
|
+
}
|
|
134
|
+
var Hash = class {
|
|
135
|
+
};
|
|
136
|
+
function createHasher(hashCons) {
|
|
137
|
+
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
|
138
|
+
const tmp = hashCons();
|
|
139
|
+
hashC.outputLen = tmp.outputLen;
|
|
140
|
+
hashC.blockLen = tmp.blockLen;
|
|
141
|
+
hashC.create = () => hashCons();
|
|
142
|
+
return hashC;
|
|
143
|
+
}
|
|
144
|
+
function randomBytes(bytesLength = 32) {
|
|
145
|
+
if (crypto && typeof crypto.getRandomValues === "function") {
|
|
146
|
+
return crypto.getRandomValues(new Uint8Array(bytesLength));
|
|
147
|
+
}
|
|
148
|
+
if (crypto && typeof crypto.randomBytes === "function") {
|
|
149
|
+
return Uint8Array.from(crypto.randomBytes(bytesLength));
|
|
150
|
+
}
|
|
151
|
+
throw new Error("crypto.getRandomValues must be defined");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/_u64.js
|
|
155
|
+
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
156
|
+
var _32n = /* @__PURE__ */ BigInt(32);
|
|
157
|
+
function fromBig(n, le = false) {
|
|
158
|
+
if (le)
|
|
159
|
+
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
160
|
+
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
161
|
+
}
|
|
162
|
+
function split(lst, le = false) {
|
|
163
|
+
const len = lst.length;
|
|
164
|
+
let Ah = new Uint32Array(len);
|
|
165
|
+
let Al = new Uint32Array(len);
|
|
166
|
+
for (let i = 0; i < len; i++) {
|
|
167
|
+
const { h, l } = fromBig(lst[i], le);
|
|
168
|
+
[Ah[i], Al[i]] = [h, l];
|
|
169
|
+
}
|
|
170
|
+
return [Ah, Al];
|
|
171
|
+
}
|
|
172
|
+
var rotlSH = (h, l, s) => h << s | l >>> 32 - s;
|
|
173
|
+
var rotlSL = (h, l, s) => l << s | h >>> 32 - s;
|
|
174
|
+
var rotlBH = (h, l, s) => l << s - 32 | h >>> 64 - s;
|
|
175
|
+
var rotlBL = (h, l, s) => h << s - 32 | l >>> 64 - s;
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
anumber,
|
|
179
|
+
abytes,
|
|
180
|
+
ahash,
|
|
181
|
+
aexists,
|
|
182
|
+
aoutput,
|
|
183
|
+
u32,
|
|
184
|
+
clean,
|
|
185
|
+
createView,
|
|
186
|
+
rotr,
|
|
187
|
+
rotl,
|
|
188
|
+
swap32IfBE,
|
|
189
|
+
bytesToHex,
|
|
190
|
+
asyncLoop,
|
|
191
|
+
toBytes,
|
|
192
|
+
kdfInputToBytes,
|
|
193
|
+
concatBytes,
|
|
194
|
+
checkOpts,
|
|
195
|
+
Hash,
|
|
196
|
+
createHasher,
|
|
197
|
+
randomBytes,
|
|
198
|
+
split,
|
|
199
|
+
rotlSH,
|
|
200
|
+
rotlSL,
|
|
201
|
+
rotlBH,
|
|
202
|
+
rotlBL
|
|
203
|
+
};
|
|
204
|
+
/*! Bundled license information:
|
|
205
|
+
|
|
206
|
+
@noble/hashes/esm/utils.js:
|
|
207
|
+
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
208
|
+
*/
|
|
209
|
+
//# sourceMappingURL=chunk-5CLSD5YN.js.map
|