instant-cli 1.0.22 → 1.0.23-branch-cli-codex-update.25390498340.1

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.
Files changed (41) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/__tests__/authClientAddGoogle.test.ts +92 -0
  3. package/__tests__/authClientList.test.ts +90 -0
  4. package/__tests__/authClientUpdate.test.ts +583 -0
  5. package/__tests__/oauthMock.ts +9 -1
  6. package/__tests__/redirectUriPrompt.test.ts +26 -0
  7. package/dist/commands/auth/client/add.d.ts +1 -2
  8. package/dist/commands/auth/client/add.d.ts.map +1 -1
  9. package/dist/commands/auth/client/add.js +173 -276
  10. package/dist/commands/auth/client/add.js.map +1 -1
  11. package/dist/commands/auth/client/delete.d.ts +1 -2
  12. package/dist/commands/auth/client/delete.d.ts.map +1 -1
  13. package/dist/commands/auth/client/delete.js +8 -18
  14. package/dist/commands/auth/client/delete.js.map +1 -1
  15. package/dist/commands/auth/client/list.d.ts.map +1 -1
  16. package/dist/commands/auth/client/list.js +11 -2
  17. package/dist/commands/auth/client/list.js.map +1 -1
  18. package/dist/commands/auth/client/shared.d.ts +72 -0
  19. package/dist/commands/auth/client/shared.d.ts.map +1 -0
  20. package/dist/commands/auth/client/shared.js +145 -0
  21. package/dist/commands/auth/client/shared.js.map +1 -0
  22. package/dist/commands/auth/client/update.d.ts +8 -0
  23. package/dist/commands/auth/client/update.d.ts.map +1 -0
  24. package/dist/commands/auth/client/update.js +515 -0
  25. package/dist/commands/auth/client/update.js.map +1 -0
  26. package/dist/index.d.ts +5 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +60 -13
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/oauth.d.ts +114 -7
  31. package/dist/lib/oauth.d.ts.map +1 -1
  32. package/dist/lib/oauth.js +51 -1
  33. package/dist/lib/oauth.js.map +1 -1
  34. package/package.json +4 -4
  35. package/src/commands/auth/client/add.ts +251 -330
  36. package/src/commands/auth/client/delete.ts +8 -20
  37. package/src/commands/auth/client/list.ts +21 -2
  38. package/src/commands/auth/client/shared.ts +195 -0
  39. package/src/commands/auth/client/update.ts +853 -0
  40. package/src/index.ts +74 -13
  41. package/src/lib/oauth.ts +83 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/commands/auth/client/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileSystem } from '@effect/platform';\nimport { Effect } from 'effect';\nimport { DEFAULT_OAUTH_CALLBACK_URL } from '@instantdb/platform';\nimport chalk from 'chalk';\nimport { BadArgsError } from '../../../errors.ts';\nimport { link } from '../../../logging.ts';\nimport { stripFirstBlankLine, validateRequired } from '../../../lib/ui.ts';\nimport { UI } from '../../../ui/index.ts';\n\ntype EmptyPromptArgs = Record<string, never>;\n\nexport const getFlag = (opts: Record<string, unknown>, flag: string) =>\n opts[flag];\n\nexport const hasFlag = (opts: Record<string, unknown>, flag: string) =>\n flag in opts;\n\nexport const hasAnyFlag = (opts: Record<string, unknown>, flags: string[]) =>\n flags.some((flag) => hasFlag(opts, flag));\n\nexport const isTrueFlag = (value: unknown) =>\n value === true || value === 'true';\n\nexport const getMetaString = (meta: unknown, key: string) => {\n if (!meta || typeof meta !== 'object') return undefined;\n const value = (meta as Record<string, unknown>)[key];\n return typeof value === 'string' ? value : undefined;\n};\n\nexport const clientIdPrompt = ({ providerUrl }: { providerUrl: string }) => ({\n prompt: `Client ID: ${chalk.dim(`(from ${link(providerUrl)})`)}`,\n validate: validateRequired,\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const clientSecretPrompt = ({\n providerUrl,\n}: {\n providerUrl: string;\n}) => ({\n prompt: `Client Secret: ${chalk.dim(`(from ${link(providerUrl)})`)}`,\n validate: validateRequired,\n sensitive: true,\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const redirectUriPrompt = ({ heading }: { heading: string }) => ({\n prompt: '',\n placeholder: 'https://yoursite.com/oauth/callback',\n modifyOutput: UI.modifiers.piped([\n (output, status) => {\n if (status === 'idle') {\n return (\n `\\n${heading}\n${chalk.dim('With a custom redirect URI, users will see \"Redirecting to yoursite.com...\" for a more branded experience.')}\n${chalk.dim(`Your URI must forward to ${DEFAULT_OAUTH_CALLBACK_URL} with all query parameters preserved.`)}\\n\\n` +\n stripFirstBlankLine(output)\n );\n }\n const answer = stripFirstBlankLine(output);\n if (status === 'submitted' && answer.trim() === '') {\n return `\\n${heading}\\n(skipped)`;\n }\n return `\\n${heading}\\n${answer}`;\n },\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const redirectSetupMessages = ({\n prompt,\n redirectUri,\n showCustomRedirectInstructions,\n}: {\n prompt: string;\n redirectUri: string;\n showCustomRedirectInstructions?: boolean;\n}) => {\n const messages = ['', chalk.bold(`${prompt}:`), chalk.bold(redirectUri)];\n\n if (showCustomRedirectInstructions) {\n messages.push(\n '',\n `Your custom redirect must forward to ${chalk.bold(DEFAULT_OAUTH_CALLBACK_URL)} with all query parameters preserved.`,\n );\n messages.push(\n `You can test it by visiting: ${chalk.bold(redirectUri + '?test-redirect=true')}`,\n );\n }\n\n return messages;\n};\n\nexport const appleServicesIdPrompt = (_opts: EmptyPromptArgs) => ({\n prompt: `Services ID ${chalk.dim(`(from ${link('https://developer.apple.com/account/resources/identifiers/list/serviceId')})`)}`,\n validate: validateRequired,\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const appleTeamIdPrompt = (_opts: EmptyPromptArgs) => ({\n prompt: `Team ID ${chalk.dim(`(from ${link('https://developer.apple.com/account#MembershipDetailsCard')})`)}`,\n validate: validateRequired,\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const appleKeyIdPrompt = (_opts: EmptyPromptArgs) => ({\n prompt: `Key ID ${chalk.dim(`(from ${link('https://developer.apple.com/account/resources/authkeys/list')})`)}`,\n validate: validateRequired,\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const applePrivateKeyFilePrompt = (_opts: EmptyPromptArgs) => ({\n prompt: `Path to .p8 private key file ${chalk.dim('(downloaded from Apple)')}`,\n validate: validateRequired,\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const clerkPublishableKeyPrompt = (_opts: EmptyPromptArgs) => ({\n prompt: `Clerk publishable key ${chalk.dim(`(from ${link('https://dashboard.clerk.com/last-active?path=api-keys')})`)}`,\n placeholder: 'pk_********************************************************',\n validate: (val: string) => {\n if (!val) return 'Publishable key is required';\n if (!val.startsWith('pk_')) {\n return 'Invalid publishable key. It should start with \"pk_\".';\n }\n },\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const firebaseProjectIdPrompt = (_opts: EmptyPromptArgs) => ({\n prompt: `Firebase project ID: (From Project Settings page on ${link('https://console.firebase.google.com/')})`,\n validate: validateFirebaseProjectId,\n modifyOutput: UI.modifiers.piped([\n UI.modifiers.topPadding,\n UI.modifiers.dimOnComplete,\n ]),\n});\n\nexport const readPrivateKeyFile = Effect.fn('readPrivateKeyFile')(function* (\n path: string,\n) {\n const fs = yield* FileSystem.FileSystem;\n // Strip shell escapes so paths like \"file\\ (2).p8\" resolve on POSIX.\n const normalizedPath =\n process.platform === 'win32' ? path : path.replace(/\\\\(.)/g, '$1');\n const contents = yield* fs.readFileString(normalizedPath, 'utf8').pipe(\n Effect.mapError(\n (e) =>\n new BadArgsError({\n message: `Could not read private key file at ${normalizedPath}: ${e.message}`,\n }),\n ),\n );\n\n const trimmed = contents.trim();\n if (!trimmed) {\n return yield* BadArgsError.make({\n message: `Private key file at ${normalizedPath} is empty.`,\n });\n }\n return trimmed;\n});\n\nexport function validateFirebaseProjectId(value: string) {\n const projectIdRegex = /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/;\n if (!value) return 'Project ID is required';\n if (!projectIdRegex.test(value)) {\n return 'Invalid Firebase project ID. It must be 6-30 characters, start with a lowercase letter, contain only lowercase letters, digits, and hyphens, and not end with a hyphen.';\n }\n}\n\nexport function firebaseDiscoveryEndpoint(projectId: string) {\n return `https://securetoken.google.com/${encodeURIComponent(projectId)}/.well-known/openid-configuration`;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { Effect } from 'effect';
2
+ import { GlobalOpts } from '../../../context/globalOpts.ts';
3
+ export declare const authClientUpdateCmd: (opts: {
4
+ id?: string | undefined;
5
+ name?: string | undefined;
6
+ app?: string | undefined;
7
+ } & Record<string, unknown>) => Effect.Effect<void | undefined, import("../../../lib/ui.ts").UIError | import("../../../lib/http.ts").InstantHttpError | import("effect/Cause").TimeoutException | import("@effect/platform/HttpClientError").RequestError | import("effect/ParseResult").ParseError | import("@effect/platform/HttpClientError").ResponseError, GlobalOpts | import("@effect/platform/FileSystem").FileSystem | import("../../../lib/http.ts").InstantHttpAuthed | import("../../../context/currentApp.ts").CurrentApp>;
8
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../../src/commands/auth/client/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAoxB5D,eAAO,MAAM,mBAAmB;;;;wgBA6D/B,CAAC"}
@@ -0,0 +1,515 @@
1
+ import { Effect, Match } from 'effect';
2
+ import { BadArgsError } from "../../../errors.js";
3
+ import { GlobalOpts } from "../../../context/globalOpts.js";
4
+ import { optOrPrompt, runUIEffect } from "../../../lib/ui.js";
5
+ import { findClientByIdOrName, getAppsAuth, OAuthClient, updateOAuthClient, } from "../../../lib/oauth.js";
6
+ import { UI } from "../../../ui/index.js";
7
+ import { clerkDomainFromPublishableKey, DEFAULT_OAUTH_CALLBACK_URL, } from '@instantdb/platform';
8
+ import chalk from 'chalk';
9
+ import boxen from 'boxen';
10
+ import { appleKeyIdPrompt, applePrivateKeyFilePrompt, appleServicesIdPrompt, appleTeamIdPrompt, clerkPublishableKeyPrompt, clientIdPrompt, clientSecretPrompt, firebaseDiscoveryEndpoint, firebaseProjectIdPrompt, getFlag, getMetaString, hasAnyFlag, hasFlag, isTrueFlag, readPrivateKeyFile, redirectSetupMessages, redirectUriPrompt, validateFirebaseProjectId, } from "./shared.js";
11
+ import { link } from "../../../logging.js";
12
+ const redirectPrompt = redirectUriPrompt({
13
+ heading: 'Custom redirect URI (optional):',
14
+ });
15
+ const newRedirectPrompt = redirectUriPrompt({ heading: 'New redirect URI:' });
16
+ const googleConsoleUrl = 'https://console.developers.google.com/apis/credentials';
17
+ const resolveClient = Effect.fn(function* (params) {
18
+ const { yes } = yield* GlobalOpts;
19
+ if (params.id || params.name) {
20
+ return yield* findClientByIdOrName({
21
+ id: params.id,
22
+ name: params.name,
23
+ });
24
+ }
25
+ if (yes) {
26
+ return yield* BadArgsError.make({ message: 'Must specify --id or --name' });
27
+ }
28
+ const auth = yield* getAppsAuth();
29
+ const clients = (auth.oauth_clients ?? []);
30
+ if (clients.length === 0) {
31
+ return yield* BadArgsError.make({
32
+ message: 'No OAuth clients found for this app.',
33
+ });
34
+ }
35
+ return yield* runUIEffect(new UI.Select({
36
+ options: clients.map((client) => ({
37
+ label: client.client_name +
38
+ (client.use_shared_credentials
39
+ ? chalk.dim(' (dev credentials)')
40
+ : '') +
41
+ chalk.dim(` (${client.id})`),
42
+ value: client,
43
+ })),
44
+ promptText: 'Select a client to update:',
45
+ modifyOutput: UI.modifiers.dimOnComplete,
46
+ })).pipe(Effect.catchTag('UIError', (e) => BadArgsError.make({ message: `UI error: ${e.message}` })), Effect.map((client) => ({ auth, client })));
47
+ });
48
+ const selectUpdateAction = Effect.fn(function* (options) {
49
+ return yield* runUIEffect(new UI.Select({
50
+ options,
51
+ promptText: 'What do you want to update?',
52
+ modifyOutput: UI.modifiers.dimOnComplete,
53
+ })).pipe(Effect.catchTag('UIError', (e) => BadArgsError.make({ message: `UI error: ${e.message}` })));
54
+ });
55
+ const updateGoogleToDevCredentials = Effect.fn(function* (client) {
56
+ const response = yield* updateOAuthClient({
57
+ oauthClientId: client.id,
58
+ clientId: null,
59
+ clientSecret: null,
60
+ useSharedCredentials: true,
61
+ redirectTo: null,
62
+ });
63
+ yield* Effect.log(boxen([
64
+ `Google OAuth client updated: ${response.client.client_name}`,
65
+ 'Credentials: Instant dev credentials',
66
+ `ID: ${response.client.id}`,
67
+ '',
68
+ 'No Google Console setup required.',
69
+ 'Works on localhost and Expo during development.',
70
+ '',
71
+ chalk.bold('Ready for production? Run:'),
72
+ ` instant-cli auth client update --name ${response.client.client_name} --client-id <id> --client-secret <secret>`,
73
+ ].join('\n'), { dimBorder: true, padding: { right: 1, left: 1 } }));
74
+ });
75
+ const hasGoogleCustomCredentialFlags = (opts) => hasAnyFlag(opts, ['client-id', 'client-secret', 'custom-redirect-uri']);
76
+ const hasGoogleUpdateFlags = (opts) => isTrueFlag(getFlag(opts, 'dev-credentials')) ||
77
+ hasGoogleCustomCredentialFlags(opts);
78
+ const optOrPromptWhenNeeded = (opts, flag, params) => Effect.gen(function* () {
79
+ const value = getFlag(opts, flag);
80
+ if (value === undefined && !params.promptIf)
81
+ return undefined;
82
+ return yield* optOrPrompt(value, {
83
+ simpleName: `--${flag}`,
84
+ required: params.required ?? params.promptIf,
85
+ skipIf: false,
86
+ prompt: params.prompt,
87
+ });
88
+ });
89
+ const selectGoogleUpdateMode = Effect.fn(function* ({ isWeb, switchingFromShared, }) {
90
+ if (switchingFromShared) {
91
+ return yield* runUIEffect(new UI.Select({
92
+ options: [
93
+ { label: 'Custom Google credentials', value: 'custom' },
94
+ {
95
+ label: 'Instant dev credentials' + chalk.dim(' (current)'),
96
+ value: 'none',
97
+ },
98
+ ],
99
+ promptText: 'Choose credential mode:',
100
+ modifyOutput: UI.modifiers.dimOnComplete,
101
+ })).pipe(Effect.catchTag('UIError', (e) => BadArgsError.make({ message: `UI error: ${e.message}` })));
102
+ }
103
+ const options = [
104
+ { label: 'Update Client ID and Client Secret', value: 'custom' },
105
+ ];
106
+ if (isWeb) {
107
+ options.push({
108
+ label: 'Switch to Instant dev credentials' +
109
+ chalk.dim(' (localhost and Expo, no Google setup)'),
110
+ value: 'dev',
111
+ }, { label: 'Update redirect URI', value: 'redirect' });
112
+ }
113
+ return yield* selectUpdateAction(options);
114
+ });
115
+ const resolveGoogleUpdateMode = Effect.fn(function* ({ opts, isWeb, switchingFromShared, }) {
116
+ const { yes } = yield* GlobalOpts;
117
+ const devCredentialsFlag = isTrueFlag(getFlag(opts, 'dev-credentials'));
118
+ const hasProvidedSomeCustomCredentials = hasGoogleCustomCredentialFlags(opts);
119
+ if (devCredentialsFlag && !isWeb) {
120
+ return yield* BadArgsError.make({
121
+ message: '--dev-credentials is only supported for Google web clients.',
122
+ });
123
+ }
124
+ if (!isWeb &&
125
+ (hasFlag(opts, 'client-secret') || hasFlag(opts, 'custom-redirect-uri'))) {
126
+ return yield* BadArgsError.make({
127
+ message: '--client-secret and --custom-redirect-uri are only supported for Google web clients.',
128
+ });
129
+ }
130
+ if (devCredentialsFlag && hasProvidedSomeCustomCredentials) {
131
+ return yield* BadArgsError.make({
132
+ message: '--dev-credentials cannot be combined with --client-id, --client-secret, or --custom-redirect-uri.',
133
+ });
134
+ }
135
+ if (devCredentialsFlag) {
136
+ return 'dev';
137
+ }
138
+ const hasAnyUpdateFlag = hasGoogleUpdateFlags(opts);
139
+ if (yes && !hasAnyUpdateFlag) {
140
+ return yield* BadArgsError.make({
141
+ message: 'Must specify at least one of --client-id, --client-secret, --custom-redirect-uri, or --dev-credentials.',
142
+ });
143
+ }
144
+ if (yes &&
145
+ isWeb &&
146
+ switchingFromShared &&
147
+ (!hasFlag(opts, 'client-id') || !hasFlag(opts, 'client-secret'))) {
148
+ return yield* BadArgsError.make({
149
+ message: 'Must specify both --client-id and --client-secret when switching from Instant dev credentials to custom credentials with --yes.',
150
+ });
151
+ }
152
+ if (hasAnyUpdateFlag) {
153
+ return 'custom';
154
+ }
155
+ return yield* selectGoogleUpdateMode({ isWeb, switchingFromShared });
156
+ });
157
+ const updateGoogleRedirect = Effect.fn(function* ({ opts, client, }) {
158
+ const redirectTo = yield* optOrPromptWhenNeeded(opts, 'custom-redirect-uri', {
159
+ promptIf: true,
160
+ required: true,
161
+ prompt: newRedirectPrompt,
162
+ });
163
+ if (!redirectTo) {
164
+ return yield* BadArgsError.make({
165
+ message: 'Missing required value for --custom-redirect-uri',
166
+ });
167
+ }
168
+ const response = yield* updateOAuthClient({
169
+ oauthClientId: client.id,
170
+ redirectTo,
171
+ });
172
+ yield* Effect.log(boxen([
173
+ `Google OAuth client updated: ${response.client.client_name}`,
174
+ `ID: ${response.client.id}`,
175
+ ...redirectSetupMessages({
176
+ prompt: 'Add this redirect URI in Google Console',
177
+ redirectUri: redirectTo,
178
+ showCustomRedirectInstructions: true,
179
+ }),
180
+ ].join('\n'), { dimBorder: true, padding: { right: 1, left: 1 } }));
181
+ });
182
+ const updateGoogleCustomCredentials = Effect.fn(function* ({ opts, client, isWeb, switchingFromShared, promptCredentials, }) {
183
+ const mustCollectCredentials = promptCredentials || switchingFromShared;
184
+ const shouldPromptClientId = promptCredentials || (switchingFromShared && !hasFlag(opts, 'client-id'));
185
+ const shouldPromptClientSecret = isWeb &&
186
+ (promptCredentials ||
187
+ (switchingFromShared && !hasFlag(opts, 'client-secret')));
188
+ const shouldPromptRedirectUri = isWeb && switchingFromShared && promptCredentials;
189
+ const clientId = yield* optOrPromptWhenNeeded(opts, 'client-id', {
190
+ promptIf: shouldPromptClientId,
191
+ required: mustCollectCredentials,
192
+ prompt: clientIdPrompt({ providerUrl: googleConsoleUrl }),
193
+ });
194
+ const clientSecret = yield* optOrPromptWhenNeeded(opts, 'client-secret', {
195
+ promptIf: shouldPromptClientSecret,
196
+ required: isWeb && mustCollectCredentials,
197
+ prompt: clientSecretPrompt({ providerUrl: googleConsoleUrl }),
198
+ });
199
+ const customRedirectUri = isWeb
200
+ ? yield* optOrPromptWhenNeeded(opts, 'custom-redirect-uri', {
201
+ promptIf: shouldPromptRedirectUri,
202
+ required: false,
203
+ prompt: redirectPrompt,
204
+ })
205
+ : undefined;
206
+ const redirectTo = switchingFromShared
207
+ ? customRedirectUri || client.redirect_to || DEFAULT_OAUTH_CALLBACK_URL
208
+ : customRedirectUri;
209
+ const response = yield* updateOAuthClient({
210
+ oauthClientId: client.id,
211
+ clientId,
212
+ clientSecret,
213
+ redirectTo,
214
+ useSharedCredentials: switchingFromShared ? false : undefined,
215
+ });
216
+ const lines = [
217
+ `Google OAuth client updated: ${response.client.client_name}`,
218
+ 'Credentials: custom',
219
+ `ID: ${response.client.id}`,
220
+ ];
221
+ if (switchingFromShared) {
222
+ lines.push('', 'This client no longer uses Instant dev credentials.');
223
+ }
224
+ if (isWeb && redirectTo) {
225
+ lines.push(...redirectSetupMessages({
226
+ prompt: 'Add this redirect URI in Google Console',
227
+ redirectUri: redirectTo,
228
+ showCustomRedirectInstructions: Boolean(customRedirectUri),
229
+ }));
230
+ }
231
+ yield* Effect.log(boxen(lines.join('\n'), {
232
+ dimBorder: true,
233
+ padding: { right: 1, left: 1 },
234
+ }));
235
+ });
236
+ const handleGoogleUpdate = Effect.fn(function* (opts, client) {
237
+ const { yes } = yield* GlobalOpts;
238
+ const appType = getMetaString(client.meta, 'appType');
239
+ const isWeb = appType === 'web' || !appType;
240
+ const switchingFromShared = Boolean(client.use_shared_credentials);
241
+ const hasAnyUpdateFlag = hasGoogleUpdateFlags(opts);
242
+ if (!hasAnyUpdateFlag && !yes) {
243
+ yield* Effect.log(`\nCurrent mode: ${switchingFromShared
244
+ ? chalk.bold('Instant dev credentials')
245
+ : 'custom credentials'}`);
246
+ }
247
+ const updateMode = yield* resolveGoogleUpdateMode({
248
+ opts,
249
+ isWeb,
250
+ switchingFromShared,
251
+ });
252
+ if (updateMode === 'dev') {
253
+ return yield* updateGoogleToDevCredentials(client);
254
+ }
255
+ if (updateMode === 'none') {
256
+ yield* Effect.log(chalk.dim('No changes made.'));
257
+ return;
258
+ }
259
+ if (updateMode === 'redirect') {
260
+ return yield* updateGoogleRedirect({ opts, client });
261
+ }
262
+ return yield* updateGoogleCustomCredentials({
263
+ opts,
264
+ client,
265
+ isWeb,
266
+ switchingFromShared,
267
+ promptCredentials: !hasAnyUpdateFlag && !yes,
268
+ });
269
+ });
270
+ const handleClientIdSecretUpdate = Effect.fn(function* (params) {
271
+ const { yes } = yield* GlobalOpts;
272
+ const hasAnyUpdateFlag = hasAnyFlag(params.opts, [
273
+ 'client-id',
274
+ 'client-secret',
275
+ 'custom-redirect-uri',
276
+ ]);
277
+ if (yes && !hasAnyUpdateFlag) {
278
+ return yield* BadArgsError.make({
279
+ message: 'Must specify at least one of --client-id, --client-secret, or --custom-redirect-uri.',
280
+ });
281
+ }
282
+ let promptCredentials = false;
283
+ let promptRedirect = false;
284
+ if (!hasAnyUpdateFlag && !yes) {
285
+ const action = yield* selectUpdateAction([
286
+ { label: 'Update Client ID and Client Secret', value: 'rotate' },
287
+ { label: 'Update redirect URI', value: 'redirect' },
288
+ ]);
289
+ promptCredentials = action === 'rotate';
290
+ promptRedirect = action === 'redirect';
291
+ }
292
+ const clientId = yield* optOrPromptWhenNeeded(params.opts, 'client-id', {
293
+ promptIf: promptCredentials,
294
+ required: promptCredentials,
295
+ prompt: clientIdPrompt({ providerUrl: params.providerUrl }),
296
+ });
297
+ const clientSecret = yield* optOrPromptWhenNeeded(params.opts, 'client-secret', {
298
+ promptIf: promptCredentials,
299
+ required: promptCredentials,
300
+ prompt: clientSecretPrompt({ providerUrl: params.providerUrl }),
301
+ });
302
+ const customRedirectUri = yield* optOrPromptWhenNeeded(params.opts, 'custom-redirect-uri', {
303
+ promptIf: promptRedirect,
304
+ required: promptRedirect,
305
+ prompt: promptRedirect ? newRedirectPrompt : redirectPrompt,
306
+ });
307
+ const response = yield* updateOAuthClient({
308
+ oauthClientId: params.client.id,
309
+ clientId,
310
+ clientSecret,
311
+ redirectTo: customRedirectUri,
312
+ });
313
+ const lines = [
314
+ `${params.providerLabel} OAuth client updated: ${response.client.client_name}`,
315
+ `ID: ${response.client.id}`,
316
+ ];
317
+ if (customRedirectUri) {
318
+ lines.push(...redirectSetupMessages({
319
+ prompt: params.redirectSetupPrompt,
320
+ redirectUri: customRedirectUri,
321
+ showCustomRedirectInstructions: true,
322
+ }));
323
+ }
324
+ yield* Effect.log(boxen(lines.join('\n'), {
325
+ dimBorder: true,
326
+ padding: { right: 1, left: 1 },
327
+ }));
328
+ });
329
+ const appleWebFlags = [
330
+ 'team-id',
331
+ 'key-id',
332
+ 'private-key-file',
333
+ 'custom-redirect-uri',
334
+ ];
335
+ const appleUpdateFlags = ['services-id', ...appleWebFlags];
336
+ const hasAppleWebFlags = (opts) => hasAnyFlag(opts, appleWebFlags);
337
+ const hasAppleUpdateFlags = (opts) => hasAnyFlag(opts, appleUpdateFlags);
338
+ const appleClientHasWebConfig = (client) => Boolean(getMetaString(client.meta, 'teamId') ||
339
+ getMetaString(client.meta, 'keyId') ||
340
+ client.redirect_to);
341
+ const resolveAppleUpdateConfig = Effect.fn(function* ({ opts, client, yes, }) {
342
+ const hasAnyUpdateFlag = hasAppleUpdateFlags(opts);
343
+ if (yes && !hasAnyUpdateFlag) {
344
+ return yield* BadArgsError.make({
345
+ message: 'Must specify at least one of --services-id, --team-id, --key-id, --private-key-file, or --custom-redirect-uri.',
346
+ });
347
+ }
348
+ const promptAll = !hasAnyUpdateFlag && !yes;
349
+ if (!promptAll) {
350
+ return { promptAll, configureWeb: hasAppleWebFlags(opts) };
351
+ }
352
+ const configureWeb = yield* runUIEffect(new UI.Confirmation({
353
+ promptText: 'Configure web redirect flow? ' +
354
+ chalk.dim('(requires Team ID, Key ID, and a .p8 private key from Apple)'),
355
+ defaultValue: appleClientHasWebConfig(client),
356
+ })).pipe(Effect.catchTag('UIError', (e) => BadArgsError.make({ message: `UI error: ${e.message}` })));
357
+ return { promptAll, configureWeb };
358
+ });
359
+ const readAppleWebUpdate = Effect.fn(function* ({ opts, client, promptAll, }) {
360
+ const teamId = yield* optOrPromptWhenNeeded(opts, 'team-id', {
361
+ promptIf: promptAll,
362
+ required: promptAll,
363
+ prompt: appleTeamIdPrompt({}),
364
+ });
365
+ const keyId = yield* optOrPromptWhenNeeded(opts, 'key-id', {
366
+ promptIf: promptAll,
367
+ required: promptAll,
368
+ prompt: appleKeyIdPrompt({}),
369
+ });
370
+ const privateKeyPath = yield* optOrPromptWhenNeeded(opts, 'private-key-file', {
371
+ promptIf: promptAll,
372
+ required: promptAll,
373
+ prompt: applePrivateKeyFilePrompt({}),
374
+ });
375
+ const privateKey = privateKeyPath
376
+ ? yield* readPrivateKeyFile(privateKeyPath)
377
+ : undefined;
378
+ const customRedirectUri = yield* optOrPromptWhenNeeded(opts, 'custom-redirect-uri', {
379
+ promptIf: promptAll,
380
+ required: false,
381
+ prompt: redirectPrompt,
382
+ });
383
+ const meta = {};
384
+ if (teamId)
385
+ meta.teamId = teamId;
386
+ if (keyId)
387
+ meta.keyId = keyId;
388
+ return {
389
+ privateKey,
390
+ redirectTo: privateKey
391
+ ? customRedirectUri || client.redirect_to || DEFAULT_OAUTH_CALLBACK_URL
392
+ : customRedirectUri,
393
+ customRedirectUri,
394
+ meta: Object.keys(meta).length ? meta : undefined,
395
+ };
396
+ });
397
+ const handleAppleUpdate = Effect.fn(function* (opts, client) {
398
+ const { yes } = yield* GlobalOpts;
399
+ const { promptAll, configureWeb } = yield* resolveAppleUpdateConfig({
400
+ opts,
401
+ client,
402
+ yes,
403
+ });
404
+ const servicesId = yield* optOrPromptWhenNeeded(opts, 'services-id', {
405
+ promptIf: promptAll,
406
+ required: promptAll,
407
+ prompt: appleServicesIdPrompt({}),
408
+ });
409
+ const webUpdate = configureWeb
410
+ ? yield* readAppleWebUpdate({ opts, client, promptAll })
411
+ : {};
412
+ const response = yield* updateOAuthClient({
413
+ oauthClientId: client.id,
414
+ clientId: servicesId,
415
+ clientSecret: webUpdate.privateKey,
416
+ redirectTo: webUpdate.redirectTo,
417
+ meta: webUpdate.meta,
418
+ });
419
+ const lines = [
420
+ `Apple OAuth client updated: ${response.client.client_name}`,
421
+ `ID: ${response.client.id}`,
422
+ ];
423
+ if (webUpdate.redirectTo) {
424
+ lines.push(...redirectSetupMessages({
425
+ prompt: `Add this return URL under your Services ID on ${link('https://developer.apple.com', 'developer.apple.com')}`,
426
+ redirectUri: webUpdate.redirectTo,
427
+ showCustomRedirectInstructions: Boolean(webUpdate.customRedirectUri),
428
+ }));
429
+ }
430
+ yield* Effect.log(boxen(lines.join('\n'), {
431
+ dimBorder: true,
432
+ padding: { right: 1, left: 1 },
433
+ }));
434
+ });
435
+ const handleClerkUpdate = Effect.fn(function* (opts, client) {
436
+ const { yes } = yield* GlobalOpts;
437
+ const publishableKey = yield* optOrPromptWhenNeeded(opts, 'publishable-key', {
438
+ promptIf: !yes && !hasFlag(opts, 'publishable-key'),
439
+ required: true,
440
+ prompt: clerkPublishableKeyPrompt({}),
441
+ });
442
+ if (!publishableKey) {
443
+ return yield* BadArgsError.make({
444
+ message: 'Missing required value for --publishable-key',
445
+ });
446
+ }
447
+ const domain = clerkDomainFromPublishableKey(publishableKey);
448
+ if (!domain) {
449
+ return yield* BadArgsError.make({
450
+ message: 'Invalid publishable key. Could not extract domain.',
451
+ });
452
+ }
453
+ const response = yield* updateOAuthClient({
454
+ oauthClientId: client.id,
455
+ discoveryEndpoint: `https://${domain}/.well-known/openid-configuration`,
456
+ meta: { clerkPublishableKey: publishableKey },
457
+ });
458
+ yield* Effect.log(boxen([
459
+ `Clerk OAuth client updated: ${response.client.client_name}`,
460
+ `ID: ${response.client.id}`,
461
+ `Clerk Domain: https://${domain}`,
462
+ ].join('\n'), { dimBorder: true, padding: { right: 1, left: 1 } }));
463
+ });
464
+ const handleFirebaseUpdate = Effect.fn(function* (opts, client) {
465
+ const { yes } = yield* GlobalOpts;
466
+ const projectId = yield* optOrPromptWhenNeeded(opts, 'project-id', {
467
+ promptIf: !yes && !hasFlag(opts, 'project-id'),
468
+ required: true,
469
+ prompt: firebaseProjectIdPrompt({}),
470
+ });
471
+ const validationError = validateFirebaseProjectId(projectId ?? '');
472
+ if (validationError) {
473
+ return yield* BadArgsError.make({ message: validationError });
474
+ }
475
+ const response = yield* updateOAuthClient({
476
+ oauthClientId: client.id,
477
+ discoveryEndpoint: firebaseDiscoveryEndpoint(projectId),
478
+ });
479
+ yield* Effect.log(boxen([
480
+ `Firebase OAuth client updated: ${response.client.client_name}`,
481
+ `ID: ${response.client.id}`,
482
+ `Firebase Project ID: ${projectId}`,
483
+ ].join('\n'), { dimBorder: true, padding: { right: 1, left: 1 } }));
484
+ });
485
+ export const authClientUpdateCmd = Effect.fn(function* (opts) {
486
+ const { auth, client: resolvedClient } = yield* resolveClient({
487
+ id: opts.id,
488
+ name: opts.name,
489
+ });
490
+ const provider = (auth.oauth_service_providers ?? []).find((entry) => entry.id === resolvedClient.provider_id);
491
+ if (!provider) {
492
+ return yield* BadArgsError.make({
493
+ message: `OAuth provider not found for client: ${resolvedClient.client_name}`,
494
+ });
495
+ }
496
+ yield* Match.value(provider.provider_name).pipe(Match.withReturnType(), Match.when('google', () => handleGoogleUpdate(opts, resolvedClient)), Match.when('github', () => handleClientIdSecretUpdate({
497
+ opts,
498
+ client: resolvedClient,
499
+ providerLabel: 'GitHub',
500
+ providerUrl: 'https://github.com/settings/developers',
501
+ redirectSetupPrompt: 'Add this callback URL in your GitHub OAuth App settings',
502
+ })), Match.when('linkedin', () => handleClientIdSecretUpdate({
503
+ opts,
504
+ client: resolvedClient,
505
+ providerLabel: 'LinkedIn',
506
+ providerUrl: 'https://www.linkedin.com/developers/apps',
507
+ redirectSetupPrompt: 'Add this redirect URI in your LinkedIn app settings',
508
+ })), Match.when('apple', () => handleAppleUpdate(opts, resolvedClient)), Match.when('clerk', () => handleClerkUpdate(opts, resolvedClient)), Match.when('firebase', () => handleFirebaseUpdate(opts, resolvedClient)), Match.orElse((providerName) => BadArgsError.make({
509
+ message: `Updating ${providerName} OAuth clients is not supported.`,
510
+ })));
511
+ }, Effect.catchTag('BadArgsError', (e) => Effect.gen(function* () {
512
+ yield* Effect.logError(e.message);
513
+ yield* Effect.log(chalk.dim('hint: run `instant-cli auth client update --help` for available arguments'));
514
+ })));
515
+ //# sourceMappingURL=update.js.map