@inixiative/archive 0.9.0 → 0.10.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/package.json +3 -3
- package/src/cli.ts +2 -0
- package/src/kingdom.ts +28 -74
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inixiative/archive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./src/index.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"prepare": "if git rev-parse --git-dir >/dev/null 2>&1; then lefthook install; fi && prisma generate"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@inixiative/signet": "^0.
|
|
38
|
+
"@inixiative/signet": "^0.3.0",
|
|
39
39
|
"@prisma/client": "^6.6.0",
|
|
40
40
|
"js-tiktoken": "1.0.21",
|
|
41
41
|
"prisma": "^6.6.0",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@biomejs/biome": "2.5.2",
|
|
46
|
-
"@inixiative/config": "^0.5.
|
|
46
|
+
"@inixiative/config": "^0.5.62",
|
|
47
47
|
"@types/bun": "1.4.2",
|
|
48
48
|
"lefthook": "2.1.9",
|
|
49
49
|
"typescript": "6.0.3"
|
package/src/cli.ts
CHANGED
|
@@ -192,6 +192,8 @@ export async function runCli(args = Bun.argv.slice(2)) {
|
|
|
192
192
|
sourceId: await local.sourceId(),
|
|
193
193
|
directory: join(home, 'kingdom'),
|
|
194
194
|
onReview: (review) => console.error(JSON.stringify(review)),
|
|
195
|
+
onError: (error) =>
|
|
196
|
+
console.error(`Still waiting: ${error instanceof Error ? error.message : String(error)}`),
|
|
195
197
|
confirmOwner: async ({ ownerName }) => {
|
|
196
198
|
if (v.yes) return true;
|
|
197
199
|
if (!process.stdin.isTTY)
|
package/src/kingdom.ts
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
collectSignet,
|
|
5
|
-
generateSignetKey,
|
|
6
|
-
installationInquiries,
|
|
7
|
-
kingdomUrl,
|
|
8
|
-
registerInstallation,
|
|
9
|
-
requestRegistration,
|
|
10
|
-
SignetClient,
|
|
11
|
-
saveCollectedSignet,
|
|
12
|
-
writePrivateJson,
|
|
13
|
-
} from '@inixiative/signet';
|
|
1
|
+
import { pairInstallation, SignetClient } from '@inixiative/signet';
|
|
14
2
|
import type { ArchiveDestination } from './config';
|
|
15
3
|
|
|
16
|
-
const pollMs = 3000;
|
|
17
|
-
|
|
18
4
|
/** Libraries this Archive's Signet may write to, as Kingdom describes them. */
|
|
19
5
|
export async function writableLibraries(credentialFile: string) {
|
|
20
6
|
const description = await (await SignetClient.fromFile(credentialFile)).describe();
|
|
@@ -36,74 +22,42 @@ type Pairing = {
|
|
|
36
22
|
directory: string;
|
|
37
23
|
onReview: (review: { reviewCode: string; review: string; expiresAt: string }) => void;
|
|
38
24
|
confirmOwner: (owner: { ownerName: string | null; owner: unknown }) => Promise<boolean>;
|
|
39
|
-
|
|
25
|
+
onError?: (error: unknown) => void;
|
|
26
|
+
socketOptions?: { pollMs?: number; retryBaseMs?: number; authTimeoutMs?: number };
|
|
40
27
|
};
|
|
41
28
|
|
|
42
|
-
/** The key that names this Archive to one Kingdom; reused for every owner it registers with. */
|
|
43
|
-
async function installationKey(directory: string) {
|
|
44
|
-
const keyFile = join(directory, 'installation-key.json');
|
|
45
|
-
if (!existsSync(keyFile)) await writePrivateJson(keyFile, generateSignetKey());
|
|
46
|
-
return keyFile;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
29
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* confirms the owner locally before collecting its Signet.
|
|
30
|
+
* Pairs this Archive with Kingdom as an Installation: a person claims the review code, the Archive
|
|
31
|
+
* confirms the owner locally, then collects the Signet for its local Archive integration.
|
|
53
32
|
*/
|
|
54
33
|
export async function pairWithKingdom(input: Pairing) {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
await registerInstallation(kingdom, keyFile, {
|
|
34
|
+
const paired = await pairInstallation({
|
|
35
|
+
url: input.kingdom,
|
|
36
|
+
root: input.directory,
|
|
59
37
|
kind: 'archive',
|
|
60
38
|
name: input.name,
|
|
61
39
|
sourceId: input.sourceId,
|
|
40
|
+
terms: {
|
|
41
|
+
name: input.name,
|
|
42
|
+
lifecycle: 'ongoing',
|
|
43
|
+
resources: [],
|
|
44
|
+
expiresAt: null,
|
|
45
|
+
maxRequests: null,
|
|
46
|
+
maxConcurrent: 4,
|
|
47
|
+
},
|
|
48
|
+
onReview: input.onReview,
|
|
49
|
+
confirmOwner: input.confirmOwner,
|
|
50
|
+
onError: input.onError,
|
|
51
|
+
socketOptions: input.socketOptions,
|
|
62
52
|
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
});
|
|
72
|
-
input.onReview({
|
|
73
|
-
reviewCode: pending.reviewCode,
|
|
74
|
-
review: `${kingdom}/dashboard?reviewSignet=${pending.reviewCode}`,
|
|
75
|
-
expiresAt: pending.expiresAt,
|
|
76
|
-
});
|
|
77
|
-
const sleep = input.sleep ?? Bun.sleep;
|
|
78
|
-
for (;;) {
|
|
79
|
-
const state = await installationInquiries(kingdom, keyFile);
|
|
80
|
-
if (state.declinedAt && Date.parse(state.declinedAt) >= askedAt)
|
|
81
|
-
throw new Error('The registration was declined in Kingdom');
|
|
82
|
-
const inquiry = state.inquiries.find(
|
|
83
|
-
(item) => item.type === 'registerIntegration' && Date.parse(item.createdAt) >= askedAt,
|
|
84
|
-
);
|
|
85
|
-
if (inquiry?.status === 'approved') {
|
|
86
|
-
if (!(await input.confirmOwner({ ownerName: inquiry.ownerName, owner: inquiry.owner })))
|
|
87
|
-
throw new Error('Not collected: the owner was not confirmed');
|
|
88
|
-
const collected = await collectSignet(kingdom, keyFile, inquiry.id);
|
|
89
|
-
if (!collected) throw new Error('Kingdom has not released the Signet yet; try again');
|
|
90
|
-
const credentialFile = join(directory, `signet-${collected.signetId}.json`);
|
|
91
|
-
await saveCollectedSignet(credentialFile, kingdom, keyFile, collected);
|
|
92
|
-
return {
|
|
93
|
-
paired: true,
|
|
94
|
-
owner: inquiry.ownerName,
|
|
95
|
-
integrationId: collected.integrationId,
|
|
96
|
-
credentialFile,
|
|
97
|
-
libraries: await writableLibraries(credentialFile),
|
|
98
|
-
next: 'archive connect --kind kingdom --url KINGDOM --credential-file FILE --integration-id ID --resource-id ID --project-id PROJECT',
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
if (inquiry && inquiry.status !== 'sent')
|
|
102
|
-
throw new Error(`The registration was ${inquiry.status} in Kingdom`);
|
|
103
|
-
if (!inquiry && !state.pending)
|
|
104
|
-
throw new Error('The review code expired before it was claimed; run archive pair again');
|
|
105
|
-
await sleep(pollMs);
|
|
106
|
-
}
|
|
53
|
+
return {
|
|
54
|
+
paired: true,
|
|
55
|
+
owner: paired.ownerName,
|
|
56
|
+
integrationId: paired.integrationId,
|
|
57
|
+
credentialFile: paired.credentialFile,
|
|
58
|
+
libraries: await writableLibraries(paired.credentialFile),
|
|
59
|
+
next: 'archive connect --kind kingdom --url KINGDOM --credential-file FILE --integration-id ID --resource-id ID --project-id PROJECT',
|
|
60
|
+
};
|
|
107
61
|
}
|
|
108
62
|
|
|
109
63
|
export async function verifyKingdomDestination(
|