|
2 | 2 | // Licensed under the MIT license.
|
3 | 3 |
|
4 | 4 | import { hooks } from "@feathersjs/hooks/lib";
|
5 |
| -import { FxError, Result, SystemError, UserError, Void, ok } from "@microsoft/teamsfx-api"; |
| 5 | +import { |
| 6 | + FxError, |
| 7 | + Result, |
| 8 | + SystemError, |
| 9 | + UserError, |
| 10 | + Void, |
| 11 | + ok, |
| 12 | + TextInputQuestion, |
| 13 | +} from "@microsoft/teamsfx-api"; |
6 | 14 | import * as dotenv from "dotenv";
|
7 | 15 | import * as fs from "fs-extra";
|
8 | 16 | import * as os from "os";
|
@@ -132,205 +140,48 @@ export class CreateOrUpdateEnvironmentFileDriver implements StepDriver {
|
132 | 140 | args: GenerateEnvArgs,
|
133 | 141 | envOutput: Map<string, string>
|
134 | 142 | ): Promise<Result<Void, FxError>> {
|
135 |
| - const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/; |
136 |
| - if (args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_API_KEY]) { |
137 |
| - const matches = placeHolderReg.exec( |
138 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_API_KEY] |
139 |
| - ); |
140 |
| - if (matches != null && matches.length > 1) { |
141 |
| - const result = await ctx.ui!.inputText({ |
142 |
| - name: azureOpenAIKeyQuestion().name, |
143 |
| - title: azureOpenAIKeyQuestion().title as string, |
144 |
| - password: azureOpenAIKeyQuestion().password, |
145 |
| - validation: (input: string): string | undefined => { |
146 |
| - if (input.length < 1) { |
147 |
| - return getLocalizedString( |
148 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIKey.validation" |
149 |
| - ); |
150 |
| - } |
151 |
| - }, |
152 |
| - }); |
153 |
| - if (result.isErr()) { |
154 |
| - return result; |
155 |
| - } else { |
156 |
| - envOutput.set(matches[1], result.value.result!); |
157 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_API_KEY] = result.value.result!; |
158 |
| - } |
159 |
| - } |
160 |
| - } |
161 |
| - |
162 |
| - if (args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_ENDPOINT]) { |
163 |
| - const matches = placeHolderReg.exec( |
164 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_ENDPOINT] |
| 143 | + for (const [envKey, envValue] of Object.entries(args.envs)) { |
| 144 | + const result = await this.processOpenAIEnvironmentVariable( |
| 145 | + ctx, |
| 146 | + args, |
| 147 | + envOutput, |
| 148 | + envKey, |
| 149 | + envValue |
165 | 150 | );
|
166 |
| - if (matches != null && matches.length > 1) { |
167 |
| - const result = await ctx.ui!.inputText({ |
168 |
| - name: azureOpenAIEndpointQuestion().name, |
169 |
| - title: azureOpenAIEndpointQuestion().title as string, |
170 |
| - validation: (input: string): string | undefined => { |
171 |
| - if (!input.startsWith("https://") && !input.startsWith("http://")) { |
172 |
| - return getLocalizedString( |
173 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIDeploymentEndpoint.validation" |
174 |
| - ); |
175 |
| - } |
176 |
| - }, |
177 |
| - }); |
178 |
| - if (result.isErr()) { |
179 |
| - return result; |
180 |
| - } else { |
181 |
| - envOutput.set(matches[1], result.value.result!); |
182 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_ENDPOINT] = result.value.result!; |
183 |
| - } |
184 |
| - } |
185 |
| - } |
186 |
| - |
187 |
| - if (args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_DEPLOYMENT_NAME]) { |
188 |
| - const matches = placeHolderReg.exec( |
189 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_DEPLOYMENT_NAME] |
190 |
| - ); |
191 |
| - if (matches != null && matches.length > 1) { |
192 |
| - const result = await ctx.ui!.inputText({ |
193 |
| - name: azureOpenAIDeploymentNameQuestion().name, |
194 |
| - title: azureOpenAIDeploymentNameQuestion().title as string, |
195 |
| - validation: (input: string): string | undefined => { |
196 |
| - if (input.length < 1) { |
197 |
| - return getLocalizedString( |
198 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIDeploymentName.validation" |
199 |
| - ); |
200 |
| - } |
201 |
| - }, |
202 |
| - }); |
203 |
| - if (result.isErr()) { |
204 |
| - return result; |
205 |
| - } else { |
206 |
| - envOutput.set(matches[1], result.value.result!); |
207 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_DEPLOYMENT_NAME] = result.value.result!; |
208 |
| - } |
209 |
| - } |
210 |
| - } |
211 |
| - |
212 |
| - if (args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_MODEL_DEPLOYMENT_NAME]) { |
213 |
| - const matches = placeHolderReg.exec( |
214 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_MODEL_DEPLOYMENT_NAME] |
215 |
| - ); |
216 |
| - if (matches != null && matches.length > 1) { |
217 |
| - const result = await ctx.ui!.inputText({ |
218 |
| - name: azureOpenAIDeploymentNameQuestion().name, |
219 |
| - title: azureOpenAIDeploymentNameQuestion().title as string, |
220 |
| - validation: (input: string): string | undefined => { |
221 |
| - if (input.length < 1) { |
222 |
| - return getLocalizedString( |
223 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIDeploymentName.validation" |
224 |
| - ); |
225 |
| - } |
226 |
| - }, |
227 |
| - }); |
228 |
| - if (result.isErr()) { |
229 |
| - return result; |
230 |
| - } else { |
231 |
| - envOutput.set(matches[1], result.value.result!); |
232 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_MODEL_DEPLOYMENT_NAME] = |
233 |
| - result.value.result!; |
234 |
| - } |
235 |
| - } |
236 |
| - } |
237 |
| - |
238 |
| - if (args.envs[OpenAIEnvironmentVariables.OPENAI_API_KEY]) { |
239 |
| - const matches = placeHolderReg.exec(args.envs[OpenAIEnvironmentVariables.OPENAI_API_KEY]); |
240 |
| - if (matches != null && matches.length > 1) { |
241 |
| - const result = await ctx.ui!.inputText({ |
242 |
| - name: openAIKeyQuestion().name, |
243 |
| - title: openAIKeyQuestion().title as string, |
244 |
| - password: true, |
245 |
| - validation: (input: string): string | undefined => { |
246 |
| - if (input.length < 1) { |
247 |
| - return getLocalizedString( |
248 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIKey.validation" |
249 |
| - ); |
250 |
| - } |
251 |
| - }, |
252 |
| - }); |
253 |
| - if (result.isErr()) { |
254 |
| - return result; |
255 |
| - } else { |
256 |
| - envOutput.set(matches[1], result.value.result!); |
257 |
| - args.envs[OpenAIEnvironmentVariables.OPENAI_API_KEY] = result.value.result!; |
258 |
| - } |
| 151 | + if (result.isErr()) { |
| 152 | + return result; |
259 | 153 | }
|
260 | 154 | }
|
| 155 | + return ok(Void); |
| 156 | + } |
261 | 157 |
|
262 |
| - if (args.envs[OpenAIEnvironmentVariables.OPENAI_ASSISTANT_ID]) { |
263 |
| - const matches = placeHolderReg.exec( |
264 |
| - args.envs[OpenAIEnvironmentVariables.OPENAI_ASSISTANT_ID] |
265 |
| - ); |
| 158 | + private async processOpenAIEnvironmentVariable( |
| 159 | + ctx: DriverContext, |
| 160 | + args: GenerateEnvArgs, |
| 161 | + envOutput: Map<string, string>, |
| 162 | + envKey: string, |
| 163 | + envValue: string |
| 164 | + ): Promise<Result<Void, FxError>> { |
| 165 | + if (envValue) { |
| 166 | + const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/; |
| 167 | + const matches = placeHolderReg.exec(envValue); |
266 | 168 | if (matches != null && matches.length > 1) {
|
267 |
| - const result = await ctx.ui!.inputText({ |
268 |
| - name: openAIAssistantIdQuestion().name, |
269 |
| - title: openAIAssistantIdQuestion().title as string, |
270 |
| - validation: (input: string): string | undefined => { |
271 |
| - if (input.length < 1) { |
272 |
| - return getLocalizedString( |
273 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIAssistantID.validation" |
274 |
| - ); |
275 |
| - } |
276 |
| - }, |
277 |
| - }); |
278 |
| - if (result.isErr()) { |
279 |
| - return result; |
280 |
| - } else { |
281 |
| - envOutput.set(matches[1], result.value.result!); |
282 |
| - args.envs[OpenAIEnvironmentVariables.OPENAI_ASSISTANT_ID] = result.value.result!; |
283 |
| - } |
284 |
| - } |
285 |
| - } |
| 169 | + const envVarName = matches[1]; |
| 170 | + const config = |
| 171 | + envVarConfigs.find((c) => c.envKey === envKey) || getGenericEnvVarConfig(envKey); |
286 | 172 |
|
287 |
| - if (args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_ASSISTANT_ID]) { |
288 |
| - const matches = placeHolderReg.exec( |
289 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_ASSISTANT_ID] |
290 |
| - ); |
291 |
| - if (matches != null && matches.length > 1) { |
292 |
| - const result = await ctx.ui!.inputText({ |
293 |
| - name: azureOpenAIAssistantIdQuestion().name, |
294 |
| - title: azureOpenAIAssistantIdQuestion().title as string, |
295 |
| - validation: (input: string): string | undefined => { |
296 |
| - if (input.length < 1) { |
297 |
| - return getLocalizedString( |
298 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIAssistantID.validation" |
299 |
| - ); |
300 |
| - } |
301 |
| - }, |
| 173 | + const result = await ctx.ui?.inputText({ |
| 174 | + name: config.question.name, |
| 175 | + title: config.question.title as string, |
| 176 | + password: config.isPassword || config.question.password, |
| 177 | + validation: config.validation, |
302 | 178 | });
|
303 |
| - if (result.isErr()) { |
304 |
| - return result; |
305 |
| - } else { |
306 |
| - envOutput.set(matches[1], result.value.result!); |
307 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_ASSISTANT_ID] = result.value.result!; |
308 |
| - } |
309 |
| - } |
310 |
| - } |
311 | 179 |
|
312 |
| - if (args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_EMBEDDING_DEPLOYMENT]) { |
313 |
| - const matches = placeHolderReg.exec( |
314 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_EMBEDDING_DEPLOYMENT] |
315 |
| - ); |
316 |
| - if (matches != null && matches.length > 1) { |
317 |
| - const result = await ctx.ui!.inputText({ |
318 |
| - name: azureOpenAIEmbeddingDeploymentNameQuestion().name, |
319 |
| - title: azureOpenAIEmbeddingDeploymentNameQuestion().title as string, |
320 |
| - validation: (input: string): string | undefined => { |
321 |
| - if (input.length < 1) { |
322 |
| - return getLocalizedString( |
323 |
| - "driver.file.createOrUpdateEnvironmentFile.OpenAIEmbeddingDeploymentName.validation" |
324 |
| - ); |
325 |
| - } |
326 |
| - }, |
327 |
| - }); |
328 |
| - if (result.isErr()) { |
| 180 | + if (result?.isErr()) { |
329 | 181 | return result;
|
330 |
| - } else { |
331 |
| - envOutput.set(matches[1], result.value.result!); |
332 |
| - args.envs[OpenAIEnvironmentVariables.AZURE_OPENAI_EMBEDDING_DEPLOYMENT] = |
333 |
| - result.value.result!; |
| 182 | + } else if (result?.isOk() && result.value.result) { |
| 183 | + envOutput.set(envVarName, result.value.result); |
| 184 | + args.envs[envKey] = result.value.result; |
334 | 185 | }
|
335 | 186 | }
|
336 | 187 | }
|
@@ -358,3 +209,101 @@ export class CreateOrUpdateEnvironmentFileDriver implements StepDriver {
|
358 | 209 | }
|
359 | 210 | }
|
360 | 211 | }
|
| 212 | + |
| 213 | +interface OpenAIEnvVarConfig { |
| 214 | + envKey: string; |
| 215 | + question: TextInputQuestion; |
| 216 | + validation: (input: string) => string | undefined; |
| 217 | + isPassword?: boolean; |
| 218 | +} |
| 219 | + |
| 220 | +const getNonEmptyStringValidation = (key: string): ((input: string) => string | undefined) => { |
| 221 | + return (input: string) => (input.length < 1 ? getLocalizedString(key) : undefined); |
| 222 | +}; |
| 223 | + |
| 224 | +const getEndpointValidation = (key: string): ((input: string) => string | undefined) => { |
| 225 | + return (input: string) => |
| 226 | + !input.startsWith("https://") && !input.startsWith("http://") |
| 227 | + ? getLocalizedString(key) |
| 228 | + : undefined; |
| 229 | +}; |
| 230 | + |
| 231 | +const getGenericEnvVarConfig = (envKey: string): OpenAIEnvVarConfig => ({ |
| 232 | + envKey, |
| 233 | + question: { |
| 234 | + type: "text", |
| 235 | + name: envKey, |
| 236 | + title: envKey, |
| 237 | + }, |
| 238 | + validation: getNonEmptyStringValidation( |
| 239 | + "driver.file.createOrUpdateEnvironmentFile.genericEnvVar.validation" |
| 240 | + ), |
| 241 | +}); |
| 242 | + |
| 243 | +const envVarConfigs: OpenAIEnvVarConfig[] = [ |
| 244 | + { |
| 245 | + envKey: OpenAIEnvironmentVariables.AZURE_OPENAI_API_KEY, |
| 246 | + question: azureOpenAIKeyQuestion(), |
| 247 | + validation: getNonEmptyStringValidation( |
| 248 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIKey.validation" |
| 249 | + ), |
| 250 | + isPassword: true, |
| 251 | + }, |
| 252 | + { |
| 253 | + envKey: OpenAIEnvironmentVariables.AZURE_OPENAI_ENDPOINT, |
| 254 | + question: azureOpenAIEndpointQuestion(), |
| 255 | + validation: getEndpointValidation( |
| 256 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIDeploymentEndpoint.validation" |
| 257 | + ), |
| 258 | + }, |
| 259 | + { |
| 260 | + envKey: OpenAIEnvironmentVariables.AZURE_OPENAI_DEPLOYMENT_NAME, |
| 261 | + question: azureOpenAIDeploymentNameQuestion(), |
| 262 | + validation: getNonEmptyStringValidation( |
| 263 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIDeploymentName.validation" |
| 264 | + ), |
| 265 | + }, |
| 266 | + { |
| 267 | + envKey: OpenAIEnvironmentVariables.AZURE_OPENAI_MODEL_DEPLOYMENT_NAME, |
| 268 | + question: azureOpenAIDeploymentNameQuestion(), |
| 269 | + validation: getNonEmptyStringValidation( |
| 270 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIDeploymentName.validation" |
| 271 | + ), |
| 272 | + }, |
| 273 | + { |
| 274 | + envKey: OpenAIEnvironmentVariables.OPENAI_API_KEY, |
| 275 | + question: openAIKeyQuestion(), |
| 276 | + validation: getNonEmptyStringValidation( |
| 277 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIKey.validation" |
| 278 | + ), |
| 279 | + isPassword: true, |
| 280 | + }, |
| 281 | + { |
| 282 | + envKey: OpenAIEnvironmentVariables.OPENAI_ASSISTANT_ID, |
| 283 | + question: openAIAssistantIdQuestion(), |
| 284 | + validation: getNonEmptyStringValidation( |
| 285 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIAssistantID.validation" |
| 286 | + ), |
| 287 | + }, |
| 288 | + { |
| 289 | + envKey: OpenAIEnvironmentVariables.AZURE_OPENAI_ASSISTANT_ID, |
| 290 | + question: azureOpenAIAssistantIdQuestion(), |
| 291 | + validation: getNonEmptyStringValidation( |
| 292 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIAssistantID.validation" |
| 293 | + ), |
| 294 | + }, |
| 295 | + { |
| 296 | + envKey: OpenAIEnvironmentVariables.AZURE_OPENAI_EMBEDDING_DEPLOYMENT, |
| 297 | + question: azureOpenAIEmbeddingDeploymentNameQuestion(), |
| 298 | + validation: getNonEmptyStringValidation( |
| 299 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIEmbeddingDeploymentName.validation" |
| 300 | + ), |
| 301 | + }, |
| 302 | + { |
| 303 | + envKey: OpenAIEnvironmentVariables.AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME, |
| 304 | + question: azureOpenAIEmbeddingDeploymentNameQuestion(), |
| 305 | + validation: getNonEmptyStringValidation( |
| 306 | + "driver.file.createOrUpdateEnvironmentFile.OpenAIEmbeddingDeploymentName.validation" |
| 307 | + ), |
| 308 | + }, |
| 309 | +]; |
0 commit comments