@ollie-shop/cli 1.2.2 → 1.3.3
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/.env.example +9 -5
- package/.turbo/turbo-build.log +3 -3
- package/CHANGELOG.md +51 -0
- package/CONTEXT.md +3 -3
- package/README.md +6 -10
- package/dist/index.js +280 -51
- package/package.json +1 -1
- package/src/cli.tsx +8 -1
- package/src/commands/function-cmd.ts +42 -10
- package/src/commands/help.tsx +5 -1
- package/src/commands/start.tsx +8 -18
- package/src/commands/store-cmd.ts +14 -4
- package/src/commands/whoami.ts +70 -9
- package/src/core/function.ts +1 -1
- package/src/core/schema.ts +8 -3
- package/src/core/store.ts +50 -3
- package/src/utils/auth.ts +4 -0
- package/src/utils/esbuild.ts +99 -15
- package/src/utils/parse-args.ts +2 -0
- package/src/utils/supabase.ts +66 -11
- package/tsup.config.ts +7 -0
package/src/utils/supabase.ts
CHANGED
|
@@ -6,15 +6,49 @@ declare const __OLLIE_SUPABASE_URL__: string;
|
|
|
6
6
|
declare const __OLLIE_SUPABASE_ANON_KEY__: string;
|
|
7
7
|
declare const __OLLIE_BUILDER_URL__: string;
|
|
8
8
|
|
|
9
|
+
// Resolution order: runtime env var > CI build-time inline > prod default.
|
|
10
|
+
// Baked-in defaults ensure `ollieshop` works zero-config when CI inject is
|
|
11
|
+
// missing or stale. All three values are public (anon Supabase key, public
|
|
12
|
+
// API URLs) so inlining them carries no secret-leak risk.
|
|
13
|
+
const PROD_DEFAULTS = {
|
|
14
|
+
supabaseUrl: "https://aazahtmqrhjqsyqoqdkm.supabase.co",
|
|
15
|
+
supabaseAnonKey:
|
|
16
|
+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFhemFodG1xcmhqcXN5cW9xZGttIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg2MzEwOTcsImV4cCI6MjA2NDIwNzA5N30.VuAbAyjDe0HcL09SZtQ-UmP1o7Z6qwGuOtvfFhnyAcM",
|
|
17
|
+
builderUrl: "https://api.ollie.shop/builder/v1",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function envOrDefault(
|
|
21
|
+
envValue: string | undefined,
|
|
22
|
+
buildTimeValue: string,
|
|
23
|
+
prodDefault: string,
|
|
24
|
+
): string {
|
|
25
|
+
return envValue || buildTimeValue || prodDefault;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Collapses a Supabase to-one embed (object, array, or null) to a single record.
|
|
29
|
+
export function unwrapToOne<T = Record<string, unknown>>(
|
|
30
|
+
embed: unknown,
|
|
31
|
+
): T | null {
|
|
32
|
+
const record = Array.isArray(embed) ? embed[0] : embed;
|
|
33
|
+
return record && typeof record === "object" ? (record as T) : null;
|
|
34
|
+
}
|
|
35
|
+
|
|
9
36
|
export async function getAuthenticatedClient(): Promise<SupabaseClient> {
|
|
10
37
|
const credentials = await getCredentials();
|
|
11
38
|
if (!credentials) {
|
|
12
39
|
throw new Error("Not authenticated. Run `ollieshop login` first.");
|
|
13
40
|
}
|
|
14
41
|
|
|
15
|
-
const supabaseUrl =
|
|
16
|
-
|
|
17
|
-
|
|
42
|
+
const supabaseUrl = envOrDefault(
|
|
43
|
+
process.env.OLLIE_SUPABASE_URL,
|
|
44
|
+
__OLLIE_SUPABASE_URL__,
|
|
45
|
+
PROD_DEFAULTS.supabaseUrl,
|
|
46
|
+
);
|
|
47
|
+
const supabaseAnonKey = envOrDefault(
|
|
48
|
+
process.env.OLLIE_SUPABASE_ANON_KEY,
|
|
49
|
+
__OLLIE_SUPABASE_ANON_KEY__,
|
|
50
|
+
PROD_DEFAULTS.supabaseAnonKey,
|
|
51
|
+
);
|
|
18
52
|
|
|
19
53
|
const client = createClient(supabaseUrl, supabaseAnonKey, {
|
|
20
54
|
auth: {
|
|
@@ -32,7 +66,11 @@ export async function getAuthenticatedClient(): Promise<SupabaseClient> {
|
|
|
32
66
|
}
|
|
33
67
|
|
|
34
68
|
export function getBuilderUrl(): string {
|
|
35
|
-
return
|
|
69
|
+
return envOrDefault(
|
|
70
|
+
process.env.OLLIE_BUILDER_URL,
|
|
71
|
+
__OLLIE_BUILDER_URL__,
|
|
72
|
+
PROD_DEFAULTS.builderUrl,
|
|
73
|
+
);
|
|
36
74
|
}
|
|
37
75
|
|
|
38
76
|
export async function getAuthToken(): Promise<string> {
|
|
@@ -45,23 +83,40 @@ export async function getAuthToken(): Promise<string> {
|
|
|
45
83
|
|
|
46
84
|
export async function getOrganizationId(
|
|
47
85
|
client: SupabaseClient,
|
|
86
|
+
preferredOrgId?: string,
|
|
48
87
|
): Promise<string> {
|
|
49
|
-
const { data:
|
|
88
|
+
const { data: orgs, error } = await client
|
|
50
89
|
.from("organizations")
|
|
51
|
-
.select("id")
|
|
52
|
-
.order("created_at", { ascending: true })
|
|
53
|
-
.limit(1)
|
|
54
|
-
.maybeSingle();
|
|
90
|
+
.select("id, name")
|
|
91
|
+
.order("created_at", { ascending: true });
|
|
55
92
|
|
|
56
93
|
if (error) {
|
|
57
94
|
throw new Error(`Failed to get organization: ${error.message}`);
|
|
58
95
|
}
|
|
59
96
|
|
|
60
|
-
if (!
|
|
97
|
+
if (!orgs || orgs.length === 0) {
|
|
61
98
|
throw new Error(
|
|
62
99
|
"No organization found for your account. Create one at https://admin.ollie.shop",
|
|
63
100
|
);
|
|
64
101
|
}
|
|
65
102
|
|
|
66
|
-
|
|
103
|
+
if (preferredOrgId) {
|
|
104
|
+
const match = orgs.find((o) => o.id === preferredOrgId);
|
|
105
|
+
if (!match) {
|
|
106
|
+
const list = orgs.map((o) => ` - ${o.id} ${o.name}`).join("\n");
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Organization ${preferredOrgId} not found or you are not a member. Orgs you can access:\n${list}`,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return match.id;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (orgs.length > 1) {
|
|
115
|
+
const list = orgs.map((o) => ` - ${o.id} ${o.name}`).join("\n");
|
|
116
|
+
throw new Error(
|
|
117
|
+
`You belong to multiple organizations. Pass --org <id> to select one:\n${list}`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return orgs[0].id;
|
|
67
122
|
}
|
package/tsup.config.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
1
2
|
import { defineConfig } from "tsup";
|
|
2
3
|
|
|
3
4
|
// CI injects SUPABASE_URL/SUPABASE_ANON_KEY/BUILDER_URL from GH Actions vars;
|
|
4
5
|
// locally they're empty and the CLI falls back to runtime process.env.
|
|
5
6
|
const env = (k: string) => JSON.stringify(process.env[k] ?? "");
|
|
6
7
|
|
|
8
|
+
// Inline the package version at build time so `-v`/`--version` report the real version.
|
|
9
|
+
const pkg = JSON.parse(
|
|
10
|
+
readFileSync(new URL("./package.json", import.meta.url), "utf8"),
|
|
11
|
+
);
|
|
12
|
+
|
|
7
13
|
export default defineConfig({
|
|
8
14
|
entry: ["src/index.tsx"],
|
|
9
15
|
format: ["esm"],
|
|
@@ -16,5 +22,6 @@ export default defineConfig({
|
|
|
16
22
|
__OLLIE_SUPABASE_URL__: env("SUPABASE_URL"),
|
|
17
23
|
__OLLIE_SUPABASE_ANON_KEY__: env("SUPABASE_ANON_KEY"),
|
|
18
24
|
__OLLIE_BUILDER_URL__: env("BUILDER_URL"),
|
|
25
|
+
__OLLIE_CLI_VERSION__: JSON.stringify(pkg.version),
|
|
19
26
|
},
|
|
20
27
|
});
|