Skip to content

Commit 86c3827

Browse files
committed
refactor: refactor code
1 parent 8442169 commit 86c3827

12 files changed

+229
-121
lines changed

LICENSE LICENSE.txt

File renamed without changes.

assets/modelRepository/main.js

+3-9
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,12 @@ function encodeHTML(value) {
9797

9898
function deleteDigitalTwinFiles() {
9999
const fileIds = this.type.value === INTERFACE ? this.selectedInterfaces.value : this.selectedCapabilityModels.value;
100-
command("azure-digital-twins.deleteModel", fileIds, this.type.value, refreshDigitalTwinFileList.bind(this));
100+
command("azure-digital-twins.deleteModels", this.publicRepository, fileIds, refreshDigitalTwinFileList.bind(this));
101101
}
102102

103103
function editDigitalTwinFiles() {
104104
const fileIds = this.type.value === INTERFACE ? this.selectedInterfaces.value : this.selectedCapabilityModels.value;
105-
command(
106-
"azure-digital-twins.downloadModel",
107-
fileIds,
108-
this.type.value,
109-
this.publicRepository,
110-
refreshDigitalTwinFileList.bind(this)
111-
);
105+
command("azure-digital-twins.downloadModels", this.publicRepository, fileIds, refreshDigitalTwinFileList.bind(this));
112106
}
113107

114108
function createDigitalTwinFile() {
@@ -136,7 +130,7 @@ function getNextPageDigitalTwinFiles(fileType) {
136130
}
137131

138132
loadingDigitalTwinFiles.value = true;
139-
command(commandName, this.searchKeywords, this.publicRepository, 50, nextToken.value, res => {
133+
command(commandName, this.publicRepository, this.searchKeywords, 50, nextToken.value, res => {
140134
Vue.set(fileList, VALUE, fileList.value.concat(res.result.results));
141135
Vue.set(nextToken, VALUE, res.result.continuationToken);
142136
Vue.set(loadingDigitalTwinFiles, VALUE, false);

src/common/colorizedChannel.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class ColorizedChannel {
88
const message: string = error
99
? subject.charAt(0).toLowerCase() + subject.slice(1)
1010
: subject.charAt(0).toUpperCase() + subject.slice(1);
11-
return error ? `Fail to ${message}. Error ${error.message}` : `${message} successfully`;
11+
return error ? `Fail to ${message}. Error: ${error.message}` : `${message} successfully`;
1212
}
1313

1414
private static buildTag(name: string | undefined): string {

src/common/command.ts

+10-16
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
export class Command {
5-
public static readonly CREATE_INTERFACE = new Command("azure-digital-twins.createInterface", "Create Interface");
6-
public static readonly CREATE_CAPABILITY_MODEL = new Command(
7-
"azure-digital-twins.createCapabilityModel",
8-
"Create Capability Model",
9-
);
10-
public static readonly OPEN_REPOSITORY = new Command("azure-digital-twins.openRepository", "Open Model Repository");
11-
public static readonly SIGN_OUT_REPOSITORY = new Command(
12-
"azure-digital-twins.signOutRepository",
13-
"Sign out Model Repository",
14-
);
15-
public static readonly SUBMIT_FILES = new Command(
16-
"azure-digital-twins.submitFiles",
17-
"Submit Files to Model Repository",
18-
);
19-
private constructor(public readonly id: string, public readonly description: string) {}
4+
export enum Command {
5+
CreateInterface = "azure-digital-twins.createInterface",
6+
CreateCapabilityModel = "azure-digital-twins.createCapabilityModeel",
7+
OpenRepository = "azure-digital-twins.openRepository",
8+
SignOutRepository = "azure-digital-twins.signOutRepository",
9+
SearchInterface = "azure-digital-twins.searchInterface",
10+
SearchCapabilityModel = "azure-digital-twins.searchCapabilityModel",
11+
SubmitFiles = "azure-digital-twins.submitFiles",
12+
DeleteModels = "azure-digital-twins.deleteModels",
13+
DownloadModels = "azure-digital-twins.downloadModels",
2014
}

src/common/constants.ts

+13-11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ export class Constants {
55
public static readonly EXTENSION_NAME = "azure-digital-twins";
66
public static readonly CHANNEL_NAME = "IoT Plug and Play";
77
public static readonly UTF8 = "utf8";
8+
public static readonly JSON_SPACE = 2;
9+
public static readonly NOT_FOUND_CODE = 404;
10+
public static readonly DEFAULT_PAGE_SIZE = 50;
811
public static readonly RESOURCE_FOLDER = "resources";
912
public static readonly TEMPLATE_FOLDER = "templates";
1013
public static readonly SAMPLE_FILENAME = "sample";
@@ -13,27 +16,26 @@ export class Constants {
1316
public static readonly MODEL_REPOSITORY_COMPONENT = "Model Repository";
1417
public static readonly MODEL_REPOSITORY_CONNECTION_KEY = "ModelRepositoryConnectionKey";
1518
public static readonly MODEL_REPOSITORY_API_VERSION = "2019-07-01-Preview";
16-
public static readonly PUBLIC_REPOSITORY_URL = "publicRepositoryUrl";
19+
public static readonly URL_PROTOCAL_REGEX = new RegExp("^[a-zA-Z]+://");
20+
public static readonly HTTPS_PROTOCAL = "https://";
21+
public static readonly MODEL_NAME_REGEX = new RegExp("^[a-zA-Z_][a-zA-Z0-9_]*$");
22+
public static readonly MODEL_NAME_REGEX_DESCRIPTION = "alphanumeric and underscore, not start with number";
23+
public static readonly DIGITAL_TWIN_ID_PLACEHOLDER = "{DigitalTwinIdentifier}";
24+
public static readonly SCHEMA_ID_KEY = "@id";
25+
public static readonly SCHEMA_TYPE_KEY = "@type";
26+
public static readonly SCHEMA_CONTEXT_KEY = "@context";
1727

1828
public static readonly EXTENSION_ACTIVATED_MSG = "extensionActivated";
1929
public static readonly NOT_EMPTY_MSG = "could not be empty";
2030
public static readonly CONNECTION_STRING_NOT_FOUND_MSG =
2131
"Company repository connection string is not found. Please sign out and sign in with a valid connection string";
2232
public static readonly PUBLIC_REPOSITORY_URL_NOT_FOUND_MSG = "Public repository url is not found";
2333
public static readonly CONNECTION_STRING_INVALID_FORMAT_MSG = "Invalid connection string format";
34+
public static readonly MODEL_TYPE_INVALID_MSG = "Invalid model type";
2435

2536
public static readonly NSAT_SURVEY_URL = "https://aka.ms/vscode-azure-digital-twins-survey";
2637
public static readonly WEB_VIEW_PATH = "assets/modelRepository";
2738
public static readonly COMPANY_REPOSITORY_PAGE = "index.html";
2839
public static readonly PUBLIC_REPOSITORY_PAGE = "index.html?public";
29-
30-
public static readonly MODEL_NAME_REGEX = new RegExp("^[a-zA-Z_][a-zA-Z0-9_]*$");
31-
public static readonly MODEL_NAME_REGEX_DESCRIPTION = "alphanumeric and underscore, not start with number";
32-
public static readonly DIGITAL_TWIN_ID_PLACEHOLDER = "{DigitalTwinIdentifier}";
33-
public static readonly URL_PROTOCAL_REGEX = new RegExp("^[a-zA-Z]+://");
34-
public static readonly HTTPS_PROTOCAL = "https://";
35-
public static readonly NOT_FOUND_CODE = 404;
36-
public static readonly SCHEMA_ID_KEY = "@id";
37-
public static readonly SCHEMA_TYPE_KEY = "@type";
38-
public static readonly SCHEMA_CONTEXT_KEY = "@context";
40+
public static readonly PUBLIC_REPOSITORY_URL = "publicRepositoryUrl";
3941
}

src/common/utility.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import * as fs from "fs-extra";
55
import * as path from "path";
66
import { DeviceModelManager, ModelType } from "../deviceModel/deviceModelManager";
7+
import { ModelFileInfo } from "../modelRepository/modelRepositoryManager";
78
import { Constants } from "./constants";
89

910
export class Utility {
@@ -15,7 +16,7 @@ export class Utility {
1516
const template: string = await fs.readFile(templatePath, Constants.UTF8);
1617
const content: string = Utility.replaceAll(template, replacement);
1718
const jsonContent = JSON.parse(content);
18-
await fs.writeFile(filePath, JSON.stringify(jsonContent, null, 2), { encoding: Constants.UTF8 });
19+
await fs.writeJson(filePath, jsonContent, { spaces: Constants.JSON_SPACE, encoding: Constants.UTF8 });
1920
}
2021

2122
public static replaceAll(str: string, replacement: Map<string, string>, caseInsensitive: boolean = false): string {
@@ -62,11 +63,7 @@ export class Utility {
6263
const replacement = new Map<string, string>();
6364
replacement.set(":", "_");
6465
const modelName: string = Utility.replaceAll(modelId, replacement);
65-
// TODO:(erichen): check if @type works
6666
const type: ModelType = DeviceModelManager.convertToModelType(content[Constants.SCHEMA_TYPE_KEY]);
67-
if (!type) {
68-
throw new Error("Invalid model type");
69-
}
7067

7168
let candidate: string = DeviceModelManager.generateModelFilename(modelName, type);
7269
let counter: number = 0;
@@ -78,7 +75,19 @@ export class Utility {
7875
candidate = DeviceModelManager.generateModelFilename(`${modelName}_${counter}`, type);
7976
}
8077

81-
await fs.writeFile(path.join(folder, candidate), JSON.stringify(content, null, 2), { encoding: Constants.UTF8 });
78+
await fs.writeJson(path.join(folder, candidate), content, {
79+
spaces: Constants.JSON_SPACE,
80+
encoding: Constants.UTF8,
81+
});
82+
}
83+
84+
public static async listModelFiles(folder: string): Promise<string[]> {
85+
const fileInfos: string[] = [];
86+
const files: string[] = await fs.readdir(folder);
87+
for (const file of files) {
88+
fileInfos.push(file);
89+
}
90+
return fileInfos;
8291
}
8392

8493
private constructor() {}

src/deviceModel/deviceModelManager.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ export enum ModelType {
1717

1818
export class DeviceModelManager {
1919
public static convertToModelType(name: string): ModelType {
20-
return ModelType[name as keyof typeof ModelType];
20+
const type: ModelType = ModelType[name as keyof typeof ModelType];
21+
if (!type) {
22+
throw new Error(Constants.MODEL_TYPE_INVALID_MSG);
23+
}
24+
return type;
2125
}
2226

2327
public static generateModelId(name: string): string {
@@ -33,26 +37,29 @@ export class DeviceModelManager {
3337
return DeviceModelManager.generateModelFilename(Constants.SAMPLE_FILENAME, type);
3438
}
3539

36-
constructor(private readonly context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel) {}
40+
private readonly component: string;
41+
constructor(private readonly context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel) {
42+
this.component = Constants.DEVICE_MODEL_COMPONENT;
43+
}
3744

3845
public async createModel(type: ModelType): Promise<void> {
3946
const folder: string = await UI.selectRootFolder(UIConstants.SELECT_ROOT_FOLDER_LABEL);
4047
const name: string = await UI.inputModelName(UIConstants.INPUT_MODEL_NAME_LABEL, type, folder);
4148

4249
const subject = `Create ${type} ${name} in folder ${folder}`;
43-
this.outputChannel.start(subject, Constants.DEVICE_MODEL_COMPONENT);
50+
this.outputChannel.start(subject, this.component);
4451

4552
let filePath: string;
4653
try {
4754
filePath = await this.doCreateModel(type, folder, name);
4855
} catch (error) {
49-
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.DEVICE_MODEL_COMPONENT);
56+
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
5057
}
5158

5259
await UI.openAndShowTextDocument(filePath);
5360
const message: string = ColorizedChannel.generateMessage(subject);
5461
UI.showNotification(MessageType.Info, message);
55-
this.outputChannel.end(message, Constants.DEVICE_MODEL_COMPONENT);
62+
this.outputChannel.end(message, this.component);
5663
}
5764

5865
private async doCreateModel(type: ModelType, folder: string, name: string): Promise<string> {

src/extension.ts

+115-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT license.
33

44
import * as vscode from "vscode";
5-
import { BadRequestError } from "./common/badRequestError";
65
import { ColorizedChannel } from "./common/colorizedChannel";
76
import { Command } from "./common/command";
87
import { Constants } from "./common/constants";
@@ -11,6 +10,7 @@ import { ProcessError } from "./common/processError";
1110
import { TelemetryClient, TelemetryContext } from "./common/telemetryClient";
1211
import { UserCancelledError } from "./common/userCancelledError";
1312
import { DeviceModelManager, ModelType } from "./deviceModel/deviceModelManager";
13+
import { SearchResult } from "./modelRepository/modelRepositoryInterface";
1414
import { ModelRepositoryManager } from "./modelRepository/modelRepositoryManager";
1515
import { MessageType, UI } from "./views/ui";
1616

@@ -29,8 +29,8 @@ export function activate(context: vscode.ExtensionContext) {
2929
outputChannel,
3030
nsat,
3131
true,
32-
Command.CREATE_INTERFACE,
33-
(): Promise<void> => {
32+
Command.CreateInterface,
33+
async (): Promise<void> => {
3434
return deviceModelManager.createModel(ModelType.Interface);
3535
},
3636
);
@@ -41,11 +41,117 @@ export function activate(context: vscode.ExtensionContext) {
4141
outputChannel,
4242
nsat,
4343
true,
44-
Command.CREATE_CAPABILITY_MODEL,
45-
(): Promise<void> => {
44+
Command.CreateCapabilityModel,
45+
async (): Promise<void> => {
4646
return deviceModelManager.createModel(ModelType.CapabilityModel);
4747
},
4848
);
49+
50+
initCommand(
51+
context,
52+
telemetryClient,
53+
outputChannel,
54+
nsat,
55+
true,
56+
Command.OpenRepository,
57+
async (): Promise<void> => {
58+
return modelRepositoryManager.signIn();
59+
},
60+
);
61+
62+
initCommand(
63+
context,
64+
telemetryClient,
65+
outputChannel,
66+
nsat,
67+
true,
68+
Command.SignOutRepository,
69+
async (): Promise<void> => {
70+
return modelRepositoryManager.signOut();
71+
},
72+
);
73+
74+
initCommand(
75+
context,
76+
telemetryClient,
77+
outputChannel,
78+
nsat,
79+
true,
80+
Command.SubmitFiles,
81+
async (): Promise<void> => {
82+
return modelRepositoryManager.submitModels();
83+
},
84+
);
85+
86+
initCommand(
87+
context,
88+
telemetryClient,
89+
outputChannel,
90+
nsat,
91+
false,
92+
Command.DeleteModels,
93+
async (publicRepository: boolean, modelIds: string[]): Promise<void> => {
94+
return modelRepositoryManager.deleteModels(publicRepository, modelIds);
95+
},
96+
);
97+
98+
initCommand(
99+
context,
100+
telemetryClient,
101+
outputChannel,
102+
nsat,
103+
false,
104+
Command.DownloadModels,
105+
async (publicRepository: boolean, modelIds: string[]): Promise<void> => {
106+
return modelRepositoryManager.downloadModels(publicRepository, modelIds);
107+
},
108+
);
109+
110+
initCommand(
111+
context,
112+
telemetryClient,
113+
outputChannel,
114+
nsat,
115+
false,
116+
Command.SearchInterface,
117+
async (
118+
publicRepository: boolean,
119+
keyword?: string,
120+
pageSize?: number,
121+
continuationToken?: string,
122+
): Promise<SearchResult> => {
123+
return modelRepositoryManager.searchModel(
124+
ModelType.Interface,
125+
publicRepository,
126+
keyword,
127+
pageSize,
128+
continuationToken,
129+
);
130+
},
131+
);
132+
133+
initCommand(
134+
context,
135+
telemetryClient,
136+
outputChannel,
137+
nsat,
138+
false,
139+
Command.SearchCapabilityModel,
140+
async (
141+
publicRepository: boolean,
142+
keyword?: string,
143+
pageSize?: number,
144+
continuationToken?: string,
145+
): Promise<SearchResult> => {
146+
return modelRepositoryManager.searchModel(
147+
ModelType.CapabilityModel,
148+
publicRepository,
149+
keyword,
150+
pageSize,
151+
continuationToken,
152+
);
153+
},
154+
);
49155
}
50156

51157
export function deactivate() {}
@@ -60,11 +166,9 @@ function initCommand(
60166
callback: (...args: any[]) => Promise<any>,
61167
): void {
62168
context.subscriptions.push(
63-
vscode.commands.registerCommand(command.id, async (...args: any[]) => {
169+
vscode.commands.registerCommand(command, async (...args: any[]) => {
64170
const telemetryContext: TelemetryContext = telemetryClient.createContext();
65-
telemetryClient.sendEvent(`${command.id}.start`);
66-
outputChannel.show();
67-
outputChannel.start(`Trigger command ${command.description}`);
171+
telemetryClient.sendEvent(`${command}.start`);
68172

69173
try {
70174
return await callback(...args);
@@ -83,8 +187,8 @@ function initCommand(
83187
}
84188
} finally {
85189
telemetryClient.closeContext(telemetryContext);
86-
telemetryClient.sendEvent(`${command.id}.end`, telemetryContext);
87-
outputChannel.end(`Complete command ${command.description}`);
190+
telemetryClient.sendEvent(`${command}.end`, telemetryContext);
191+
outputChannel.show();
88192
if (enableSurvey) {
89193
nsat.takeSurvey(context);
90194
}

src/modelRepository/modelRepositoryClient.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export class ModelRepositoryClient {
6363
return new Promise<SearchResult>((resolve, reject) => {
6464
request(options)
6565
.then((response) => {
66-
const result = response as SearchResult;
66+
const result = response.body as SearchResult;
6767
return resolve(result);
6868
})
6969
.catch((err) => {

0 commit comments

Comments
 (0)