refactor: refactor code
This commit is contained in:
Родитель
8442169af5
Коммит
86c3827e2d
|
@ -97,18 +97,12 @@ function encodeHTML(value) {
|
|||
|
||||
function deleteDigitalTwinFiles() {
|
||||
const fileIds = this.type.value === INTERFACE ? this.selectedInterfaces.value : this.selectedCapabilityModels.value;
|
||||
command("azure-digital-twins.deleteModel", fileIds, this.type.value, refreshDigitalTwinFileList.bind(this));
|
||||
command("azure-digital-twins.deleteModels", this.publicRepository, fileIds, refreshDigitalTwinFileList.bind(this));
|
||||
}
|
||||
|
||||
function editDigitalTwinFiles() {
|
||||
const fileIds = this.type.value === INTERFACE ? this.selectedInterfaces.value : this.selectedCapabilityModels.value;
|
||||
command(
|
||||
"azure-digital-twins.downloadModel",
|
||||
fileIds,
|
||||
this.type.value,
|
||||
this.publicRepository,
|
||||
refreshDigitalTwinFileList.bind(this)
|
||||
);
|
||||
command("azure-digital-twins.downloadModels", this.publicRepository, fileIds, refreshDigitalTwinFileList.bind(this));
|
||||
}
|
||||
|
||||
function createDigitalTwinFile() {
|
||||
|
@ -136,7 +130,7 @@ function getNextPageDigitalTwinFiles(fileType) {
|
|||
}
|
||||
|
||||
loadingDigitalTwinFiles.value = true;
|
||||
command(commandName, this.searchKeywords, this.publicRepository, 50, nextToken.value, res => {
|
||||
command(commandName, this.publicRepository, this.searchKeywords, 50, nextToken.value, res => {
|
||||
Vue.set(fileList, VALUE, fileList.value.concat(res.result.results));
|
||||
Vue.set(nextToken, VALUE, res.result.continuationToken);
|
||||
Vue.set(loadingDigitalTwinFiles, VALUE, false);
|
||||
|
|
|
@ -8,7 +8,7 @@ export class ColorizedChannel {
|
|||
const message: string = error
|
||||
? subject.charAt(0).toLowerCase() + subject.slice(1)
|
||||
: subject.charAt(0).toUpperCase() + subject.slice(1);
|
||||
return error ? `Fail to ${message}. Error ${error.message}` : `${message} successfully`;
|
||||
return error ? `Fail to ${message}. Error: ${error.message}` : `${message} successfully`;
|
||||
}
|
||||
|
||||
private static buildTag(name: string | undefined): string {
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
export class Command {
|
||||
public static readonly CREATE_INTERFACE = new Command("azure-digital-twins.createInterface", "Create Interface");
|
||||
public static readonly CREATE_CAPABILITY_MODEL = new Command(
|
||||
"azure-digital-twins.createCapabilityModel",
|
||||
"Create Capability Model",
|
||||
);
|
||||
public static readonly OPEN_REPOSITORY = new Command("azure-digital-twins.openRepository", "Open Model Repository");
|
||||
public static readonly SIGN_OUT_REPOSITORY = new Command(
|
||||
"azure-digital-twins.signOutRepository",
|
||||
"Sign out Model Repository",
|
||||
);
|
||||
public static readonly SUBMIT_FILES = new Command(
|
||||
"azure-digital-twins.submitFiles",
|
||||
"Submit Files to Model Repository",
|
||||
);
|
||||
private constructor(public readonly id: string, public readonly description: string) {}
|
||||
export enum Command {
|
||||
CreateInterface = "azure-digital-twins.createInterface",
|
||||
CreateCapabilityModel = "azure-digital-twins.createCapabilityModeel",
|
||||
OpenRepository = "azure-digital-twins.openRepository",
|
||||
SignOutRepository = "azure-digital-twins.signOutRepository",
|
||||
SearchInterface = "azure-digital-twins.searchInterface",
|
||||
SearchCapabilityModel = "azure-digital-twins.searchCapabilityModel",
|
||||
SubmitFiles = "azure-digital-twins.submitFiles",
|
||||
DeleteModels = "azure-digital-twins.deleteModels",
|
||||
DownloadModels = "azure-digital-twins.downloadModels",
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ export class Constants {
|
|||
public static readonly EXTENSION_NAME = "azure-digital-twins";
|
||||
public static readonly CHANNEL_NAME = "IoT Plug and Play";
|
||||
public static readonly UTF8 = "utf8";
|
||||
public static readonly JSON_SPACE = 2;
|
||||
public static readonly NOT_FOUND_CODE = 404;
|
||||
public static readonly DEFAULT_PAGE_SIZE = 50;
|
||||
public static readonly RESOURCE_FOLDER = "resources";
|
||||
public static readonly TEMPLATE_FOLDER = "templates";
|
||||
public static readonly SAMPLE_FILENAME = "sample";
|
||||
|
@ -13,7 +16,14 @@ export class Constants {
|
|||
public static readonly MODEL_REPOSITORY_COMPONENT = "Model Repository";
|
||||
public static readonly MODEL_REPOSITORY_CONNECTION_KEY = "ModelRepositoryConnectionKey";
|
||||
public static readonly MODEL_REPOSITORY_API_VERSION = "2019-07-01-Preview";
|
||||
public static readonly PUBLIC_REPOSITORY_URL = "publicRepositoryUrl";
|
||||
public static readonly URL_PROTOCAL_REGEX = new RegExp("^[a-zA-Z]+://");
|
||||
public static readonly HTTPS_PROTOCAL = "https://";
|
||||
public static readonly MODEL_NAME_REGEX = new RegExp("^[a-zA-Z_][a-zA-Z0-9_]*$");
|
||||
public static readonly MODEL_NAME_REGEX_DESCRIPTION = "alphanumeric and underscore, not start with number";
|
||||
public static readonly DIGITAL_TWIN_ID_PLACEHOLDER = "{DigitalTwinIdentifier}";
|
||||
public static readonly SCHEMA_ID_KEY = "@id";
|
||||
public static readonly SCHEMA_TYPE_KEY = "@type";
|
||||
public static readonly SCHEMA_CONTEXT_KEY = "@context";
|
||||
|
||||
public static readonly EXTENSION_ACTIVATED_MSG = "extensionActivated";
|
||||
public static readonly NOT_EMPTY_MSG = "could not be empty";
|
||||
|
@ -21,19 +31,11 @@ export class Constants {
|
|||
"Company repository connection string is not found. Please sign out and sign in with a valid connection string";
|
||||
public static readonly PUBLIC_REPOSITORY_URL_NOT_FOUND_MSG = "Public repository url is not found";
|
||||
public static readonly CONNECTION_STRING_INVALID_FORMAT_MSG = "Invalid connection string format";
|
||||
public static readonly MODEL_TYPE_INVALID_MSG = "Invalid model type";
|
||||
|
||||
public static readonly NSAT_SURVEY_URL = "https://aka.ms/vscode-azure-digital-twins-survey";
|
||||
public static readonly WEB_VIEW_PATH = "assets/modelRepository";
|
||||
public static readonly COMPANY_REPOSITORY_PAGE = "index.html";
|
||||
public static readonly PUBLIC_REPOSITORY_PAGE = "index.html?public";
|
||||
|
||||
public static readonly MODEL_NAME_REGEX = new RegExp("^[a-zA-Z_][a-zA-Z0-9_]*$");
|
||||
public static readonly MODEL_NAME_REGEX_DESCRIPTION = "alphanumeric and underscore, not start with number";
|
||||
public static readonly DIGITAL_TWIN_ID_PLACEHOLDER = "{DigitalTwinIdentifier}";
|
||||
public static readonly URL_PROTOCAL_REGEX = new RegExp("^[a-zA-Z]+://");
|
||||
public static readonly HTTPS_PROTOCAL = "https://";
|
||||
public static readonly NOT_FOUND_CODE = 404;
|
||||
public static readonly SCHEMA_ID_KEY = "@id";
|
||||
public static readonly SCHEMA_TYPE_KEY = "@type";
|
||||
public static readonly SCHEMA_CONTEXT_KEY = "@context";
|
||||
public static readonly PUBLIC_REPOSITORY_URL = "publicRepositoryUrl";
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import * as fs from "fs-extra";
|
||||
import * as path from "path";
|
||||
import { DeviceModelManager, ModelType } from "../deviceModel/deviceModelManager";
|
||||
import { ModelFileInfo } from "../modelRepository/modelRepositoryManager";
|
||||
import { Constants } from "./constants";
|
||||
|
||||
export class Utility {
|
||||
|
@ -15,7 +16,7 @@ export class Utility {
|
|||
const template: string = await fs.readFile(templatePath, Constants.UTF8);
|
||||
const content: string = Utility.replaceAll(template, replacement);
|
||||
const jsonContent = JSON.parse(content);
|
||||
await fs.writeFile(filePath, JSON.stringify(jsonContent, null, 2), { encoding: Constants.UTF8 });
|
||||
await fs.writeJson(filePath, jsonContent, { spaces: Constants.JSON_SPACE, encoding: Constants.UTF8 });
|
||||
}
|
||||
|
||||
public static replaceAll(str: string, replacement: Map<string, string>, caseInsensitive: boolean = false): string {
|
||||
|
@ -62,11 +63,7 @@ export class Utility {
|
|||
const replacement = new Map<string, string>();
|
||||
replacement.set(":", "_");
|
||||
const modelName: string = Utility.replaceAll(modelId, replacement);
|
||||
// TODO:(erichen): check if @type works
|
||||
const type: ModelType = DeviceModelManager.convertToModelType(content[Constants.SCHEMA_TYPE_KEY]);
|
||||
if (!type) {
|
||||
throw new Error("Invalid model type");
|
||||
}
|
||||
|
||||
let candidate: string = DeviceModelManager.generateModelFilename(modelName, type);
|
||||
let counter: number = 0;
|
||||
|
@ -78,7 +75,19 @@ export class Utility {
|
|||
candidate = DeviceModelManager.generateModelFilename(`${modelName}_${counter}`, type);
|
||||
}
|
||||
|
||||
await fs.writeFile(path.join(folder, candidate), JSON.stringify(content, null, 2), { encoding: Constants.UTF8 });
|
||||
await fs.writeJson(path.join(folder, candidate), content, {
|
||||
spaces: Constants.JSON_SPACE,
|
||||
encoding: Constants.UTF8,
|
||||
});
|
||||
}
|
||||
|
||||
public static async listModelFiles(folder: string): Promise<string[]> {
|
||||
const fileInfos: string[] = [];
|
||||
const files: string[] = await fs.readdir(folder);
|
||||
for (const file of files) {
|
||||
fileInfos.push(file);
|
||||
}
|
||||
return fileInfos;
|
||||
}
|
||||
|
||||
private constructor() {}
|
||||
|
|
|
@ -17,7 +17,11 @@ export enum ModelType {
|
|||
|
||||
export class DeviceModelManager {
|
||||
public static convertToModelType(name: string): ModelType {
|
||||
return ModelType[name as keyof typeof ModelType];
|
||||
const type: ModelType = ModelType[name as keyof typeof ModelType];
|
||||
if (!type) {
|
||||
throw new Error(Constants.MODEL_TYPE_INVALID_MSG);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static generateModelId(name: string): string {
|
||||
|
@ -33,26 +37,29 @@ export class DeviceModelManager {
|
|||
return DeviceModelManager.generateModelFilename(Constants.SAMPLE_FILENAME, type);
|
||||
}
|
||||
|
||||
constructor(private readonly context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel) {}
|
||||
private readonly component: string;
|
||||
constructor(private readonly context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel) {
|
||||
this.component = Constants.DEVICE_MODEL_COMPONENT;
|
||||
}
|
||||
|
||||
public async createModel(type: ModelType): Promise<void> {
|
||||
const folder: string = await UI.selectRootFolder(UIConstants.SELECT_ROOT_FOLDER_LABEL);
|
||||
const name: string = await UI.inputModelName(UIConstants.INPUT_MODEL_NAME_LABEL, type, folder);
|
||||
|
||||
const subject = `Create ${type} ${name} in folder ${folder}`;
|
||||
this.outputChannel.start(subject, Constants.DEVICE_MODEL_COMPONENT);
|
||||
this.outputChannel.start(subject, this.component);
|
||||
|
||||
let filePath: string;
|
||||
try {
|
||||
filePath = await this.doCreateModel(type, folder, name);
|
||||
} catch (error) {
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.DEVICE_MODEL_COMPONENT);
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
|
||||
}
|
||||
|
||||
await UI.openAndShowTextDocument(filePath);
|
||||
const message: string = ColorizedChannel.generateMessage(subject);
|
||||
UI.showNotification(MessageType.Info, message);
|
||||
this.outputChannel.end(message, Constants.DEVICE_MODEL_COMPONENT);
|
||||
this.outputChannel.end(message, this.component);
|
||||
}
|
||||
|
||||
private async doCreateModel(type: ModelType, folder: string, name: string): Promise<string> {
|
||||
|
|
126
src/extension.ts
126
src/extension.ts
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import * as vscode from "vscode";
|
||||
import { BadRequestError } from "./common/badRequestError";
|
||||
import { ColorizedChannel } from "./common/colorizedChannel";
|
||||
import { Command } from "./common/command";
|
||||
import { Constants } from "./common/constants";
|
||||
|
@ -11,6 +10,7 @@ import { ProcessError } from "./common/processError";
|
|||
import { TelemetryClient, TelemetryContext } from "./common/telemetryClient";
|
||||
import { UserCancelledError } from "./common/userCancelledError";
|
||||
import { DeviceModelManager, ModelType } from "./deviceModel/deviceModelManager";
|
||||
import { SearchResult } from "./modelRepository/modelRepositoryInterface";
|
||||
import { ModelRepositoryManager } from "./modelRepository/modelRepositoryManager";
|
||||
import { MessageType, UI } from "./views/ui";
|
||||
|
||||
|
@ -29,8 +29,8 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
outputChannel,
|
||||
nsat,
|
||||
true,
|
||||
Command.CREATE_INTERFACE,
|
||||
(): Promise<void> => {
|
||||
Command.CreateInterface,
|
||||
async (): Promise<void> => {
|
||||
return deviceModelManager.createModel(ModelType.Interface);
|
||||
},
|
||||
);
|
||||
|
@ -41,11 +41,117 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
outputChannel,
|
||||
nsat,
|
||||
true,
|
||||
Command.CREATE_CAPABILITY_MODEL,
|
||||
(): Promise<void> => {
|
||||
Command.CreateCapabilityModel,
|
||||
async (): Promise<void> => {
|
||||
return deviceModelManager.createModel(ModelType.CapabilityModel);
|
||||
},
|
||||
);
|
||||
|
||||
initCommand(
|
||||
context,
|
||||
telemetryClient,
|
||||
outputChannel,
|
||||
nsat,
|
||||
true,
|
||||
Command.OpenRepository,
|
||||
async (): Promise<void> => {
|
||||
return modelRepositoryManager.signIn();
|
||||
},
|
||||
);
|
||||
|
||||
initCommand(
|
||||
context,
|
||||
telemetryClient,
|
||||
outputChannel,
|
||||
nsat,
|
||||
true,
|
||||
Command.SignOutRepository,
|
||||
async (): Promise<void> => {
|
||||
return modelRepositoryManager.signOut();
|
||||
},
|
||||
);
|
||||
|
||||
initCommand(
|
||||
context,
|
||||
telemetryClient,
|
||||
outputChannel,
|
||||
nsat,
|
||||
true,
|
||||
Command.SubmitFiles,
|
||||
async (): Promise<void> => {
|
||||
return modelRepositoryManager.submitModels();
|
||||
},
|
||||
);
|
||||
|
||||
initCommand(
|
||||
context,
|
||||
telemetryClient,
|
||||
outputChannel,
|
||||
nsat,
|
||||
false,
|
||||
Command.DeleteModels,
|
||||
async (publicRepository: boolean, modelIds: string[]): Promise<void> => {
|
||||
return modelRepositoryManager.deleteModels(publicRepository, modelIds);
|
||||
},
|
||||
);
|
||||
|
||||
initCommand(
|
||||
context,
|
||||
telemetryClient,
|
||||
outputChannel,
|
||||
nsat,
|
||||
false,
|
||||
Command.DownloadModels,
|
||||
async (publicRepository: boolean, modelIds: string[]): Promise<void> => {
|
||||
return modelRepositoryManager.downloadModels(publicRepository, modelIds);
|
||||
},
|
||||
);
|
||||
|
||||
initCommand(
|
||||
context,
|
||||
telemetryClient,
|
||||
outputChannel,
|
||||
nsat,
|
||||
false,
|
||||
Command.SearchInterface,
|
||||
async (
|
||||
publicRepository: boolean,
|
||||
keyword?: string,
|
||||
pageSize?: number,
|
||||
continuationToken?: string,
|
||||
): Promise<SearchResult> => {
|
||||
return modelRepositoryManager.searchModel(
|
||||
ModelType.Interface,
|
||||
publicRepository,
|
||||
keyword,
|
||||
pageSize,
|
||||
continuationToken,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
initCommand(
|
||||
context,
|
||||
telemetryClient,
|
||||
outputChannel,
|
||||
nsat,
|
||||
false,
|
||||
Command.SearchCapabilityModel,
|
||||
async (
|
||||
publicRepository: boolean,
|
||||
keyword?: string,
|
||||
pageSize?: number,
|
||||
continuationToken?: string,
|
||||
): Promise<SearchResult> => {
|
||||
return modelRepositoryManager.searchModel(
|
||||
ModelType.CapabilityModel,
|
||||
publicRepository,
|
||||
keyword,
|
||||
pageSize,
|
||||
continuationToken,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function deactivate() {}
|
||||
|
@ -60,11 +166,9 @@ function initCommand(
|
|||
callback: (...args: any[]) => Promise<any>,
|
||||
): void {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand(command.id, async (...args: any[]) => {
|
||||
vscode.commands.registerCommand(command, async (...args: any[]) => {
|
||||
const telemetryContext: TelemetryContext = telemetryClient.createContext();
|
||||
telemetryClient.sendEvent(`${command.id}.start`);
|
||||
outputChannel.show();
|
||||
outputChannel.start(`Trigger command ${command.description}`);
|
||||
telemetryClient.sendEvent(`${command}.start`);
|
||||
|
||||
try {
|
||||
return await callback(...args);
|
||||
|
@ -83,8 +187,8 @@ function initCommand(
|
|||
}
|
||||
} finally {
|
||||
telemetryClient.closeContext(telemetryContext);
|
||||
telemetryClient.sendEvent(`${command.id}.end`, telemetryContext);
|
||||
outputChannel.end(`Complete command ${command.description}`);
|
||||
telemetryClient.sendEvent(`${command}.end`, telemetryContext);
|
||||
outputChannel.show();
|
||||
if (enableSurvey) {
|
||||
nsat.takeSurvey(context);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ export class ModelRepositoryClient {
|
|||
return new Promise<SearchResult>((resolve, reject) => {
|
||||
request(options)
|
||||
.then((response) => {
|
||||
const result = response as SearchResult;
|
||||
const result = response.body as SearchResult;
|
||||
return resolve(result);
|
||||
})
|
||||
.catch((err) => {
|
||||
|
|
|
@ -7,7 +7,6 @@ import { Constants } from "../common/constants";
|
|||
const PROPERTY_SEPARATOR = ";";
|
||||
const KEY_VALUE_SEPARATOR = "=";
|
||||
const PROPERTY_COUNT = 4;
|
||||
const KEY_VALUE_COUNT = 2;
|
||||
const HOSTNAME_PROPERTY = "HostName";
|
||||
const REPOSITORY_ID_PROPERTY = "RepositoryId";
|
||||
const SHARED_ACCESS_KEY_NAME_PROPERTY = "SharedAccessKeyName";
|
||||
|
@ -32,11 +31,16 @@ export class ModelRepositoryConnection {
|
|||
throw new Error(Constants.CONNECTION_STRING_INVALID_FORMAT_MSG);
|
||||
}
|
||||
for (const property of properties) {
|
||||
const fields: string[] = property.split(KEY_VALUE_SEPARATOR);
|
||||
if (fields.length !== KEY_VALUE_COUNT) {
|
||||
const index: number = property.indexOf(KEY_VALUE_SEPARATOR);
|
||||
if (index <= 0) {
|
||||
throw new Error(Constants.CONNECTION_STRING_INVALID_FORMAT_MSG);
|
||||
}
|
||||
map[fields[0]] = fields[1];
|
||||
const name: string = property.substring(0, index);
|
||||
const value: string = property.substring(index + 1);
|
||||
if (!name || !value) {
|
||||
throw new Error(Constants.CONNECTION_STRING_INVALID_FORMAT_MSG);
|
||||
}
|
||||
map[name] = value;
|
||||
}
|
||||
|
||||
return new ModelRepositoryConnection(
|
||||
|
|
|
@ -25,7 +25,7 @@ export interface DigitalTwinModelBase {
|
|||
publisherId: string;
|
||||
publisherName: string;
|
||||
createdOn: string;
|
||||
lastUpdated: string;
|
||||
updatedOn: string;
|
||||
}
|
||||
|
||||
export interface SearchOptions {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { Constants } from "../common/constants";
|
|||
import { CredentialStore } from "../common/credentialStore";
|
||||
import { ProcessError } from "../common/processError";
|
||||
import { Utility } from "../common/utility";
|
||||
import { DeviceModelManager, ModelType } from "../deviceModel/deviceModelManager";
|
||||
import { ModelType } from "../deviceModel/deviceModelManager";
|
||||
import { MessageType, UI } from "../views/ui";
|
||||
import { UIConstants } from "../views/uiConstants";
|
||||
import { ModelRepositoryClient } from "./modelRepositoryClient";
|
||||
|
@ -36,8 +36,17 @@ export interface ModelFileInfo {
|
|||
}
|
||||
|
||||
export class ModelRepositoryManager {
|
||||
private static async buildRepositoryInfo(isCompany: boolean): Promise<RepositoryInfo> {
|
||||
if (isCompany) {
|
||||
private static async buildRepositoryInfo(publicRepository: boolean): Promise<RepositoryInfo> {
|
||||
if (publicRepository) {
|
||||
const url: string | undefined = Configuration.getProperty<string>(Constants.PUBLIC_REPOSITORY_URL);
|
||||
if (!url) {
|
||||
throw new Error(Constants.PUBLIC_REPOSITORY_URL_NOT_FOUND_MSG);
|
||||
}
|
||||
return {
|
||||
hostname: Utility.enforceHttps(url),
|
||||
apiVersion: Constants.MODEL_REPOSITORY_API_VERSION,
|
||||
};
|
||||
} else {
|
||||
const connectionString: string | null = await CredentialStore.get(Constants.MODEL_REPOSITORY_CONNECTION_KEY);
|
||||
if (!connectionString) {
|
||||
throw new Error(Constants.CONNECTION_STRING_NOT_FOUND_MSG);
|
||||
|
@ -49,21 +58,12 @@ export class ModelRepositoryManager {
|
|||
repositoryId: connection.repositoryId,
|
||||
accessToken: connection.generateAccessToken(),
|
||||
};
|
||||
} else {
|
||||
const url: string | undefined = Configuration.getProperty<string>(Constants.PUBLIC_REPOSITORY_URL);
|
||||
if (!url) {
|
||||
throw new Error(Constants.PUBLIC_REPOSITORY_URL_NOT_FOUND_MSG);
|
||||
}
|
||||
return {
|
||||
hostname: Utility.enforceHttps(url),
|
||||
apiVersion: Constants.MODEL_REPOSITORY_API_VERSION,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static async setupConnection(connectionString: string, isNew: boolean): Promise<void> {
|
||||
private static async setupConnection(connectionString: string, newConnection: boolean): Promise<void> {
|
||||
const connection: ModelRepositoryConnection = ModelRepositoryConnection.parse(connectionString);
|
||||
if (isNew) {
|
||||
if (newConnection) {
|
||||
ModelRepositoryConnection.validate(connection);
|
||||
}
|
||||
|
||||
|
@ -74,8 +74,8 @@ export class ModelRepositoryManager {
|
|||
accessToken: connection.generateAccessToken(),
|
||||
};
|
||||
// test connection by searching interface
|
||||
ModelRepositoryClient.searchModel(repoInfo, ModelType.Interface, "", 1, null);
|
||||
if (isNew) {
|
||||
await ModelRepositoryClient.searchModel(repoInfo, ModelType.Interface, "", 1, null);
|
||||
if (newConnection) {
|
||||
await CredentialStore.set(Constants.MODEL_REPOSITORY_CONNECTION_KEY, connectionString);
|
||||
}
|
||||
}
|
||||
|
@ -87,8 +87,10 @@ export class ModelRepositoryManager {
|
|||
}
|
||||
|
||||
private readonly express: VSCExpress;
|
||||
private readonly component: string;
|
||||
constructor(context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel, filePath: string) {
|
||||
this.express = new VSCExpress(context, filePath);
|
||||
this.component = Constants.MODEL_REPOSITORY_COMPONENT;
|
||||
}
|
||||
|
||||
public async signIn(): Promise<void> {
|
||||
|
@ -96,7 +98,7 @@ export class ModelRepositoryManager {
|
|||
const selected: vscode.QuickPickItem = await UI.showQuickPick(UIConstants.SELECT_REPOSITORY_LABEL, items);
|
||||
|
||||
const subject = `Connect to ${selected.label}`;
|
||||
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.start(subject, this.component);
|
||||
|
||||
if (selected.label === RepositoryType.Company) {
|
||||
let isNew: boolean = false;
|
||||
|
@ -107,15 +109,15 @@ export class ModelRepositoryManager {
|
|||
}
|
||||
|
||||
try {
|
||||
ModelRepositoryManager.setupConnection(connectionString, isNew);
|
||||
await ModelRepositoryManager.setupConnection(connectionString, isNew);
|
||||
} catch (error) {
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
|
||||
}
|
||||
}
|
||||
|
||||
const message: string = ColorizedChannel.generateMessage(subject);
|
||||
UI.showNotification(MessageType.Info, message);
|
||||
this.outputChannel.end(message, Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.end(message, this.component);
|
||||
|
||||
// open web view
|
||||
const uri =
|
||||
|
@ -128,7 +130,7 @@ export class ModelRepositoryManager {
|
|||
|
||||
public async signOut(): Promise<void> {
|
||||
const subject = "Sign out company repository";
|
||||
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.start(subject, this.component);
|
||||
|
||||
const success: boolean = await CredentialStore.delete(Constants.MODEL_REPOSITORY_CONNECTION_KEY);
|
||||
|
||||
|
@ -136,77 +138,75 @@ export class ModelRepositoryManager {
|
|||
if (success) {
|
||||
UI.showNotification(MessageType.Info, message);
|
||||
}
|
||||
this.outputChannel.end(message, Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.end(message, this.component);
|
||||
|
||||
if (this.express) {
|
||||
this.express.close(Constants.COMPANY_REPOSITORY_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public async submitFiles(): Promise<void> {
|
||||
public async submitModels(): Promise<void> {
|
||||
const folder: string = await UI.selectRootFolder(UIConstants.SELECT_ROOT_FOLDER_LABEL);
|
||||
// const fileInfos: ModelFileInfo[] = await Utility.listModelFiles();
|
||||
const fileInfos: string[] = await Utility.listModelFiles(folder);
|
||||
vscode.window.showInformationMessage(`${fileInfos}`);
|
||||
}
|
||||
|
||||
public async searchModel(
|
||||
modelType: string,
|
||||
isCompany: boolean,
|
||||
type: ModelType,
|
||||
publicRepository: boolean,
|
||||
keyword: string = "",
|
||||
pageSize: number = 20,
|
||||
pageSize: number = Constants.DEFAULT_PAGE_SIZE,
|
||||
continuationToken: string | null = null,
|
||||
): Promise<SearchResult> {
|
||||
const type: ModelType = DeviceModelManager.convertToModelType(modelType);
|
||||
if (!type) {
|
||||
throw new BadRequestError("unrecognized modelType");
|
||||
}
|
||||
if (pageSize <= 0) {
|
||||
throw new BadRequestError("pageSize should be greater than 0");
|
||||
}
|
||||
|
||||
const subject = `Search ${type} by keyword "${keyword}" from ${
|
||||
isCompany ? RepositoryType.Company : RepositoryType.Public
|
||||
publicRepository ? RepositoryType.Public : RepositoryType.Company
|
||||
}`;
|
||||
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.start(subject, this.component);
|
||||
|
||||
let result: SearchResult;
|
||||
try {
|
||||
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(isCompany);
|
||||
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(publicRepository);
|
||||
result = await ModelRepositoryClient.searchModel(repoInfo, type, keyword, pageSize, continuationToken);
|
||||
} catch (error) {
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
|
||||
}
|
||||
|
||||
const message = ColorizedChannel.generateMessage(subject);
|
||||
this.outputChannel.end(message, Constants.DEVICE_MODEL_COMPONENT);
|
||||
this.outputChannel.end(message, this.component);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async deleteModels(isCompany: boolean, modelIds: string[]): Promise<void> {
|
||||
if (!isCompany) {
|
||||
public async deleteModels(publicRepository: boolean, modelIds: string[]): Promise<void> {
|
||||
if (publicRepository) {
|
||||
throw new BadRequestError(`${RepositoryType.Public} not support delete operation`);
|
||||
}
|
||||
ModelRepositoryManager.validateModelIds(modelIds);
|
||||
|
||||
try {
|
||||
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(isCompany);
|
||||
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(publicRepository);
|
||||
await this.doDeleteLoopSilently(repoInfo, modelIds);
|
||||
} catch (error) {
|
||||
const subject = `Delete models from ${RepositoryType.Company}`;
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
|
||||
}
|
||||
}
|
||||
|
||||
public async downloadModels(isCompany: boolean, modelIds: string[]): Promise<void> {
|
||||
public async downloadModels(publicRepository: boolean, modelIds: string[]): Promise<void> {
|
||||
ModelRepositoryManager.validateModelIds(modelIds);
|
||||
|
||||
const folder: string = await UI.selectRootFolder(UIConstants.SELECT_ROOT_FOLDER_LABEL);
|
||||
|
||||
try {
|
||||
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(isCompany);
|
||||
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(publicRepository);
|
||||
await this.doDownloadLoopSilently([repoInfo], modelIds, folder);
|
||||
} catch (error) {
|
||||
const subject = `Download models from ${isCompany ? RepositoryType.Company : RepositoryType.Public}`;
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
const subject = `Download models from ${publicRepository ? RepositoryType.Public : RepositoryType.Company}`;
|
||||
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,19 +218,16 @@ export class ModelRepositoryManager {
|
|||
// download interface files
|
||||
}
|
||||
|
||||
private async doDownloadLoopSilently(repoInfos: RepositoryInfo[], modelIds: string[], folder: string) {
|
||||
private async doDownloadLoopSilently(repoInfos: RepositoryInfo[], modelIds: string[], folder: string): Promise<void> {
|
||||
for (const modelId of modelIds) {
|
||||
const subject = `Download model by id ${modelId}`;
|
||||
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.start(subject, this.component);
|
||||
|
||||
try {
|
||||
await this.doDownloadModel(repoInfos, modelId, folder);
|
||||
this.outputChannel.end(ColorizedChannel.generateMessage(subject), Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.end(ColorizedChannel.generateMessage(subject), this.component);
|
||||
} catch (error) {
|
||||
this.outputChannel.error(
|
||||
ColorizedChannel.generateMessage(subject, error),
|
||||
Constants.MODEL_REPOSITORY_COMPONENT,
|
||||
);
|
||||
this.outputChannel.error(ColorizedChannel.generateMessage(subject, error), this.component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,16 +255,13 @@ export class ModelRepositoryManager {
|
|||
private async doDeleteLoopSilently(repoInfo: RepositoryInfo, modelIds: string[]): Promise<void> {
|
||||
for (const modelId of modelIds) {
|
||||
const subject = `Delete model by id ${modelId}`;
|
||||
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.start(subject, this.component);
|
||||
|
||||
try {
|
||||
await ModelRepositoryClient.deleteModel(repoInfo, modelId);
|
||||
this.outputChannel.end(ColorizedChannel.generateMessage(subject), Constants.MODEL_REPOSITORY_COMPONENT);
|
||||
this.outputChannel.end(ColorizedChannel.generateMessage(subject), this.component);
|
||||
} catch (error) {
|
||||
this.outputChannel.error(
|
||||
ColorizedChannel.generateMessage(subject, error),
|
||||
Constants.MODEL_REPOSITORY_COMPONENT,
|
||||
);
|
||||
this.outputChannel.error(ColorizedChannel.generateMessage(subject, error), this.component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче