@theholocron/holocron-plugin-clerk 2.0.0-alpha.20 → 2.0.0-alpha.22
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/index.d.mts +8 -53
- package/dist/index.mjs +26 -86
- package/package.json +9 -8
package/dist/index.d.mts
CHANGED
|
@@ -1,59 +1,14 @@
|
|
|
1
|
-
import { Auth, AuthDescription, AuthEvent, AuthIdentity, AuthUser, CreateAuthUserInput, ParseWebhookInput, WebhookDashboardInfo } from "@theholocron/cli";
|
|
1
|
+
import { Auth, AuthDescription, AuthError, AuthEvent, AuthIdentity, AuthUser, CreateAuthUserInput, ParseWebhookInput, ResolveTokenInput, RestClient, RestClient as RestClient$1, WebhookDashboardInfo } from "@theholocron/cli";
|
|
2
2
|
|
|
3
3
|
//#region src/auth.d.ts
|
|
4
|
-
|
|
5
|
-
* Token resolution for the Clerk plugin.
|
|
6
|
-
*
|
|
7
|
-
* Resolution order (matches the standard 4-step precedence set by
|
|
8
|
-
* `.notes/tech-auth-bootstrap.spec.md`):
|
|
9
|
-
* 1. explicit `cliToken` argument (from `--token` flag)
|
|
10
|
-
* 2. HOLOCRON_CLERK_SECRET_KEY env var (preferred — explicit intent)
|
|
11
|
-
* 3. CLERK_SECRET_KEY env var (the default Clerk's docs reference)
|
|
12
|
-
* 4. keyring (com.theholocron.cli / "clerk")
|
|
13
|
-
* 5. AuthError naming all four options + the bootstrap hint
|
|
14
|
-
*
|
|
15
|
-
* The key (sk_test_* / sk_live_*) determines which Clerk instance —
|
|
16
|
-
* Development or Production — every call hits.
|
|
17
|
-
*/
|
|
18
|
-
declare class AuthError extends Error {
|
|
19
|
-
name: string;
|
|
20
|
-
}
|
|
21
|
-
interface ResolveTokenInput {
|
|
22
|
-
/** From `--token` CLI flag. */
|
|
23
|
-
cliToken?: string;
|
|
24
|
-
/** Env vars; passed in for testability. Defaults to `process.env`. */
|
|
25
|
-
env?: NodeJS.ProcessEnv;
|
|
26
|
-
/** Keyring lookup fn; passed in for testability. Defaults to `getToken(provider)`. */
|
|
27
|
-
keyring?: (provider: string) => string | null;
|
|
28
|
-
}
|
|
29
|
-
declare function resolveToken(input?: ResolveTokenInput): string;
|
|
4
|
+
declare const resolveToken: (input?: import("@theholocron/http-client").ResolveTokenInput) => string;
|
|
30
5
|
//#endregion
|
|
31
6
|
//#region src/rest.d.ts
|
|
32
|
-
|
|
33
|
-
* Thin REST wrapper around api.clerk.com/v1.
|
|
34
|
-
*
|
|
35
|
-
* Same pattern as the github/vercel/neon REST clients — bearer auth,
|
|
36
|
-
* JSON-only bodies, transport-failure wrapping with `status: 0` so the
|
|
37
|
-
* orchestrator's soft-skip path sees a clear "Clerk GET /path failed"
|
|
38
|
-
* message instead of a generic `TypeError: fetch failed`.
|
|
39
|
-
*/
|
|
40
|
-
interface RestClientOptions {
|
|
7
|
+
declare function createClerkRestClient(opts: {
|
|
41
8
|
token: string;
|
|
42
|
-
fetch?: typeof fetch;
|
|
43
9
|
baseUrl?: string;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
method?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
|
|
47
|
-
body?: unknown;
|
|
48
|
-
query?: Record<string, string>;
|
|
49
|
-
}
|
|
50
|
-
declare class ClerkRestClient {
|
|
51
|
-
private readonly token;
|
|
52
|
-
private readonly fetchImpl;
|
|
53
|
-
readonly baseUrl: string;
|
|
54
|
-
constructor(opts: RestClientOptions);
|
|
55
|
-
request<T>(path: string, opts?: RequestOptions): Promise<T>;
|
|
56
|
-
}
|
|
10
|
+
fetch?: typeof fetch;
|
|
11
|
+
}): RestClient$1;
|
|
57
12
|
//#endregion
|
|
58
13
|
//#region src/capabilities/auth.d.ts
|
|
59
14
|
type ClerkAuthOptions = Record<string, never>;
|
|
@@ -61,7 +16,7 @@ declare class ClerkAuth implements Auth {
|
|
|
61
16
|
private readonly rest;
|
|
62
17
|
readonly key: "auth";
|
|
63
18
|
readonly providerName = "clerk";
|
|
64
|
-
constructor(rest:
|
|
19
|
+
constructor(rest: RestClient, _opts?: ClerkAuthOptions);
|
|
65
20
|
describe(): Promise<AuthDescription>;
|
|
66
21
|
whoami(): Promise<AuthIdentity>;
|
|
67
22
|
ensureWebhookApp(): Promise<{
|
|
@@ -109,7 +64,7 @@ interface ClerkPluginOptions extends ResolveTokenInput {
|
|
|
109
64
|
}
|
|
110
65
|
interface PluginContext {
|
|
111
66
|
options: ClerkPluginOptions;
|
|
112
|
-
rest:
|
|
67
|
+
rest: RestClient;
|
|
113
68
|
}
|
|
114
69
|
declare function createContext(options?: ClerkPluginOptions): PluginContext;
|
|
115
70
|
declare function auth(ctx: PluginContext): Auth;
|
|
@@ -127,4 +82,4 @@ declare function createPlugin(options?: ClerkPluginOptions): {
|
|
|
127
82
|
*/
|
|
128
83
|
declare const AUTH_HINT: string;
|
|
129
84
|
//#endregion
|
|
130
|
-
export { AUTH_HINT, AuthError, ClerkAuth, ClerkPluginOptions,
|
|
85
|
+
export { AUTH_HINT, AuthError, ClerkAuth, ClerkPluginOptions, PluginContext, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, auth, createClerkRestClient, createContext, createPlugin, parseWebhook, resolveToken, verifyToken };
|
package/dist/index.mjs
CHANGED
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
import { ProviderApiError, WebhookVerificationError,
|
|
1
|
+
import { AuthError, ProviderApiError, WebhookVerificationError, createResolveToken, createRestClient } from "@theholocron/cli";
|
|
2
2
|
//#region src/auth.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* 2. HOLOCRON_CLERK_SECRET_KEY env var (preferred — explicit intent)
|
|
10
|
-
* 3. CLERK_SECRET_KEY env var (the default Clerk's docs reference)
|
|
11
|
-
* 4. keyring (com.theholocron.cli / "clerk")
|
|
12
|
-
* 5. AuthError naming all four options + the bootstrap hint
|
|
13
|
-
*
|
|
14
|
-
* The key (sk_test_* / sk_live_*) determines which Clerk instance —
|
|
15
|
-
* Development or Production — every call hits.
|
|
16
|
-
*/
|
|
17
|
-
var AuthError = class extends Error {
|
|
18
|
-
name = "AuthError";
|
|
19
|
-
};
|
|
20
|
-
function resolveToken(input = {}) {
|
|
21
|
-
const env = input.env ?? process.env;
|
|
22
|
-
const keyring = input.keyring ?? getToken;
|
|
23
|
-
const token = input.cliToken || env["HOLOCRON_CLERK_SECRET_KEY"] || env["CLERK_SECRET_KEY"] || keyring("clerk");
|
|
24
|
-
if (!token) throw new AuthError("no Clerk secret key found. Pass --token <KEY>, set HOLOCRON_CLERK_SECRET_KEY / CLERK_SECRET_KEY, or run: holocron auth set clerk <KEY>");
|
|
25
|
-
return token;
|
|
26
|
-
}
|
|
3
|
+
const resolveToken = createResolveToken({
|
|
4
|
+
envName: "HOLOCRON_CLERK_SECRET_KEY",
|
|
5
|
+
vendorEnvName: "CLERK_SECRET_KEY",
|
|
6
|
+
keyringService: "clerk",
|
|
7
|
+
errorMessage: "no Clerk secret key found. Pass --token <KEY>, set HOLOCRON_CLERK_SECRET_KEY / CLERK_SECRET_KEY, or run: holocron auth set clerk <KEY>"
|
|
8
|
+
});
|
|
27
9
|
//#endregion
|
|
28
10
|
//#region src/capabilities/auth.ts
|
|
29
11
|
/**
|
|
@@ -116,58 +98,14 @@ function isAlreadyExistsError(err) {
|
|
|
116
98
|
}
|
|
117
99
|
//#endregion
|
|
118
100
|
//#region src/rest.ts
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
var ClerkRestClient = class {
|
|
128
|
-
token;
|
|
129
|
-
fetchImpl;
|
|
130
|
-
baseUrl;
|
|
131
|
-
constructor(opts) {
|
|
132
|
-
this.token = opts.token;
|
|
133
|
-
this.fetchImpl = opts.fetch ?? globalThis.fetch;
|
|
134
|
-
let url = opts.baseUrl ?? "https://api.clerk.com/v1";
|
|
135
|
-
while (url.endsWith("/")) url = url.slice(0, -1);
|
|
136
|
-
this.baseUrl = url;
|
|
137
|
-
}
|
|
138
|
-
async request(path, opts = {}) {
|
|
139
|
-
const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : "/" + path}`);
|
|
140
|
-
for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v);
|
|
141
|
-
const fullUrl = url.toString();
|
|
142
|
-
const headers = {
|
|
143
|
-
authorization: `Bearer ${this.token}`,
|
|
144
|
-
accept: "application/json"
|
|
145
|
-
};
|
|
146
|
-
const init = {
|
|
147
|
-
method: opts.method ?? "GET",
|
|
148
|
-
headers
|
|
149
|
-
};
|
|
150
|
-
if (opts.body !== void 0) {
|
|
151
|
-
headers["content-type"] = "application/json";
|
|
152
|
-
init.body = JSON.stringify(opts.body);
|
|
153
|
-
}
|
|
154
|
-
let res;
|
|
155
|
-
try {
|
|
156
|
-
res = await this.fetchImpl(fullUrl, init);
|
|
157
|
-
} catch (err) {
|
|
158
|
-
const detail = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
|
|
159
|
-
throw new ProviderApiError(`Clerk ${init.method} ${path} failed: ${detail}`, 0, void 0);
|
|
160
|
-
}
|
|
161
|
-
if (!res.ok) {
|
|
162
|
-
const body = await res.text().catch(() => "");
|
|
163
|
-
throw new ProviderApiError(`Clerk ${init.method} ${path} → ${res.status}`, res.status, body);
|
|
164
|
-
}
|
|
165
|
-
if (res.status === 204) return void 0;
|
|
166
|
-
const text = await res.text();
|
|
167
|
-
if (!text) return void 0;
|
|
168
|
-
return JSON.parse(text);
|
|
169
|
-
}
|
|
170
|
-
};
|
|
101
|
+
function createClerkRestClient(opts) {
|
|
102
|
+
return createRestClient({
|
|
103
|
+
baseUrl: opts.baseUrl ?? "https://api.clerk.com/v1",
|
|
104
|
+
token: opts.token,
|
|
105
|
+
vendor: "Clerk",
|
|
106
|
+
fetch: opts.fetch
|
|
107
|
+
});
|
|
108
|
+
}
|
|
171
109
|
//#endregion
|
|
172
110
|
//#region src/parse-webhook.ts
|
|
173
111
|
/**
|
|
@@ -248,10 +186,11 @@ async function verifySignature(input) {
|
|
|
248
186
|
* canonical "is this secret key valid?" endpoint.
|
|
249
187
|
*/
|
|
250
188
|
async function verifyToken(token, opts = {}) {
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
189
|
+
const rest = createClerkRestClient({
|
|
190
|
+
token,
|
|
191
|
+
baseUrl: opts.baseUrl,
|
|
192
|
+
fetch: opts.fetch
|
|
193
|
+
});
|
|
255
194
|
try {
|
|
256
195
|
const instance = await rest.request("/instance");
|
|
257
196
|
return {
|
|
@@ -268,12 +207,13 @@ async function verifyToken(token, opts = {}) {
|
|
|
268
207
|
//#endregion
|
|
269
208
|
//#region src/index.ts
|
|
270
209
|
function createContext(options = {}) {
|
|
271
|
-
const restOpts = { token: resolveToken(options) };
|
|
272
|
-
if (options.baseUrl !== void 0) restOpts.baseUrl = options.baseUrl;
|
|
273
|
-
if (options.fetch !== void 0) restOpts.fetch = options.fetch;
|
|
274
210
|
return {
|
|
275
211
|
options,
|
|
276
|
-
rest:
|
|
212
|
+
rest: createClerkRestClient({
|
|
213
|
+
token: resolveToken(options),
|
|
214
|
+
baseUrl: options.baseUrl,
|
|
215
|
+
fetch: options.fetch
|
|
216
|
+
})
|
|
277
217
|
};
|
|
278
218
|
}
|
|
279
219
|
function auth(ctx) {
|
|
@@ -294,4 +234,4 @@ function createPlugin(options = {}) {
|
|
|
294
234
|
*/
|
|
295
235
|
const AUTH_HINT = "grab your SECRET key (sk_test_* / sk_live_*) at https://dashboard.clerk.com → API Keys, then run: holocron auth set clerk <KEY>. Do NOT use the publishable key.";
|
|
296
236
|
//#endregion
|
|
297
|
-
export { AUTH_HINT, AuthError, ClerkAuth,
|
|
237
|
+
export { AUTH_HINT, AuthError, ClerkAuth, auth, createClerkRestClient, createContext, createPlugin, parseWebhook, resolveToken, verifyToken };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-clerk",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.22",
|
|
4
4
|
"description": "Holocron plugin for Clerk. Implements the auth capability against Clerk's Backend REST API.",
|
|
5
5
|
"homepage": "https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-clerk#readme",
|
|
6
6
|
"bugs": "https://github.com/theholocron/holocron/issues",
|
|
@@ -21,13 +21,14 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@theholocron/cli": "2.0.0-alpha.
|
|
24
|
+
"@theholocron/cli": "2.0.0-alpha.22"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@theholocron/
|
|
29
|
-
"@tsconfig
|
|
30
|
-
"@
|
|
27
|
+
"@types/node": "^26",
|
|
28
|
+
"@theholocron/eslint-config": "^5.2.0",
|
|
29
|
+
"@theholocron/tsconfig": "^6.0.0",
|
|
30
|
+
"@theholocron/tsdown-config": "^5.1.2",
|
|
31
|
+
"@theholocron/vitest-config": "^5.2.0",
|
|
31
32
|
"@vitest/eslint-plugin": "^1.6.23",
|
|
32
33
|
"eslint": "^10.7.0",
|
|
33
34
|
"eslint-plugin-n": "^18.2.2",
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
"tsdown": "^0.22.3",
|
|
36
37
|
"tsx": "^4.22.4",
|
|
37
38
|
"typescript": "^5.9.3",
|
|
38
|
-
"vitest": "^
|
|
39
|
-
"@theholocron/cli": "2.0.0-alpha.
|
|
39
|
+
"vitest": "^4.1.10",
|
|
40
|
+
"@theholocron/cli": "2.0.0-alpha.22"
|
|
40
41
|
},
|
|
41
42
|
"publishConfig": {
|
|
42
43
|
"access": "public"
|