Skip to content

Commit f99a25b

Browse files
committed
add local settings node
1 parent 02aeea2 commit f99a25b

File tree

3 files changed

+86
-4
lines changed

3 files changed

+86
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.md in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { type StringDictionary } from "@azure/arm-appservice";
7+
import { type AppSettingsClientProvider, type IAppSettingsClient } from "@microsoft/vscode-azext-azureappsettings";
8+
import { AzExtFsExtra, callWithTelemetryAndErrorHandling, type IActionContext } from "@microsoft/vscode-azext-utils";
9+
import * as vscode from 'vscode';
10+
import { type ILocalSettingsJson } from "../../../funcConfig/local.settings";
11+
import { type LocalProjectTreeItem } from "../../../tree/localProject/LocalProjectTreeItem";
12+
import { decryptLocalSettings } from "./decryptLocalSettings";
13+
import { encryptLocalSettings } from "./encryptLocalSettings";
14+
import { getLocalSettingsFileNoPrompt } from "./getLocalSettingsFile";
15+
16+
export class LocalSettingsClientProvider implements AppSettingsClientProvider {
17+
private _node: LocalProjectTreeItem;
18+
constructor(node: LocalProjectTreeItem) {
19+
this._node = node;
20+
}
21+
22+
public async createClient(): Promise<IAppSettingsClient> {
23+
return new LocalSettingsClient(this._node);
24+
}
25+
}
26+
27+
export class LocalSettingsClient implements IAppSettingsClient {
28+
public fullName: string;
29+
public isLinux: boolean;
30+
31+
private _node: LocalProjectTreeItem;
32+
33+
constructor(node: LocalProjectTreeItem) {
34+
this.isLinux = false;
35+
this._node = node;
36+
}
37+
38+
public async listApplicationSettings(): Promise<StringDictionary> {
39+
const result = await callWithTelemetryAndErrorHandling<StringDictionary | undefined>('listApplicationSettings', async (context: IActionContext) => {
40+
const localSettingsPath: string | undefined = await getLocalSettingsFileNoPrompt(context, this._node.workspaceFolder);
41+
if (localSettingsPath === undefined) {
42+
return { properties: {} };
43+
} else {
44+
const localSettingsUri: vscode.Uri = vscode.Uri.file(localSettingsPath);
45+
46+
let localSettings: ILocalSettingsJson = <ILocalSettingsJson>await AzExtFsExtra.readJSON(localSettingsPath);
47+
if (localSettings.IsEncrypted) {
48+
await decryptLocalSettings(context, localSettingsUri);
49+
try {
50+
localSettings = await AzExtFsExtra.readJSON<ILocalSettingsJson>(localSettingsPath);
51+
} finally {
52+
await encryptLocalSettings(context, localSettingsUri);
53+
}
54+
}
55+
return { properties: localSettings.Values };
56+
}
57+
});
58+
return result ?? { properties: {} };
59+
}
60+
61+
public async updateApplicationSettings(): Promise<StringDictionary> {
62+
throw new Error('Method not implemented.');
63+
}
64+
}

