gitd-client 0.7.0 → 0.9.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/dist/compare-convert.d.ts +6 -0
- package/dist/compare-convert.js +33 -0
- package/dist/convert.d.ts +6 -2
- package/dist/convert.js +54 -6
- package/dist/credential-convert.d.ts +3 -0
- package/dist/credential-convert.js +27 -0
- package/dist/credential-types.d.ts +57 -0
- package/dist/credential-types.js +1 -0
- package/dist/credentials.d.ts +27 -0
- package/dist/credentials.js +66 -0
- package/dist/endpoint-types.d.ts +28 -0
- package/dist/endpoint-types.js +1 -0
- package/dist/endpoint.d.ts +18 -0
- package/dist/endpoint.js +49 -0
- package/dist/gen/gitd/v1/gitd_pb.d.ts +2154 -151
- package/dist/gen/gitd/v1/gitd_pb.js +565 -17
- package/dist/gitd.d.ts +46 -5
- package/dist/gitd.js +137 -11
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -0
- package/dist/publishing-convert.d.ts +8 -0
- package/dist/publishing-convert.js +74 -0
- package/dist/publishing-types.d.ts +72 -0
- package/dist/publishing-types.js +1 -0
- package/dist/publishing.d.ts +23 -0
- package/dist/publishing.js +40 -0
- package/dist/types.d.ts +113 -7
- package/dist/warm-convert.d.ts +4 -0
- package/dist/warm-convert.js +12 -0
- package/package.json +1 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { MessageInitShape } from "@bufbuild/protobuf";
|
|
2
|
+
import { type Side as SideMessage, type SideSchema, type WatchResponse } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
|
+
import type { Side, WorkspaceEvent } from "./types.js";
|
|
4
|
+
export declare function sideProto(side: Side): MessageInitShape<typeof SideSchema>;
|
|
5
|
+
export declare function toSide(side: SideMessage | undefined): Side;
|
|
6
|
+
export declare function toEvent(event: WatchResponse): WorkspaceEvent;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
2
|
+
import { WatchResponse_Kind, } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
|
+
export function sideProto(side) {
|
|
4
|
+
return "workspace" in side
|
|
5
|
+
? { of: { case: "workspace", value: side.workspace } }
|
|
6
|
+
: { of: { case: "branch", value: side.branch } };
|
|
7
|
+
}
|
|
8
|
+
export function toSide(side) {
|
|
9
|
+
return side?.of.case === "workspace" ? { workspace: side.of.value } : { branch: side?.of.value ?? "" };
|
|
10
|
+
}
|
|
11
|
+
export function toEvent(event) {
|
|
12
|
+
return {
|
|
13
|
+
kind: eventKind(event.kind),
|
|
14
|
+
path: event.path,
|
|
15
|
+
time: event.time ? timestampDate(event.time) : new Date(0),
|
|
16
|
+
branch: event.branch,
|
|
17
|
+
detail: event.detail,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function eventKind(kind) {
|
|
21
|
+
switch (kind) {
|
|
22
|
+
case WatchResponse_Kind.MADE:
|
|
23
|
+
return "made";
|
|
24
|
+
case WatchResponse_Kind.PUBLISHED:
|
|
25
|
+
return "published";
|
|
26
|
+
case WatchResponse_Kind.REFUSED:
|
|
27
|
+
return "refused";
|
|
28
|
+
case WatchResponse_Kind.REMOVED:
|
|
29
|
+
return "removed";
|
|
30
|
+
default:
|
|
31
|
+
return "changed";
|
|
32
|
+
}
|
|
33
|
+
}
|
package/dist/convert.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MessageInitShape } from "@bufbuild/protobuf";
|
|
2
|
-
import { ProbeResponse_Access, Strategy, type AuditEntry as AuditEntryMessage, type PublishedRepository as PublishedRepositoryMessage, type RevisionSchema, type WorkspaceResult } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
|
-
import type { AuditEntry, Probe, PublishedRepository, StrategyName, Workspace } from "./types.js";
|
|
2
|
+
import { ProbeResponse_Access, Strategy, type AuditEntry as AuditEntryMessage, type ChangedFile as ChangedFileMessage, type ChangesResponse, type PublishResponse, type PublishedRepository as PublishedRepositoryMessage, type RevisionSchema, type WorkspaceResult } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
|
+
import type { AuditEntry, ChangedFile, Changes, Probe, Published, PublishedRepository, StrategyName, Workspace } from "./types.js";
|
|
4
4
|
export declare function toWorkspace(path: string, result: WorkspaceResult): Workspace;
|
|
5
5
|
export declare function strategyName(strategy: Strategy): StrategyName;
|
|
6
6
|
export declare function strategyProto(name?: StrategyName): Strategy;
|
|
@@ -9,4 +9,8 @@ export declare function accessName(access: ProbeResponse_Access): Probe["access"
|
|
|
9
9
|
export declare function revisionOf(branch?: string, commit?: string): MessageInitShape<typeof RevisionSchema> | undefined;
|
|
10
10
|
/** What a publish pushed: the workspace's repository first, then each submodule. */
|
|
11
11
|
export declare function pushedOf(repository: PublishedRepositoryMessage | undefined, submodules: PublishedRepositoryMessage[]): PublishedRepository[];
|
|
12
|
+
/** What a publish pushed, and the pull request it opened or why it could not. */
|
|
13
|
+
export declare function publishedOf(answer: PublishResponse): Published;
|
|
12
14
|
export declare function toAuditEntry(entry: AuditEntryMessage): AuditEntry;
|
|
15
|
+
export declare function toChanges(answer: ChangesResponse): Changes;
|
|
16
|
+
export declare function toChangedFiles(files: ChangedFileMessage[]): ChangedFile[];
|
package/dist/convert.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
2
|
-
import { GitFailure_Reason, ProbeResponse_Access, Strategy, } from "./gen/gitd/v1/gitd_pb.js";
|
|
2
|
+
import { ChangedFile_Kind, ConfigurationChange_Action, GitFailure_Reason, ProbeResponse_Access, Strategy, } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
3
|
export function toWorkspace(path, result) {
|
|
4
4
|
const layers = result.layers;
|
|
5
5
|
return {
|
|
@@ -7,7 +7,7 @@ export function toWorkspace(path, result) {
|
|
|
7
7
|
commit: result.commit,
|
|
8
8
|
branch: result.branch,
|
|
9
9
|
strategy: strategyName(result.strategy),
|
|
10
|
-
layers: layers && { lower: layers.lower, upper: layers.upper, work: layers.work },
|
|
10
|
+
layers: layers && { lower: layers.lower, upper: layers.upper, work: layers.work, warm: layers.warm },
|
|
11
11
|
pendingSubmodules: result.pendingSubmodules.map((submodule) => ({
|
|
12
12
|
path: submodule.path,
|
|
13
13
|
url: submodule.url,
|
|
@@ -64,17 +64,65 @@ export function pushedOf(repository, submodules) {
|
|
|
64
64
|
.filter((pushed) => pushed !== undefined)
|
|
65
65
|
.map((pushed) => ({ url: pushed.url, path: pushed.path, commit: pushed.commit, subjects: pushed.subjects }));
|
|
66
66
|
}
|
|
67
|
+
/** What a publish pushed, and the pull request it opened or why it could not. */
|
|
68
|
+
export function publishedOf(answer) {
|
|
69
|
+
return {
|
|
70
|
+
branch: answer.branch,
|
|
71
|
+
repositories: pushedOf(answer.repository, answer.submodules),
|
|
72
|
+
pullRequest: openedOf(answer.pullRequest),
|
|
73
|
+
pullRequestRefused: refusalOf(answer.pullRequestFailure),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
67
76
|
export function toAuditEntry(entry) {
|
|
68
|
-
const
|
|
77
|
+
const change = entry.change;
|
|
69
78
|
return {
|
|
70
79
|
time: entry.time ? timestampDate(entry.time) : new Date(0),
|
|
71
80
|
workspace: entry.workspace,
|
|
72
81
|
url: entry.url,
|
|
73
82
|
branch: entry.branch,
|
|
74
83
|
repositories: pushedOf(entry.repository, entry.submodules),
|
|
75
|
-
refused: refusal
|
|
76
|
-
|
|
77
|
-
|
|
84
|
+
refused: refusalOf(entry.refusal),
|
|
85
|
+
requestedBy: entry.requestedBy,
|
|
86
|
+
pullRequest: openedOf(entry.pullRequest),
|
|
87
|
+
pullRequestRefused: refusalOf(entry.pullRequestFailure),
|
|
88
|
+
provenance: entry.provenance && {
|
|
89
|
+
agent: entry.provenance.agent,
|
|
90
|
+
model: entry.provenance.model,
|
|
91
|
+
session: entry.provenance.session,
|
|
92
|
+
taskUrl: entry.provenance.taskUrl,
|
|
93
|
+
},
|
|
94
|
+
change: change && {
|
|
95
|
+
action: (ConfigurationChange_Action[change.action] ?? "").replace("ACTION_", "").toLowerCase(),
|
|
96
|
+
subject: change.subject,
|
|
97
|
+
urlPrefix: change.urlPrefix,
|
|
78
98
|
},
|
|
79
99
|
};
|
|
80
100
|
}
|
|
101
|
+
function openedOf(opened) {
|
|
102
|
+
return opened && { url: opened.url, number: Number(opened.number) };
|
|
103
|
+
}
|
|
104
|
+
function refusalOf(failure) {
|
|
105
|
+
return failure && { reason: (GitFailure_Reason[failure.reason] ?? "").replace("REASON_", ""), said: failure.gitSaid };
|
|
106
|
+
}
|
|
107
|
+
export function toChanges(answer) {
|
|
108
|
+
return { base: answer.base, fromLayer: answer.fromLayer, files: toChangedFiles(answer.files) };
|
|
109
|
+
}
|
|
110
|
+
export function toChangedFiles(files) {
|
|
111
|
+
return files.map((file) => ({
|
|
112
|
+
path: file.path,
|
|
113
|
+
kind: kindName(file.kind),
|
|
114
|
+
addedLines: file.addedLines,
|
|
115
|
+
removedLines: file.removedLines,
|
|
116
|
+
binary: file.binary,
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
function kindName(kind) {
|
|
120
|
+
switch (kind) {
|
|
121
|
+
case ChangedFile_Kind.ADDED:
|
|
122
|
+
return "added";
|
|
123
|
+
case ChangedFile_Kind.DELETED:
|
|
124
|
+
return "deleted";
|
|
125
|
+
default:
|
|
126
|
+
return "modified";
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
2
|
+
import { Connection_Kind } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
|
+
export function toKeptCredential(connection) {
|
|
4
|
+
return {
|
|
5
|
+
id: connection?.id ?? "",
|
|
6
|
+
kind: kindName(connection?.kind ?? Connection_Kind.UNSPECIFIED),
|
|
7
|
+
urlPrefix: connection?.urlPrefix ?? "",
|
|
8
|
+
actsAs: connection?.actsAs ?? "",
|
|
9
|
+
appId: Number(connection?.appId ?? 0),
|
|
10
|
+
manageUrl: connection?.manageUrl ?? "",
|
|
11
|
+
expires: connection?.expires && timestampDate(connection.expires),
|
|
12
|
+
fromFile: connection?.fromFile ?? false,
|
|
13
|
+
created: connection?.created && timestampDate(connection.created),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function kindName(kind) {
|
|
17
|
+
switch (kind) {
|
|
18
|
+
case Connection_Kind.SSH_KEY:
|
|
19
|
+
return "ssh_key";
|
|
20
|
+
case Connection_Kind.GITHUB_APP:
|
|
21
|
+
return "github_app";
|
|
22
|
+
case Connection_Kind.GITHUB_LOGIN:
|
|
23
|
+
return "github_login";
|
|
24
|
+
default:
|
|
25
|
+
return "token";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** What a credential gitd keeps is: a token, an SSH key, a GitHub App, or a person signed in. */
|
|
2
|
+
export type CredentialKind = "token" | "ssh_key" | "github_app" | "github_login";
|
|
3
|
+
/** One credential gitd keeps, never its secret. */
|
|
4
|
+
export interface KeptCredential {
|
|
5
|
+
/** What to remove it by. */
|
|
6
|
+
id: string;
|
|
7
|
+
kind: CredentialKind;
|
|
8
|
+
/** The repositories it opens: those whose address starts with this. */
|
|
9
|
+
urlPrefix: string;
|
|
10
|
+
/** Whom it acts as: an App's bot (`acme-agents[bot]`) or a person. */
|
|
11
|
+
actsAs: string;
|
|
12
|
+
appId: number;
|
|
13
|
+
/** Where an App's installations are managed. */
|
|
14
|
+
manageUrl: string;
|
|
15
|
+
/** When a sign-in stops renewing. */
|
|
16
|
+
expires?: Date;
|
|
17
|
+
/** Declared in gitd.toml: shown, never changed through the API. */
|
|
18
|
+
fromFile: boolean;
|
|
19
|
+
created?: Date;
|
|
20
|
+
}
|
|
21
|
+
/** A GitHub App or sign-in gitd now keeps, and where it is installed on repositories. */
|
|
22
|
+
export interface Connected {
|
|
23
|
+
credential: KeptCredential;
|
|
24
|
+
installUrl: string;
|
|
25
|
+
}
|
|
26
|
+
/** What a browser posts to GitHub to create an App: `manifest`, as a form field, to `formAction`. */
|
|
27
|
+
export interface AppToCreate {
|
|
28
|
+
formAction: string;
|
|
29
|
+
manifest: string;
|
|
30
|
+
/** Sent back by GitHub with the code, for completeGitHubApp. */
|
|
31
|
+
state: string;
|
|
32
|
+
}
|
|
33
|
+
/** A sign-in waiting for a person to enter `userCode` at `verificationUrl`. */
|
|
34
|
+
export interface SignIn {
|
|
35
|
+
userCode: string;
|
|
36
|
+
verificationUrl: string;
|
|
37
|
+
loginId: string;
|
|
38
|
+
expiresInSeconds: number;
|
|
39
|
+
}
|
|
40
|
+
export interface BeginGitHubAppOptions {
|
|
41
|
+
/** The App's name on GitHub; its bot is `<name>[bot]`. */
|
|
42
|
+
name: string;
|
|
43
|
+
/** Where GitHub sends the person back with a code and the state. */
|
|
44
|
+
redirectUrl: string;
|
|
45
|
+
/** The organisation that owns it; default: the person creating it. */
|
|
46
|
+
organization?: string;
|
|
47
|
+
/** A GitHub Enterprise Server's host; default github.com. */
|
|
48
|
+
host?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface AddGitHubAppOptions {
|
|
51
|
+
appId: number;
|
|
52
|
+
/** The App's private key, in PEM. */
|
|
53
|
+
privateKey: string;
|
|
54
|
+
host?: string;
|
|
55
|
+
/** The repositories it opens; default every one on the host. */
|
|
56
|
+
urlPrefix?: string;
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Client } from "@connectrpc/connect";
|
|
2
|
+
import type { ConnectionService } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
|
+
import type { AddGitHubAppOptions, AppToCreate, BeginGitHubAppOptions, Connected, KeptCredential, SignIn } from "./credential-types.js";
|
|
4
|
+
/**
|
|
5
|
+
* The credentials gitd keeps, as `gitd.credentials`: for a platform's own pages, never for
|
|
6
|
+
* an agent.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Credentials {
|
|
9
|
+
private readonly connections;
|
|
10
|
+
constructor(connections: Client<typeof ConnectionService>);
|
|
11
|
+
/** Every credential gitd keeps, gitd.toml's included, never a secret. */
|
|
12
|
+
list(): Promise<KeptCredential[]>;
|
|
13
|
+
/** Forgets a credential kept through the API. */
|
|
14
|
+
remove(id: string): Promise<void>;
|
|
15
|
+
/** Keeps a token for the repositories under urlPrefix, which names the host. */
|
|
16
|
+
addToken(urlPrefix: string, token: string, user?: string): Promise<KeptCredential>;
|
|
17
|
+
/** Keeps a GitHub App a platform already has, once GitHub takes the key as its own. */
|
|
18
|
+
addGitHubApp(options: AddGitHubAppOptions): Promise<KeptCredential>;
|
|
19
|
+
/** Starts creating the organisation's own GitHub App from a manifest. */
|
|
20
|
+
beginGitHubApp(options: BeginGitHubAppOptions): Promise<AppToCreate>;
|
|
21
|
+
/** Finishes creating the App with the code and state GitHub sent back. */
|
|
22
|
+
completeGitHubApp(code: string, state: string): Promise<Connected>;
|
|
23
|
+
/** Asks GitHub for the code a person enters to sign in through gitd's public App. */
|
|
24
|
+
startGitHubLogin(host?: string): Promise<SignIn>;
|
|
25
|
+
/** Waits until the person has entered the code, and keeps the sign-in. */
|
|
26
|
+
finishGitHubLogin(loginId: string): Promise<Connected>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { call } from "./calls.js";
|
|
2
|
+
import { toKeptCredential } from "./credential-convert.js";
|
|
3
|
+
/**
|
|
4
|
+
* The credentials gitd keeps, as `gitd.credentials`: for a platform's own pages, never for
|
|
5
|
+
* an agent.
|
|
6
|
+
*/
|
|
7
|
+
export class Credentials {
|
|
8
|
+
connections;
|
|
9
|
+
constructor(connections) {
|
|
10
|
+
this.connections = connections;
|
|
11
|
+
}
|
|
12
|
+
/** Every credential gitd keeps, gitd.toml's included, never a secret. */
|
|
13
|
+
async list() {
|
|
14
|
+
const answer = await call(() => this.connections.listConnections({}));
|
|
15
|
+
return answer.connections.map(toKeptCredential);
|
|
16
|
+
}
|
|
17
|
+
/** Forgets a credential kept through the API. */
|
|
18
|
+
async remove(id) {
|
|
19
|
+
await call(() => this.connections.removeConnection({ id }));
|
|
20
|
+
}
|
|
21
|
+
/** Keeps a token for the repositories under urlPrefix, which names the host. */
|
|
22
|
+
async addToken(urlPrefix, token, user = "") {
|
|
23
|
+
const answer = await call(() => this.connections.addToken({ urlPrefix, token, user }));
|
|
24
|
+
return toKeptCredential(answer.connection);
|
|
25
|
+
}
|
|
26
|
+
/** Keeps a GitHub App a platform already has, once GitHub takes the key as its own. */
|
|
27
|
+
async addGitHubApp(options) {
|
|
28
|
+
const answer = await call(() => this.connections.addGitHubApp({
|
|
29
|
+
appId: BigInt(options.appId),
|
|
30
|
+
privateKey: options.privateKey,
|
|
31
|
+
host: options.host ?? "",
|
|
32
|
+
urlPrefix: options.urlPrefix ?? "",
|
|
33
|
+
}));
|
|
34
|
+
return toKeptCredential(answer.connection);
|
|
35
|
+
}
|
|
36
|
+
/** Starts creating the organisation's own GitHub App from a manifest. */
|
|
37
|
+
async beginGitHubApp(options) {
|
|
38
|
+
const answer = await call(() => this.connections.beginGitHubApp({
|
|
39
|
+
name: options.name,
|
|
40
|
+
redirectUrl: options.redirectUrl,
|
|
41
|
+
organization: options.organization ?? "",
|
|
42
|
+
host: options.host ?? "",
|
|
43
|
+
}));
|
|
44
|
+
return { formAction: answer.formAction, manifest: answer.manifest, state: answer.state };
|
|
45
|
+
}
|
|
46
|
+
/** Finishes creating the App with the code and state GitHub sent back. */
|
|
47
|
+
async completeGitHubApp(code, state) {
|
|
48
|
+
const answer = await call(() => this.connections.completeGitHubApp({ code, state }));
|
|
49
|
+
return { credential: toKeptCredential(answer.connection), installUrl: answer.installUrl };
|
|
50
|
+
}
|
|
51
|
+
/** Asks GitHub for the code a person enters to sign in through gitd's public App. */
|
|
52
|
+
async startGitHubLogin(host = "") {
|
|
53
|
+
const answer = await call(() => this.connections.startGitHubLogin({ host }));
|
|
54
|
+
return {
|
|
55
|
+
userCode: answer.userCode,
|
|
56
|
+
verificationUrl: answer.verificationUrl,
|
|
57
|
+
loginId: answer.loginId,
|
|
58
|
+
expiresInSeconds: answer.expiresInSeconds,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Waits until the person has entered the code, and keeps the sign-in. */
|
|
62
|
+
async finishGitHubLogin(loginId) {
|
|
63
|
+
const answer = await call(() => this.connections.finishGitHubLogin({ loginId }));
|
|
64
|
+
return { credential: toKeptCredential(answer.connection), installUrl: answer.installUrl };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** A token of gitd's endpoint as gitd shows it, never its secret. */
|
|
2
|
+
export interface TokenInfo {
|
|
3
|
+
id: string;
|
|
4
|
+
/** The repository it reads. */
|
|
5
|
+
url: string;
|
|
6
|
+
/** The sandbox repository it pushes to, when writable. */
|
|
7
|
+
sandbox: string;
|
|
8
|
+
writable: boolean;
|
|
9
|
+
issuedAt: Date;
|
|
10
|
+
expiresAt: Date;
|
|
11
|
+
}
|
|
12
|
+
/** A token just issued: its secret, shown this once, and where the sandbox clones from. */
|
|
13
|
+
export interface IssuedToken {
|
|
14
|
+
secret: string;
|
|
15
|
+
cloneUrl: string;
|
|
16
|
+
/** The clone URL with the secret in it, for the sandbox's git: `git clone <this>`. */
|
|
17
|
+
authenticatedUrl: string;
|
|
18
|
+
info: TokenInfo;
|
|
19
|
+
}
|
|
20
|
+
export interface IssueTokenOptions {
|
|
21
|
+
/** The branch the sandbox starts from; default the repository's default branch. */
|
|
22
|
+
branch?: string;
|
|
23
|
+
/** How long the token lives, in seconds: an hour by default, a day at most. */
|
|
24
|
+
lifetimeSeconds?: number;
|
|
25
|
+
readOnly?: boolean;
|
|
26
|
+
/** A sandbox repository from an earlier token, to keep pushing to. */
|
|
27
|
+
sandbox?: string;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Client } from "@connectrpc/connect";
|
|
2
|
+
import type { EndpointService } from "./gen/gitd/v1/gitd_pb.js";
|
|
3
|
+
import type { IssuedToken, IssueTokenOptions, TokenInfo } from "./endpoint-types.js";
|
|
4
|
+
/**
|
|
5
|
+
* gitd's endpoint, as `gitd.endpoint`: tokens for sandboxes that clone over HTTP instead of
|
|
6
|
+
* mounting a workspace. What a sandbox pushes is published with `gitd.publish("", branch,
|
|
7
|
+
* { sandbox })`.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Endpoint {
|
|
10
|
+
private readonly endpoint;
|
|
11
|
+
constructor(endpoint: Client<typeof EndpointService>);
|
|
12
|
+
/** A token for a sandbox: it reads url and pushes to its own sandbox repository. */
|
|
13
|
+
issue(url: string, options?: IssueTokenOptions): Promise<IssuedToken>;
|
|
14
|
+
/** Ends a token now, and removes its sandbox repository when asked. */
|
|
15
|
+
revoke(id: string, removeSandbox?: boolean): Promise<void>;
|
|
16
|
+
/** The tokens alive, never their secrets. */
|
|
17
|
+
tokens(): Promise<TokenInfo[]>;
|
|
18
|
+
}
|
package/dist/endpoint.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
|
2
|
+
import { call } from "./calls.js";
|
|
3
|
+
/**
|
|
4
|
+
* gitd's endpoint, as `gitd.endpoint`: tokens for sandboxes that clone over HTTP instead of
|
|
5
|
+
* mounting a workspace. What a sandbox pushes is published with `gitd.publish("", branch,
|
|
6
|
+
* { sandbox })`.
|
|
7
|
+
*/
|
|
8
|
+
export class Endpoint {
|
|
9
|
+
endpoint;
|
|
10
|
+
constructor(endpoint) {
|
|
11
|
+
this.endpoint = endpoint;
|
|
12
|
+
}
|
|
13
|
+
/** A token for a sandbox: it reads url and pushes to its own sandbox repository. */
|
|
14
|
+
async issue(url, options = {}) {
|
|
15
|
+
const answer = await call(() => this.endpoint.issueToken({
|
|
16
|
+
url,
|
|
17
|
+
branch: options.branch ?? "",
|
|
18
|
+
lifetimeSeconds: BigInt(options.lifetimeSeconds ?? 0),
|
|
19
|
+
readOnly: options.readOnly ?? false,
|
|
20
|
+
sandbox: options.sandbox ?? "",
|
|
21
|
+
}));
|
|
22
|
+
const [scheme, rest] = answer.cloneUrl.split("://", 2);
|
|
23
|
+
return {
|
|
24
|
+
secret: answer.token,
|
|
25
|
+
cloneUrl: answer.cloneUrl,
|
|
26
|
+
authenticatedUrl: rest ? `${scheme}://x:${answer.token}@${rest}` : answer.cloneUrl,
|
|
27
|
+
info: toTokenInfo(answer.info),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Ends a token now, and removes its sandbox repository when asked. */
|
|
31
|
+
async revoke(id, removeSandbox = false) {
|
|
32
|
+
await call(() => this.endpoint.revokeToken({ id, removeSandbox }));
|
|
33
|
+
}
|
|
34
|
+
/** The tokens alive, never their secrets. */
|
|
35
|
+
async tokens() {
|
|
36
|
+
const answer = await call(() => this.endpoint.listTokens({}));
|
|
37
|
+
return answer.tokens.map(toTokenInfo);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function toTokenInfo(info) {
|
|
41
|
+
return {
|
|
42
|
+
id: info?.id ?? "",
|
|
43
|
+
url: info?.url ?? "",
|
|
44
|
+
sandbox: info?.sandbox ?? "",
|
|
45
|
+
writable: info?.writable ?? false,
|
|
46
|
+
issuedAt: info?.issuedAt ? timestampDate(info.issuedAt) : new Date(0),
|
|
47
|
+
expiresAt: info?.expiresAt ? timestampDate(info.expiresAt) : new Date(0),
|
|
48
|
+
};
|
|
49
|
+
}
|