@ours.network/sdk 1.7.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -29
- package/dist/api/contacts.js +1 -1
- package/dist/api/conversations.js +1 -1
- package/dist/api/files.js +1 -1
- package/dist/api/identity.js +1 -1
- package/dist/api/messaging.js +1 -1
- package/dist/api/profile.js +1 -1
- package/dist/book.js +1 -1
- package/dist/boot.js +1 -1
- package/dist/chunk-3KI5FM4I.js +2 -0
- package/dist/{chunk-4SXZ6CUL.js → chunk-4IGLXDJS.js} +1 -1
- package/dist/{chunk-BWTNLYDF.js → chunk-6SMQG6NV.js} +1 -1
- package/dist/chunk-CHDY74S7.js +3 -0
- package/dist/{chunk-2BSXRX6I.js → chunk-CQDCCH6N.js} +1 -1
- package/dist/{chunk-ZTGUX6EV.js → chunk-CUMFIDHH.js} +1 -1
- package/dist/{chunk-PPJAMKLP.js → chunk-DVYJ3STO.js} +1 -1
- package/dist/{chunk-IU6MOFTJ.js → chunk-EHCBEY52.js} +1 -1
- package/dist/{chunk-SBQCXH54.js → chunk-ENJRQKGS.js} +1 -1
- package/dist/chunk-OCHXHPQZ.js +2 -0
- package/dist/{chunk-QXKDTQMT.js → chunk-OPCXNIGD.js} +1 -1
- package/dist/{chunk-ARYFH7MF.js → chunk-QSDEMIZQ.js} +1 -1
- package/dist/{chunk-WOPXC4VC.js → chunk-SGTVMU5E.js} +1 -1
- package/dist/{chunk-EWT5DWPA.js → chunk-TIIFYDXJ.js} +1 -1
- package/dist/{chunk-K2UCTMMS.js → chunk-TNTHPI3A.js} +1 -1
- package/dist/{chunk-JHS7YUMA.js → chunk-UH4CZUMI.js} +1 -1
- package/dist/{chunk-UOHHUOWR.js → chunk-VJGMISQ5.js} +1 -1
- package/dist/chunk-WS6UFNKF.js +5 -0
- package/dist/{chunk-3RZX2WOJ.js → chunk-WU5WT7LA.js} +1 -1
- package/dist/{chunk-E2RQVNQK.js → chunk-WWTR33CX.js} +1 -1
- package/dist/{chunk-G3CKYZJ7.js → chunk-XL6UKHPU.js} +1 -1
- package/dist/chunk-Y3VPZJTG.js +2 -0
- package/dist/{chunk-BCVDO2DW.js → chunk-YDCAL5R3.js} +1 -1
- package/dist/{chunk-LIJDSFUD.js → chunk-YDWSAX43.js} +1 -1
- package/dist/chunk-ZGPYTIOX.js +2 -0
- package/dist/client/http.d.ts +5 -0
- package/dist/client/select.d.ts +29 -1
- package/dist/client/select.js +1 -1
- package/dist/client.js +1 -1
- package/dist/cluster/control.js +1 -1
- package/dist/cluster/manifest.js +1 -1
- package/dist/config.d.ts +0 -1
- package/dist/config.js +1 -1
- package/dist/connector.js +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/gc.js +1 -1
- package/dist/http/api-routes.js +1 -1
- package/dist/http/server.d.ts +2 -0
- package/dist/http/server.js +1 -1
- package/dist/identity/hierarchy.js +1 -1
- package/dist/identity/lease.js +1 -1
- package/dist/identity/lifecycle.js +1 -1
- package/dist/identity/model.d.ts +1 -2
- package/dist/identity/model.js +1 -1
- package/dist/identity/provision.js +1 -1
- package/dist/index.d.ts +3 -11
- package/dist/index.js +1 -1
- package/dist/internal/daemon.d.ts +11 -0
- package/dist/internal/daemon.js +2 -0
- package/dist/internal/state-root-lock.d.ts +25 -0
- package/dist/internal/state-root-lock.js +2 -0
- package/dist/messaging/send.js +1 -1
- package/dist/mufl/handlers.js +1 -1
- package/dist/mufl/tx.js +1 -1
- package/dist/mufl_code/7962BB01B1D3E782A1F80B083A900AEC30BAC8F8CE79282B31821802B94A39B6.muflo +0 -0
- package/dist/notify.js +1 -1
- package/dist/render/adapt-to-json.js +1 -1
- package/dist/runtime/config-drift.js +1 -1
- package/dist/runtime/env.js +1 -1
- package/dist/state.js +1 -1
- package/dist/sweeps.js +1 -1
- package/dist/uploads.js +1 -1
- package/package.json +2 -6
- package/dist/chunk-EUILVQOZ.js +0 -2
- package/dist/chunk-IB2U7K6Y.js +0 -5
- package/dist/chunk-IDH22QWU.js +0 -2
- package/dist/chunk-NOOGH2RZ.js +0 -2
- package/dist/chunk-SYRQA3MQ.js +0 -2
- package/dist/daemon.d.ts +0 -5
- package/dist/daemon.js +0 -2
package/README.md
CHANGED
|
@@ -1,52 +1,69 @@
|
|
|
1
1
|
# @ours.network/sdk
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
3
|
+
The typed application client for the shared [ours](https://ours.network)
|
|
4
|
+
daemon, plus the daemon's package-private runtime used by the operator CLI.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
definitions, result formatting and CLI text.
|
|
6
|
+
One loopback daemon normally owns all runtime and global identity state for an
|
|
7
|
+
OS user. Applications attach as clients and keep any application-specific
|
|
8
|
+
identity lists in their own configuration. Those lists are organizational
|
|
9
|
+
bookkeeping, not a daemon authorization boundary.
|
|
11
10
|
|
|
12
11
|
## Exports
|
|
13
12
|
|
|
14
13
|
| Entry point | What it gives you |
|
|
15
14
|
|---|---|
|
|
16
|
-
| `@ours.network/sdk` |
|
|
17
|
-
| `@ours.network/sdk/
|
|
15
|
+
| `@ours.network/sdk` | Client-only default: `attachOursClient`, `OursClient`, client errors/types, and engine-free utilities |
|
|
16
|
+
| `@ours.network/sdk/client` | The same client/attach surface for dependency-graph enforcement |
|
|
18
17
|
| `@ours.network/sdk/connector` | `runProxy(opts)` — the stdio↔HTTP connector client |
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
There is deliberately no public daemon or kernel entry. `startDaemon` and
|
|
20
|
+
`bootWrapper` are not package exports. Install and operate the daemon through
|
|
21
|
+
`@ours.network/cli`; SDK applications never fall back to an embedded runtime.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
`SIGTERM` handlers that tear down the daemon and exit the process. An embedded
|
|
24
|
-
host can retain process ownership by passing `handleSignals: false`:
|
|
23
|
+
## Attach to the shared daemon
|
|
25
24
|
|
|
26
25
|
```ts
|
|
27
|
-
|
|
26
|
+
import { attachOursClient } from '@ours.network/sdk';
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const ours = await attachOursClient({
|
|
29
|
+
leaseToken: 'a-stable-token-owned-by-this-application-session',
|
|
30
|
+
});
|
|
31
|
+
const identities = await ours.listIdentities();
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
`attachOursClient` resolves endpoint, state directory and token as one coherent
|
|
35
|
+
selection. It calls unauthenticated `/state-dir` first; only after the daemon
|
|
36
|
+
proves it owns the expected state root can a credential-bearing request be sent.
|
|
37
|
+
A missing daemon raises `DaemonUnavailableError` with the CLI install/start
|
|
38
|
+
commands. Direct `new OursClient(...)` remains a low-level, unverified seam for
|
|
39
|
+
injected tests and expert transports.
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
Old `autoStart` JSON and `OURS_AUTOSTART` are ignored in SDK 2. Start the daemon
|
|
42
|
+
with `ours daemon start` or install its per-user service with
|
|
43
|
+
`ours daemon install-service`.
|
|
44
|
+
|
|
45
|
+
## Internal singleton contract
|
|
46
|
+
|
|
47
|
+
The CLI bundle acquires a cross-process lock before importing any module that
|
|
48
|
+
can write startup progress, mint the daemon token, restore identities, start the
|
|
49
|
+
native engine, or arm GC. The lock is keyed by the canonical state directory and
|
|
50
|
+
uses this live Unix-domain socket:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
/tmp/ours-<uid>/locks/<sha256(canonical-state-dir)>.sock
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`/tmp/ours-<uid>` and `locks` must be real, owner-owned mode-0700 directories.
|
|
57
|
+
The fixed ASCII pathname is at most 96 bytes for a ten-digit uid, below macOS's
|
|
58
|
+
approximately 104-byte `sun_path` limit. A live socket reports the owner PID and
|
|
59
|
+
state root; an `ECONNREFUSED` stale pathname after crash/SIGKILL is removed and
|
|
60
|
+
retried. Ambiguous probes are never stolen. This contract supports Linux and
|
|
61
|
+
macOS only; other platforms refuse daemon startup instead of skipping the lock.
|
|
45
62
|
|
|
46
63
|
## Operator CLI
|
|
47
64
|
|
|
48
65
|
The supported operator surface is the separate `@ours.network/cli` workspace,
|
|
49
|
-
whose executable is `ours`. The SDK package remains library
|
|
66
|
+
whose executable is `ours`. The SDK package remains client/library-only and
|
|
50
67
|
does not claim a bin. See [packages/cli/README.md](packages/cli/README.md) for
|
|
51
68
|
commands and [CLI-MIGRATION.md](CLI-MIGRATION.md) for the ours-mcp and connector
|
|
52
69
|
ownership boundary.
|
|
@@ -59,7 +76,9 @@ Node ≥ 20. The MUFL packet is compiled from `mufl_code/`, which pins the
|
|
|
59
76
|
## Build and test
|
|
60
77
|
|
|
61
78
|
```bash
|
|
62
|
-
npm ci
|
|
79
|
+
# This helper is a normal lockfile-strict npm ci; on a pre-release 1.x checkout
|
|
80
|
+
# it temporarily presents the automation-owned 2.0 workspace version, then restores it.
|
|
81
|
+
bash scripts/npm-ci-major-workspace.sh
|
|
63
82
|
npm run build
|
|
64
83
|
npm test
|
|
65
84
|
```
|
package/dist/api/contacts.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d,e,f,g,h,i,j}from"../chunk-
|
|
2
|
+
import{a,b,c,d,e,f,g,h,i,j}from"../chunk-QSDEMIZQ.js";import"../chunk-ENJRQKGS.js";import"../chunk-TNTHPI3A.js";import"../chunk-65KGEJBX.js";import"../chunk-TIIFYDXJ.js";import"../chunk-6SMQG6NV.js";import"../chunk-CQDCCH6N.js";import"../chunk-XL6UKHPU.js";import"../chunk-YRPUM6JG.js";import"../chunk-WU5WT7LA.js";import"../chunk-DIRW7I4S.js";import"../chunk-YDCAL5R3.js";import"../chunk-OCHXHPQZ.js";import"../chunk-OPCXNIGD.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{d as addContact,a as generateInvite,e as listContacts,b as listInvites,f as listLocalContactBook,h as removeContact,i as renameContact,j as respondToIntroduction,c as revokeInvite,g as setLocalBookPolicy};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d}from"../chunk-
|
|
2
|
+
import{a,b,c,d}from"../chunk-DVYJ3STO.js";import"../chunk-ENJRQKGS.js";import"../chunk-TNTHPI3A.js";import"../chunk-65KGEJBX.js";import"../chunk-TIIFYDXJ.js";import"../chunk-6SMQG6NV.js";import"../chunk-CQDCCH6N.js";import"../chunk-XL6UKHPU.js";import"../chunk-YRPUM6JG.js";import"../chunk-WU5WT7LA.js";import"../chunk-DIRW7I4S.js";import"../chunk-YDCAL5R3.js";import"../chunk-OCHXHPQZ.js";import"../chunk-OPCXNIGD.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{a as getConversation,b as getReceipts,c as markRead,d as setConversationPolicy};
|
package/dist/api/files.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d}from"../chunk-
|
|
2
|
+
import{a,b,c,d}from"../chunk-ZGPYTIOX.js";import"../chunk-ENJRQKGS.js";import"../chunk-TNTHPI3A.js";import"../chunk-65KGEJBX.js";import"../chunk-TIIFYDXJ.js";import"../chunk-6SMQG6NV.js";import"../chunk-CQDCCH6N.js";import"../chunk-XL6UKHPU.js";import"../chunk-YRPUM6JG.js";import"../chunk-WU5WT7LA.js";import"../chunk-DIRW7I4S.js";import"../chunk-YDCAL5R3.js";import"../chunk-OCHXHPQZ.js";import"../chunk-OPCXNIGD.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{d as deferFiles,b as getFiles,a as listIncomingFiles,c as saveFileFallbackNotice};
|
package/dist/api/identity.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d,e,f,g,h,i,j,k}from"../chunk-
|
|
2
|
+
import{a,b,c,d,e,f,g,h,i,j,k}from"../chunk-ENJRQKGS.js";import"../chunk-TNTHPI3A.js";import"../chunk-65KGEJBX.js";import"../chunk-TIIFYDXJ.js";import"../chunk-6SMQG6NV.js";import"../chunk-CQDCCH6N.js";import"../chunk-XL6UKHPU.js";import"../chunk-YRPUM6JG.js";import"../chunk-WU5WT7LA.js";import"../chunk-DIRW7I4S.js";import"../chunk-YDCAL5R3.js";import"../chunk-OCHXHPQZ.js";import"../chunk-OPCXNIGD.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{g as chooseIdentity,d as closeTemporaryIdentityOp,b as createIdentity,e as createRootIdentity,c as createTemporaryIdentity,i as currentIdentity,f as defineLocalIdentityFile,h as listIdentities,k as releaseLease,j as removeIdentity,a as requireBound};
|
package/dist/api/messaging.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d,e}from"../chunk-
|
|
2
|
+
import{a,b,c,d,e}from"../chunk-CUMFIDHH.js";import"../chunk-WWTR33CX.js";import"../chunk-VXVW4KJU.js";import"../chunk-YDWSAX43.js";import"../chunk-ENJRQKGS.js";import"../chunk-TNTHPI3A.js";import"../chunk-65KGEJBX.js";import"../chunk-TIIFYDXJ.js";import"../chunk-6SMQG6NV.js";import"../chunk-CQDCCH6N.js";import"../chunk-XL6UKHPU.js";import"../chunk-YRPUM6JG.js";import"../chunk-WU5WT7LA.js";import"../chunk-DIRW7I4S.js";import"../chunk-YDCAL5R3.js";import"../chunk-OCHXHPQZ.js";import"../chunk-OPCXNIGD.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{e as deferMessages,d as getMessages,c as listIncomingMessages,b as sendFile,a as sendMessage};
|
package/dist/api/profile.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d}from"../chunk-
|
|
2
|
+
import{a,b,c,d}from"../chunk-SGTVMU5E.js";import"../chunk-ENJRQKGS.js";import"../chunk-TNTHPI3A.js";import"../chunk-65KGEJBX.js";import"../chunk-TIIFYDXJ.js";import"../chunk-6SMQG6NV.js";import"../chunk-CQDCCH6N.js";import"../chunk-XL6UKHPU.js";import"../chunk-YRPUM6JG.js";import"../chunk-WU5WT7LA.js";import"../chunk-DIRW7I4S.js";import"../chunk-YDCAL5R3.js";import"../chunk-OCHXHPQZ.js";import"../chunk-OPCXNIGD.js";import"../chunk-ZHH3PWEW.js";import"../chunk-LKFYUCN7.js";import"../chunk-Y3VPZJTG.js";import"../chunk-P55RJGZU.js";import"../chunk-XYU2DSWR.js";import"../chunk-WS6UFNKF.js";export{b as advertiseMigrate,d as readvertiseOnUpgrade,a as setBio,c as setPersona};
|
package/dist/book.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{N as a,O as b,P as c,Q as d,R as e,S as f,T as g,U as h,V as i,W as j}from"./chunk-
|
|
2
|
+
import{N as a,O as b,P as c,Q as d,R as e,S as f,T as g,U as h,V as i,W as j}from"./chunk-XL6UKHPU.js";import"./chunk-YRPUM6JG.js";import"./chunk-WU5WT7LA.js";import"./chunk-DIRW7I4S.js";import"./chunk-YDCAL5R3.js";import"./chunk-OCHXHPQZ.js";import"./chunk-OPCXNIGD.js";import"./chunk-ZHH3PWEW.js";import"./chunk-LKFYUCN7.js";import"./chunk-Y3VPZJTG.js";import"./chunk-P55RJGZU.js";import"./chunk-XYU2DSWR.js";import"./chunk-WS6UFNKF.js";export{a as bookDir,c as bookPath,f as exportAdBlob,g as exportSigningSecret,j as pinRegistrar,h as publishToBook,d as readBook,b as registrarKeyPath,i as unpublishFromBook,e as writeBook};
|
package/dist/boot.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b}from"./chunk-
|
|
2
|
+
import{a,b}from"./chunk-VJGMISQ5.js";import"./chunk-EHCBEY52.js";import"./chunk-TNTHPI3A.js";import"./chunk-TIIFYDXJ.js";import"./chunk-6SMQG6NV.js";import"./chunk-CQDCCH6N.js";import"./chunk-XL6UKHPU.js";import"./chunk-YRPUM6JG.js";import"./chunk-WU5WT7LA.js";import"./chunk-DIRW7I4S.js";import"./chunk-YDCAL5R3.js";import"./chunk-OCHXHPQZ.js";import"./chunk-OPCXNIGD.js";import"./chunk-ZHH3PWEW.js";import"./chunk-LKFYUCN7.js";import"./chunk-Y3VPZJTG.js";import"./chunk-P55RJGZU.js";import"./chunk-XYU2DSWR.js";import"./chunk-WS6UFNKF.js";export{b as bootWrapper,a as wrapperBooted};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a as O}from"./chunk-OA7XXAFG.js";import{b as N,e as T}from"./chunk-WS6UFNKF.js";import{randomBytes as I}from"node:crypto";import{readFileSync as w}from"node:fs";import{homedir as x}from"node:os";import{join as v,resolve as p}from"node:path";var a=class extends Error{constructor(i,n){super(n);this.code=i;this.name="DaemonSelectionError"}},S=class extends a{constructor(i,n,d={}){super("DAEMON_UNAVAILABLE",`no ours daemon is running at ${i} for state directory ${JSON.stringify(n)}. Install the operator CLI with \`npm install --global @ours.network/cli\`, then start the shared daemon with \`ours daemon start\` or install/start its per-user service through \`ours daemon install-service\`. SDK applications attach to the shared daemon and do not start an embedded daemon.`);this.endpoint=i;this.stateDir=n;this.name="DaemonUnavailableError",d.cause!==void 0&&(this.cause=d.cause)}},b=N.port,C=T,R=".ours",k=["explicit","environment","config-file"];function _(e={}){let t=e.env??process.env,i=e.readTextFile??(h=>w(h,"utf8")),n=e.homeDir??x(),d=f(t,"OURS_INSTANCE");if(d!==void 0)throw new a("INCOHERENT_SELECTION",`OURS_INSTANCE=${JSON.stringify(d)} is set, but named daemon instances are not implemented. Select the daemon with an explicit endpoint/port option or with OURS_PORT, and unset OURS_INSTANCE.`);if(e.stateDir!==void 0&&e.expectStateDir!==void 0){let h=p(e.stateDir),D=p(e.expectStateDir);if(h!==D)throw new a("INCOHERENT_SELECTION",`stateDir ${JSON.stringify(h)} and expectStateDir ${JSON.stringify(D)} name different directories. The state directory decides which token is read; the expected one decides which daemon that token may be sent to. Reconcile them, or pass only one.`)}let r=V(e.configPath,f(t,"OURS_CONFIG")),s=r?L(r.value,i):{},o=E(e.port,F(f(t,"OURS_PORT")),s.port,b),c=E(e.stateDir??e.expectStateDir,f(t,"OURS_STATE_DIR"),s.stateDir,v(n,R)),l={value:p(c.value),source:c.source},g=e.endpoint!==void 0?{value:P(e.endpoint),source:"explicit"}:{value:`http://127.0.0.1:${o.value}`,source:o.source},m=f(t,"OURS_API_TOKEN");A({endpointSelected:e.endpoint!==void 0||o.source!=="default",endpointSource:g.source,stateDirIntentional:k.includes(l.source),stateDirSource:l.source,hasExplicitToken:e.token!==void 0&&e.token!=="",hasEnvToken:m!==void 0,requireExplicitSelection:e.requireExplicitSelection===!0,portSource:o.source});let y=U(e.token,m,s,l,i);return{baseUrl:g,port:o,stateDir:l,expectStateDir:e.expectStateDir!==void 0?p(e.expectStateDir):l.value,...y?{token:y}:{},...r?{configPath:r}:{}}}function K(e){return{baseUrl:e.baseUrl.value,baseUrlSource:e.baseUrl.source,port:e.port.value,portSource:e.port.source,stateDir:e.stateDir.value,stateDirSource:e.stateDir.source,expectStateDir:e.expectStateDir,tokenSource:e.token?.source??"none",configPath:e.configPath?.value??null}}function A(e){if(e.requireExplicitSelection){if(e.endpointSource==="default"&&e.portSource==="default")throw u(`requireExplicitSelection is set, but no daemon was selected. Pass endpoint/port, set OURS_PORT, or point OURS_CONFIG at a config file. Refusing the built-in default 127.0.0.1:${b}.`);if(!e.stateDirIntentional)throw u("requireExplicitSelection is set, but the state directory is the built-in default. Every auth-affecting field must be chosen deliberately: pass stateDir or expectStateDir, set OURS_STATE_DIR, or name a config file. Refusing before reading any token or opening any socket.")}if(e.endpointSelected&&!e.stateDirIntentional)throw u(`the endpoint was selected (source: ${e.endpointSource}) but the state directory is the built-in default. A daemon's API token belongs to one state directory, so reading the default token and sending it to a separately chosen endpoint would disclose a credential to it. Select the state directory too: stateDir, expectStateDir, OURS_STATE_DIR, or one config file. An explicit token alone is not enough \u2014 without an expected state directory there is nothing to assert the endpoint against before the token is sent.`);if(e.hasEnvToken&&!e.stateDirIntentional)throw u("OURS_API_TOKEN is set, but the state directory is the built-in default. An environment token is process-wide and authenticates to every daemon it is offered to, so it requires an explicitly expected state directory: pass stateDir or expectStateDir, or set OURS_STATE_DIR.");if(e.hasExplicitToken&&!e.stateDirIntentional)throw u("an explicit token was given, but the state directory is the built-in default, so there would be nothing to assert the daemon against before the token is sent. Pass expectStateDir (or stateDir) naming the state directory that token belongs to.")}function u(e){return new a("INCOHERENT_SELECTION",e)}function U(e,t,i,n,d){if(e!==void 0&&e!=="")return{value:e,source:"explicit"};if(t!==void 0)return{value:t,source:"environment"};let r=i.apiToken?.trim();if(r)return{value:r,source:"config-file"};try{let s=d(v(n.value,C)).trim();if(s)return{value:s,source:"token-file"}}catch{}}function L(e,t){let i;try{i=t(e)}catch{throw new a("CONFIG_UNREADABLE",`the daemon config file ${JSON.stringify(e)} could not be read.`)}let n;try{n=JSON.parse(i)}catch{throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} is not valid JSON.`)}if(n===null||typeof n!="object"||Array.isArray(n))throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} is not a JSON object.`);let d=n,r={},s=d.port;if(s!==void 0){if(typeof s!="number"||!Number.isInteger(s)||s<1||s>65535)throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an invalid port; expected an integer 1-65535.`);r.port=s}let o=d.stateDir;if(o!==void 0){if(typeof o!="string"||o.trim()==="")throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an invalid stateDir; expected a non-empty string.`);r.stateDir=o}let c=d.apiToken;if(c!==void 0){if(typeof c!="string"||c.trim()==="")throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an invalid apiToken; expected a non-empty string.`);r.apiToken=c}let l=d.apiVisibility;if(l!==void 0){if(l!=="owner"&&l!=="shared"&&l!=="open")throw new a("CONFIG_INVALID",`the daemon config file ${JSON.stringify(e)} declares an unknown apiVisibility ${JSON.stringify(l)}; expected "owner", "shared" or "open".`);r.apiVisibility=l}return r}function f(e,t){let i=e[t];if(i===void 0)return;let n=i.trim();return n===""?void 0:n}function F(e){if(e===void 0)return;let t=Number.parseInt(e,10);if(!Number.isInteger(t)||t<1||t>65535)throw new a("INCOHERENT_SELECTION",`OURS_PORT=${JSON.stringify(e)} is not a TCP port between 1 and 65535.`);return t}function P(e){return e.endsWith("/")?e.slice(0,-1):e}function E(e,t,i,n){return e!==void 0?{value:e,source:"explicit"}:t!==void 0?{value:t,source:"environment"}:i!==void 0?{value:i,source:"config-file"}:{value:n,source:"default"}}function V(e,t){if(e!==void 0)return{value:e,source:"explicit"};if(t!==void 0)return{value:t,source:"environment"}}async function $(e,t={}){let i=t.fetch??globalThis.fetch,n=new AbortController,d=setTimeout(()=>n.abort(),t.timeoutMs??5e3),r;try{let o=await i(`${e.baseUrl.value}/state-dir`,{signal:n.signal});if(!o.ok)throw new a("INCOHERENT_SELECTION",`${e.baseUrl.value}/state-dir answered HTTP ${o.status}, so the daemon at that address could not be identified. Refusing to send a credential to it.`);r=await o.json()}catch(o){throw o instanceof a?o:new S(e.baseUrl.value,e.expectStateDir,{cause:o})}finally{clearTimeout(d)}let s=typeof r.stateDir=="string"?p(r.stateDir):null;if(s===null)throw new a("INCOHERENT_SELECTION",`${e.baseUrl.value}/state-dir did not report a state directory, so this is not an ours daemon or not one this client understands. Refusing to send a credential to it.`);if(s!==e.expectStateDir)throw new a("INCOHERENT_SELECTION",`the daemon at ${e.baseUrl.value} owns state directory ${JSON.stringify(s)}, but this selection expects ${JSON.stringify(e.expectStateDir)}. The token belongs to the expected directory, so it is NOT being sent. Point the endpoint and the state directory at the same daemon.`)}async function j(e={}){let{leaseToken:t,clientPid:i,fetch:n,...d}=e,r=_(d);return await $(r,{fetch:n}),new O({url:r.baseUrl.value,leaseToken:t??I(32).toString("hex"),clientPid:i,apiToken:r.token?.value,fetch:n})}export{a,S as b,b as c,C as d,_ as e,K as f,$ as g,j as h};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as M,b,c as F,d as w,e as T,f as N,g as L,h as H,i as B,j}from"./chunk-
|
|
2
|
+
import{a as M,b,c as F,d as w,e as T,f as N,g as L,h as H,i as B,j}from"./chunk-QSDEMIZQ.js";import{a as E,b as J,c as _,d as $}from"./chunk-DVYJ3STO.js";import{a as U,b as V,c as X,d as q}from"./chunk-ZGPYTIOX.js";import{a as z,b as D,c as G,d as K,e as Q}from"./chunk-CUMFIDHH.js";import{a as W,b as Y,c as Z,d as ee}from"./chunk-SGTVMU5E.js";import{b as u,c as v,d as k,e as R,f as C,g as S,h as x,i as h,j as P,k as O}from"./chunk-ENJRQKGS.js";import{a as I}from"./chunk-65KGEJBX.js";import{c as d}from"./chunk-YDCAL5R3.js";import{o as f}from"./chunk-OCHXHPQZ.js";import{i as m,m as y}from"./chunk-OPCXNIGD.js";var ne="/api/v1/",e=i=>(t,n)=>i(t,n),s=i=>t=>i(t),oe=i=>(t,n)=>i(n),te={createIdentity:e(u),createTemporaryIdentity:e(v),closeTemporaryIdentityOp:e(k),createRootIdentity:e(R),defineLocalIdentityFile:oe(C),chooseIdentity:e(S),listIdentities:s(x),currentIdentity:s(h),removeIdentity:e(P),releaseLease:s(O),generateInvite:e(M),listInvites:s(b),revokeInvite:e(F),addContact:e(w),listContacts:s(T),listLocalContactBook:s(N),setLocalBookPolicy:e(L),removeContact:e(H),renameContact:e(B),respondToIntroduction:e(j),setBio:e(W),advertiseMigrate:s(Y),readvertiseOnUpgrade:s(ee),setPersona:e(Z),sendMessage:e(z),sendFile:e(D),listIncomingMessages:s(G),getMessages:s(K),deferMessages:e(Q),deferFiles:e(q),getConversation:e(E),getReceipts:e(J),markRead:e(_),setConversationPolicy:e($),listIncomingFiles:s(U),getFiles:e(V),saveFileFallbackNotice:e(X)},l=new Map,ie=(i,t)=>{let n=i.headers[t];return typeof n=="string"&&n!==""?n:void 0};function se(i){let t=ie(i,"x-ours-lease-token"),n=ie(i,"x-ours-client-pid"),A=n?parseInt(n,10):NaN,a=Number.isInteger(A)?A:void 0,o=t?`api:${f(t)}`:"api:anonymous";return d.set(o,{token:t,pid:a}),l.set(o,(l.get(o)??0)+1),{ctx:{sessionId:()=>o,leaseToken:()=>d.get(o)?.token,clientPid:()=>d.get(o)?.pid},release:()=>{let r=(l.get(o)??1)-1;if(r>0){l.set(o,r);return}l.delete(o),d.delete(o)}}}var p=(i,t,n)=>{i.writableEnded||(i.writeHead(t,{"Content-Type":"application/json"}),i.end(JSON.stringify(n??null)))};async function fe(i,t,n,A){let a=n.slice(ne.length);if(!y(i,t))return;if(i.method!=="POST"){p(t,405,{error:"method not allowed: the typed API is POST-only"});return}let o=Object.prototype.hasOwnProperty.call(te,a)?te[a]:void 0;if(!o){p(t,404,{error:`unknown operation "${a}"`});return}let r;try{r=await A(i)}catch{p(t,400,{error:"the request body must be JSON"});return}if(r===null||typeof r!="object"||Array.isArray(r)){p(t,400,{error:"the request body must be a JSON object"});return}let g=se(i);try{p(t,200,await o(g.ctx,r))}catch(c){if(c instanceof I){p(t,400,{error:{code:c.code,message:c.message}});return}m("api handler error:",a,String(c)),p(t,500,{error:`internal error in ${a}: ${String(c)}`})}finally{g.release()}}export{ne as a,te as b,se as c,fe as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{e as d}from"./chunk-
|
|
2
|
+
import{e as d}from"./chunk-CQDCCH6N.js";import{H as a,J as c}from"./chunk-XL6UKHPU.js";import{c as s}from"./chunk-OCHXHPQZ.js";function y(e){try{return a(n=>{let i=c(e,"::a2a_capabilities::get_manifest",n).Reduce("capabilities");return i.IsNil()?[]:[...i.GetKeys()].map(t=>typeof t=="string"?t:t.Visualize())})}catch{return[]}}function R(e){let n="",i="",t="",u="",l=[];try{a(g=>{let p=c(e,"::a2a_capabilities::get_manifest",g),r=o=>{let f=p.Reduce(o);return f.IsNil()?"":f.Visualize()};n=r("app_id"),i=r("name"),t=r("description"),u=r("version");let m=p.Reduce("capabilities");m.IsNil()||(l=[...m.GetKeys()].map(o=>typeof o=="string"?o:o.Visualize()))})}catch{}return{app_id:n,name:i,description:t,version:u,capabilities:l,monitoring_status:"unbound"}}function h(e){let n=[];for(let i of s.values()){if(i.name===e.name)continue;let t=d(i);t.rootCid===e.cid&&n.push({name:i.name,cid:i.cid,role_id:t.roleId,bio:t.bio,monitoring:t.monitoringEnabled,capabilities:y(i)})}return n}function v(e,n){let i=s.get(n)??[...s.values()].find(t=>t.cid===n);return!i||i.name===e.name?null:d(i).rootCid===e.cid?i:null}export{y as a,R as b,h as c,v as d};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{createHash as k}from"node:crypto";import*as a from"node:fs";import*as l from"node:net";import{dirname as S,join as m,resolve as y}from"node:path";var g=new Set(["linux","darwin"]),h=103,p=8,u=class extends Error{constructor(t,n,i){super(`ours daemon state directory ${JSON.stringify(t)} is already owned by `+(n===null?"another live process":`pid ${n}`)+". Stop that daemon through the ours CLI before starting another one for the same state directory.");this.stateDir=t;this.ownerPid=n;this.owner=i;this.name="StateRootLockedError"}code="STATE_ROOT_LOCKED"};function d(r){return r&&typeof r=="object"&&"code"in r?String(r.code):void 0}function E(r){let o=y(r),t=[];for(;;)try{let n=a.realpathSync.native(o);return y(n,...t.reverse())}catch(n){if(d(n)!=="ENOENT")throw n;let i=S(o);if(i===o)throw n;t.push(o.slice(i.length+(i.endsWith("/")?0:1))),o=i}}function w(r,o){try{a.mkdirSync(r,{mode:448})}catch(n){if(d(n)!=="EEXIST")throw n}let t=a.lstatSync(r);if(!t.isDirectory()||t.isSymbolicLink())throw new Error(`daemon lock path ${JSON.stringify(r)} must be a real directory, not a symlink or file`);if(t.uid!==o)throw new Error(`daemon lock path ${JSON.stringify(r)} is owned by uid ${t.uid}, expected uid ${o}`);a.chmodSync(r,448)}function O(r){if(!g.has(process.platform))throw new Error(`the ours daemon state-root lock supports Linux and macOS only; platform ${JSON.stringify(process.platform)} has no verified Unix-domain-socket lock contract, so startup is refused`);let o=process.getuid;if(typeof o!="function")throw new Error("the ours daemon state-root lock requires a Unix uid; startup is refused");let t=o.call(process),n=`/tmp/ours-${t}`,i=m(n,"locks");w(n,t),w(i,t);let c=k("sha256").update(r).digest("hex"),e=m(i,`${c}.sock`);if(Buffer.byteLength(e)>h)throw new Error(`daemon lock socket path is ${Buffer.byteLength(e)} bytes, exceeding the portable ${h}-byte Linux/macOS contract: ${JSON.stringify(e)}`);return{directory:i,socketPath:e}}function b(r){return new Promise(o=>{let t=l.createConnection(r),n="",i=!1,c=e=>{i||(i=!0,t.destroy(),o(e))};t.setEncoding("utf8"),t.setTimeout(1e3),t.on("data",e=>{n+=e}),t.once("end",()=>{try{let e=JSON.parse(n),s=Number.isInteger(e.pid)&&typeof e.stateDir=="string"&&typeof e.startedAt=="string"?e:null;c({kind:"live",owner:s})}catch{c({kind:"live",owner:null})}}),t.once("timeout",()=>c({kind:"ambiguous",error:new Error("timed out probing the live lock socket")})),t.once("error",e=>{let s=d(e);c(s==="ECONNREFUSED"||s==="ENOENT"?{kind:"stale"}:{kind:"ambiguous",error:e})})})}function N(r,o){return new Promise((t,n)=>{let i=c=>n(c);r.once("error",i),r.listen(o,()=>{r.off("error",i),t()})})}async function L(r){let o=E(r),{socketPath:t}=O(o),n={pid:process.pid,stateDir:o,startedAt:new Date().toISOString()};for(let i=1;i<=p;i++){let c=l.createServer(e=>e.end(`${JSON.stringify(n)}
|
|
3
|
+
`));try{await N(c,t),c.unref();let e=!1;return{stateDir:o,socketPath:t,owner:n,close:async()=>{if(!e){e=!0,await new Promise(s=>c.close(()=>s()));try{a.unlinkSync(t)}catch(s){if(d(s)!=="ENOENT")throw s}}}}}catch(e){try{c.close()}catch{}if(d(e)!=="EADDRINUSE")throw e;let s=await b(t);if(s.kind==="live")throw new u(o,s.owner?.pid??null,s.owner);if(s.kind==="ambiguous")throw new Error(`could not prove whether daemon lock ${JSON.stringify(t)} is live or stale; refusing to remove it: ${s.error.message}`);try{a.unlinkSync(t)}catch(f){if(d(f)!=="ENOENT")throw f}}}throw new Error(`could not acquire daemon state-root lock for ${JSON.stringify(o)} after ${p} races`)}export{u as a,E as b,O as c,L as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{H as m,I as p,J as l,M as a,S as f}from"./chunk-
|
|
2
|
+
import{H as m,I as p,J as l,M as a,S as f}from"./chunk-XL6UKHPU.js";import{c as u}from"./chunk-OCHXHPQZ.js";import{c as d,i}from"./chunk-OPCXNIGD.js";import{join as x}from"node:path";import*as r from"node:fs";function V(e){y=e}var c=()=>x(d,"root.json"),y=null;function $(){try{let e=JSON.parse(r.readFileSync(c(),"utf8"));return typeof e.name=="string"?e.name:null}catch{return null}}function I(e){r.mkdirSync(d,{recursive:!0});let o=`${c()}.tmp`;r.writeFileSync(o,JSON.stringify({v:1,name:e})),r.renameSync(o,c())}function G(){r.rmSync(c(),{force:!0})}function z(e){return m(o=>{let t=l(e,"::actor::describe_identity",o);return{bio:t.Reduce("bio").Visualize(),persona:t.Reduce("persona").Visualize(),hasCert:t.Reduce("has_cert").GetBoolean(),roleId:t.Reduce("role_id").Visualize(),rootCid:t.Reduce("root_cid").Visualize(),rootName:t.Reduce("root_name").Visualize(),monitoringEnabled:t.Reduce("monitoring_enabled").GetBoolean()}})}async function A(e,o){await p(async t=>{let n=f(o),s=await a(e,"::actor::sign_delegation",{role_ad:e.pw.packet.NewBinaryFromBuffer(n).Attach(t),role_id:o.name},t),g=Buffer.from(s.Reduce("cert").GetBinary()),B=await a(e,"::actor::export_root_profile",{},t),w=Buffer.from(B.Reduce("profile").GetBinary()),h=f(e),_=Buffer.from((await a(o,"::actor::export_v1_address_document",{},t)).Reduce("ad").GetBinary()),R=await a(e,"::actor::sign_delegation",{role_ad:e.pw.packet.NewBinaryFromBuffer(_).Attach(t),role_id:o.name},t),b=Buffer.from(R.Reduce("cert").GetBinary());await a(o,"::actor::set_delegation",{cert:o.pw.packet.NewBinaryFromBuffer(g).Attach(t),root_ad:o.pw.packet.NewBinaryFromBuffer(h).Attach(t),root_profile:o.pw.packet.NewBinaryFromBuffer(w).Attach(t),cert_v1:o.pw.packet.NewBinaryFromBuffer(b).Attach(t)},t)}),i(`[${o.name}] delegated as a role under root "${e.name}"`)}async function C(e){y=e.name,I(e.name);let o=[],t=[];for(let n of u.values())if(n.name!==e.name&&!n.temp)try{await A(e,n),o.push(n.name)}catch(s){i(`failed to adopt "${n.name}" as a role under new root "${e.name}":`,String(s)),t.push(n.name)}return i(`[${e.name}] established as the host root${o.length?` (adopted ${o.length} role(s))`:""}`),{adopted:o,failed:t}}export{V as a,y as b,$ as c,G as d,z as e,A as f,C as g};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{g as z}from"./chunk-
|
|
2
|
+
import{g as z}from"./chunk-WWTR33CX.js";import{b as D,g as V}from"./chunk-VXVW4KJU.js";import{a as O,b as q,c as L,d as v}from"./chunk-YDWSAX43.js";import{a as u}from"./chunk-ENJRQKGS.js";import{A as P,B as M,C as N,D as T,E as U,F as C,M as c,a as F}from"./chunk-65KGEJBX.js";import{H as k,I as p,J as E,M as _,j as S,k as A,p as x}from"./chunk-XL6UKHPU.js";import{c as b}from"./chunk-WU5WT7LA.js";import{i as f}from"./chunk-OPCXNIGD.js";import{d as $}from"./chunk-LKFYUCN7.js";import{a as R}from"./chunk-P55RJGZU.js";import{readFile as G}from"node:fs/promises";import{basename as H}from"node:path";function j(s,i){if(s)return i!==void 0?{wire_id:s,sentence:i}:{wire_id:s}}async function de(s,i){let t=u(s),{contact:a,text:n}=i,d=j(i.reply_to_wire_id,i.reply_to_sentence);try{let r=await p(async o=>v(await _(t,"::a2a_messaging::send_message",{contact:a,text:n,...d?{reply_to:d}:{}},o)));switch(r.kind){case"refused":f(`[e2e-route] refused cid=${r.cid} wire_id=${r.wireId} (downgrade_refused)`);break;case"migrating":f(`[migration] queued cid=${r.cid} wire_id=${r.wireId} (migrating, ${r.queued} queued)`);break;case"e2e":f(`[e2e-route] cid=${r.cid} wire_id=${r.wireId} verdict=e2e (core delivered over migrated session)${r.notRetained?" NOT RETAINED (oversized)":""}`),r.notRetained&&S(t,{event:"send_not_retained",wire_id:r.wireId,kind:"message"});break;default:break}return r}catch(r){if(!/Unknown contact/.test(String(r)))throw c("send_message",String(r));try{let o=O(t,a);return{kind:"introduced",text:o?await q(t,o,n):await L(t,a,n)}}catch(o){throw c("send_message",String(o),"FALLBACK_FAILED")}}}async function ce(s,i){let t=u(s),{contact:a,path:n,data_base64:d,upload_id:r,filename:o,mime:B}=i;if((n?1:0)+(d?1:0)+(r?1:0)!=1)throw r?T():P();let l,m,I=null;try{if(n)l=await G(n),m=o??H(n);else if(r){let e=z(t,r);if(!e)throw U(r);I=e.meta,l=e.buf,m=o??e.meta.filename}else{if(!o)throw M();l=Buffer.from(d,"base64"),m=o}}catch(e){throw e instanceof F?e:N(String(e))}let y=B??(n?R(n):I?.mime||""),h=j(i.reply_to_wire_id,i.reply_to_sentence),W=D(),g;try{g=k(e=>V({packet:{NewBinaryFromBuffer:w=>t.pw.packet.NewBinaryFromBuffer(w)},lifetime:e,filename:m,mime:y,payload:l,replyTo:h,cap:W}))}catch(e){throw e instanceof F?e:c("send_file",String(e))}if(!g.ok)throw C({filename:m,bytes:g.bytes,limit:g.cap,envelopeBytes:g.envelopeBytes,maxPayloadBytes:g.maxPayloadBytes});try{let e=await p(async w=>{let K=t.pw.packet.NewBinaryFromBuffer(l).Attach(w);return v(await _(t,"::a2a_messaging::send_file",{contact:a,filename:m,mime:y,data:K,...h?{reply_to:h}:{}},w))});switch(e.kind){case"refused":f(`[e2e-route] refused cid=${e.cid} wire_id=${e.wireId} (downgrade_refused, file)`);break;case"migrating":f(`[migration] file-defer cid=${e.cid} wire_id=${e.wireId} (migrating, not queued)`);break;case"e2e":f(`[e2e-route] cid=${e.cid} wire_id=${e.wireId} verdict=e2e file (core delivered over migrated session)${e.notRetained?" NOT RETAINED (oversized)":""}`),e.notRetained&&S(t,{event:"send_not_retained",wire_id:e.wireId,kind:"file"});break;default:break}return{...e,filename:m,bytes:l.length,mime:y}}catch(e){throw c("send_file",String(e))}}async function me(s){let i=u(s);try{return k(t=>b(E(i,"::actor::list_incoming_messages",t)))}catch(t){throw c("list_incoming_messages",String(t))}}async function fe(s){let i=u(s);try{let t=await p(async n=>{let d=await _(i,"::actor::get_messages",{},n);return b(d.Reduce("messages"))});x(i);let a=A(i);return $(t,a)}catch(t){throw c("get_messages",String(t))}}async function le(s,i){let t=u(s),{msg_ids:a}=i;try{let n=await p(async d=>(await _(t,"::actor::defer_messages",{msg_ids:a},d)).Reduce("deferred").Visualize());return x(t),{deferred:n}}catch(n){throw c("defer_messages",String(n))}}export{de as a,ce as b,me as c,fe as d,le as e};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a}from"./chunk-
|
|
2
|
+
import{a}from"./chunk-ENJRQKGS.js";import{M as i}from"./chunk-65KGEJBX.js";import{H as u,I as d,J as l,M as p}from"./chunk-XL6UKHPU.js";function m(s){let o=[],r=s.Reduce("messages");if(r.IsNil())return o;for(let e=0;;e++){let t=r.Reduce(e);if(t.IsNil())break;let n=t.Reduce("wire_id"),c=t.Reduce("receipt");o.push({dir:t.Reduce("dir").Visualize()==="out"?"out":"in",text:t.Reduce("text").Visualize(),date:t.Reduce("date").Visualize(),read:t.Reduce("read").GetBoolean(),wire_id:n.IsNil()?"":n.Visualize(),receipt:c.IsNil()?null:c.Visualize()})}return o}async function _(s,o){let r=a(s);try{let e=u(t=>m(l(r,"::actor::get_conversation",t,{contact:o.contact})));return{contact:o.contact,messages:e}}catch(e){throw i("get_conversation",String(e))}}async function v(s,o){let r=a(s);try{let e=u(t=>{let n=l(r,"::actor::get_receipts",t,{contact:o.contact}).Reduce("receipts"),c={};if(n.IsNil())return c;for(let R of n.GetKeys()){let y=R.Visualize();c[y]=n.Reduce(y).Visualize()}return c});return{contact:o.contact,receipts:e}}catch(e){throw i("get_receipts",String(e))}}async function h(s,o){let r=a(s);try{let e=await d(async t=>{let n=await p(r,"::actor::mark_read",{contact:o.contact},t);return Number(n.Reduce("marked").Visualize())});return{contact:o.contact,marked:e}}catch(e){throw i("mark_read",String(e))}}async function C(s,o){let r=a(s);try{return await d(async e=>{let t=await p(r,"::actor::set_local_policy",{keep_history:o.keep_history},e);return{keepHistory:t.Reduce("keep_history").GetBoolean(),autoAccept:t.Reduce("auto_accept").GetBoolean()}})}catch(e){throw i("set_local_policy",String(e))}}export{_ as a,v as b,h as c,C as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{d as o}from"./chunk-
|
|
2
|
+
import{d as o}from"./chunk-WS6UFNKF.js";var n=["OURS_STATE_DIR","OURS_BROKER_URL","OURS_PORT","OURS_API_VISIBILITY","OURS_CONFIG"],i=Object.fromEntries(n.map(e=>[e,process.env[e]])),{stateDir:s,brokerUrl:a}=o();function c(){let e=n.filter(t=>process.env[t]!==i[t]);if(e.length===0)return;let r=e.map(t=>`${t}: was ${JSON.stringify(i[t]??"(unset)")} at import, is now ${JSON.stringify(process.env[t]??"(unset)")}`).join("; ");throw new Error(`configuration changed after @ours.network/sdk was imported (${r}). The SDK reads its config ONCE, at module load, because CONFIG and STATE_DIR back process-wide singletons that cannot be re-pointed once identities exist. Setting these after the import does not fail and does not take effect \u2014 without this check the daemon would boot against ${JSON.stringify(s)} and broker ${JSON.stringify(a)} and look like it worked. Set every OURS_* config variable BEFORE the first import of this package.`)}export{c as a};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as se,b as A}from"./chunk-
|
|
2
|
+
import{a as se,b as A}from"./chunk-TNTHPI3A.js";import{M as p,a as T,f as k,g as q,h as W,i as z,j as U,k as Y,l as G,m as J,n as K,o as Q,p as S,q as X,r as Z,s as ee,t as te,u as oe,v as ne,w as re,x as ie}from"./chunk-65KGEJBX.js";import{a as ae,c as de}from"./chunk-TIIFYDXJ.js";import{b as f,e as b,f as N,g as E}from"./chunk-CQDCCH6N.js";import{A as L,B as _,I as M,M as j}from"./chunk-XL6UKHPU.js";import{a as h,b as v,e as I,f as B,g as H,h as V,i as g}from"./chunk-YDCAL5R3.js";import{c,o as w,p as $}from"./chunk-OCHXHPQZ.js";import{i as R,p as x}from"./chunk-OPCXNIGD.js";import{k as D,m as F}from"./chunk-WS6UFNKF.js";import{randomBytes as ce}from"node:crypto";import{isAbsolute as me}from"node:path";function le(r){try{return b(r)}catch{return null}}function C(r){let o=le(r);return{name:r.name,cid:r.cid,bio:o?.bio??"",persona:o?.persona??"",roleId:o?.roleId??"",rootCid:o?.rootCid??"",rootName:o?.rootName??""}}async function P(r,o){o&&await M(async e=>{await j(r,"::a2a_messaging::set_my_bio",{bio:o},e)})}function pe(r){let o=V(r.sessionId());if(!("error"in o))return o.id;throw new T(o.code,o.error)}async function ke(r,o){let{name:e,bio:i,exposeLocal:d,localAutoAccept:s}=o,n=x(e);if(n)throw p("create_identity",n,"NAME_INVALID");if(c.has(e))throw k("create_identity",e);try{let t=await _(e,{exposeLocal:d,localAutoAccept:s});await P(t,i);let a,l=null,m=[],u=[],y=f?c.get(f):void 0;if(y)await N(y,t),a="role",l=y.name,ae()&&de(y);else{a="root";let O=await E(t);m=O.adopted,u=O.failed}return g(r.sessionId(),e),{info:C(t),hierarchy:a,underRoot:l,adopted:m,failed:u,exposedLocal:d,localAutoAccept:s}}catch(t){throw p("create_identity",String(t),"PROVISION_FAILED")}}async function Ae(r,o){let{bio:e,exposeLocal:i,localAutoAccept:d}=o,s=r.leaseToken(),n=r.clientPid();if(!s||!n)throw q();let t=o.name;if(t!==void 0){let l=x(t);if(l)throw p("create_temporary_identity",l,"NAME_INVALID");if(c.has(t)||L.has(t))throw k("create_temporary_identity",t)}else{for(let l=0;l<5&&t===void 0;l++){let m=`tmp-${ce(5).toString("hex")}`;!c.has(m)&&!L.has(m)&&(t=m)}if(t===void 0)throw W()}let a=t;try{let l=await _(a,{exposeLocal:i,localAutoAccept:d,temp:{tokenHash:w(s),pid:n}});return await P(l,e),g(r.sessionId(),a),{info:C(l),ownerPid:n,exposedLocal:i,localAutoAccept:d}}catch(l){throw p("create_temporary_identity",String(l),"PROVISION_FAILED")}}async function Ce(r,o){let e=r.leaseToken(),i;if(o.name!==void 0){if(i=c.get(o.name),!i)return{name:o.name,result:null}}else{let n=e?B(e):void 0;if(i=n?c.get(n.identity):void 0,!i)throw U()}if(!i.temp)throw Y(i.name);let d=i.temp.owner,s=e!==void 0&&d.tokenHash===w(e);if(!s&&!i.temp.closing&&I(d.pid))throw G(i.name,d.pid);try{let n=await A(i,s?"explicit close by owner":"stale reclaim via close_temporary_identity");if(n.deleteError){let t=n.attempted===0?"It had no contacts, so no remove-me notices were needed.":`Remove-me notices: ${n.notified}/${n.attempted} queued, ${n.failed} not sent (best effort \u2014 delivery and remote contact deletion are not guaranteed).`;throw J(i.name,n.deleteError,t)}return{name:i.name,result:n}}catch(n){throw n instanceof T?n:p("close_temporary_identity",String(n),"CLOSE_FAILED")}}async function ve(r,o){let{name:e,bio:i,exposeLocal:d,localAutoAccept:s,skipIfRootExists:n}=o,t=x(e);if(t)throw p("create_root_identity",t,"NAME_INVALID");let a=f;if(n&&a&&c.has(a))throw z(a);if(c.has(e))throw k("create_root_identity",e);try{let l=await _(e,{exposeLocal:d,localAutoAccept:s});await P(l,i);let m=f?c.get(f):void 0;if(m&&m.name!==e)return await N(m,l),g(r.sessionId(),e),{info:C(l),hierarchy:"role",underRoot:m.name,adopted:[],failed:[],exposedLocal:d,localAutoAccept:s};let{adopted:u,failed:y}=await E(l);return g(r.sessionId(),e),{info:C(l),hierarchy:"root",underRoot:null,adopted:u,failed:y,exposedLocal:d,localAutoAccept:s}}catch(l){throw p("create_root_identity",String(l),"PROVISION_FAILED")}}async function Le(r){if(!me(r.path))throw K(r.path);let o={name:r.name,force:r.force,exposeLocal:r.exposeLocal,localAutoAccept:r.localAutoAccept};try{return{written:F(r.path,o,r.overwrite),json:D(o)}}catch(e){throw p("define_local_identity_file",String(e),"WRITE_FAILED")}}async function Se(r,o){let{name:e,force:i}=o;if(!c.has(e))throw Q(e);let d=r.sessionId(),s=r.leaseToken();if(!s)throw S();let n=c.get(e);if(n.temp){if(n.temp.closing)throw X(e);let m=n.temp.owner;if(m.tokenHash!==w(s))throw I(m.pid)?Z(e,m.pid):ee(e,m.pid);let u=r.clientPid();if(u&&u!==m.pid){m.pid=u;try{$(n.dir,n.temp)}catch(y){R(`[${e}] temp marker refresh failed:`,String(y))}}}let t=h.get(e);if(t&&t.token!==s)if(!I(t.pid))R(`auto-reclaiming "${e}" from dead client pid ${t.pid}`),h.delete(e);else if(i)v.add(t.token),h.delete(e);else throw te(e);let a=[...h.values()].find(m=>m.token===s&&m.identity!==e)?.identity,l=a&&c.has(a)?a:null;return g(d,e),{name:e,cid:c.get(e).cid,switchedFrom:l}}async function Ne(r){if(c.size===0)return[];let o=r.leaseToken(),e=t=>{let a=h.get(t);return a?a.token===o?"mine":I(a.pid)?"other-live":null:null},i=t=>{if(!t.temp)return null;let a=t.temp.owner.pid;return t.temp.closing?{state:"closing",ownerPid:a}:o!==void 0&&t.temp.owner.tokenHash===w(o)?{state:"mine",ownerPid:a}:I(a)?{state:"other-live",ownerPid:a}:{state:"stale",ownerPid:a}},d=(t,a)=>({name:t.name,cid:t.cid,kind:a,temp:i(t),session:e(t.name)}),s=f?c.get(f):void 0,n=[];if(s){n.push({...d(s,"root"),temp:null});for(let t of c.values())t.name!==s.name&&b(t).roleId!==""&&n.push(d(t,"role"));for(let t of c.values())t.name===s.name||b(t).roleId!==""||n.push(d(t,"flat"))}else for(let t of c.values())n.push(d(t,"flat"));return n}async function Ee(r){let o=pe(r),e=le(o);return{name:o.name,cid:o.cid,bio:e?.bio??"",persona:e?.persona??"",roleId:e?.roleId??"",rootCid:e?.rootCid??"",rootName:e?.rootName??"",temporary:o.temp!==void 0,isRoot:o.name===f,described:e!==null}}async function Pe(r,o){let{name:e}=o,i=c.get(e);if(!i)throw p("remove_identity",`no identity named "${e}".`,"NO_SUCH_IDENTITY");if(i.temp){let s=r.leaseToken(),n=i.temp.owner;if((s===void 0||n.tokenHash!==w(s))&&!i.temp.closing&&I(n.pid))throw oe(e,n.pid);try{let t=await A(i,"remove_identity");if(t.deleteError){let a=t.attempted===0?"":` Remove-me notices: ${t.notified}/${t.attempted} queued, ${t.failed} not sent (best effort).`;throw ne(e,t.deleteError,a)}return{name:e,kind:"temporary",close:t}}catch(t){throw t instanceof T?t:p("remove_identity",String(t),"CLOSE_FAILED")}}if(e===f){let s=[...c.values()].filter(n=>n.name!==e&&b(n).rootCid===i.cid);if(s.length>0)throw re(e,s.map(n=>n.name))}let d=se(i);if(d)throw ie(e,d);return{name:e,kind:"permanent"}}async function Oe(r){let o=r.leaseToken();if(!o)throw S();let e=[];for(let[i,d]of[...h]){if(d.token!==o)continue;h.delete(i),e.push(i);let s=c.get(i);s?.temp&&s.temp.owner.tokenHash===w(o)&&!s.temp.closing&&A(s,"owning session released its lease").catch(n=>R(`[${i}] close on lease release failed:`,String(n)))}return v.delete(o),H(),R(`lease released by token \u2026${o.slice(-6)}`),{released:e}}export{pe as a,ke as b,Ae as c,Ce as d,ve as e,Le as f,Se as g,Ne as h,Ee as i,Pe as j,Oe as k};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{c as i,i as a}from"./chunk-OPCXNIGD.js";import{join as n}from"node:path";import{createHash as u}from"node:crypto";import*as r from"node:fs";var m;function v(t){m=t}var T=new Map,g=null,y=null;function I(t){g=t}function _(t){y=t}var F=t=>n(i,t),d=t=>n(t,"identity.key"),h=t=>n(t,"state_data.bin"),W=t=>n(t,"notifications.log"),E=t=>n(t,"unread.json"),x=t=>n(t.dir,"files"),c=t=>n(t,"temp.json"),H=t=>u("sha256").update(t).digest("hex");function M(t,e){r.writeFileSync(c(t),JSON.stringify({v:1,owner:{token_sha256:e.owner.tokenHash,pid:e.owner.pid},created_at:e.createdAt}),{mode:384})}function R(t){try{let e=JSON.parse(r.readFileSync(c(t),"utf8"));return e.v!==1||typeof e.owner?.token_sha256!="string"||typeof e.owner?.pid!="number"?null:{owner:{tokenHash:e.owner.token_sha256,pid:e.owner.pid},createdAt:typeof e.created_at=="number"?e.created_at:0}}catch{return null}}function $(){for(let t of w()){let e=n(i,t);try{r.chmodSync(e,448)}catch(o){a(`[${t}] chmod 0700 failed:`,String(o))}for(let o of[h(e),d(e)])if(r.existsSync(o))try{r.chmodSync(o,384)}catch(s){a(`[${t}] chmod 0600 ${o} failed:`,String(s))}}}var k=t=>/^[A-Za-z0-9]+$/.test(t)&&t.length>0&&t.length<=128,j=t=>/^[A-Fa-f0-9]{64}$/.test(t);function B(t,e){if(!k(e))return null;let o=x(t),s;try{s=r.readdirSync(o)}catch{return null}let l=`${e}-`,p=s.find(f=>f.startsWith(l));return p?n(o,p):null}function w(){return r.existsSync(i)?r.readdirSync(i,{withFileTypes:!0}).filter(t=>t.isDirectory()&&r.existsSync(d(n(i,t.name)))).map(t=>t.name):[]}export{m as a,v as b,T as c,g as d,y as e,I as f,_ as g,F as h,d as i,h as j,W as k,E as l,x as m,c as n,H as o,M as p,R as q,$ as r,k as s,j as t,B as u,w as v};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{e as a}from"./chunk-ZHH3PWEW.js";import{d as s,f as i,g as u,h as p}from"./chunk-
|
|
2
|
+
import{e as a}from"./chunk-ZHH3PWEW.js";import{d as s,f as i,g as u,h as p}from"./chunk-WS6UFNKF.js";import{timingSafeEqual as d}from"node:crypto";var b="2.0.0",r=s(),_=r.stateDir,k=r.brokerUrl,g=process.env.OURS_TRANSPORT??"http",E=r.port,A=r.gcIntervalMs,c=r.apiVisibility,R=Number(process.env.OURS_TEST_STARTUP_HEARTBEAT_MS||"")||void 0,N=g==="http"?a(_,{heartbeatMs:R}):null,v=(...e)=>process.stderr.write(`ours: ${e.join(" ")}
|
|
3
3
|
`);function S(){if(c==="open")return null;if(c==="shared"){let e=u(r);if(!e)throw new Error(`apiVisibility=shared requires an operator-supplied token so it can be distributed to cross-user agents \u2014 set OURS_API_TOKEN or "apiToken" in config (${i(r)} is not used for shared mode). Use apiVisibility=owner for a same-user-only auto-token, or =open to disable auth.`);return e}return p(r,{generate:!0}).token}var f=S();function T(e){let t=e.headers["x-ours-api-token"];if(typeof t=="string"&&t)return t;let o=e.headers.authorization;if(typeof o=="string"){let n=/^Bearer\s+(.+)$/i.exec(o.trim());if(n)return n[1]}}function h(e){if(f===null)return!0;let t=T(e);if(!t)return!1;let o=Buffer.from(t),n=Buffer.from(f);return o.length===n.length&&d(o,n)}function P(e,t){return h(e)?!0:(t.writeHead(401,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"unauthorized"})),!1)}var O=/^[A-Za-z0-9 _.@-]{1,64}$/,l="contact-book";function y(e){return O.test(e)?e==="."||e===".."||e.includes("/")||e.includes("\\")?"invalid name":e===l?`"${l}" is reserved for the local contact book`:e==="root.json"||e==="bindings.json"?`"${e}" is reserved for daemon bookkeeping`:null:"name must be 1-64 chars of letters, digits, space, _ . @ or -"}export{b as a,r as b,_ as c,k as d,E as e,A as f,c as g,N as h,v as i,f as j,T as k,h as l,P as m,O as n,l as o,y as p};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as d}from"./chunk-
|
|
2
|
+
import{a as d}from"./chunk-ENJRQKGS.js";import{M as r,y as T,z as j}from"./chunk-65KGEJBX.js";import{H as y,I as u,J as p,M as l,Q as N,U as L,V as A,p as z,r as P,w as f}from"./chunk-XL6UKHPU.js";import{a as C,b as V,g as x,h as I,j as S,k as B}from"./chunk-WU5WT7LA.js";import{d as _,f as k}from"./chunk-YDCAL5R3.js";async function U(s,a={}){let e=d(s),{name:i,mode:o}=a;if(o==="public"&&i)throw T();try{return await u(async t=>{let n={};i&&(n.name=i),o&&(n.mode=o);let c=await l(e,"::a2a_messaging::generate_invite",n,t);return{blob:S(Buffer.from(c.Reduce("invite").GetBinary())),inviteId:c.Reduce("invite_id").Visualize(),mode:c.Reduce("mode").Visualize()==="public"?"public":"one_time"}})}catch(t){throw r("generate_invite",String(t))}}async function $(s){let a=d(s);try{return y(e=>{let i=p(a,"::a2a_messaging::list_invites",e),o=[];if(i.IsNil())return o;for(let t of i.GetKeys()){let n=i.Reduce(t);if(n.IsNil())continue;let c=n.Reduce("assigned").Visualize(),m=n.Reduce("created").Visualize();o.push({invite_id:typeof t=="string"?t:t.Visualize(),mode:n.Reduce("mode").Visualize(),assigned:c==="%%NIL"?"":c,created:m==="%%NIL"?"":m})}return o})}catch(e){throw r("list_invites",String(e))}}async function H(s,a){let e=d(s),{invite_id:i}=a;try{return await u(async o=>{let t=await l(e,"::a2a_messaging::revoke_invite",{invite_id:i},o),n=t.Reduce("was_public");return{revoked:t.Reduce("revoked").GetBoolean(),wasPublic:n.IsNil()?!1:n.GetBoolean()}})}catch(o){throw r("revoke_invite",String(o))}}async function J(s,a){let e=d(s),{invite:i,name:o}=a,t;try{if(t=B(i),t.length===0)throw new Error("the invite blob is empty")}catch(n){throw r("add_contact",n instanceof Error?n.message:"the invite blob is not valid.","INVITE_MALFORMED")}try{return await u(async n=>{let m={invite:e.pw.packet.NewBinaryFromBuffer(t).Attach(n)};o&&(m.name=o);let g=await l(e,"::a2a_messaging::add_contact",m,n),R=g.Reduce("container_id").Visualize(),v=g.Reduce("pending").Visualize(),h=g.Reduce("inviter_name").Visualize(),w=b=>!b||b==="%%NIL",G=w(v)?w(h)?R:h:v;return f(e),{display:G,cid:R}})}catch(n){throw r("add_contact",String(n))}}async function Q(s){let a=d(s);try{return y(e=>({contacts:C(p(a,"::a2a_messaging::list_contacts",e)),pending:x(p(a,"::actor::list_pending_introductions",e)),roots:I(p(a,"::a2a_messaging::list_contact_roots",e)),degraded:P(p(a,"::a2a_messaging::list_degraded_contacts",e)),renames:V(p(a,"::a2a_messaging::list_import_renames",e))}))}catch(e){throw r("list_contacts",String(e))}}async function X(s){let a=Object.values(N()),e=s.leaseToken(),i=e?k(e)?.identity:void 0;return a.map(o=>({name:o.name,container_id:o.container_id,published_at:o.published_at,isMine:o.name===i}))}async function Y(s,a){let e=d(s),{expose:i,auto_accept:o}=a;if(i===void 0&&o===void 0)throw j();let t=[];try{return o!==void 0&&(await u(async n=>{await l(e,"::actor::set_local_policy",{auto_accept:o},n)}),t.push(`auto_accept=${o}`)),i===!0?(await L(e),t.push("published in the local contact book")):i===!1&&(A(e),t.push("removed from the local contact book")),{identity:e.name,changes:t}}catch(n){throw r("set_local_book_policy",String(n))}}async function Z(s,a){let e=d(s),{contact:i}=a;try{return _.add(e.name),await u(async o=>{let t=await l(e,"::a2a_messaging::remove_contact",{contact:i},o),n=t.Reduce("removed").Visualize(),c=t.Reduce("container_id").Visualize(),m=t.Reduce("notified"),g=m.IsNil()?void 0:m.GetBoolean();return{name:n,cid:c,notified:g}})}catch(o){throw r("remove_contact",String(o))}finally{_.delete(e.name)}}async function ee(s,a){let e=d(s),{contact:i,name:o}=a;try{return await u(async t=>{let n=await l(e,"::a2a_messaging::rename_contact",{contact:i,name:o},t);return{from:n.Reduce("renamed").Visualize(),cid:n.Reduce("container_id").Visualize()}})}catch(t){throw r("rename_contact",String(t))}}async function te(s,a){let e=d(s),{contact:i,action:o}=a;try{if(o==="approve"){let t=await u(async n=>{let c=await l(e,"::actor::approve_introduction",{contact:i},n);return{action:"approve",name:c.Reduce("approved").Visualize(),cid:c.Reduce("container_id").Visualize(),flushed:c.Reduce("flushed").Visualize()}});return z(e),f(e),t}return await u(async t=>{let n=await l(e,"::actor::reject_introduction",{contact:i},t);return{action:"reject",name:n.Reduce("rejected").Visualize(),dropped:n.Reduce("dropped_messages").Visualize()}})}catch(t){throw r("respond_to_introduction",String(t))}}export{U as a,$ as b,H as c,J as d,Q as e,X as f,Y as g,Z as h,ee as i,te as j};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as c}from"./chunk-
|
|
2
|
+
import{a as c}from"./chunk-ENJRQKGS.js";import{M as d}from"./chunk-65KGEJBX.js";import{b as g,e as f,f as p}from"./chunk-CQDCCH6N.js";import{I as o,M as n}from"./chunk-XL6UKHPU.js";import{c as m}from"./chunk-OCHXHPQZ.js";import{i as u}from"./chunk-OPCXNIGD.js";async function h(i,s){let e=c(i),{bio:t}=s;try{await o(async a=>{await n(e,"::a2a_messaging::set_my_bio",{bio:t},a)});let r=0;if(e.name===g){for(let a of m.values())if(a.name!==e.name&&f(a).rootCid===e.cid)try{await p(e,a),r+=1}catch(y){u(`failed to refresh root profile in role "${a.name}":`,String(y))}}return{identity:e.name,rolesRefreshed:r}}catch(r){throw d("set_bio",String(r))}}async function x(i){let s=c(i);try{return await o(async e=>{let t=await n(s,"::a2a_messaging::advertise_migrate",{},e);return{wasAdvertising:t.Reduce("was_advertising").Visualize()==="true",advertising:t.Reduce("advertising").Visualize()==="true",offers:parseInt(t.Reduce("offers_initiated").Visualize(),10)||0}})}catch(e){throw d("advertise_migrate",String(e))}}async function P(i,s){let e=c(i),{persona:t}=s;try{return await o(async r=>{await n(e,"::a2a_messaging::set_my_persona",{persona:t},r)}),{identity:e.name}}catch(r){throw d("set_persona",String(r))}}async function C(i){let s=c(i);try{return{readvertised:await o(async t=>(await n(s,"::a2a_messaging::readvertise_on_upgrade",{},t)).Reduce("readvertised").Visualize())}}catch(e){throw d("readvertise_on_upgrade",String(e))}}export{h as a,x as b,P as c,C as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as l}from"./chunk-
|
|
2
|
+
import{a as l}from"./chunk-6SMQG6NV.js";import{e as o}from"./chunk-CQDCCH6N.js";import{I as p,J as f,M as m}from"./chunk-XL6UKHPU.js";import{c as r}from"./chunk-OCHXHPQZ.js";import{i as u}from"./chunk-OPCXNIGD.js";var A=()=>d,d=!0,C=d?2:1;function g(e,n){let a=[];for(let t of r.values()){if(t.name===e.name)continue;let i=o(t);if(i.rootCid!==e.cid)continue;let c=f(t,"::actor::export_address_document_native",n);a.push({cid:c.Reduce("identity").Reduce("container_id"),role_id:i.roleId,name:t.name,bio:i.bio,persona:i.persona,caps:l(t),child_ad:c})}return a}var s=new Set;async function y(e){if(!s.has(e.name)){s.add(e.name);try{await p(async n=>{await m(e,"::a2a_cluster::reconcile",{pending_handle:"",children:g(e,n)},n)})}catch(n){u(`[${e.name}] cluster sweep failed:`,String(n))}finally{s.delete(e.name)}}}var w=6e4;function T(){setInterval(()=>{if(d)for(let e of r.values())o(e).roleId===""&&y(e)},w).unref()}export{A as a,C as b,y as c,T as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as E,b as k,d as A}from"./chunk-
|
|
2
|
+
import{a as E,b as k,d as A}from"./chunk-CQDCCH6N.js";import{A as y,H as T,I,J as _,M as R,V as x}from"./chunk-XL6UKHPU.js";import{a as S}from"./chunk-WU5WT7LA.js";import{a as l,d as u,e as d,g as w}from"./chunk-YDCAL5R3.js";import{a as $,c as m,q as v}from"./chunk-OCHXHPQZ.js";import{c as s,i as r}from"./chunk-OPCXNIGD.js";import{join as b}from"node:path";import*as i from"node:fs";function D(e){try{$.remove_packet(e.cid)}catch(t){r(`remove_packet(${e.cid}) failed:`,String(t))}m.delete(e.name);try{x(e)}catch(t){r(`failed to unpublish "${e.name}" from the contact book:`,String(t))}l.has(e.name)&&(l.delete(e.name),w()),e.name===k&&(E(null),A());try{i.rmSync(e.dir,{recursive:!0,force:!0}),y.delete(e.name)}catch(t){return`deleting ${e.dir} failed: ${String(t)}`}return null}function F(e,t){let n=e.temp;return n?(n.closing||(n.closing=(async()=>{r(`[${e.name}] closing temporary identity (${t})`);let o=[];try{o=T(a=>S(_(e,"::a2a_messaging::list_contacts",a)))}catch(a){r(`[${e.name}] contact snapshot failed during close (continuing with local cleanup):`,String(a))}let p=0,c=0;u.add(e.name);try{for(let a of o)try{await I(async C=>{let h=(await R(e,"::a2a_messaging::remove_contact",{contact:a.container_id},C)).Reduce("notified");return h.IsNil()?!1:h.GetBoolean()})?p++:c++}catch(g){c++,r(`[${e.name}] remove-me to ${a.container_id} failed (continuing):`,String(g))}}finally{u.delete(e.name)}let f=D(e);return f?r(`[${e.name}] temporary identity close: LOCAL DELETE FAILED \u2014 ${f}`):r(`[${e.name}] temporary identity closed: ${o.length} contact(s), ${p} remove-me notice(s) queued, ${c} not sent (delivery unverified by design)`),{attempted:o.length,notified:p,failed:c,deleteError:f}})()),n.closing):Promise.reject(new Error(`identity "${e.name}" is not temporary`))}function H(){for(let e of[...m.values()]){let t=e.temp;if(!t||t.closing||d(t.owner.pid))continue;let n=l.get(e.name);n&&d(n.pid)||F(e,`stale lease \u2014 owner pid ${t.owner.pid} is dead`).catch(o=>r(`[${e.name}] stale-temp reclaim failed:`,String(o)))}}function J(){if(i.existsSync(s))for(let e of i.readdirSync(s,{withFileTypes:!0})){if(!e.isDirectory()||m.has(e.name))continue;let t=b(s,e.name),n=v(t);if(!(!n||d(n.owner.pid)))try{i.rmSync(t,{recursive:!0,force:!0}),y.delete(e.name),r(`[${e.name}] removed orphaned temporary-identity dir (owner pid ${n.owner.pid} dead, no live packet)`)}catch(o){r(`[${e.name}] failed to remove orphaned temporary-identity dir:`,String(o))}}}export{D as a,F as b,H as c,J as d};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{I as m,M as s,u as c,v as l,x as f}from"./chunk-
|
|
2
|
+
import{I as m,M as s,u as c,v as l,x as f}from"./chunk-XL6UKHPU.js";import{c as o}from"./chunk-OCHXHPQZ.js";import{f as i,i as a}from"./chunk-OPCXNIGD.js";var e=null,n=!1;function v(){e||(e=setInterval(()=>{n||(n=!0,(async()=>{try{for(let t of o.values()){try{await m(async r=>{await s(t,"::actor::gc",{},r)})}catch(r){a(`gc(${t.name}) failed:`,String(r))}await c(t),await l(t),await f(t)}}finally{n=!1}})())},i),e.unref?.(),a(`message GC timer armed (every ${i}ms)`))}function w(){e&&(clearInterval(e),e=null)}export{v as a,w as b};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as H}from"./chunk-
|
|
2
|
+
import{a as H}from"./chunk-EHCBEY52.js";import{c as L,d as B}from"./chunk-TNTHPI3A.js";import{d as F}from"./chunk-TIIFYDXJ.js";import{a as u,b as n,c as A,d as U,e as P,f as C}from"./chunk-CQDCCH6N.js";import{A as I,C as D,D as N,W as M,j as k,v as h,x as g}from"./chunk-XL6UKHPU.js";import{a as v,b as E,c as O}from"./chunk-YRPUM6JG.js";import{g as $}from"./chunk-YDCAL5R3.js";import{a as f,b as _,c as l,d as b,q as y,r as S,v as R}from"./chunk-OCHXHPQZ.js";import{d as m,h as s,i as o}from"./chunk-OPCXNIGD.js";import{adapt_wrapper as K}from"@adapt-toolkit/sdk/executables";var T=!1;function ne(){return T}function j(){if(T)throw new Error('bootWrapper() has already run in this process. It boots the ADAPT environment, which can only be initialised once \u2014 a second call fails inside the native layer with "Failed to invoke initializer in ADAPT environment", which names neither the double init nor the caller. NOTE THAT startDaemon() CALLS bootWrapper() ITSELF: the two are alternatives, not steps. Use startDaemon() for the HTTP daemon, or bootWrapper() alone for a stdio/in-process host \u2014 never both.');T=!0,H()}async function ae(){j(),s?.update("wrapper"),O(v());let x=["--broker_address",m,"--test_mode","--logger_config","--level","INFO","--stdout","stderr","--logger_config_end"];o(`booting wrapper (unit ${E.hash.slice(0,12)}\u2026, broker ${m})`),_(await K.start(x)),f.on_packet_created_cb=e=>o(`wrapper: packet ready ${e.slice(0,12)}\u2026`),f.start();let p=Number(process.env.OURS_TEST_BOOT_HOLD_MS||"")||0;p>0&&(o(`TEST HOLD: boot window open ${p}ms (OURS_TEST_BOOT_HOLD_MS)`),await new Promise(e=>setTimeout(e,p))),s?.update("registrar");try{await N()}catch(e){o("failed to start the contact-book registrar (local contact book disabled):",String(e))}S();let i=R(),d=Math.max(0,Number(process.env.OURS_TEST_FAKE_RESTORE_COUNT||"")||0),c=Math.max(0,Number(process.env.OURS_TEST_FAKE_RESTORE_MS||"")||0),W=i.length===0&&d>0?d:i.length;s?.update("identities",{completed:0,total:W});for(let e of i)I.add(e);if(i.length===0&&d>0){o(`TEST: simulating ${d} fake identity restore(s), ${c}ms each`);for(let e=0;e<d;e++)c>0&&await new Promise(a=>setTimeout(a,c)),s?.update("identities",{completed:e+1,total:d})}else if(i.length===0)o("no persisted identities \u2014 start with create_identity");else{o(`restoring ${i.length} identit${i.length===1?"y":"ies"}: ${i.join(", ")}`);for(let[e,a]of i.entries()){try{let t=await D(a);b&&await M(t);let r=y(t.dir);r&&(t.temp=r)}catch(t){o(`failed to restore "${a}":`,String(t))}s?.update("identities",{completed:e+1,total:i.length})}}s?.update("reconciliation"),F(),u(A()),n&&!l.has(n)&&(o(`root marker names a missing identity "${n}" \u2014 clearing it`),u(null),U()),n&&o(`root identity: ${n}`);{let e=n?l.get(n):void 0;n&&!e&&o(`re-delegation on upgrade DEGRADED: root "${n}" is not among the restored identities \u2014 role certs not refreshed this boot`);let a=[];if(e)for(let t of l.values()){if(t.name===e.name)continue;let r;try{r=P(t)}catch{r=void 0}if(!(!r||!r.hasCert)){if(r.rootCid!==e.cid){o(`[${t.name}] re-delegation skipped: delegated by a different root (${r.rootCid.slice(0,12)}\u2026), not this host root \u2014 left as-is`);continue}try{await C(e,t),a.push(t)}catch(w){k(t,{event:"redelegation_failed",error:String(w).slice(0,300)}),o(`[${t.name}] boot re-delegation (upgrade cert refresh) failed:`,String(w))}}}for(let t of l.values()){await h(t),await g(t);for(let r of[1e4,3e4,9e4])setTimeout(()=>{h(t).catch(()=>{})},r),setTimeout(()=>{g(t).catch(()=>{})},r)}a.length>0&&o(`refreshed ${a.length} role delegation cert(s) against the live AD on boot`)}$(),B(),L()}export{ne as a,ae as b};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import*as o from"node:fs";import{randomBytes as S}from"node:crypto";import{homedir as g}from"node:os";import{resolve as c,join as a,dirname as p,basename as b}from"node:path";var y=["owner","shared","open"],s={brokerUrl:"wss://broker1.ours.network",port:3050,stateDir:c(g(),".ours"),gcIntervalMs:36e5,apiVisibility:"owner"};function d(){return process.env.OURS_CONFIG??a(g(),".ours","config.json")}function T(){let t;try{t=o.readFileSync(d(),"utf8")}catch{return{}}let e;try{e=JSON.parse(t)}catch{return{}}let r={};if(typeof e.brokerUrl=="string"&&(r.brokerUrl=e.brokerUrl),typeof e.port=="number"&&Number.isFinite(e.port)&&(r.port=e.port),typeof e.stateDir=="string"&&(r.stateDir=c(e.stateDir)),typeof e.gcIntervalMs=="number"&&Number.isFinite(e.gcIntervalMs)&&(r.gcIntervalMs=e.gcIntervalMs),typeof e.apiVisibility=="string"&&y.includes(e.apiVisibility)&&(r.apiVisibility=e.apiVisibility),typeof e.apiToken=="string"&&e.apiToken.trim()&&(r.apiToken=e.apiToken.trim()),e.stt&&typeof e.stt=="object"){let i=e.stt,n={};typeof i.provider=="string"&&(n.provider=i.provider),typeof i.apiKey=="string"&&(n.apiKey=i.apiKey),typeof i.model=="string"&&(n.model=i.model),typeof i.baseUrl=="string"&&(n.baseUrl=i.baseUrl),typeof i.language=="string"&&(n.language=i.language),typeof i.maxBytes=="number"&&Number.isFinite(i.maxBytes)&&(n.maxBytes=i.maxBytes),typeof i.timeoutMs=="number"&&Number.isFinite(i.timeoutMs)&&(n.timeoutMs=i.timeoutMs),i.custom&&typeof i.custom=="object"&&(n.custom=i.custom),r.stt=n}return r}function _(){let t=process.env.OURS_API_VISIBILITY?.trim().toLowerCase();return t&&y.includes(t)?t:void 0}function l(t){let e=process.env[t];if(e===void 0)return;let r=parseInt(e,10);return Number.isNaN(r)?void 0:r}function E(){let t=T();return{brokerUrl:process.env.OURS_BROKER_URL??t.brokerUrl??s.brokerUrl,port:l("OURS_PORT")??t.port??s.port,stateDir:c(process.env.OURS_STATE_DIR??t.stateDir??s.stateDir),gcIntervalMs:l("OURS_GC_INTERVAL_MS")??t.gcIntervalMs??s.gcIntervalMs,apiVisibility:_()??t.apiVisibility??s.apiVisibility,apiToken:process.env.OURS_API_TOKEN?.trim()||t.apiToken,stt:v(t.stt)}}function v(t){let e={};process.env.OURS_STT_PROVIDER?.trim()&&(e.provider=process.env.OURS_STT_PROVIDER.trim()),process.env.OURS_STT_API_KEY?.trim()&&(e.apiKey=process.env.OURS_STT_API_KEY.trim()),process.env.OURS_STT_MODEL?.trim()&&(e.model=process.env.OURS_STT_MODEL.trim()),process.env.OURS_STT_BASE_URL?.trim()&&(e.baseUrl=process.env.OURS_STT_BASE_URL.trim()),process.env.OURS_STT_LANGUAGE?.trim()&&(e.language=process.env.OURS_STT_LANGUAGE.trim());let r={...t??{},...e};return Object.keys(r).length?r:void 0}var O="daemon-token";function k(t){return a(t.stateDir,O)}function C(t){let e=process.env.OURS_API_TOKEN?.trim();return e||t.apiToken?.trim()||void 0}function F(t,e={}){let r=process.env.OURS_API_TOKEN?.trim();if(r)return{token:r,source:"env"};let i=t.apiToken?.trim();if(i)return{token:i,source:"config"};let n=k(t);try{let u=o.readFileSync(n,"utf8").trim();if(u)return{token:u,source:"file"}}catch{}if(!e.generate)return null;let f=S(32).toString("hex");try{o.mkdirSync(p(n),{recursive:!0}),o.writeFileSync(n,f+`
|
|
3
|
+
`,{mode:384}),o.chmodSync(n,384)}catch{}return{token:f,source:"generated"}}function w(t){let e=d();o.mkdirSync(p(e),{recursive:!0}),o.writeFileSync(e,JSON.stringify(t,null,2)+`
|
|
4
|
+
`,{mode:384});try{o.chmodSync(e,384)}catch{}return e}var m=".ours-identity";function I(t){if(!t.name.trim())throw new Error("identity name must not be empty");let e={identity:t.name.trim()};return t.force&&(e.force=!0),e.expose_local=t.exposeLocal??!0,e.local_auto_accept=t.localAutoAccept??!0,e}function U(t){let e=c(t);return b(e)===m?e:a(e,m)}function N(t,e,r=!1){let i=I(e),n=U(t);if(!r&&o.existsSync(n))throw new Error(`${n} already exists \u2014 pass overwrite to replace it`);return o.mkdirSync(p(n),{recursive:!0}),o.writeFileSync(n,JSON.stringify(i,null,2)+`
|
|
5
|
+
`),n}export{y as a,s as b,d as c,E as d,O as e,k as f,C as g,F as h,w as i,m as j,I as k,U as l,N as m};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{c as p,h as w,j as I,k as b,l as x}from"./chunk-DIRW7I4S.js";import{m as h}from"./chunk-
|
|
2
|
+
import{c as p,h as w,j as I,k as b,l as x}from"./chunk-DIRW7I4S.js";import{m as h}from"./chunk-OCHXHPQZ.js";import{b as _}from"./chunk-OPCXNIGD.js";import{b as z}from"./chunk-P55RJGZU.js";import{basename as M,join as $}from"node:path";import{createHash as S,randomUUID as G}from"node:crypto";import{mkdir as C,open as O,rename as v,unlink as N,lstat as D}from"node:fs/promises";import{brotliCompressSync as K,brotliDecompressSync as P}from"node:zlib";function Z(e){let n=[];if(e.IsNil())return n;for(let i of e.GetKeys()){let t=e.Reduce(i);t.IsNil()||n.push({name:t.Reduce("name").Visualize(),container_id:t.Reduce("container_id").Visualize()})}return n}function ee(e){let n={};if(e.IsNil())return n;for(let i of e.GetKeys()){let t=e.Reduce(i);t.IsNil()||(n[typeof i=="string"?i:i.Visualize()]=t.Visualize())}return n}function te(e){let n=[];if(e.IsNil())return n;for(let i=0;;i++){let t=e.Reduce(i);if(t.IsNil())break;let s=t.Reduce("reply_to"),o=null;if(!s.IsNil()){o={wire_id:s.Reduce("wire_id").Visualize()};let r=s.Reduce("sentence");r.IsNil()||(o.sentence=parseInt(r.Visualize(),10))}n.push({msg_id:parseInt(t.Reduce("msg_id").Visualize(),10),sender_id:t.Reduce("sender_id").Visualize(),sender_name:t.Reduce("sender_name").Visualize(),text:t.Reduce("text").Visualize(),date:t.Reduce("date").Visualize(),status:t.Reduce("status").Visualize(),wire_id:t.Reduce("wire_id").Visualize(),reply_to:o})}return n}function ie(e){let n=[];if(e.IsNil())return n;for(let i=0;;i++){let t=e.Reduce(i);if(t.IsNil())break;let s=t.Reduce("filename").Visualize(),o=t.Reduce("mime").Visualize()||"application/octet-stream",r=t.Reduce("reply_to"),a=null;if(!r.IsNil()){a={wire_id:r.Reduce("wire_id").Visualize()};let u=parseInt(r.Reduce("sentence").Visualize(),10);Number.isSafeInteger(u)&&u>0&&(a.sentence=u)}n.push({file_id:parseInt(t.Reduce("file_id").Visualize(),10),wire_id:t.Reduce("wire_id").Visualize(),from:{id:t.Reduce("sender_id").Visualize(),name:t.Reduce("sender_name").Visualize()},filename:s,mime:o,size:parseInt(t.Reduce("size").Visualize(),10),size_source:"received_payload",status:t.Reduce("status").Visualize(),date:t.Reduce("date").Visualize(),sha256:null,reply_to:a,kind:p(o,s)?"voice_message":"file"})}return n}function ne(e){if(e.length===0)return"No files received.";let n=[];for(let i of e){let t=i.kind==="voice_message"?"\u{1F3A4} voice message \xB7 ":"";n.push(` \u2022 ${t}${i.filename} (${i.mime}, ${i.size} B) from ${i.from.name} [${i.status}] {${i.wire_id}} sender_id=${i.from.id}`)}return`${n.length} file(s):
|
|
3
3
|
${n.join(`
|
|
4
4
|
`)}`}async function j(e,n,i){await C(e,{recursive:!0,mode:448});let t=await D(e);if(!t.isDirectory()||t.isSymbolicLink())throw new Error("received-files directory is not a safe directory");let s=$(e,`.${M(n)}.${G()}.tmp`),o=await O(s,"wx",384);try{await o.writeFile(i),await o.sync()}catch(r){throw await o.close().catch(()=>{}),await N(s).catch(()=>{}),r}await o.close();try{await v(s,n)}catch(r){throw await N(s).catch(()=>{}),r}}async function re(e,n){let i=[];if(n.IsNil())return{text:"No new files.",files:i};let t=h(e),s=[];for(let o=0;;o++){let r=n.Reduce(o);if(r.IsNil())break;let a=r.Reduce("filename").Visualize(),u=r.Reduce("mime").Visualize()||"application/octet-stream",f=r.Reduce("sender_name").Visualize(),A=r.Reduce("sender_id").Visualize(),F=parseInt(r.Reduce("file_id").Visualize(),10),B=r.Reduce("date").Visualize(),d=r.Reduce("wire_id").Visualize(),c=Buffer.from(r.Reduce("data").GetBinary()),V=S("sha256").update(c).digest("hex"),l=$(t,`${d}-${z(a)}`);await j(t,l,c);let g={file_id:F,wire_id:d,from:{id:A,name:f},filename:a,path:l,mime:u,size:c.length,sha256:V,status:"processed",date:B,kind:p(u,a)?"voice_message":"file",sender:f};if(p(u,a)){let y=w(_.stt),m;if(!y.ready)m={kind:"unconfigured",reason:y.reason};else{let R=await I(c,a,u,_.stt);m=R.ok?{kind:"transcript",text:R.text}:{kind:"failed",error:R.error}}g.transcription=b(y,m,{audioPath:l,wireId:d}),s.push(x({sender:f,wire:d,savedPath:l,sizeBytes:c.length},m)),i.push(g);continue}i.push(g),s.push(` \u2022 ${a} (${u}, ${c.length} B, sha256 ${V}) from ${f} \u2192 ${l} {${d}}`)}return s.length===0?{text:"No new files.",files:i}:{text:`${s.length} new file(s) written to your identity's files dir \u2014 paths + metadata below (bytes stay on disk, never in this result). If your OS user can read the path, use it directly; otherwise use save_file({ wire_id, dest_path }) to stream a copy to a path you can write:
|
|
5
5
|
${s.join(`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{c as b}from"./chunk-
|
|
2
|
+
import{c as b}from"./chunk-OCHXHPQZ.js";import{i as S}from"./chunk-OPCXNIGD.js";import*as n from"node:fs";import{createHash as w}from"node:crypto";import{basename as _,join as f}from"node:path";var u=e=>f(e.dir,"uploads"),D=Number(process.env.OURS_UPLOAD_TTL_MS)>0?Number(process.env.OURS_UPLOAD_TTL_MS):60*60*1e3,I=/^[0-9a-f]{32}$/,L=()=>w("sha256").update(`${process.pid}:${Date.now()}:${Math.random()}`).digest("hex").slice(0,32),O=e=>I.test(e),U=(e,r)=>f(u(e),r),y=(e,r)=>f(u(e),`${r}.json`);function $(e){let r=e.replace(/[\u0000-\u001f\u007f]/g,"").replace(/\\/g,"/"),t=_(r);return(t===""||t==="."||t===".."?"":t).slice(0,255)}var i=class extends Error{constructor(t,s){super(s);this.status=t;this.name="UploadRefused"}};async function T(e,r,t){let s=$(t.filename);if(s==="")throw new i(400,"x-ours-filename is required and must be a plain file name");if(t.declaredBytes===null)throw new i(411,"Content-Length is required");if(t.declaredBytes>=t.cap)throw new i(400,`upload is ${t.declaredBytes} bytes, at or over the transport's ${t.cap}-byte envelope budget \u2014 it could not be sent even with no filename or MIME, so it is refused before it is stored`);let o=L();n.mkdirSync(u(e),{recursive:!0,mode:448});let d=U(e,o),a=w("sha256"),p=0,c=n.createWriteStream(d,{mode:384});try{await new Promise((m,x)=>{let g=l=>{r.unpipe?.(c),c.destroy(),x(l)};r.on("data",l=>{if(p+=l.length,p>t.declaredBytes){g(new i(400,"request body is longer than its Content-Length"));return}a.update(l)}),r.on("error",g),c.on("error",g),c.on("finish",()=>m()),r.pipe(c)})}catch(m){try{n.rmSync(d,{force:!0})}catch{}throw m}let h={upload_id:o,filename:s,mime:t.mime,size:p,sha256:a.digest("hex"),at:new Date().toISOString()};return n.writeFileSync(y(e,o),JSON.stringify(h),{mode:384}),h}function F(e,r){if(!O(r))return null;let t=U(e,r),s,o;try{s=n.readFileSync(t),o=JSON.parse(n.readFileSync(y(e,r),"utf8"))}catch{return null}finally{try{n.rmSync(t,{force:!0})}catch{}try{n.rmSync(y(e,r),{force:!0})}catch{}}return{meta:o,buf:s}}function R(){let e=0,r=Date.now()-D;for(let t of b.values()){let s=u(t),o;try{o=n.readdirSync(s)}catch{continue}for(let d of o){let a=f(s,d);try{if(n.statSync(a).mtimeMs>=r)continue;n.rmSync(a,{force:!0}),e++}catch{}}e>0&&S(`[${t.name}] swept ${e} stale staged upload file(s)`)}return e}export{u as a,D as b,O as c,$ as d,i as e,T as f,F as g,R as h};
|