@farthershore/cli 0.3.3 → 0.3.5
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 +13 -47
- package/dist/client.js +2 -43
- package/dist/commands/apply.js +42 -35
- package/dist/types.d.ts +0 -38
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Product,
|
|
1
|
+
import type { Product, InitProductResponse } from "./types.js";
|
|
2
2
|
export declare function createClient(opts: {
|
|
3
3
|
apiUrl: string;
|
|
4
4
|
token: string;
|
|
@@ -22,23 +22,7 @@ export declare function createClient(opts: {
|
|
|
22
22
|
role: string;
|
|
23
23
|
}>;
|
|
24
24
|
}>;
|
|
25
|
-
validateToken: () => Promise<{
|
|
26
|
-
valid: boolean;
|
|
27
|
-
type: string;
|
|
28
|
-
orgId: string;
|
|
29
|
-
productId: string | null;
|
|
30
|
-
permissions: string[];
|
|
31
|
-
}>;
|
|
32
25
|
listProducts: () => Promise<Product[]>;
|
|
33
|
-
getProduct: (id: string) => Promise<Product>;
|
|
34
|
-
createProduct: (data: {
|
|
35
|
-
name: string;
|
|
36
|
-
baseUrl: string;
|
|
37
|
-
description?: string;
|
|
38
|
-
}) => Promise<Product>;
|
|
39
|
-
updateProduct: (id: string, data: Record<string, unknown>) => Promise<Product>;
|
|
40
|
-
deleteProduct: (id: string) => Promise<void>;
|
|
41
|
-
publishProduct: (id: string) => Promise<Product>;
|
|
42
26
|
initProduct: (data: {
|
|
43
27
|
name: string;
|
|
44
28
|
baseUrl?: string;
|
|
@@ -46,30 +30,6 @@ export declare function createClient(opts: {
|
|
|
46
30
|
displayName?: string;
|
|
47
31
|
billingStrategy?: string;
|
|
48
32
|
}) => Promise<InitProductResponse>;
|
|
49
|
-
listPlans: (productId: string) => Promise<Plan[]>;
|
|
50
|
-
createPlan: (productId: string, data: Record<string, unknown>) => Promise<Plan>;
|
|
51
|
-
updatePlan: (productId: string, planId: string, data: Record<string, unknown>) => Promise<Plan>;
|
|
52
|
-
deletePlan: (productId: string, planId: string) => Promise<void>;
|
|
53
|
-
exportPlanConfig: (productId: string) => Promise<string>;
|
|
54
|
-
applyPlanConfig: (productId: string, config: string, opts?: {
|
|
55
|
-
configHash?: string;
|
|
56
|
-
force?: boolean;
|
|
57
|
-
validateOnly?: boolean;
|
|
58
|
-
}) => Promise<ApplyResponse>;
|
|
59
|
-
listTokens: () => Promise<MakerToken[]>;
|
|
60
|
-
revokeToken: (id: string) => Promise<void>;
|
|
61
|
-
listMembers: (orgId: string) => Promise<OrgMember[]>;
|
|
62
|
-
inviteMember: (orgId: string, email: string, role: string) => Promise<unknown>;
|
|
63
|
-
removeMember: (orgId: string, userId: string) => Promise<void>;
|
|
64
|
-
getStripeStatus: () => Promise<{
|
|
65
|
-
connected: boolean;
|
|
66
|
-
chargesEnabled?: boolean;
|
|
67
|
-
accountId?: string;
|
|
68
|
-
}>;
|
|
69
|
-
startStripeOnboard: () => Promise<{
|
|
70
|
-
url: string;
|
|
71
|
-
}>;
|
|
72
|
-
getUsage: (productId: string) => Promise<Record<string, unknown>>;
|
|
73
33
|
compileProduct: (productId: string) => Promise<{
|
|
74
34
|
success: boolean;
|
|
75
35
|
errors?: Array<{
|
|
@@ -81,6 +41,18 @@ export declare function createClient(opts: {
|
|
|
81
41
|
message: string;
|
|
82
42
|
}>;
|
|
83
43
|
}>;
|
|
44
|
+
managementCompileSelf: () => Promise<{
|
|
45
|
+
success: boolean;
|
|
46
|
+
productId: string;
|
|
47
|
+
errors?: Array<{
|
|
48
|
+
code?: string;
|
|
49
|
+
message: string;
|
|
50
|
+
}>;
|
|
51
|
+
warnings?: Array<{
|
|
52
|
+
code?: string;
|
|
53
|
+
message: string;
|
|
54
|
+
}>;
|
|
55
|
+
}>;
|
|
84
56
|
managementCompile: (productId: string) => Promise<{
|
|
85
57
|
success: boolean;
|
|
86
58
|
errors?: Array<{
|
|
@@ -93,12 +65,6 @@ export declare function createClient(opts: {
|
|
|
93
65
|
}>;
|
|
94
66
|
}>;
|
|
95
67
|
managementListProducts: () => Promise<Product[]>;
|
|
96
|
-
whoami: () => Promise<{
|
|
97
|
-
tokenId: string;
|
|
98
|
-
organizationId: string;
|
|
99
|
-
productId: string | null;
|
|
100
|
-
scopes: string[];
|
|
101
|
-
}>;
|
|
102
68
|
isMakerToken: () => boolean;
|
|
103
69
|
};
|
|
104
70
|
export type ApiClient = ReturnType<typeof createClient>;
|
package/dist/client.js
CHANGED
|
@@ -18,60 +18,19 @@ export function createClient(opts) {
|
|
|
18
18
|
return undefined;
|
|
19
19
|
return res.json();
|
|
20
20
|
}
|
|
21
|
-
async function rawText(method, path) {
|
|
22
|
-
const res = await fetch(`${opts.apiUrl}${path}`, {
|
|
23
|
-
method,
|
|
24
|
-
headers: { Authorization: `Bearer ${opts.token}` },
|
|
25
|
-
});
|
|
26
|
-
if (!res.ok) {
|
|
27
|
-
throw new CliError(`API error: ${res.status}`, res.status);
|
|
28
|
-
}
|
|
29
|
-
return res.text();
|
|
30
|
-
}
|
|
31
21
|
return {
|
|
32
22
|
// --- Auth ---
|
|
33
23
|
bootstrap: () => request("POST", "/builder/context/bootstrap"),
|
|
34
|
-
validateToken: () => request("POST", "/auth/validate-token"),
|
|
35
24
|
// --- Products ---
|
|
36
25
|
listProducts: () => request("GET", "/products"),
|
|
37
|
-
getProduct: (id) => request("GET", `/products/${id}`),
|
|
38
|
-
createProduct: (data) => request("POST", "/products", data),
|
|
39
|
-
updateProduct: (id, data) => request("PATCH", `/products/${id}`, data),
|
|
40
|
-
deleteProduct: (id) => request("DELETE", `/products/${id}`),
|
|
41
|
-
publishProduct: (id) => request("POST", `/products/${id}/publish`),
|
|
42
26
|
initProduct: (data) => request("POST", "/products/init", data),
|
|
43
|
-
// --- Plans ---
|
|
44
|
-
listPlans: (productId) => request("GET", `/products/${productId}/plans`),
|
|
45
|
-
createPlan: (productId, data) => request("POST", `/products/${productId}/plans`, data),
|
|
46
|
-
updatePlan: (productId, planId, data) => request("PATCH", `/products/${productId}/plans/${planId}`, data),
|
|
47
|
-
deletePlan: (productId, planId) => request("DELETE", `/products/${productId}/plans/${planId}`),
|
|
48
|
-
// --- Plan config (declarative) ---
|
|
49
|
-
exportPlanConfig: (productId) => rawText("GET", `/products/${productId}/plans/export`),
|
|
50
|
-
applyPlanConfig: (productId, config, opts) => {
|
|
51
|
-
const params = opts?.validateOnly ? "?validate_only=true" : "";
|
|
52
|
-
return request("POST", `/products/${productId}/plans/apply${params}`, { config, configHash: opts?.configHash, force: opts?.force });
|
|
53
|
-
},
|
|
54
|
-
// --- Tokens ---
|
|
55
|
-
listTokens: () => request("GET", "/maker-tokens"),
|
|
56
|
-
revokeToken: (id) => request("DELETE", `/maker-tokens/${id}`),
|
|
57
|
-
// --- Team ---
|
|
58
|
-
listMembers: (orgId) => request("GET", `/builder/organizations/${orgId}/members`),
|
|
59
|
-
inviteMember: (orgId, email, role) => request("POST", `/builder/organizations/${orgId}/invitations`, {
|
|
60
|
-
email,
|
|
61
|
-
role,
|
|
62
|
-
}),
|
|
63
|
-
removeMember: (orgId, userId) => request("DELETE", `/builder/organizations/${orgId}/members/${userId}`),
|
|
64
|
-
// --- Billing ---
|
|
65
|
-
getStripeStatus: () => request("GET", "/builder/stripe/status"),
|
|
66
|
-
startStripeOnboard: () => request("POST", "/builder/stripe/onboard"),
|
|
67
|
-
// --- Usage ---
|
|
68
|
-
getUsage: (productId) => request("GET", `/products/${productId}/usage`),
|
|
69
27
|
// --- Compile ---
|
|
70
28
|
compileProduct: (productId) => request("POST", `/products/${productId}/compile`),
|
|
71
29
|
// --- Management (maker token) ---
|
|
30
|
+
// Compile the product associated with the token — no product ID needed.
|
|
31
|
+
managementCompileSelf: () => request("POST", "/management/compile"),
|
|
72
32
|
managementCompile: (productId) => request("POST", `/management/products/${productId}/compile`),
|
|
73
33
|
managementListProducts: () => request("GET", "/management/products"),
|
|
74
|
-
whoami: () => request("GET", "/management/whoami"),
|
|
75
34
|
isMakerToken: () => opts.token.startsWith("mk_"),
|
|
76
35
|
};
|
|
77
36
|
}
|
package/dist/commands/apply.js
CHANGED
|
@@ -48,6 +48,33 @@ async function resolveProductId(client, arg) {
|
|
|
48
48
|
return null;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
function handleResult(result) {
|
|
52
|
+
// GitHub Actions annotations
|
|
53
|
+
if (CI) {
|
|
54
|
+
for (const err of result.errors ?? []) {
|
|
55
|
+
console.log(`::error file=product.yaml::${err.code ? `[${err.code}] ` : ""}${err.message}`);
|
|
56
|
+
}
|
|
57
|
+
for (const w of result.warnings ?? []) {
|
|
58
|
+
console.log(`::warning file=product.yaml::${w.code ? `[${w.code}] ` : ""}${w.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (result.success) {
|
|
62
|
+
output.success("Compilation passed");
|
|
63
|
+
if (result.warnings?.length) {
|
|
64
|
+
console.log();
|
|
65
|
+
for (const w of result.warnings) {
|
|
66
|
+
output.warn(`${w.code ? `[${w.code}] ` : ""}${w.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
output.error("Compilation failed\n");
|
|
72
|
+
for (const err of result.errors ?? []) {
|
|
73
|
+
console.log(` • ${err.code ? `[${err.code}] ` : ""}${err.message}`);
|
|
74
|
+
}
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
51
78
|
export function registerApplyCommand(program, getClient) {
|
|
52
79
|
program
|
|
53
80
|
.command("apply [product]")
|
|
@@ -55,21 +82,25 @@ export function registerApplyCommand(program, getClient) {
|
|
|
55
82
|
"Pass a product slug, or run inside a product repo to auto-detect from product.yaml.")
|
|
56
83
|
.action(async (productArg) => {
|
|
57
84
|
const client = getClient();
|
|
58
|
-
//
|
|
59
|
-
// the token — no
|
|
60
|
-
|
|
85
|
+
// Fast path for CI: product-scoped maker token with no argument.
|
|
86
|
+
// Server auto-resolves product from the token — no product.yaml,
|
|
87
|
+
// no slug lookup, single API call.
|
|
61
88
|
if (client.isMakerToken() && !productArg) {
|
|
62
89
|
try {
|
|
63
|
-
const
|
|
64
|
-
|
|
90
|
+
const result = await client.managementCompileSelf();
|
|
91
|
+
handleResult(result);
|
|
92
|
+
return;
|
|
65
93
|
}
|
|
66
|
-
catch {
|
|
67
|
-
|
|
94
|
+
catch (err) {
|
|
95
|
+
const msg = err instanceof Error ? err.message : "Compilation check failed";
|
|
96
|
+
if (CI)
|
|
97
|
+
console.log(`::error::${msg}`);
|
|
98
|
+
output.error(msg);
|
|
99
|
+
process.exitCode = 1;
|
|
100
|
+
return;
|
|
68
101
|
}
|
|
69
102
|
}
|
|
70
|
-
|
|
71
|
-
productId = await resolveProductId(client, productArg);
|
|
72
|
-
}
|
|
103
|
+
const productId = await resolveProductId(client, productArg);
|
|
73
104
|
if (!productId) {
|
|
74
105
|
const hint = productArg
|
|
75
106
|
? `Product "${productArg}" not found. Check the name and try again.`
|
|
@@ -83,31 +114,7 @@ export function registerApplyCommand(program, getClient) {
|
|
|
83
114
|
const result = client.isMakerToken()
|
|
84
115
|
? await client.managementCompile(productId)
|
|
85
116
|
: await client.compileProduct(productId);
|
|
86
|
-
|
|
87
|
-
if (CI) {
|
|
88
|
-
for (const err of result.errors ?? []) {
|
|
89
|
-
console.log(`::error file=product.yaml::${err.code ? `[${err.code}] ` : ""}${err.message}`);
|
|
90
|
-
}
|
|
91
|
-
for (const w of result.warnings ?? []) {
|
|
92
|
-
console.log(`::warning file=product.yaml::${w.code ? `[${w.code}] ` : ""}${w.message}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (result.success) {
|
|
96
|
-
output.success("Compilation passed");
|
|
97
|
-
if (result.warnings?.length) {
|
|
98
|
-
console.log();
|
|
99
|
-
for (const w of result.warnings) {
|
|
100
|
-
output.warn(`${w.code ? `[${w.code}] ` : ""}${w.message}`);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
output.error("Compilation failed\n");
|
|
106
|
-
for (const err of result.errors ?? []) {
|
|
107
|
-
console.log(` • ${err.code ? `[${err.code}] ` : ""}${err.message}`);
|
|
108
|
-
}
|
|
109
|
-
process.exitCode = 1;
|
|
110
|
-
}
|
|
117
|
+
handleResult(result);
|
|
111
118
|
}
|
|
112
119
|
catch (err) {
|
|
113
120
|
const msg = err instanceof Error ? err.message : "Compilation check failed";
|
package/dist/types.d.ts
CHANGED
|
@@ -20,44 +20,6 @@ export type Plan = {
|
|
|
20
20
|
isActive: boolean;
|
|
21
21
|
selfServeEnabled: boolean;
|
|
22
22
|
};
|
|
23
|
-
export type ApplyResponse = {
|
|
24
|
-
valid: boolean;
|
|
25
|
-
errors: Array<{
|
|
26
|
-
line?: number;
|
|
27
|
-
message: string;
|
|
28
|
-
}>;
|
|
29
|
-
warnings: Array<{
|
|
30
|
-
message: string;
|
|
31
|
-
}>;
|
|
32
|
-
changes: Array<{
|
|
33
|
-
action: "create" | "update" | "deactivate";
|
|
34
|
-
key: string;
|
|
35
|
-
name: string;
|
|
36
|
-
details: string;
|
|
37
|
-
}>;
|
|
38
|
-
applied: boolean;
|
|
39
|
-
results?: Array<{
|
|
40
|
-
action: string;
|
|
41
|
-
key: string;
|
|
42
|
-
id: string;
|
|
43
|
-
}>;
|
|
44
|
-
};
|
|
45
|
-
export type MakerToken = {
|
|
46
|
-
id: string;
|
|
47
|
-
label: string;
|
|
48
|
-
lastFour: string;
|
|
49
|
-
productId: string | null;
|
|
50
|
-
permissions: string[];
|
|
51
|
-
createdAt: string;
|
|
52
|
-
};
|
|
53
|
-
export type OrgMember = {
|
|
54
|
-
userId: string;
|
|
55
|
-
role: string;
|
|
56
|
-
user?: {
|
|
57
|
-
email?: string;
|
|
58
|
-
name?: string;
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
23
|
export type CliConfig = {
|
|
62
24
|
apiUrl: string;
|
|
63
25
|
activeOrg?: string;
|