instant-cli 1.0.23-branch-codex-cli-args-combinators.25394030897.1 → 1.0.23-branch-codex-cli-args-combinators.25395572961.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.
- package/.turbo/turbo-build.log +1 -1
- package/__tests__/args.test.ts +89 -45
- package/__tests__/oauthMock.ts +3 -2
- package/dist/commands/auth/client/add.d.ts.map +1 -1
- package/dist/commands/auth/client/add.js +57 -28
- package/dist/commands/auth/client/add.js.map +1 -1
- package/dist/commands/auth/client/shared.d.ts +0 -4
- package/dist/commands/auth/client/shared.d.ts.map +1 -1
- package/dist/commands/auth/client/shared.js +0 -4
- package/dist/commands/auth/client/shared.js.map +1 -1
- package/dist/commands/auth/client/update.d.ts.map +1 -1
- package/dist/commands/auth/client/update.js +59 -29
- package/dist/commands/auth/client/update.js.map +1 -1
- package/dist/commands/auth/origin/add.d.ts.map +1 -1
- package/dist/commands/auth/origin/add.js +8 -4
- package/dist/commands/auth/origin/add.js.map +1 -1
- package/dist/lib/args.d.ts +42 -29
- package/dist/lib/args.d.ts.map +1 -1
- package/dist/lib/args.js +91 -73
- package/dist/lib/args.js.map +1 -1
- package/dist/lib/oauth.d.ts.map +1 -1
- package/dist/lib/oauth.js +2 -1
- package/dist/lib/oauth.js.map +1 -1
- package/package.json +4 -4
- package/src/commands/auth/client/add.ts +88 -78
- package/src/commands/auth/client/shared.ts +0 -12
- package/src/commands/auth/client/update.ts +106 -98
- package/src/commands/auth/origin/add.ts +12 -8
- package/src/lib/args.ts +175 -120
- package/src/lib/oauth.ts +3 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
> instant-cli@1.0.23-branch-codex-cli-args-combinators.
|
|
2
|
+
> instant-cli@1.0.23-branch-codex-cli-args-combinators.25395572961.1 build /home/runner/work/instant/instant/client/packages/cli
|
|
3
3
|
> rm -rf dist; tsc -p tsconfig.build.json
|
|
4
4
|
|
package/__tests__/args.test.ts
CHANGED
|
@@ -27,17 +27,20 @@ vi.mock('../src/ui/lib.ts', async (importOriginal) => {
|
|
|
27
27
|
|
|
28
28
|
const basePrompt = { prompt: 'Client ID:' } as any;
|
|
29
29
|
|
|
30
|
-
describe('
|
|
31
|
-
test('
|
|
30
|
+
describe('availableWhen', () => {
|
|
31
|
+
test('unavailable + value provided -> error', async () => {
|
|
32
32
|
const err = await runFail(
|
|
33
|
-
Args.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
Args.from({
|
|
34
|
+
'custom-redirect-uri': 'https://mysite.com/callback',
|
|
35
|
+
})
|
|
36
|
+
.text('custom-redirect-uri')
|
|
37
|
+
.pipe(
|
|
38
|
+
Args.availableWhen(false, {
|
|
39
|
+
message:
|
|
40
|
+
'Provided custom redirect URI when not using web app type.',
|
|
41
|
+
}),
|
|
42
|
+
Args.optional(),
|
|
43
|
+
),
|
|
41
44
|
false,
|
|
42
45
|
);
|
|
43
46
|
|
|
@@ -46,9 +49,30 @@ describe('forbidIf', () => {
|
|
|
46
49
|
);
|
|
47
50
|
});
|
|
48
51
|
|
|
49
|
-
test('
|
|
52
|
+
test('unavailable + empty value provided -> error', async () => {
|
|
53
|
+
const err = await runFail(
|
|
54
|
+
Args.from({ 'custom-redirect-uri': '' })
|
|
55
|
+
.text('custom-redirect-uri')
|
|
56
|
+
.pipe(
|
|
57
|
+
Args.availableWhen(false, {
|
|
58
|
+
message:
|
|
59
|
+
'Provided custom redirect URI when not using web app type.',
|
|
60
|
+
}),
|
|
61
|
+
Args.optional(),
|
|
62
|
+
),
|
|
63
|
+
false,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
expect(err.message).toBe(
|
|
67
|
+
'Provided custom redirect URI when not using web app type.',
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('unavailable + no value -> undefined', async () => {
|
|
50
72
|
const result = await run(
|
|
51
|
-
Args.
|
|
73
|
+
Args.from({})
|
|
74
|
+
.text('custom-redirect-uri')
|
|
75
|
+
.pipe(Args.availableWhen(false), Args.optional()),
|
|
52
76
|
false,
|
|
53
77
|
);
|
|
54
78
|
|
|
@@ -59,10 +83,9 @@ describe('forbidIf', () => {
|
|
|
59
83
|
describe('non-interactive', () => {
|
|
60
84
|
test('required missing value -> error', async () => {
|
|
61
85
|
const err = await runFail(
|
|
62
|
-
Args.
|
|
63
|
-
|
|
64
|
-
Args.required(),
|
|
65
|
-
),
|
|
86
|
+
Args.from({})
|
|
87
|
+
.text('client-id')
|
|
88
|
+
.pipe(Args.prompt(basePrompt), Args.required()),
|
|
66
89
|
true,
|
|
67
90
|
);
|
|
68
91
|
|
|
@@ -71,7 +94,7 @@ describe('non-interactive', () => {
|
|
|
71
94
|
|
|
72
95
|
test('number value -> stringified', async () => {
|
|
73
96
|
const result = await run(
|
|
74
|
-
Args.
|
|
97
|
+
Args.from({ 'client-id': 42 }).text('client-id').pipe(Args.required()),
|
|
75
98
|
true,
|
|
76
99
|
);
|
|
77
100
|
|
|
@@ -80,7 +103,7 @@ describe('non-interactive', () => {
|
|
|
80
103
|
|
|
81
104
|
test('non-string/number value -> error', async () => {
|
|
82
105
|
const err = await runFail(
|
|
83
|
-
Args.
|
|
106
|
+
Args.from({ 'client-id': true }).text('client-id').pipe(Args.required()),
|
|
84
107
|
true,
|
|
85
108
|
);
|
|
86
109
|
|
|
@@ -89,10 +112,9 @@ describe('non-interactive', () => {
|
|
|
89
112
|
|
|
90
113
|
test('valid string -> trimmed value', async () => {
|
|
91
114
|
const result = await run(
|
|
92
|
-
Args.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
).pipe(Args.required()),
|
|
115
|
+
Args.from({ 'client-id': ' abc123.apps.googleusercontent.com ' })
|
|
116
|
+
.text('client-id')
|
|
117
|
+
.pipe(Args.required()),
|
|
96
118
|
true,
|
|
97
119
|
);
|
|
98
120
|
|
|
@@ -100,14 +122,30 @@ describe('non-interactive', () => {
|
|
|
100
122
|
});
|
|
101
123
|
|
|
102
124
|
test('optional missing value -> undefined', async () => {
|
|
103
|
-
const result = await run(
|
|
125
|
+
const result = await run(
|
|
126
|
+
Args.from({}).text('custom-redirect-uri').pipe(Args.optional()),
|
|
127
|
+
true,
|
|
128
|
+
);
|
|
104
129
|
|
|
105
130
|
expect(result).toBeUndefined();
|
|
106
131
|
});
|
|
107
132
|
|
|
133
|
+
test('flag name can include leading dashes', async () => {
|
|
134
|
+
const result = await run(
|
|
135
|
+
Args.from({ 'client-id': 'abc123' })
|
|
136
|
+
.text('--client-id')
|
|
137
|
+
.pipe(Args.required()),
|
|
138
|
+
true,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
expect(result).toBe('abc123');
|
|
142
|
+
});
|
|
143
|
+
|
|
108
144
|
test('boolean value -> parsed', async () => {
|
|
109
145
|
const result = await run(
|
|
110
|
-
Args.
|
|
146
|
+
Args.from({ 'configure-web': true })
|
|
147
|
+
.bool('configure-web')
|
|
148
|
+
.pipe(Args.optional()),
|
|
111
149
|
true,
|
|
112
150
|
);
|
|
113
151
|
|
|
@@ -116,7 +154,9 @@ describe('non-interactive', () => {
|
|
|
116
154
|
|
|
117
155
|
test('boolean string value -> parsed', async () => {
|
|
118
156
|
const result = await run(
|
|
119
|
-
Args.
|
|
157
|
+
Args.from({ 'configure-web': 'false' })
|
|
158
|
+
.bool('configure-web')
|
|
159
|
+
.pipe(Args.optional()),
|
|
120
160
|
true,
|
|
121
161
|
);
|
|
122
162
|
|
|
@@ -125,7 +165,9 @@ describe('non-interactive', () => {
|
|
|
125
165
|
|
|
126
166
|
test('invalid boolean value -> error', async () => {
|
|
127
167
|
const err = await runFail(
|
|
128
|
-
Args.
|
|
168
|
+
Args.from({ 'configure-web': 'sometimes' })
|
|
169
|
+
.bool('configure-web')
|
|
170
|
+
.pipe(Args.optional()),
|
|
129
171
|
true,
|
|
130
172
|
);
|
|
131
173
|
|
|
@@ -136,10 +178,9 @@ describe('non-interactive', () => {
|
|
|
136
178
|
describe('interactive', () => {
|
|
137
179
|
test('value already provided -> use it directly', async () => {
|
|
138
180
|
const result = await run(
|
|
139
|
-
Args.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
).pipe(Args.orPrompt(basePrompt), Args.required()),
|
|
181
|
+
Args.from({ 'client-id': ' abc123.apps.googleusercontent.com ' })
|
|
182
|
+
.text('client-id')
|
|
183
|
+
.pipe(Args.prompt(basePrompt), Args.required()),
|
|
143
184
|
false,
|
|
144
185
|
);
|
|
145
186
|
|
|
@@ -150,10 +191,9 @@ describe('interactive', () => {
|
|
|
150
191
|
mockPromptReturn = ' GOCSPX-secret123 ';
|
|
151
192
|
|
|
152
193
|
const result = await run(
|
|
153
|
-
Args.
|
|
154
|
-
|
|
155
|
-
Args.required(),
|
|
156
|
-
),
|
|
194
|
+
Args.from({})
|
|
195
|
+
.text('client-secret')
|
|
196
|
+
.pipe(Args.prompt(basePrompt), Args.required()),
|
|
157
197
|
false,
|
|
158
198
|
);
|
|
159
199
|
|
|
@@ -164,10 +204,9 @@ describe('interactive', () => {
|
|
|
164
204
|
mockPromptReturn = '';
|
|
165
205
|
|
|
166
206
|
const err = await runFail(
|
|
167
|
-
Args.
|
|
168
|
-
|
|
169
|
-
Args.required(),
|
|
170
|
-
),
|
|
207
|
+
Args.from({})
|
|
208
|
+
.text('client-secret')
|
|
209
|
+
.pipe(Args.prompt(basePrompt), Args.required()),
|
|
171
210
|
false,
|
|
172
211
|
);
|
|
173
212
|
|
|
@@ -178,7 +217,9 @@ describe('interactive', () => {
|
|
|
178
217
|
mockPromptReturn = '';
|
|
179
218
|
|
|
180
219
|
const result = await run(
|
|
181
|
-
Args.
|
|
220
|
+
Args.from({})
|
|
221
|
+
.text('custom-redirect-uri')
|
|
222
|
+
.pipe(Args.prompt(basePrompt), Args.optional()),
|
|
182
223
|
false,
|
|
183
224
|
);
|
|
184
225
|
|
|
@@ -189,12 +230,15 @@ describe('interactive', () => {
|
|
|
189
230
|
mockPromptReturn = true;
|
|
190
231
|
|
|
191
232
|
const result = await run(
|
|
192
|
-
Args.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
233
|
+
Args.from({})
|
|
234
|
+
.bool('configure-web')
|
|
235
|
+
.pipe(
|
|
236
|
+
Args.confirm({
|
|
237
|
+
promptText: 'Configure web redirect flow?',
|
|
238
|
+
defaultValue: false,
|
|
239
|
+
}),
|
|
240
|
+
Args.optional(),
|
|
241
|
+
),
|
|
198
242
|
false,
|
|
199
243
|
);
|
|
200
244
|
|
package/__tests__/oauthMock.ts
CHANGED
|
@@ -40,13 +40,14 @@ export const makeOAuthMock = (mocks: {
|
|
|
40
40
|
providerType: string,
|
|
41
41
|
opts: Record<string, unknown>,
|
|
42
42
|
) {
|
|
43
|
+
const args = Args.from(opts);
|
|
43
44
|
const { auth, provider } = yield* getOrCreateProvider(providerType);
|
|
44
45
|
const used: Set<string> = new Set(
|
|
45
46
|
(auth.oauth_clients ?? []).map((c: any) => c.client_name),
|
|
46
47
|
);
|
|
47
48
|
const suggested = findName(providerType, used);
|
|
48
|
-
const clientName = yield*
|
|
49
|
-
Args.
|
|
49
|
+
const clientName = yield* args.text('name').pipe(
|
|
50
|
+
Args.prompt({
|
|
50
51
|
prompt: 'Client Name:',
|
|
51
52
|
defaultValue: suggested,
|
|
52
53
|
placeholder: suggested,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../../src/commands/auth/client/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../../src/commands/auth/client/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AA4C5D,eAAO,MAAM,gBAAgB,gFAO5B,CAAC;AAopBF,eAAO,MAAM,gBAAgB;;;;wgBAwD5B,CAAC"}
|
|
@@ -9,7 +9,7 @@ import { UI } from "../../../ui/index.js";
|
|
|
9
9
|
import chalk from 'chalk';
|
|
10
10
|
import boxen from 'boxen';
|
|
11
11
|
import { link } from "../../../logging.js";
|
|
12
|
-
import { appleKeyIdPrompt, applePrivateKeyFilePrompt, appleServicesIdPrompt, appleTeamIdPrompt, clerkPublishableKeyPrompt, clientIdPrompt, clientSecretPrompt, firebaseDiscoveryEndpoint, firebaseProjectIdPrompt,
|
|
12
|
+
import { appleKeyIdPrompt, applePrivateKeyFilePrompt, appleServicesIdPrompt, appleTeamIdPrompt, clerkPublishableKeyPrompt, clientIdPrompt, clientSecretPrompt, firebaseDiscoveryEndpoint, firebaseProjectIdPrompt, readPrivateKeyFile, redirectSetupMessages, redirectUriPrompt, validateFirebaseProjectId, } from "./shared.js";
|
|
13
13
|
export const ClientTypeSchema = Schema.Literal('google', 'github', 'apple', 'linkedin', 'clerk', 'firebase');
|
|
14
14
|
const googleConsoleUrl = 'https://console.developers.google.com/apis/credentials';
|
|
15
15
|
const githubDeveloperUrl = 'https://github.com/settings/developers';
|
|
@@ -70,8 +70,9 @@ const selectGoogleCredentialMode = Effect.fn(function* () {
|
|
|
70
70
|
});
|
|
71
71
|
const resolveGoogleCredentialMode = Effect.fn(function* ({ appType, opts, }) {
|
|
72
72
|
const { yes } = yield* GlobalOpts;
|
|
73
|
-
const
|
|
74
|
-
const
|
|
73
|
+
const args = Args.from(opts);
|
|
74
|
+
const devCredentialsFlag = args.isTrue('dev-credentials');
|
|
75
|
+
const hasProvidedSomeCustomCredentials = args.hasAny([
|
|
75
76
|
'client-id',
|
|
76
77
|
'client-secret',
|
|
77
78
|
'custom-redirect-uri',
|
|
@@ -132,6 +133,7 @@ const printGoogleCustomCredentialsClient = Effect.fn(function* ({ appType, clien
|
|
|
132
133
|
].join('\n'), { dimBorder: true, padding: { right: 1, left: 1 } }));
|
|
133
134
|
});
|
|
134
135
|
const handleGoogleClient = Effect.fn(function* (opts) {
|
|
136
|
+
const args = Args.from(opts);
|
|
135
137
|
// This one requires special logic for getting client name
|
|
136
138
|
// because the suggested name includes the app type
|
|
137
139
|
const appType = yield* selectGoogleAppType(opts['app-type']);
|
|
@@ -143,7 +145,7 @@ const handleGoogleClient = Effect.fn(function* (opts) {
|
|
|
143
145
|
const { auth, provider } = yield* getOrCreateProvider('google');
|
|
144
146
|
const usedClientNames = new Set((auth.oauth_clients ?? []).map((client) => client.client_name));
|
|
145
147
|
const suggestedClientName = findName(`google-${appType}`, usedClientNames);
|
|
146
|
-
const clientName = yield*
|
|
148
|
+
const clientName = yield* args.text('name').pipe(Args.prompt({
|
|
147
149
|
prompt: 'Client Name:',
|
|
148
150
|
defaultValue: suggestedClientName,
|
|
149
151
|
placeholder: suggestedClientName,
|
|
@@ -158,20 +160,20 @@ const handleGoogleClient = Effect.fn(function* (opts) {
|
|
|
158
160
|
message: `The unique name '${clientName}' is already in use.`,
|
|
159
161
|
});
|
|
160
162
|
}
|
|
161
|
-
const clientId = yield*
|
|
163
|
+
const clientId = yield* args.text('client-id').pipe(Args.availableWhen(!useSharedCredentials, {
|
|
162
164
|
message: '--client-id is not compatible with --dev-credentials. Drop one or the other.',
|
|
163
|
-
}), Args.
|
|
165
|
+
}), Args.prompt(clientIdPrompt({ providerUrl: googleConsoleUrl })), Args.required());
|
|
164
166
|
const usesCustomWebCredentials = !useSharedCredentials && appType === 'web';
|
|
165
|
-
const clientSecret = yield*
|
|
167
|
+
const clientSecret = yield* args.text('client-secret').pipe(Args.availableWhen(usesCustomWebCredentials, {
|
|
166
168
|
message: useSharedCredentials
|
|
167
169
|
? '--client-secret is not compatible with --dev-credentials. Drop one or the other.'
|
|
168
170
|
: undefined,
|
|
169
|
-
}), Args.
|
|
170
|
-
const customRedirectUri = yield*
|
|
171
|
+
}), Args.prompt(clientSecretPrompt({ providerUrl: googleConsoleUrl })), Args.required());
|
|
172
|
+
const customRedirectUri = yield* args.text('custom-redirect-uri').pipe(Args.availableWhen(usesCustomWebCredentials, {
|
|
171
173
|
message: useSharedCredentials
|
|
172
174
|
? '--custom-redirect-uri is not compatible with --dev-credentials.'
|
|
173
175
|
: 'Provided custom redirect URI when not using web app type.',
|
|
174
|
-
}), Args.
|
|
176
|
+
}), Args.prompt(optionalRedirectPrompt), Args.optional());
|
|
175
177
|
if (!clientName) {
|
|
176
178
|
return yield* BadArgsError.make({ message: 'Client name is required.' }); // Should never reach this
|
|
177
179
|
}
|
|
@@ -209,10 +211,17 @@ const handleGoogleClient = Effect.fn(function* (opts) {
|
|
|
209
211
|
});
|
|
210
212
|
});
|
|
211
213
|
const handleGithubClient = Effect.fn(function* (opts) {
|
|
214
|
+
const args = Args.from(opts);
|
|
212
215
|
const { clientName, provider } = yield* getClientNameAndProvider('github', opts);
|
|
213
|
-
const clientId = yield*
|
|
214
|
-
|
|
215
|
-
|
|
216
|
+
const clientId = yield* args
|
|
217
|
+
.text('client-id')
|
|
218
|
+
.pipe(Args.prompt(clientIdPrompt({ providerUrl: githubDeveloperUrl })), Args.required());
|
|
219
|
+
const clientSecret = yield* args
|
|
220
|
+
.text('client-secret')
|
|
221
|
+
.pipe(Args.prompt(clientSecretPrompt({ providerUrl: githubDeveloperUrl })), Args.required());
|
|
222
|
+
const customRedirectUri = yield* args
|
|
223
|
+
.text('custom-redirect-uri')
|
|
224
|
+
.pipe(Args.prompt(optionalRedirectPrompt), Args.optional());
|
|
216
225
|
if (!clientName) {
|
|
217
226
|
return yield* BadArgsError.make({ message: 'Client name is required.' });
|
|
218
227
|
}
|
|
@@ -240,10 +249,17 @@ const handleGithubClient = Effect.fn(function* (opts) {
|
|
|
240
249
|
].join('\n'), { dimBorder: true, padding: { right: 1, left: 1 } }));
|
|
241
250
|
});
|
|
242
251
|
const handleLinkedInClient = Effect.fn(function* (opts) {
|
|
252
|
+
const args = Args.from(opts);
|
|
243
253
|
const { clientName, provider } = yield* getClientNameAndProvider('linkedin', opts);
|
|
244
|
-
const clientId = yield*
|
|
245
|
-
|
|
246
|
-
|
|
254
|
+
const clientId = yield* args
|
|
255
|
+
.text('client-id')
|
|
256
|
+
.pipe(Args.prompt(clientIdPrompt({ providerUrl: linkedinDeveloperUrl })), Args.required());
|
|
257
|
+
const clientSecret = yield* args
|
|
258
|
+
.text('client-secret')
|
|
259
|
+
.pipe(Args.prompt(clientSecretPrompt({ providerUrl: linkedinDeveloperUrl })), Args.required());
|
|
260
|
+
const customRedirectUri = yield* args
|
|
261
|
+
.text('custom-redirect-uri')
|
|
262
|
+
.pipe(Args.prompt(optionalRedirectPrompt), Args.optional());
|
|
247
263
|
if (!clientName) {
|
|
248
264
|
return yield* BadArgsError.make({ message: 'Client name is required.' });
|
|
249
265
|
}
|
|
@@ -272,33 +288,40 @@ const handleLinkedInClient = Effect.fn(function* (opts) {
|
|
|
272
288
|
});
|
|
273
289
|
const handleAppleClient = Effect.fn(function* (opts) {
|
|
274
290
|
const { yes } = yield* GlobalOpts;
|
|
291
|
+
const args = Args.from(opts);
|
|
275
292
|
const { clientName, provider } = yield* getClientNameAndProvider('apple', opts);
|
|
276
|
-
const servicesId = yield*
|
|
293
|
+
const servicesId = yield* args
|
|
294
|
+
.text('services-id')
|
|
295
|
+
.pipe(Args.prompt(appleServicesIdPrompt({})), Args.required());
|
|
277
296
|
// If any web-flow flag is provided, enable web flow; otherwise ask
|
|
278
297
|
// (non-interactively with --yes we default to native-only).
|
|
279
|
-
const anyWebFlagProvided = Boolean(
|
|
298
|
+
const anyWebFlagProvided = Boolean(args.hasAny(['team-id', 'key-id', 'private-key-file']));
|
|
280
299
|
const configureWeb = anyWebFlagProvided
|
|
281
300
|
? true
|
|
282
301
|
: yes
|
|
283
302
|
? false
|
|
284
|
-
: Boolean(yield*
|
|
303
|
+
: Boolean(yield* args.bool('configure-web').pipe(Args.confirm({
|
|
285
304
|
promptText: 'Configure web redirect flow? ' +
|
|
286
305
|
chalk.dim('(requires Team ID, Key ID, and a .p8 private key from Apple)'),
|
|
287
306
|
defaultValue: false,
|
|
288
|
-
})));
|
|
307
|
+
}), Args.optional()));
|
|
289
308
|
const skipWeb = !configureWeb;
|
|
290
309
|
const webSkipMessage = 'requires configuring the web redirect flow (also provide --team-id, --key-id, and --private-key-file).';
|
|
291
|
-
const teamId = yield*
|
|
292
|
-
|
|
293
|
-
|
|
310
|
+
const teamId = yield* args
|
|
311
|
+
.text('team-id')
|
|
312
|
+
.pipe(Args.availableWhen(!skipWeb, { message: `--team-id ${webSkipMessage}` }), Args.prompt(appleTeamIdPrompt({})), Args.required());
|
|
313
|
+
const keyId = yield* args
|
|
314
|
+
.text('key-id')
|
|
315
|
+
.pipe(Args.availableWhen(!skipWeb, { message: `--key-id ${webSkipMessage}` }), Args.prompt(appleKeyIdPrompt({})), Args.required());
|
|
316
|
+
const privateKeyPath = yield* args.text('private-key-file').pipe(Args.availableWhen(!skipWeb, {
|
|
294
317
|
message: `--private-key-file ${webSkipMessage}`,
|
|
295
|
-
}), Args.
|
|
318
|
+
}), Args.prompt(applePrivateKeyFilePrompt({})), Args.required());
|
|
296
319
|
const privateKey = privateKeyPath
|
|
297
320
|
? yield* readPrivateKeyFile(privateKeyPath)
|
|
298
321
|
: undefined;
|
|
299
|
-
const customRedirectUri = yield*
|
|
322
|
+
const customRedirectUri = yield* args.text('custom-redirect-uri').pipe(Args.availableWhen(!skipWeb, {
|
|
300
323
|
message: `--custom-redirect-uri ${webSkipMessage}`,
|
|
301
|
-
}), Args.
|
|
324
|
+
}), Args.prompt(optionalRedirectPrompt), Args.optional());
|
|
302
325
|
if (!clientName) {
|
|
303
326
|
return yield* BadArgsError.make({ message: 'Client name is required.' });
|
|
304
327
|
}
|
|
@@ -341,8 +364,11 @@ const handleAppleClient = Effect.fn(function* (opts) {
|
|
|
341
364
|
}));
|
|
342
365
|
});
|
|
343
366
|
const handleClerkClient = Effect.fn(function* (opts) {
|
|
367
|
+
const args = Args.from(opts);
|
|
344
368
|
const { clientName, provider } = yield* getClientNameAndProvider('clerk', opts);
|
|
345
|
-
const publishableKey = yield*
|
|
369
|
+
const publishableKey = yield* args
|
|
370
|
+
.text('publishable-key')
|
|
371
|
+
.pipe(Args.prompt(clerkPublishableKeyPrompt({})), Args.required());
|
|
346
372
|
if (!clientName) {
|
|
347
373
|
return yield* BadArgsError.make({ message: 'Client name is required.' });
|
|
348
374
|
}
|
|
@@ -377,8 +403,11 @@ const handleClerkClient = Effect.fn(function* (opts) {
|
|
|
377
403
|
}`, { borderStyle: 'none' }));
|
|
378
404
|
});
|
|
379
405
|
const handleFirebaseClient = Effect.fn(function* (opts) {
|
|
406
|
+
const args = Args.from(opts);
|
|
380
407
|
const { clientName, provider } = yield* getClientNameAndProvider('firebase', opts);
|
|
381
|
-
const projectId = yield*
|
|
408
|
+
const projectId = yield* args
|
|
409
|
+
.text('project-id')
|
|
410
|
+
.pipe(Args.prompt(firebaseProjectIdPrompt({})), Args.required());
|
|
382
411
|
// typeguard
|
|
383
412
|
if (!clientName || !projectId) {
|
|
384
413
|
return yield* BadArgsError.make({
|