Skip to content

Commit 99be0e3

Browse files
authored
Improve local settings for V2 schema templates (#3927)
* Add values as desciptions for local settings. Select emulator for storage connection * Add string to end of placeholder * Revert package.json dependencies * Revert package-lock.json dependencies * Fix linter * Hide app settings value by default * Convert types for v2 schema * Fix error validators and parsing UserPrompts * Fix build error * Clean up some code * Add comment
1 parent 65c686b commit 99be0e3

24 files changed

+115
-92
lines changed

src/commands/addBinding/settingSteps/AzureConnectionCreateStepBase.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,24 @@ import { type Progress } from 'vscode';
88
import { setLocalAppSetting } from '../../../funcConfig/local.settings';
99
import { localize } from '../../../localize';
1010
import { type IBindingSetting } from '../../../templates/IBindingTemplate';
11-
import { nonNullProp } from '../../../utils/nonNull';
12-
import { setBindingSetting } from '../../createFunction/IFunctionWizardContext';
13-
import { type IBindingWizardContext } from '../IBindingWizardContext';
11+
import { type ParsedInput } from '../../../templates/script/parseScriptTemplatesV2';
12+
import { setBindingSetting, type IFunctionWizardContext } from '../../createFunction/IFunctionWizardContext';
1413

1514
export interface IConnection {
1615
name: string;
1716
connectionString: string;
1817
}
1918

20-
export abstract class AzureConnectionCreateStepBase<T extends IBindingWizardContext> extends AzureWizardExecuteStep<T> {
19+
export abstract class AzureConnectionCreateStepBase<T extends IFunctionWizardContext> extends AzureWizardExecuteStep<T> {
2120
public priority: number = 200;
2221

23-
private readonly _setting: IBindingSetting;
22+
private readonly _setting: IBindingSetting | ParsedInput;
23+
private readonly _resourceType: string;
2424

25-
constructor(setting: IBindingSetting) {
25+
constructor(setting: IBindingSetting | ParsedInput) {
2626
super();
2727
this._setting = setting;
28+
this._resourceType = (setting as IBindingSetting).resourceType ?? (setting as ParsedInput).resource ?? '';
2829
}
2930

3031
public abstract getConnection(context: T): Promise<IConnection>;
@@ -33,7 +34,7 @@ export abstract class AzureConnectionCreateStepBase<T extends IBindingWizardCont
3334
progress.report({ message: localize('retrieving', 'Retrieving connection string...') });
3435

3536
const result: IConnection = await this.getConnection(context);
36-
let appSettingKey: string = `${result.name}_${nonNullProp(this._setting, 'resourceType').toUpperCase()}`;
37+
let appSettingKey: string = `${result.name}_${this._resourceType.toUpperCase()}`;
3738
appSettingKey = appSettingKey.replace(/[^a-z0-9_\.]/gi, ''); // remove invalid chars
3839
setBindingSetting(context, this._setting, appSettingKey);
3940
await setLocalAppSetting(context, context.projectPath, appSettingKey, result.connectionString);

src/commands/addBinding/settingSteps/BindingSettingStepBase.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,27 @@
66
import { AzureWizardPromptStep } from "@microsoft/vscode-azext-utils";
77
import { type BindingSettingValue } from "../../../funcConfig/function";
88
import { type IBindingSetting } from "../../../templates/IBindingTemplate";
9-
import { getBindingSetting, setBindingSetting } from "../../createFunction/IFunctionWizardContext";
10-
import { type IBindingWizardContext } from "../IBindingWizardContext";
9+
import { type ParsedInput } from "../../../templates/script/parseScriptTemplatesV2";
10+
import { getBindingSetting, setBindingSetting, type IFunctionWizardContext } from "../../createFunction/IFunctionWizardContext";
1111

12-
export abstract class BindingSettingStepBase extends AzureWizardPromptStep<IBindingWizardContext> {
13-
protected readonly _setting: IBindingSetting;
12+
export abstract class BindingSettingStepBase extends AzureWizardPromptStep<IFunctionWizardContext> {
13+
protected readonly _setting: IBindingSetting | ParsedInput;
14+
protected readonly _resourceType: string;
1415

15-
constructor(setting: IBindingSetting) {
16+
constructor(setting: IBindingSetting | ParsedInput) {
1617
super();
1718
this._setting = setting;
1819
this.id = setting.name;
20+
this._resourceType = (setting as IBindingSetting).resourceType ?? (setting as ParsedInput).resource ?? '';
1921
}
2022

21-
public abstract promptCore(context: IBindingWizardContext): Promise<BindingSettingValue>;
23+
public abstract promptCore(context: IFunctionWizardContext): Promise<BindingSettingValue>;
2224

23-
public async prompt(context: IBindingWizardContext): Promise<void> {
25+
public async prompt(context: IFunctionWizardContext): Promise<void> {
2426
setBindingSetting(context, this._setting, await this.promptCore(context));
2527
}
2628

27-
public shouldPrompt(context: IBindingWizardContext): boolean {
29+
public shouldPrompt(context: IFunctionWizardContext): boolean {
2830
return !getBindingSetting(context, this._setting);
2931
}
3032
}

src/commands/addBinding/settingSteps/BooleanPromptStep.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils";
77
import { type BindingSettingValue } from "../../../funcConfig/function";
8+
import { type IBindingSetting } from "../../../templates/IBindingTemplate";
89
import { envUtils } from "../../../utils/envUtils";
910
import { type IBindingWizardContext } from "../IBindingWizardContext";
1011
import { BindingSettingStepBase } from "./BindingSettingStepBase";
@@ -18,6 +19,6 @@ export class BooleanPromptStep extends BindingSettingStepBase {
1819
picks = picks.reverse();
1920
}
2021

21-
return (await context.ui.showQuickPick(picks, { placeHolder: this._setting.description || this._setting.label })).data;
22+
return (await context.ui.showQuickPick(picks, { placeHolder: (this._setting as IBindingSetting).description || this._setting.label })).data;
2223
}
2324
}

src/commands/addBinding/settingSteps/EnumPromptStep.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55

66
import { type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils";
77
import { type BindingSettingValue } from "../../../funcConfig/function";
8+
import { type IBindingSetting } from "../../../templates/IBindingTemplate";
89
import { type IBindingWizardContext } from "../IBindingWizardContext";
910
import { BindingSettingStepBase } from "./BindingSettingStepBase";
1011

1112
export class EnumPromptStep extends BindingSettingStepBase {
13+
// not used by v2 schema so enforce IBindingSetting
14+
protected readonly _setting: IBindingSetting;
15+
1216
public async promptCore(context: IBindingWizardContext): Promise<BindingSettingValue> {
1317
const picks: IAzureQuickPickItem<string>[] = this._setting.enums.map(e => { return { data: e.value, label: e.displayName }; });
1418
return (await context.ui.showQuickPick(picks, { placeHolder: this._setting.label })).data;

src/commands/addBinding/settingSteps/LocalAppSettingCreateStep.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ import { localSettingsFileName } from '../../../constants';
99
import { setLocalAppSetting } from '../../../funcConfig/local.settings';
1010
import { localize } from '../../../localize';
1111
import { type IBindingSetting } from '../../../templates/IBindingTemplate';
12+
import { type ParsedInput } from '../../../templates/script/parseScriptTemplatesV2';
1213
import { nonNullProp, nonNullValue } from '../../../utils/nonNull';
13-
import { getBindingSetting } from '../../createFunction/IFunctionWizardContext';
14+
import { getBindingSetting, setBindingSetting } from '../../createFunction/IFunctionWizardContext';
1415
import { type IBindingWizardContext } from '../IBindingWizardContext';
1516

1617
export class LocalAppSettingCreateStep extends AzureWizardExecuteStep<IBindingWizardContext> {
1718
public priority: number = 210;
1819

19-
private readonly _setting: IBindingSetting;
20+
private readonly _setting: IBindingSetting | ParsedInput;
2021
private readonly _valueKey: string;
2122

22-
constructor(setting: IBindingSetting, valueKey: string) {
23+
constructor(setting: IBindingSetting | ParsedInput, valueKey: string) {
2324
super();
2425
this._setting = setting;
2526
this._valueKey = valueKey;
@@ -29,6 +30,10 @@ export class LocalAppSettingCreateStep extends AzureWizardExecuteStep<IBindingWi
2930
progress.report({ message: localize('updatingLocalSettings', 'Updating {0}...', localSettingsFileName) });
3031
const appSettingName = String(nonNullValue(getBindingSetting(context, this._setting), this._setting.name));
3132
await setLocalAppSetting(context, context.projectPath, appSettingName, nonNullProp(context, this._valueKey as keyof IBindingWizardContext) as string);
33+
// if the binding isn't already set then a new one was created
34+
if (!getBindingSetting(context, this._setting)) {
35+
setBindingSetting(context, this._setting, nonNullProp(context, this._valueKey as keyof IBindingWizardContext) as string);
36+
}
3237
}
3338

3439
public shouldExecute(context: IBindingWizardContext): boolean {

src/commands/addBinding/settingSteps/LocalAppSettingListStep.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ import { getLocalSettingsJson, type ILocalSettingsJson } from '../../../funcConf
1212
import { localize } from '../../../localize';
1313
import { ResourceType } from '../../../templates/IBindingTemplate';
1414
import { type IEventHubsConnectionWizardContext } from '../../appSettings/connectionSettings/eventHubs/IEventHubsConnectionWizardContext';
15-
import { getBindingSetting } from '../../createFunction/IFunctionWizardContext';
15+
import { getBindingSetting, type FunctionV2WizardContext, type IFunctionWizardContext } from '../../createFunction/IFunctionWizardContext';
1616
import { EventHubsNamespaceListStep } from '../../createFunction/durableSteps/netherite/EventHubsNamespaceListStep';
17-
import { type IBindingWizardContext } from '../IBindingWizardContext';
1817
import { BindingSettingStepBase } from './BindingSettingStepBase';
1918
import { LocalAppSettingCreateStep } from './LocalAppSettingCreateStep';
2019
import { LocalAppSettingNameStep } from './LocalAppSettingNameStep';
@@ -33,7 +32,7 @@ const showHiddenValuesItem = { label: localize('showHiddenValues', '$(eye) Show
3332
const hideHiddenValuesItem = { label: localize('hideHiddenValues', '$(eye-closed) Hide hidden values'), data: 'hiddenValues' }
3433
export class LocalAppSettingListStep extends BindingSettingStepBase {
3534
private _showHiddenValues: boolean = false;
36-
public async promptCore(context: IBindingWizardContext): Promise<BindingSettingValue> {
35+
public async promptCore(context: IFunctionWizardContext): Promise<BindingSettingValue> {
3736
const localSettingsPath: string = path.join(context.projectPath, localSettingsFileName);
3837
const settings: ILocalSettingsJson = await getLocalSettingsJson(context, localSettingsPath);
3938
const existingSettings: [string, string][] = settings.Values ? Object.entries(settings.Values) : [];
@@ -43,7 +42,10 @@ export class LocalAppSettingListStep extends BindingSettingStepBase {
4342
do {
4443
let picks: IAzureQuickPickItem<string | undefined>[] = [{ label: localize('newAppSetting', '$(plus) Create new local app setting'), data: undefined }];
4544
picks = picks.concat(existingSettings.map((s: [string, string]) => { return { data: s[0], label: s[0], description: this._showHiddenValues ? s[1] : '******' }; }));
46-
picks.push(this._showHiddenValues ? hideHiddenValuesItem : showHiddenValuesItem);
45+
if (picks.length > 1) {
46+
// don't add hidden values item if there are no existing settings
47+
picks.push(this._showHiddenValues ? hideHiddenValuesItem : showHiddenValuesItem);
48+
}
4749
result = (await context.ui.showQuickPick(picks, { placeHolder })).data;
4850
if (result === 'hiddenValues') {
4951
this._showHiddenValues = !this._showHiddenValues;
@@ -54,11 +56,11 @@ export class LocalAppSettingListStep extends BindingSettingStepBase {
5456
} while (true);
5557
}
5658

57-
public async getSubWizard(context: IBindingWizardContext): Promise<IWizardOptions<IBindingWizardContext> | undefined> {
59+
public async getSubWizard(context: IFunctionWizardContext): Promise<IWizardOptions<IFunctionWizardContext & FunctionV2WizardContext> | undefined> {
5860
if (!getBindingSetting(context, this._setting)) {
59-
const azurePromptSteps: AzureWizardPromptStep<IBindingWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
60-
const azureExecuteSteps: AzureWizardExecuteStep<IBindingWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
61-
switch (this._setting.resourceType) {
61+
const azurePromptSteps: AzureWizardPromptStep<IFunctionWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
62+
const azureExecuteSteps: AzureWizardExecuteStep<IFunctionWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
63+
switch (this._resourceType) {
6264
case ResourceType.DocumentDB:
6365
azurePromptSteps.push(new CosmosDBListStep());
6466
azureExecuteSteps.push(new CosmosDBConnectionCreateStep(this._setting));

src/commands/addBinding/settingSteps/LocalAppSettingNameStep.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55

66
import { type BindingSettingValue } from '../../../funcConfig/function';
77
import { localize } from '../../../localize';
8-
import { nonNullProp } from '../../../utils/nonNull';
98
import { type IBindingWizardContext } from '../IBindingWizardContext';
109
import { BindingSettingStepBase } from './BindingSettingStepBase';
1110

1211
export class LocalAppSettingNameStep extends BindingSettingStepBase {
1312
public async promptCore(context: IBindingWizardContext): Promise<BindingSettingValue> {
14-
const appSettingSuffix: string = `_${nonNullProp(this._setting, 'resourceType').toUpperCase()}`;
13+
const appSettingSuffix: string = `_${this._resourceType.toUpperCase()}`;
1514
return await context.ui.showInputBox({
1615
placeHolder: localize('appSettingKeyPlaceholder', 'Local app setting key'),
1716
prompt: localize('appSettingKeyPrompt', 'Provide a key for a connection string'),

src/commands/addBinding/settingSteps/StorageConnectionCreateStep.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66
import { type IStorageAccountWizardContext } from '@microsoft/vscode-azext-azureutils';
77
import { getStorageConnectionString } from '../../appSettings/connectionSettings/getLocalConnectionSetting';
8-
import { type IBindingWizardContext } from '../IBindingWizardContext';
8+
import { type IFunctionWizardContext } from '../../createFunction/IFunctionWizardContext';
99
import { AzureConnectionCreateStepBase, type IConnection } from './AzureConnectionCreateStepBase';
1010

11-
export class StorageConnectionCreateStep extends AzureConnectionCreateStepBase<IStorageAccountWizardContext & IBindingWizardContext> {
12-
public async getConnection(context: IStorageAccountWizardContext & Partial<IBindingWizardContext>): Promise<IConnection> {
11+
export class StorageConnectionCreateStep extends AzureConnectionCreateStepBase<IStorageAccountWizardContext & IFunctionWizardContext> {
12+
public async getConnection(context: IStorageAccountWizardContext & IFunctionWizardContext): Promise<IConnection> {
1313
return await getStorageConnectionString(context);
1414
}
1515

16-
public shouldExecute(context: IStorageAccountWizardContext & Partial<IBindingWizardContext>): boolean {
16+
public shouldExecute(context: IStorageAccountWizardContext & IFunctionWizardContext): boolean {
1717
return !!context.storageAccount || !!context.useStorageEmulator;
1818
}
1919
}

src/commands/addBinding/settingSteps/StorageTypePromptStep.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@ import { StorageAccountKind, StorageAccountListStep, StorageAccountPerformance,
77
import { AzureWizardPromptStep, type AzureWizardExecuteStep, type IAzureQuickPickItem, type ISubscriptionActionContext, type IWizardOptions } from "@microsoft/vscode-azext-utils";
88
import { localize } from "../../../localize";
99
import { type IBindingSetting } from "../../../templates/IBindingTemplate";
10+
import { type ParsedInput } from "../../../templates/script/parseScriptTemplatesV2";
1011
import { type IEventHubsConnectionWizardContext } from "../../appSettings/connectionSettings/eventHubs/IEventHubsConnectionWizardContext";
11-
import { type IBindingWizardContext } from "../IBindingWizardContext";
12+
import { type IFunctionWizardContext } from "../../createFunction/IFunctionWizardContext";
1213
import { StorageConnectionCreateStep } from "./StorageConnectionCreateStep";
1314

14-
export class StorageTypePromptStep extends AzureWizardPromptStep<IBindingWizardContext> {
15-
private readonly _setting: IBindingSetting;
15+
export class StorageTypePromptStep extends AzureWizardPromptStep<IFunctionWizardContext> {
16+
private readonly _setting: IBindingSetting | ParsedInput;
1617

17-
constructor(setting: IBindingSetting) {
18+
constructor(setting: IBindingSetting | ParsedInput) {
1819
super();
1920
this._setting = setting;
2021
}
2122

22-
public async prompt(context: IBindingWizardContext): Promise<void> {
23+
public async prompt(context: IFunctionWizardContext): Promise<void> {
2324
const picks: IAzureQuickPickItem<boolean>[] = [
2425
{ label: localize('useAzurite', 'Use Azurite emulator for local storage'), data: true },
2526
{ label: localize('useAzureStorage', 'Use Azure Storage for remote storage'), data: false }
@@ -29,13 +30,13 @@ export class StorageTypePromptStep extends AzureWizardPromptStep<IBindingWizardC
2930
return;
3031
}
3132

32-
public shouldPrompt(context: IBindingWizardContext): boolean {
33+
public shouldPrompt(context: IFunctionWizardContext): boolean {
3334
return context.useStorageEmulator === undefined;
3435
}
3536

36-
public async getSubWizard(context: IBindingWizardContext): Promise<IWizardOptions<IBindingWizardContext> | undefined> {
37-
const promptSteps: AzureWizardPromptStep<IBindingWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
38-
const executeSteps: AzureWizardExecuteStep<IBindingWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
37+
public async getSubWizard(context: IFunctionWizardContext): Promise<IWizardOptions<IFunctionWizardContext> | undefined> {
38+
const promptSteps: AzureWizardPromptStep<IFunctionWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
39+
const executeSteps: AzureWizardExecuteStep<IFunctionWizardContext & ISubscriptionActionContext & IEventHubsConnectionWizardContext>[] = [];
3940

4041
if (!context.useStorageEmulator) {
4142
promptSteps.push(new StorageAccountListStep(

src/commands/addBinding/settingSteps/StringPromptStep.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55

66
import { type BindingSettingValue } from "../../../funcConfig/function";
77
import { localize } from "../../../localize";
8+
import { type IBindingSetting } from "../../../templates/IBindingTemplate";
89
import { type IBindingWizardContext } from "../IBindingWizardContext";
910
import { BindingSettingStepBase } from "./BindingSettingStepBase";
1011

1112
export class StringPromptStep extends BindingSettingStepBase {
13+
// not used by v2 schema so enforce IBindingSetting
14+
protected readonly _setting: IBindingSetting;
1215
public async promptCore(context: IBindingWizardContext): Promise<BindingSettingValue> {
1316
return await context.ui.showInputBox({
1417
placeHolder: this._setting.label,

0 commit comments

Comments
 (0)