@myapihq/sdk 2.4.0 → 2.4.2
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/client.d.ts +23 -2
- package/dist/client.js +174 -22
- package/dist/crm.d.ts +2 -0
- package/dist/crm.js +15 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +11 -0
- package/package.json +11 -2
- package/scripts/scaffold-sdk.js +0 -501
- package/src/audience.ts +0 -162
- package/src/auth.ts +0 -161
- package/src/client.ts +0 -121
- package/src/company.ts +0 -48
- package/src/config.ts +0 -39
- package/src/container.ts +0 -187
- package/src/crm.ts +0 -239
- package/src/database.ts +0 -106
- package/src/domain.ts +0 -246
- package/src/email.ts +0 -247
- package/src/exposes.ts +0 -16
- package/src/function.ts +0 -141
- package/src/funds.ts +0 -66
- package/src/funnel.ts +0 -203
- package/src/git.ts +0 -171
- package/src/hq.ts +0 -393
- package/src/image.ts +0 -67
- package/src/index.ts +0 -32
- package/src/llm.ts +0 -189
- package/src/payments.ts +0 -98
- package/src/people.ts +0 -84
- package/src/pixel.ts +0 -80
- package/src/queue.ts +0 -115
- package/src/services.ts +0 -323
- package/src/storage.ts +0 -80
- package/src/task.ts +0 -198
- package/src/types.ts +0 -15
- package/src/url.ts +0 -18
- package/src/webhook.ts +0 -88
- package/src/workflow.ts +0 -162
- package/tsconfig.json +0 -14
package/src/funnel.ts
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { request, MyApiError } from './client';
|
|
2
|
-
import { ApiResponse } from './types';
|
|
3
|
-
import { FUNNEL_BASE as BASE_URL } from './config';
|
|
4
|
-
import type { Exposes } from './exposes';
|
|
5
|
-
|
|
6
|
-
export const EXPOSES: Exposes = [
|
|
7
|
-
'POST /funnel/orgs/{org_id}/funnels',
|
|
8
|
-
'GET /funnel/orgs/{org_id}/funnels',
|
|
9
|
-
'GET /funnel/orgs/{org_id}/funnels/{funnel_id}',
|
|
10
|
-
'DELETE /funnel/orgs/{org_id}/funnels/{funnel_id}',
|
|
11
|
-
'POST /funnel/orgs/{org_id}/funnels/{funnel_id}/push-page',
|
|
12
|
-
'POST /funnel/orgs/{org_id}/funnels/{funnel_id}/verify',
|
|
13
|
-
'GET /funnel/orgs/{org_id}/funnels/{funnel_id}/pages',
|
|
14
|
-
'POST /funnel/orgs/{org_id}/funnels/{funnel_id}/files',
|
|
15
|
-
// Backend (2026-06-03): canonical funnel-form proxy lands per-slug
|
|
16
|
-
// bindings — destination (webhook/workflow), fields, honeypot, rate
|
|
17
|
-
// limit. See docs/cross-repo-prompts/cli-funnel-form-canonical-followup-2026-06-04.md.
|
|
18
|
-
'POST /funnel/orgs/{org_id}/funnels/{funnel_id}/forms',
|
|
19
|
-
'GET /funnel/orgs/{org_id}/funnels/{funnel_id}/forms',
|
|
20
|
-
'DELETE /funnel/orgs/{org_id}/funnels/{funnel_id}/forms/{slug}',
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
export interface Funnel {
|
|
24
|
-
id: string;
|
|
25
|
-
org_id: string;
|
|
26
|
-
// Backend (2026-05-15): POST /funnels now accepts optional `name`. Defaults
|
|
27
|
-
// to the org's preview_subdomain for back-compat. Get / list responses
|
|
28
|
-
// include it when set.
|
|
29
|
-
name?: string;
|
|
30
|
-
// Backend (2026-06-03): every funnel auto-provisions a webhook_endpoints
|
|
31
|
-
// row at create. Submissions to `/submit/{slug}` without a per-slug
|
|
32
|
-
// binding fall through to this webhook. Optional only because legacy
|
|
33
|
-
// funnels migrated by the boot job may be briefly null.
|
|
34
|
-
org_webhook_id?: string;
|
|
35
|
-
created_at: string;
|
|
36
|
-
updated_at: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Per-slug binding from `POST /funnel/.../forms`. Backend resolves a
|
|
40
|
-
// submission's destination at submit time: per-slug binding wins, then
|
|
41
|
-
// `Funnel.org_webhook_id`, else `NO_DESTINATION`.
|
|
42
|
-
export interface FormFieldSpec {
|
|
43
|
-
name: string;
|
|
44
|
-
required?: boolean;
|
|
45
|
-
oneof?: string[];
|
|
46
|
-
max_length?: number;
|
|
47
|
-
regex?: string;
|
|
48
|
-
}
|
|
49
|
-
export interface FormBinding {
|
|
50
|
-
slug: string;
|
|
51
|
-
// "<kind>:<uuid>" — kind is "webhook" or "workflow".
|
|
52
|
-
destination: string;
|
|
53
|
-
fields?: FormFieldSpec[];
|
|
54
|
-
honeypot_field?: string;
|
|
55
|
-
rate_limit?: { per_minute: number };
|
|
56
|
-
}
|
|
57
|
-
export interface CreateFunnelResponse { funnel: Funnel; subdomain_url?: string; domain_url?: string }
|
|
58
|
-
// Same envelope shape on read — kept as its own name so call sites read
|
|
59
|
-
// honestly. Wire shape is `{funnel: {...}, subdomain_url?, domain_url?}`.
|
|
60
|
-
export interface GetFunnelResponse { funnel: Funnel; subdomain_url?: string; domain_url?: string }
|
|
61
|
-
export interface VerifyResult {
|
|
62
|
-
pages?: Array<{ slug: string; tests: VerifyTest[] }>;
|
|
63
|
-
tests?: VerifyTest[];
|
|
64
|
-
}
|
|
65
|
-
export interface VerifyTest { type: 'link' | 'image' | 'webhook'; url: string; passed: boolean; details: string }
|
|
66
|
-
|
|
67
|
-
export async function createFunnel(apiKey: string, orgId: string, opts?: { name?: string }): Promise<CreateFunnelResponse> {
|
|
68
|
-
// v2: accept optional name for N-funnels-per-org. Backend rejects names
|
|
69
|
-
// matching the reserved-suffix rules; agent should pre-validate.
|
|
70
|
-
return request('POST', `${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels`, apiKey, opts?.name ? { name: opts.name } : {});
|
|
71
|
-
}
|
|
72
|
-
export async function getFunnel(apiKey: string, orgId: string, funnelId: string): Promise<GetFunnelResponse> {
|
|
73
|
-
// Backend has wrapped GET responses since 2026-04 (`{funnel, subdomain_url, domain_url}`).
|
|
74
|
-
// Older builds returned a flat Funnel — normalize to the envelope so
|
|
75
|
-
// callers can rely on the typed shape.
|
|
76
|
-
const raw = await request<GetFunnelResponse | Funnel>(
|
|
77
|
-
'GET',
|
|
78
|
-
`${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}`,
|
|
79
|
-
apiKey,
|
|
80
|
-
);
|
|
81
|
-
if (raw && typeof raw === 'object' && 'funnel' in raw && (raw as GetFunnelResponse).funnel) {
|
|
82
|
-
return raw as GetFunnelResponse;
|
|
83
|
-
}
|
|
84
|
-
return { funnel: raw as Funnel };
|
|
85
|
-
}
|
|
86
|
-
export async function listFunnels(apiKey: string, orgId: string): Promise<Funnel[]> {
|
|
87
|
-
return request('GET', `${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels`, apiKey);
|
|
88
|
-
}
|
|
89
|
-
export async function deleteFunnel(apiKey: string, orgId: string, funnelId: string): Promise<void> {
|
|
90
|
-
return request('DELETE', `${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}`, apiKey);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export async function pushFunnelPage(apiKey: string, orgId: string, funnelId: string, payload: { slug: string; html: string }): Promise<{ url: string }> {
|
|
94
|
-
return request('POST', `${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}/push-page`, apiKey, payload);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export interface FunnelPage {
|
|
98
|
-
slug: string;
|
|
99
|
-
url?: string;
|
|
100
|
-
published_at?: string;
|
|
101
|
-
updated_at?: string;
|
|
102
|
-
// Backend may include other fields; we type the common ones and let the
|
|
103
|
-
// rest pass through for printJson() / printTable() consumers.
|
|
104
|
-
[key: string]: unknown;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export async function listFunnelPages(apiKey: string, orgId: string, funnelId: string): Promise<FunnelPage[]> {
|
|
108
|
-
// Backend returns `{ pages: [...] }` for this endpoint (every other list
|
|
109
|
-
// endpoint returns a flat array). Unwrap so the SDK's contract matches the
|
|
110
|
-
// rest — callers expect an array.
|
|
111
|
-
const res = await request<{ pages?: FunnelPage[] } | FunnelPage[]>(
|
|
112
|
-
'GET',
|
|
113
|
-
`${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}/pages`,
|
|
114
|
-
apiKey,
|
|
115
|
-
);
|
|
116
|
-
if (Array.isArray(res)) return res;
|
|
117
|
-
return res?.pages ?? [];
|
|
118
|
-
}
|
|
119
|
-
export async function verifyFunnel(apiKey: string, orgId: string, funnelId: string, opts?: { html?: string; slug?: string }): Promise<VerifyResult> {
|
|
120
|
-
return request('POST', `${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}/verify`, apiKey, opts || {});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// One file in a directory publish: `path` is the path within the site
|
|
124
|
-
// (e.g. "index.html", "assets/app.js"); the backend roots it ("/index.html").
|
|
125
|
-
export interface PublishFile {
|
|
126
|
-
path: string;
|
|
127
|
-
content: Blob | Buffer | string;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export interface PublishOptions {
|
|
131
|
-
// 'dev' or 'prod' channel — defaults to 'prod' server-side.
|
|
132
|
-
env?: 'dev' | 'prod';
|
|
133
|
-
// Force SPA fallback. Auto-true server-side when an index.html is present.
|
|
134
|
-
spaMode?: boolean;
|
|
135
|
-
// Bind /api/* on the funnel to a deployed function.
|
|
136
|
-
apiFunctionId?: string;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export interface PublishResult {
|
|
140
|
-
manifest_id: string;
|
|
141
|
-
channel: 'dev' | 'prod';
|
|
142
|
-
file_count: number;
|
|
143
|
-
size_bytes: number;
|
|
144
|
-
spa_mode: boolean;
|
|
145
|
-
published_url: string;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// publishFiles is the my-funnel-api v2 directory publish. Every file is a
|
|
149
|
-
// multipart part named `files`; the part's filename carries the site path.
|
|
150
|
-
// 25MB total cap server-side.
|
|
151
|
-
export async function publishFiles(
|
|
152
|
-
apiKey: string,
|
|
153
|
-
orgId: string,
|
|
154
|
-
funnelId: string,
|
|
155
|
-
files: PublishFile[],
|
|
156
|
-
opts: PublishOptions = {},
|
|
157
|
-
): Promise<PublishResult> {
|
|
158
|
-
const formData = new FormData();
|
|
159
|
-
for (const f of files) {
|
|
160
|
-
formData.append('files', new Blob([f.content as any]), f.path);
|
|
161
|
-
}
|
|
162
|
-
if (opts.env) formData.append('env', opts.env);
|
|
163
|
-
if (opts.spaMode !== undefined) formData.append('spa_mode', String(opts.spaMode));
|
|
164
|
-
if (opts.apiFunctionId) formData.append('api_function_id', opts.apiFunctionId);
|
|
165
|
-
|
|
166
|
-
const response = await fetch(
|
|
167
|
-
`${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}/files`,
|
|
168
|
-
{ method: 'POST', headers: { Authorization: `Bearer ${apiKey}` }, body: formData as any },
|
|
169
|
-
);
|
|
170
|
-
|
|
171
|
-
let result: any;
|
|
172
|
-
try {
|
|
173
|
-
result = await response.json();
|
|
174
|
-
} catch {
|
|
175
|
-
throw new MyApiError('invalid_json_response', response.status);
|
|
176
|
-
}
|
|
177
|
-
if (!response.ok || !result?.success) {
|
|
178
|
-
const err = result?.error;
|
|
179
|
-
const code = typeof err === 'object' ? (err?.code || 'unknown_error') : (err || 'unknown_error');
|
|
180
|
-
const detail = typeof err === 'object' ? err?.message : undefined;
|
|
181
|
-
throw new MyApiError(code, response.status, detail, typeof err === 'object' ? err : undefined);
|
|
182
|
-
}
|
|
183
|
-
return (result as ApiResponse<PublishResult>).data as PublishResult;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// ── Form bindings (canonical funnel-form proxy) ────────────────────────────
|
|
187
|
-
|
|
188
|
-
function formsBase(orgId: string, funnelId: string): string {
|
|
189
|
-
return `${BASE_URL}/funnel/orgs/${encodeURIComponent(orgId)}/funnels/${encodeURIComponent(funnelId)}/forms`;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export async function createFormBinding(apiKey: string, orgId: string, funnelId: string, binding: FormBinding): Promise<FormBinding> {
|
|
193
|
-
return request('POST', formsBase(orgId, funnelId), apiKey, binding);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export async function listFormBindings(apiKey: string, orgId: string, funnelId: string): Promise<FormBinding[]> {
|
|
197
|
-
const res = await request<FormBinding[] | { forms?: FormBinding[] }>('GET', formsBase(orgId, funnelId), apiKey);
|
|
198
|
-
return Array.isArray(res) ? res : (res?.forms ?? []);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
export async function deleteFormBinding(apiKey: string, orgId: string, funnelId: string, slug: string): Promise<void> {
|
|
202
|
-
return request('DELETE', `${formsBase(orgId, funnelId)}/${encodeURIComponent(slug)}`, apiKey);
|
|
203
|
-
}
|
package/src/git.ts
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { request } from './client';
|
|
2
|
-
import { GIT_BASE as BASE_URL } from './config';
|
|
3
|
-
import type { Exposes } from './exposes';
|
|
4
|
-
|
|
5
|
-
// Backend: my-git-api per myapi-hq/internal/routes/git/. A stateless
|
|
6
|
-
// git-over-HTTP surface — repositories, refs, commits, and history served
|
|
7
|
-
// by a go-git engine (objects in GCS packfiles, refs in Postgres).
|
|
8
|
-
export const EXPOSES: Exposes = [
|
|
9
|
-
'POST /git/orgs/{org_id}/repos',
|
|
10
|
-
'GET /git/orgs/{org_id}/repos',
|
|
11
|
-
'GET /git/orgs/{org_id}/repos/{repo}',
|
|
12
|
-
'DELETE /git/orgs/{org_id}/repos/{repo}',
|
|
13
|
-
'GET /git/orgs/{org_id}/repos/{repo}/refs',
|
|
14
|
-
'GET /git/orgs/{org_id}/repos/{repo}/tree/{ref}',
|
|
15
|
-
'GET /git/orgs/{org_id}/repos/{repo}/blob/{ref}/{path}',
|
|
16
|
-
'GET /git/orgs/{org_id}/repos/{repo}/commits',
|
|
17
|
-
'GET /git/orgs/{org_id}/repos/{repo}/commits/{sha}',
|
|
18
|
-
'GET /git/orgs/{org_id}/repos/{repo}/diff',
|
|
19
|
-
'POST /git/orgs/{org_id}/repos/{repo}/commits',
|
|
20
|
-
'POST /git/orgs/{org_id}/repos/{repo}/branches',
|
|
21
|
-
'DELETE /git/orgs/{org_id}/repos/{repo}/branches/{branch}',
|
|
22
|
-
'POST /git/orgs/{org_id}/repos/{repo}/tags',
|
|
23
|
-
'POST /git/orgs/{org_id}/repos/{repo}/merges',
|
|
24
|
-
'POST /git/orgs/{org_id}/repos/{repo}/repack',
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
export interface RepoSummary { name: string }
|
|
28
|
-
export interface Repo {
|
|
29
|
-
name: string;
|
|
30
|
-
default_branch: string;
|
|
31
|
-
branches: number;
|
|
32
|
-
tags: number;
|
|
33
|
-
}
|
|
34
|
-
export interface RefInfo { name: string; sha: string }
|
|
35
|
-
export interface Refs {
|
|
36
|
-
head: string; // symbolic HEAD target, e.g. "refs/heads/main"
|
|
37
|
-
branches: RefInfo[];
|
|
38
|
-
tags: RefInfo[];
|
|
39
|
-
}
|
|
40
|
-
export interface TreeEntry {
|
|
41
|
-
name: string;
|
|
42
|
-
path: string;
|
|
43
|
-
type: 'file' | 'dir';
|
|
44
|
-
mode: string;
|
|
45
|
-
sha: string;
|
|
46
|
-
size: number;
|
|
47
|
-
}
|
|
48
|
-
export interface CommitInfo {
|
|
49
|
-
sha: string;
|
|
50
|
-
message: string;
|
|
51
|
-
author: string;
|
|
52
|
-
email: string;
|
|
53
|
-
when: string;
|
|
54
|
-
parents: string[];
|
|
55
|
-
}
|
|
56
|
-
export interface CommitResult { sha: string; tree: string; branch: string }
|
|
57
|
-
export interface RepackResult { packs_before: number; packs_after: number; objects: number }
|
|
58
|
-
export interface Blob { path: string; size: number; content_base64: string }
|
|
59
|
-
|
|
60
|
-
// One file edit in an atomic commit. Either `content` (UTF-8 text) or
|
|
61
|
-
// `content_base64` (binary); set `delete` to remove the path instead.
|
|
62
|
-
export interface FileChange {
|
|
63
|
-
path: string;
|
|
64
|
-
content?: string;
|
|
65
|
-
content_base64?: string;
|
|
66
|
-
delete?: boolean;
|
|
67
|
-
mode?: string; // "100644" (default), "100755" (exec), "120000" (symlink)
|
|
68
|
-
}
|
|
69
|
-
export interface CommitPayload {
|
|
70
|
-
branch: string; // required — short name or full ref
|
|
71
|
-
base?: string; // expected branch tip; "" => branch must not exist
|
|
72
|
-
message: string;
|
|
73
|
-
author?: { name: string; email: string };
|
|
74
|
-
changes: FileChange[];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function repoBase(orgId: string, repo: string): string {
|
|
78
|
-
return `${BASE_URL}/git/orgs/${encodeURIComponent(orgId)}/repos/${encodeURIComponent(repo)}`;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// ── Repos ────────────────────────────────────────────────────────────────────
|
|
82
|
-
|
|
83
|
-
export async function createRepo(apiKey: string, orgId: string, name: string, defaultBranch?: string): Promise<{ name: string; default_branch: string }> {
|
|
84
|
-
const body: Record<string, string> = { name };
|
|
85
|
-
if (defaultBranch) body.default_branch = defaultBranch;
|
|
86
|
-
return request('POST', `${BASE_URL}/git/orgs/${encodeURIComponent(orgId)}/repos`, apiKey, body);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export async function listRepos(apiKey: string, orgId: string): Promise<RepoSummary[]> {
|
|
90
|
-
const res = await request<{ repos?: RepoSummary[] }>('GET', `${BASE_URL}/git/orgs/${encodeURIComponent(orgId)}/repos`, apiKey);
|
|
91
|
-
return res?.repos ?? [];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export async function getRepo(apiKey: string, orgId: string, repo: string): Promise<Repo> {
|
|
95
|
-
return request('GET', repoBase(orgId, repo), apiKey);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export async function deleteRepo(apiKey: string, orgId: string, repo: string): Promise<void> {
|
|
99
|
-
return request('DELETE', repoBase(orgId, repo), apiKey);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// ── Refs / history ───────────────────────────────────────────────────────────
|
|
103
|
-
|
|
104
|
-
export async function listRefs(apiKey: string, orgId: string, repo: string): Promise<Refs> {
|
|
105
|
-
return request('GET', `${repoBase(orgId, repo)}/refs`, apiKey);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// listCommits walks history from `ref` (default HEAD); `limit` is 1-500.
|
|
109
|
-
export async function listCommits(apiKey: string, orgId: string, repo: string, opts: { ref?: string; limit?: number } = {}): Promise<CommitInfo[]> {
|
|
110
|
-
const q = new URLSearchParams();
|
|
111
|
-
if (opts.ref) q.set('ref', opts.ref);
|
|
112
|
-
if (opts.limit !== undefined) q.set('limit', String(opts.limit));
|
|
113
|
-
const qs = q.toString();
|
|
114
|
-
const res = await request<{ commits?: CommitInfo[] }>('GET', `${repoBase(orgId, repo)}/commits${qs ? `?${qs}` : ''}`, apiKey);
|
|
115
|
-
return res?.commits ?? [];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function getCommit(apiKey: string, orgId: string, repo: string, sha: string): Promise<CommitInfo> {
|
|
119
|
-
return request('GET', `${repoBase(orgId, repo)}/commits/${encodeURIComponent(sha)}`, apiKey);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// getDiff returns the unified diff text between two refs.
|
|
123
|
-
export async function getDiff(apiKey: string, orgId: string, repo: string, base: string, head: string): Promise<string> {
|
|
124
|
-
const q = new URLSearchParams({ base, head });
|
|
125
|
-
const res = await request<{ diff?: string }>('GET', `${repoBase(orgId, repo)}/diff?${q}`, apiKey);
|
|
126
|
-
return res?.diff ?? '';
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// listTree lists a ref's tree; `path` scopes it to a subdirectory.
|
|
130
|
-
export async function listTree(apiKey: string, orgId: string, repo: string, ref: string, path?: string): Promise<TreeEntry[]> {
|
|
131
|
-
const qs = path ? `?path=${encodeURIComponent(path)}` : '';
|
|
132
|
-
const res = await request<{ entries?: TreeEntry[] }>('GET', `${repoBase(orgId, repo)}/tree/${encodeURIComponent(ref)}${qs}`, apiKey);
|
|
133
|
-
return res?.entries ?? [];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// readBlob returns a file's content (base64-encoded — safe for binary).
|
|
137
|
-
export async function readBlob(apiKey: string, orgId: string, repo: string, ref: string, path: string): Promise<Blob> {
|
|
138
|
-
// The backend route is /blob/{ref}/{path...} — a catch-all — so slashes
|
|
139
|
-
// in the path must survive; encode each segment, not the separators.
|
|
140
|
-
const encPath = path.split('/').map(encodeURIComponent).join('/');
|
|
141
|
-
return request('GET', `${repoBase(orgId, repo)}/blob/${encodeURIComponent(ref)}/${encPath}`, apiKey);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// ── Writes ───────────────────────────────────────────────────────────────────
|
|
145
|
-
|
|
146
|
-
// commit applies all `changes` atomically onto `branch`.
|
|
147
|
-
export async function commit(apiKey: string, orgId: string, repo: string, payload: CommitPayload): Promise<CommitResult> {
|
|
148
|
-
return request('POST', `${repoBase(orgId, repo)}/commits`, apiKey, payload);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export async function createBranch(apiKey: string, orgId: string, repo: string, name: string, from: string): Promise<{ name: string }> {
|
|
152
|
-
return request('POST', `${repoBase(orgId, repo)}/branches`, apiKey, { name, from });
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export async function deleteBranch(apiKey: string, orgId: string, repo: string, branch: string): Promise<void> {
|
|
156
|
-
return request('DELETE', `${repoBase(orgId, repo)}/branches/${encodeURIComponent(branch)}`, apiKey);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export async function createTag(apiKey: string, orgId: string, repo: string, name: string, ref: string): Promise<{ name: string }> {
|
|
160
|
-
return request('POST', `${repoBase(orgId, repo)}/tags`, apiKey, { name, ref });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// merge fast-forwards `target` to `source` (fast-forward only).
|
|
164
|
-
export async function merge(apiKey: string, orgId: string, repo: string, target: string, source: string): Promise<{ sha: string }> {
|
|
165
|
-
return request('POST', `${repoBase(orgId, repo)}/merges`, apiKey, { target, source });
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// repack compacts the repository's incremental packfiles into one.
|
|
169
|
-
export async function repack(apiKey: string, orgId: string, repo: string): Promise<RepackResult> {
|
|
170
|
-
return request('POST', `${repoBase(orgId, repo)}/repack`, apiKey);
|
|
171
|
-
}
|