@myapihq/sdk 1.3.0 → 1.3.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/container.d.ts +9 -0
- package/dist/container.js +18 -0
- package/dist/hq.d.ts +32 -0
- package/dist/hq.js +5 -0
- package/package.json +1 -1
- package/src/container.ts +31 -0
- package/src/hq.ts +43 -0
package/dist/container.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface Container {
|
|
|
14
14
|
max_instances: number;
|
|
15
15
|
port: number;
|
|
16
16
|
url?: string;
|
|
17
|
+
custom_domain?: string;
|
|
17
18
|
status: string;
|
|
18
19
|
created_at: string;
|
|
19
20
|
updated_at: string;
|
|
@@ -52,3 +53,11 @@ export interface LogEntry {
|
|
|
52
53
|
text: string;
|
|
53
54
|
}
|
|
54
55
|
export declare function getContainerLogs(apiKey: string, orgId: string, containerId: string, tail?: number): Promise<LogEntry[]>;
|
|
56
|
+
export interface DomainBinding {
|
|
57
|
+
container_id: string;
|
|
58
|
+
custom_domain: string;
|
|
59
|
+
origin: string;
|
|
60
|
+
status: string;
|
|
61
|
+
}
|
|
62
|
+
export declare function bindDomain(apiKey: string, orgId: string, containerId: string, domain: string): Promise<DomainBinding>;
|
|
63
|
+
export declare function unbindDomain(apiKey: string, orgId: string, containerId: string): Promise<void>;
|
package/dist/container.js
CHANGED
|
@@ -7,6 +7,8 @@ exports.getContainer = getContainer;
|
|
|
7
7
|
exports.deleteContainer = deleteContainer;
|
|
8
8
|
exports.deployContainer = deployContainer;
|
|
9
9
|
exports.getContainerLogs = getContainerLogs;
|
|
10
|
+
exports.bindDomain = bindDomain;
|
|
11
|
+
exports.unbindDomain = unbindDomain;
|
|
10
12
|
const client_1 = require("./client");
|
|
11
13
|
const config_1 = require("./config");
|
|
12
14
|
// Backend: my-container-api per myapi-hq/internal/routes/container/. Phase 1
|
|
@@ -19,6 +21,8 @@ exports.EXPOSES = [
|
|
|
19
21
|
'DELETE /container/orgs/{org_id}/containers/{id}',
|
|
20
22
|
'POST /container/orgs/{org_id}/containers/{id}/deploy',
|
|
21
23
|
'GET /container/orgs/{org_id}/containers/{id}/logs',
|
|
24
|
+
'POST /container/orgs/{org_id}/containers/{id}/domain',
|
|
25
|
+
'DELETE /container/orgs/{org_id}/containers/{id}/domain',
|
|
22
26
|
];
|
|
23
27
|
async function createContainer(apiKey, orgId, payload) {
|
|
24
28
|
return (0, client_1.request)('POST', `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers`, apiKey, payload);
|
|
@@ -44,3 +48,17 @@ async function getContainerLogs(apiKey, orgId, containerId, tail) {
|
|
|
44
48
|
const query = tail ? `?tail=${encodeURIComponent(String(tail))}` : '';
|
|
45
49
|
return (0, client_1.request)('GET', `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers/${encodeURIComponent(containerId)}/logs${query}`, apiKey);
|
|
46
50
|
}
|
|
51
|
+
// bindDomain points a custom domain at a deployed container. The parent
|
|
52
|
+
// domain must be MyAPI-managed. Errors: 422 (container not deployed, or no
|
|
53
|
+
// MyAPI-managed parent domain), 409 (container already has a domain, or the
|
|
54
|
+
// hostname is taken).
|
|
55
|
+
function domainUrl(orgId, containerId) {
|
|
56
|
+
return `${config_1.CONTAINER_BASE}/container/orgs/${encodeURIComponent(orgId)}/containers/${encodeURIComponent(containerId)}/domain`;
|
|
57
|
+
}
|
|
58
|
+
async function bindDomain(apiKey, orgId, containerId, domain) {
|
|
59
|
+
return (0, client_1.request)('POST', domainUrl(orgId, containerId), apiKey, { domain });
|
|
60
|
+
}
|
|
61
|
+
// unbindDomain removes the custom domain from a container.
|
|
62
|
+
async function unbindDomain(apiKey, orgId, containerId) {
|
|
63
|
+
return (0, client_1.request)('DELETE', domainUrl(orgId, containerId), apiKey);
|
|
64
|
+
}
|
package/dist/hq.d.ts
CHANGED
|
@@ -132,3 +132,35 @@ export declare function setupPayment(apiKey: string): Promise<{
|
|
|
132
132
|
export declare function topUp(apiKey: string, amountDollars: number): Promise<{
|
|
133
133
|
new_balance_display: string;
|
|
134
134
|
}>;
|
|
135
|
+
export type DoctorSeverity = 'ok' | 'warn' | 'crit';
|
|
136
|
+
export interface DoctorEntityRef {
|
|
137
|
+
slot: string;
|
|
138
|
+
id: string;
|
|
139
|
+
name?: string;
|
|
140
|
+
}
|
|
141
|
+
export interface DoctorIssue {
|
|
142
|
+
id: string;
|
|
143
|
+
severity: DoctorSeverity;
|
|
144
|
+
scope: string;
|
|
145
|
+
entity?: DoctorEntityRef;
|
|
146
|
+
category?: string;
|
|
147
|
+
message: string;
|
|
148
|
+
hint?: string;
|
|
149
|
+
}
|
|
150
|
+
export interface DoctorSection {
|
|
151
|
+
name: string;
|
|
152
|
+
summary: string;
|
|
153
|
+
issues: DoctorIssue[];
|
|
154
|
+
}
|
|
155
|
+
export interface DoctorReport {
|
|
156
|
+
org_id: string;
|
|
157
|
+
generated_at: string;
|
|
158
|
+
cache_ttl_seconds?: number;
|
|
159
|
+
sections: DoctorSection[];
|
|
160
|
+
totals: {
|
|
161
|
+
ok: number;
|
|
162
|
+
warn: number;
|
|
163
|
+
crit: number;
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
export declare function getDoctor(apiKey: string, orgId: string): Promise<DoctorReport>;
|
package/dist/hq.js
CHANGED
|
@@ -25,6 +25,7 @@ exports.getBillingHistory = getBillingHistory;
|
|
|
25
25
|
exports.getBillingUsage = getBillingUsage;
|
|
26
26
|
exports.setupPayment = setupPayment;
|
|
27
27
|
exports.topUp = topUp;
|
|
28
|
+
exports.getDoctor = getDoctor;
|
|
28
29
|
const client_1 = require("./client");
|
|
29
30
|
const config_1 = require("./config");
|
|
30
31
|
exports.EXPOSES = [
|
|
@@ -52,6 +53,7 @@ exports.EXPOSES = [
|
|
|
52
53
|
'GET /hq/billing/usage',
|
|
53
54
|
'POST /hq/billing/setup-payment',
|
|
54
55
|
'POST /hq/billing/topup',
|
|
56
|
+
'GET /hq/orgs/{org_id}/doctor',
|
|
55
57
|
];
|
|
56
58
|
// The closed grantable-slot vocabulary. Mirrors `iam.GrantableSlots` in the
|
|
57
59
|
// backend — keep in sync. Used to validate `--grant` client-side before the
|
|
@@ -153,3 +155,6 @@ async function setupPayment(apiKey) {
|
|
|
153
155
|
async function topUp(apiKey, amountDollars) {
|
|
154
156
|
return (0, client_1.request)('POST', `${config_1.HQ_BASE}/hq/billing/topup`, apiKey, { amount_dollars: amountDollars });
|
|
155
157
|
}
|
|
158
|
+
async function getDoctor(apiKey, orgId) {
|
|
159
|
+
return (0, client_1.request)('GET', `${config_1.HQ_BASE}/hq/orgs/${encodeURIComponent(orgId)}/doctor`, apiKey);
|
|
160
|
+
}
|
package/package.json
CHANGED
package/src/container.ts
CHANGED
|
@@ -12,6 +12,8 @@ export const EXPOSES: Exposes = [
|
|
|
12
12
|
'DELETE /container/orgs/{org_id}/containers/{id}',
|
|
13
13
|
'POST /container/orgs/{org_id}/containers/{id}/deploy',
|
|
14
14
|
'GET /container/orgs/{org_id}/containers/{id}/logs',
|
|
15
|
+
'POST /container/orgs/{org_id}/containers/{id}/domain',
|
|
16
|
+
'DELETE /container/orgs/{org_id}/containers/{id}/domain',
|
|
15
17
|
];
|
|
16
18
|
|
|
17
19
|
// service = HTTP server, worker = always-on background process, job = runs
|
|
@@ -33,6 +35,9 @@ export interface Container {
|
|
|
33
35
|
max_instances: number;
|
|
34
36
|
port: number;
|
|
35
37
|
url?: string;
|
|
38
|
+
// Custom domain bound to this container, if any. Served via a Cloudflare
|
|
39
|
+
// Origin Rule that rewrites Host + SNI to the Cloud Run hostname.
|
|
40
|
+
custom_domain?: string;
|
|
36
41
|
status: string;
|
|
37
42
|
created_at: string;
|
|
38
43
|
updated_at: string;
|
|
@@ -104,3 +109,29 @@ export async function getContainerLogs(apiKey: string, orgId: string, containerI
|
|
|
104
109
|
const query = tail ? `?tail=${encodeURIComponent(String(tail))}` : '';
|
|
105
110
|
return request('GET', `${BASE_URL}/container/orgs/${encodeURIComponent(orgId)}/containers/${encodeURIComponent(containerId)}/logs${query}`, apiKey);
|
|
106
111
|
}
|
|
112
|
+
|
|
113
|
+
// bindDomain response. `origin` is the Cloud Run hostname the custom domain
|
|
114
|
+
// is fronted onto via a Cloudflare Origin Rule (Host + SNI rewrite).
|
|
115
|
+
export interface DomainBinding {
|
|
116
|
+
container_id: string;
|
|
117
|
+
custom_domain: string;
|
|
118
|
+
origin: string;
|
|
119
|
+
status: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// bindDomain points a custom domain at a deployed container. The parent
|
|
123
|
+
// domain must be MyAPI-managed. Errors: 422 (container not deployed, or no
|
|
124
|
+
// MyAPI-managed parent domain), 409 (container already has a domain, or the
|
|
125
|
+
// hostname is taken).
|
|
126
|
+
function domainUrl(orgId: string, containerId: string): string {
|
|
127
|
+
return `${BASE_URL}/container/orgs/${encodeURIComponent(orgId)}/containers/${encodeURIComponent(containerId)}/domain`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export async function bindDomain(apiKey: string, orgId: string, containerId: string, domain: string): Promise<DomainBinding> {
|
|
131
|
+
return request('POST', domainUrl(orgId, containerId), apiKey, { domain });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// unbindDomain removes the custom domain from a container.
|
|
135
|
+
export async function unbindDomain(apiKey: string, orgId: string, containerId: string): Promise<void> {
|
|
136
|
+
return request('DELETE', domainUrl(orgId, containerId), apiKey);
|
|
137
|
+
}
|
package/src/hq.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const EXPOSES: Exposes = [
|
|
|
27
27
|
'GET /hq/billing/usage',
|
|
28
28
|
'POST /hq/billing/setup-payment',
|
|
29
29
|
'POST /hq/billing/topup',
|
|
30
|
+
'GET /hq/orgs/{org_id}/doctor',
|
|
30
31
|
];
|
|
31
32
|
|
|
32
33
|
export interface Org {
|
|
@@ -264,3 +265,45 @@ export async function setupPayment(apiKey: string): Promise<{ url: string }> {
|
|
|
264
265
|
export async function topUp(apiKey: string, amountDollars: number): Promise<{ new_balance_display: string }> {
|
|
265
266
|
return request('POST', `${BASE_URL}/hq/billing/topup`, apiKey, { amount_dollars: amountDollars });
|
|
266
267
|
}
|
|
268
|
+
|
|
269
|
+
// ── Org doctor ─────────────────────────────────────────────────────────
|
|
270
|
+
// Aggregated consistency report across slots. The endpoint resolves the
|
|
271
|
+
// reported org from the API key's binding, so the `{org_id}` path param
|
|
272
|
+
// is currently positional/cosmetic (pass your default — the response will
|
|
273
|
+
// indicate which org was actually scored under `report.org_id`).
|
|
274
|
+
|
|
275
|
+
export type DoctorSeverity = 'ok' | 'warn' | 'crit';
|
|
276
|
+
|
|
277
|
+
export interface DoctorEntityRef {
|
|
278
|
+
slot: string; // 'funnel' | 'webhook' | 'workflow' | 'container' | 'domain' | …
|
|
279
|
+
id: string;
|
|
280
|
+
name?: string;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export interface DoctorIssue {
|
|
284
|
+
id: string; // stable across runs, dedupable
|
|
285
|
+
severity: DoctorSeverity;
|
|
286
|
+
scope: string; // logical scope, e.g. 'funnel/<slug>'
|
|
287
|
+
entity?: DoctorEntityRef;
|
|
288
|
+
category?: string; // 'reference_integrity' | 'orphan' | 'activity' | 'security' | 'billing' | 'network'
|
|
289
|
+
message: string;
|
|
290
|
+
hint?: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface DoctorSection {
|
|
294
|
+
name: string;
|
|
295
|
+
summary: string;
|
|
296
|
+
issues: DoctorIssue[];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface DoctorReport {
|
|
300
|
+
org_id: string;
|
|
301
|
+
generated_at: string; // RFC3339
|
|
302
|
+
cache_ttl_seconds?: number;
|
|
303
|
+
sections: DoctorSection[];
|
|
304
|
+
totals: { ok: number; warn: number; crit: number };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export async function getDoctor(apiKey: string, orgId: string): Promise<DoctorReport> {
|
|
308
|
+
return request('GET', `${BASE_URL}/hq/orgs/${encodeURIComponent(orgId)}/doctor`, apiKey);
|
|
309
|
+
}
|