src/commands/appSettings/localSettings/getLocalSettingsFile.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { AzExtFsExtra, type IActionContext } from '@microsoft/vscode-azext-utils';
77
import * as path from 'path';
8-
import { type WorkspaceFolder } from "vscode";
8+
import type * as vscode from 'vscode';
99
import { localSettingsFileName } from '../../../constants';
1010
import { getRootWorkspaceFolder, selectWorkspaceFile } from '../../../utils/workspace';
1111
import { tryGetFunctionProjectRoot } from '../../createNewProject/verifyIsProject';
@@ -14,7 +14,7 @@ import { tryGetFunctionProjectRoot } from '../../createNewProject/verifyIsProjec
1414
* If only one project is open and the default local settings file exists, return that.
1515
* Otherwise, prompt
1616
*/
17-
export async function getLocalSettingsFile(context: IActionContext, message: string, workspaceFolder?: WorkspaceFolder): Promise<string> {
17+
export async function getLocalSettingsFile(context: IActionContext, message: string, workspaceFolder?: vscode.WorkspaceFolder): Promise<string> {
1818
workspaceFolder ||= await getRootWorkspaceFolder();
1919
if (workspaceFolder) {
2020
const projectPath: string | undefined = await tryGetFunctionProjectRoot(context, workspaceFolder);
@@ -26,8 +26,19 @@ export async function getLocalSettingsFile(context: IActionContext, message: str
2626
}
2727
}
2828

29-
return await selectWorkspaceFile(context, message, async (f: WorkspaceFolder): Promise<string> => {
29+
return await selectWorkspaceFile(context, message, async (f: vscode.WorkspaceFolder): Promise<string> => {
3030
const projectPath: string = await tryGetFunctionProjectRoot(context, f) || f.uri.fsPath;
3131
return path.relative(f.uri.fsPath, path.join(projectPath, localSettingsFileName));
3232
});
3333
}
34+
35+
export async function getLocalSettingsFileNoPrompt(context: IActionContext, workspaceFolder: vscode.WorkspaceFolder): Promise<string | undefined> {
36+
const projectPath: string | undefined = await tryGetFunctionProjectRoot(context, workspaceFolder);
37+
if (projectPath) {
38+
const localSettingsFile: string = path.join(projectPath, localSettingsFileName);
39+
if (await AzExtFsExtra.pathExists(localSettingsFile)) {
40+
return localSettingsFile;
41+
}
42+
}
43+
return undefined;
44+
}

src/tree/localProject/LocalProjectTreeItem.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6+
import { AppSettingsTreeItem } from '@microsoft/vscode-azext-azureappsettings';
67
import { callWithTelemetryAndErrorHandling, type AzExtParentTreeItem, type AzExtTreeItem, type IActionContext } from '@microsoft/vscode-azext-utils';
78
import * as path from 'path';
89
import { Disposable, type TaskScope, type WorkspaceFolder } from 'vscode';
910
import { type FuncVersion } from '../../FuncVersion';
11+
import { LocalSettingsClientProvider } from '../../commands/appSettings/localSettings/LocalSettingsClient';
1012
import { onDotnetFuncTaskReady } from '../../commands/pickFuncProcess';
1113
import { functionJsonFileName, localSettingsFileName, type ProjectLanguage } from '../../constants';
14+
import { ext } from '../../extensionVariables';
1215
import { type IParsedHostJson } from '../../funcConfig/host';
1316
import { onFuncTaskStarted } from '../../funcCoreTools/funcHostTask';
1417
import { type LocalProjectInternal } from '../../workspace/listLocalProjects';
@@ -35,6 +38,7 @@ export class LocalProjectTreeItem extends LocalProjectTreeItemBase implements Di
3538

3639
private readonly _disposables: Disposable[] = [];
3740
private readonly _localFunctionsTreeItem: LocalFunctionsTreeItem;
41+
private readonly _localSettingsTreeItem: AppSettingsTreeItem;
3842

3943
public constructor(parent: AzExtParentTreeItem, localProject: LocalProjectInternal) {
4044
const options = localProject.options;
@@ -56,6 +60,9 @@ export class LocalProjectTreeItem extends LocalProjectTreeItemBase implements Di
5660
this._disposables.push(onDotnetFuncTaskReady(async scope => this.onFuncTaskChanged(scope)));
5761

5862
this._localFunctionsTreeItem = new LocalFunctionsTreeItem(this);
63+
this._localSettingsTreeItem = new AppSettingsTreeItem(this, new LocalSettingsClientProvider(this), ext.prefix, {
64+
contextValuesToAdd: ['localSettings']
65+
});
5966
}
6067

6168
public async getHostRequest(context: IActionContext): Promise<FuncHostRequest> {
@@ -72,7 +79,7 @@ export class LocalProjectTreeItem extends LocalProjectTreeItemBase implements Di
7279

7380
// eslint-disable-next-line @typescript-eslint/require-await
7481
public async loadMoreChildrenImpl(_clearCache: boolean): Promise<AzExtTreeItem[]> {
75-
return [this._localFunctionsTreeItem];
82+
return [this._localFunctionsTreeItem, this._localSettingsTreeItem];
7683
}
7784

7885
public isAncestorOfImpl(contextValue: string | RegExp): boolean {

0 commit comments

Comments
 (0)