This commit is contained in:
Eugene Olonov 2024-03-14 11:58:14 -07:00
Родитель 9f17feb6dd
Коммит 758b5be86e
80 изменённых файлов: 359 добавлений и 342 удалений

Просмотреть файл

@ -6,6 +6,7 @@ module.exports = {
extends: [
'eslint:recommended',
'plugin:prettier/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:react/recommended',
],
@ -41,6 +42,7 @@ module.exports = {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-use-before-define': 'warn',
'@typescript-eslint/prefer-optional-chain': 'error',
@ -110,7 +112,7 @@ module.exports = {
'react/no-danger': 'error',
'react/no-deprecated': 'warn',
'react/prop-types': 'off',
'react/no-unknown-property': 'error',
'react/no-unknown-property': ['error', { 'ignore': ['css'] }],
'react/jsx-boolean-value': ['error', 'never'],
'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
// https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-sort-props.md

Просмотреть файл

@ -18,20 +18,20 @@ module.exports = {
} else {
done(null, false, { message: 'Incorrect password' });
}
})
}),
);
// define this BEFORE turning on the middleware...
composer.addWebRoute('get', '/login', (req, res) => {
res.send(
'LOGIN REQUIRED <form method="post" action="/login/submit"><input name="username" placeholder="username" value="admin" /><input name="password" type="password" value="secret" /><button type="submit">Login</button></form>'
'LOGIN REQUIRED <form method="post" action="/login/submit"><input name="username" placeholder="username" value="admin" /><input name="password" type="password" value="secret" /><button type="submit">Login</button></form>',
);
});
composer.addWebRoute(
'post',
'/login/submit',
composer.passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' })
composer.passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' }),
);
composer.addAllowedUrl('/login/submit');

Просмотреть файл

@ -79,7 +79,7 @@ const CreateActionContent = () => {
<Summary>
<Text>
{formatMessage(
'Select this option when you want to provision new Azure resources and publish a bot. A subscription to'
'Select this option when you want to provision new Azure resources and publish a bot. A subscription to',
)}
</Text>
&nbsp;
@ -138,14 +138,14 @@ const ImportActionContent = () => {
<p>
<Text>
{formatMessage(
'Select this option if you have access to existing Azure resources and their associated values.'
'Select this option if you have access to existing Azure resources and their associated values.',
)}
</Text>
</p>
<p>
<Text>
{formatMessage(
'Copy and paste the JSON file containing the values of your existing Azure resources, from the Azure portal. This file includes values for some or all of the following:'
'Copy and paste the JSON file containing the values of your existing Azure resources, from the Azure portal. This file includes values for some or all of the following:',
)}
</Text>
</p>
@ -190,7 +190,7 @@ const GenerateActionContent = () => {
<Summary>
<Text>
{formatMessage(
'Select this option to request your Azure admin to provision resources on your behalf, for example, when you dont have proper permissions to use Azure or you want to generate resources from a sovereign cloud.'
'Select this option to request your Azure admin to provision resources on your behalf, for example, when you dont have proper permissions to use Azure or you want to generate resources from a sovereign cloud.',
)}
</Text>
</Summary>
@ -200,7 +200,7 @@ const GenerateActionContent = () => {
<InstructionDetails>
<Text>
{formatMessage(
'Add resources you need for the bot and generate a resource request to share with your Azure admin.'
'Add resources you need for the bot and generate a resource request to share with your Azure admin.',
)}
</Text>
</InstructionDetails>
@ -210,7 +210,7 @@ const GenerateActionContent = () => {
<InstructionDetails>
<Text>
{formatMessage(
'Once you get the resource details from your Azure admin, use them to import existing resources.'
'Once you get the resource details from your Azure admin, use them to import existing resources.',
)}
</Text>
</InstructionDetails>

Просмотреть файл

@ -86,8 +86,8 @@ export const ResourceGroupPicker = ({
if (debouncedNewName && !debouncedNewName.match(/^[-\w._()]+$/)) {
setNewNameErrorMessage(
formatMessage(
'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.'
)
'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.',
),
);
} else if (alreadyExists) {
setNewNameErrorMessage(formatMessage('A resource with this name already exists.'));

Просмотреть файл

@ -53,7 +53,7 @@ export const getSubscriptions = async (token: string): Promise<Array<Subscriptio
let message = JSON.stringify(err, Object.getOwnPropertyNames(err));
if (err?.code === 12 && err?.message?.match(/Bearer/gi)) {
message = formatMessage(
'There was an authentication problem retrieving subscriptions. Verify your login session has not expired and you have permission to list subscriptions in this account.'
'There was an authentication problem retrieving subscriptions. Verify your login session has not expired and you have permission to list subscriptions in this account.',
);
}
@ -100,7 +100,7 @@ export const getResourceGroups = async (token: string, subscriptionId: string):
export const getResources = async (
token: string,
subscriptionId: string,
resourceGroupName: string
resourceGroupName: string,
): Promise<Array<GenericResource>> => {
try {
if (!subscriptionId) {
@ -143,7 +143,7 @@ export const getDeployLocations = async (token: string, subscriptionId: string)
`https://management.azure.com/subscriptions/${subscriptionId}/locations?api-version=2019-10-01`,
{
headers: { Authorization: `Bearer ${token}` },
}
},
);
return result.data.value;
} catch (error) {
@ -159,7 +159,7 @@ export const getDeployLocations = async (token: string, subscriptionId: string)
export const getSupportedRegionsByType = async (
token: string,
subscriptionId: string,
resourceType: AzureResourceProviderType
resourceType: AzureResourceProviderType,
): Promise<Array<string>> => {
try {
if (!subscriptionId) {
@ -207,7 +207,7 @@ export const getSupportedRegionsByType = async (
export const CheckBotNameAvailability = async (
token: string,
botName: string,
subscriptionId: string
subscriptionId: string,
): Promise<CheckNameAvailabilityResponseBody> => {
try {
if (!botName) {
@ -265,7 +265,7 @@ export const CheckBotNameAvailability = async (
export const CheckWebAppNameAvailability = async (
token: string,
webAppName: string,
subscriptionId: string
subscriptionId: string,
): Promise<ResourceNameAvailability> => {
try {
if (!webAppName) {
@ -292,7 +292,7 @@ export const CheckWebAppNameAvailability = async (
const webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId);
const getCheckNameAvailabilityResult = await webSiteManagementClient.checkNameAvailability(
webAppName,
'Microsoft.Web/sites'
'Microsoft.Web/sites',
);
if (getCheckNameAvailabilityResult._response.status >= 300) {
logger({
@ -326,7 +326,7 @@ export const CheckCognitiveResourceSku = async (
location: string,
sku: string,
kind: string,
type: string
type: string,
): Promise<boolean> => {
try {
if (!subscriptionId) {

Просмотреть файл

@ -205,13 +205,13 @@ const DialogTitle = {
{children}
</a>
),
}
},
),
},
REVIEW: {
title: formatMessage('Review resources to be created'),
subText: formatMessage(
'The following resources will be created and provisioned for your bot. Once provisioned, they will be available in the Azure portal.'
'The following resources will be created and provisioned for your bot. Once provisioned, they will be available in the Azure portal.',
),
},
CONFIG_RESOURCES: {
@ -403,7 +403,7 @@ export const AzureProvisionDialog: React.FC = () => {
const preferredAppServiceOS = useMemo(getPreferredAppServiceOS, [currentProjectId, projectCollection]);
const [formData, setFormData] = useState<ProvisionFormData>(
getDefaultFormData(currentConfig, { ...extensionState, appServiceOperatingSystem: preferredAppServiceOS })
getDefaultFormData(currentConfig, { ...extensionState, appServiceOperatingSystem: preferredAppServiceOS }),
);
const [isLoading, setIsLoading] = useState(true);
@ -454,7 +454,7 @@ export const AzureProvisionDialog: React.FC = () => {
'Provisoning Command:\n' +
'{command}\n\n' +
'Detailed instructions:\nhttps://aka.ms/how-to-complete-provision-handoff',
{ command: provisionComposer }
{ command: provisionComposer },
);
setHandoffInstructions(instructions);
@ -539,8 +539,8 @@ export const AzureProvisionDialog: React.FC = () => {
if (data.length === 0) {
setSubscriptionsErrorMessage(
formatMessage(
'Your subscription list is empty, please add your subscription, or login with another account.'
)
'Your subscription list is empty, please add your subscription, or login with another account.',
),
);
}
}
@ -614,7 +614,7 @@ export const AzureProvisionDialog: React.FC = () => {
}
}, 500);
},
[publishType, formData.subscriptionId, currentUser]
[publishType, formData.subscriptionId, currentUser],
);
const newHostName = useCallback(
@ -623,7 +623,7 @@ export const AzureProvisionDialog: React.FC = () => {
// debounce name check
checkNameAvailability(newName);
},
[checkNameAvailability]
[checkNameAvailability],
);
const updateCurrentLocation = useCallback(
@ -639,7 +639,7 @@ export const AzureProvisionDialog: React.FC = () => {
}
}
},
[deployLocations, luisLocations]
[deployLocations, luisLocations],
);
useEffect(() => {
@ -693,7 +693,7 @@ export const AzureProvisionDialog: React.FC = () => {
setPageAndTitle(PageTypes.AddResources);
},
[extensionResourceOptions]
[extensionResourceOptions],
);
const onSubmit = useCallback(
@ -710,7 +710,7 @@ export const AzureProvisionDialog: React.FC = () => {
clearAll();
closeDialog();
},
[currentUser]
[currentUser],
);
const onSave = useCallback(() => {
@ -723,17 +723,17 @@ export const AzureProvisionDialog: React.FC = () => {
const isSignedOut = await logOut();
if (isSignedOut) {
addNotification(
getLogoutNotificationSettings(formatMessage('You have successfully signed out of Azure'), 'info')
getLogoutNotificationSettings(formatMessage('You have successfully signed out of Azure'), 'info'),
);
closeDialog();
} else {
addNotification(
getLogoutNotificationSettings(
formatMessage(
'There was an error attempting to sign out of Azure. To complete sign out, you may need to restart Composer.'
'There was an error attempting to sign out of Azure. To complete sign out, you may need to restart Composer.',
),
'error'
)
'error',
),
);
}
}, [addNotification]);
@ -748,13 +748,13 @@ export const AzureProvisionDialog: React.FC = () => {
const confirmed = await OpenConfirmModal(
formatMessage('Sign out of Azure'),
formatMessage(
'By signing out of Azure, your new publishing profile will be canceled and this dialog will close. Do you want to continue?'
'By signing out of Azure, your new publishing profile will be canceled and this dialog will close. Do you want to continue?',
),
{
onRenderContent: (subtitle: string) => <div>{subtitle}</div>,
confirmText: formatMessage('Sign out'),
cancelText: formatMessage('Cancel'),
}
},
);
if (confirmed) {
await signoutAndNotify();
@ -765,7 +765,7 @@ export const AzureProvisionDialog: React.FC = () => {
</div>
);
},
[signoutAndNotify]
[signoutAndNotify],
);
const isNextDisabled = useMemo(() => {
@ -777,7 +777,7 @@ export const AzureProvisionDialog: React.FC = () => {
!formData.region ||
subscriptionsErrorMessage ||
errorResourceGroupName ||
errorHostName !== ''
errorHostName !== '',
);
}, [
formData.subscriptionId,
@ -867,8 +867,8 @@ export const AzureProvisionDialog: React.FC = () => {
</ConfigureResourcesPropertyLabel>
{renderPropertyInfoIcon(
formatMessage(
'A custom resource group name that you choose or create. Resource groups allow you to group Azure resources for access and management.'
)
'A custom resource group name that you choose or create. Resource groups allow you to group Azure resources for access and management.',
),
)}
</Stack>
<ResourceGroupPicker
@ -892,7 +892,7 @@ export const AzureProvisionDialog: React.FC = () => {
{formatMessage('Operating System')}
</ConfigureResourcesPropertyLabel>
{renderPropertyInfoIcon(
formatMessage('Select the operating system that will host your application service.')
formatMessage('Select the operating system that will host your application service.'),
)}
</Stack>
<ChoiceGroup
@ -1282,7 +1282,7 @@ export const AzureProvisionDialog: React.FC = () => {
<Fragment>
<ProvisionHandoff
developerInstructions={formatMessage(
'If Azure resources and subscription are managed by others, use the following information to request creation of the resources that you need to build and run your bot.'
'If Azure resources and subscription are managed by others, use the following information to request creation of the resources that you need to build and run your bot.',
)}
handoffInstructions={handoffInstructions}
hidden={!showHandoff}

Просмотреть файл

@ -91,7 +91,7 @@ const isUsingAdaptiveRuntimeKey = (runtimeKey?: string): boolean =>
* @default { isUsingAdaptiveRuntime: false, runtimeLanguage: 'dotnet', runtimeType: 'webapp'}
*/
export const parseRuntimeKey = (
runtimeKey?: string
runtimeKey?: string,
): { isUsingAdaptiveRuntime: boolean; runtimeLanguage?: string; runtimeType?: string } => {
const isAdaptive = isUsingAdaptiveRuntimeKey(runtimeKey);

Просмотреть файл

@ -60,14 +60,14 @@ export class AzureResourceMananger {
if (!config.name) {
throw createCustomizeError(
ProvisionErrors.CREATE_RESOURCEGROUP_ERROR,
'You should provide a valid resource group name.'
'You should provide a valid resource group name.',
);
}
// Create a new resource group
if (!config.location) {
throw createCustomizeError(
ProvisionErrors.CREATE_RESOURCEGROUP_ERROR,
'You should provide a valid resource group name.'
'You should provide a valid resource group name.',
);
}
@ -93,7 +93,7 @@ export class AzureResourceMananger {
});
throw createCustomizeError(
ProvisionErrors.CREATE_RESOURCEGROUP_ERROR,
resourceGroupGetResult._response.bodyAsText
resourceGroupGetResult._response.bodyAsText,
);
}
@ -120,7 +120,7 @@ export class AzureResourceMananger {
if (resourceGroupResult._response.status >= 300) {
throw createCustomizeError(
ProvisionErrors.CREATE_RESOURCEGROUP_ERROR,
resourceGroupResult._response.bodyAsText
resourceGroupResult._response.bodyAsText,
);
}
@ -140,7 +140,7 @@ export class AzureResourceMananger {
* @param config
*/
public async deployLuisAuthoringResource(
config: LuisAuthoringResourceConfig
config: LuisAuthoringResourceConfig,
): Promise<{ authoringKey: string; authoringEndpoint: string; location: string }> {
try {
this.logger({
@ -150,7 +150,7 @@ export class AzureResourceMananger {
const cognitiveServicesManagementClient = new CognitiveServicesManagementClient(
this.creds,
this.subscriptionId,
this.options
this.options,
);
// check location is validated
let authoringLocation = config.location;
@ -166,7 +166,7 @@ export class AzureResourceMananger {
name: config.sku ?? 'F0',
},
location: authoringLocation,
}
},
);
if (deployResult._response.status >= 300) {
this.logger({
@ -175,7 +175,7 @@ export class AzureResourceMananger {
});
throw createCustomizeError(
ProvisionErrors.CREATE_LUIS_AUTHORING_RESOURCE_ERROR,
deployResult._response.bodyAsText
deployResult._response.bodyAsText,
);
}
@ -198,7 +198,7 @@ export class AzureResourceMananger {
* @param config
*/
public async deployLuisResource(
config: LuisResourceConfig
config: LuisResourceConfig,
): Promise<{ endpoint: string; endpointKey: string; location: string }> {
try {
this.logger({
@ -208,7 +208,7 @@ export class AzureResourceMananger {
const cognitiveServicesManagementClient = new CognitiveServicesManagementClient(
this.creds,
this.subscriptionId,
this.options
this.options,
);
// check luis publish location is validated
let authoringLocation = config.location;
@ -224,7 +224,7 @@ export class AzureResourceMananger {
name: config.sku ?? 'S0',
},
location: authoringLocation,
}
},
);
if (deployResult._response.status >= 300) {
this.logger({
@ -281,7 +281,7 @@ export class AzureResourceMananger {
replicaCount: 1,
partitionCount: 1,
hostingMode: 'default',
}
},
);
if (searchServiceDeployResult._response.status >= 300) {
@ -307,7 +307,7 @@ export class AzureResourceMananger {
family: 'S',
capacity: 1,
},
}
},
);
if (servicePlanResult._response.status >= 300) {
@ -322,7 +322,7 @@ export class AzureResourceMananger {
const applicationInsightsManagementClient = new ApplicationInsightsManagementClient(
this.creds,
this.subscriptionId,
this.options
this.options,
);
const appinsightsName = config.resourceGroupName;
const appinsightsDeployResult = await applicationInsightsManagementClient.components.createOrUpdate(
@ -332,7 +332,7 @@ export class AzureResourceMananger {
location: config.location,
applicationType: 'web',
kind: 'web',
}
},
);
if (appinsightsDeployResult._response.status >= 300 || appinsightsDeployResult.provisioningState != 'Succeeded') {
this.logger({
@ -348,7 +348,7 @@ export class AzureResourceMananger {
).primaryKey;
const appInsightsComponent = await applicationInsightsManagementClient.components.get(
config.resourceGroupName,
appinsightsName
appinsightsName,
);
const userAppInsightsKey = appInsightsComponent.instrumentationKey;
const userAppInsightsName = appinsightsName;
@ -415,7 +415,7 @@ export class AzureResourceMananger {
],
},
enabled: true,
}
},
);
if (webAppResult._response.status >= 300) {
@ -430,7 +430,7 @@ export class AzureResourceMananger {
const cognitiveServicesManagementClient = new CognitiveServicesManagementClient(
this.creds,
this.subscriptionId,
this.options
this.options,
);
const deployResult = await cognitiveServicesManagementClient.accounts.create(
config.resourceGroupName,
@ -446,7 +446,7 @@ export class AzureResourceMananger {
qnaRuntimeEndpoint: `https://${webAppResult.hostNames?.[0]}`,
},
},
}
},
);
if (deployResult._response.status >= 300) {
this.logger({
@ -459,7 +459,7 @@ export class AzureResourceMananger {
const endpoint = webAppResult.hostNames?.[0];
const keys = await cognitiveServicesManagementClient.accounts.listKeys(
config.resourceGroupName,
qnaMakerServiceName
qnaMakerServiceName,
);
const subscriptionKey = keys?.key1 ?? '';
return {
@ -480,7 +480,7 @@ export class AzureResourceMananger {
* @param config
*/
public async deployAppInsightsResource(
config: ApplicationInsightsConfig
config: ApplicationInsightsConfig,
): Promise<{ instrumentationKey: string; connectionString: string }> {
try {
this.logger({
@ -490,7 +490,7 @@ export class AzureResourceMananger {
const applicationInsightsManagementClient = new ApplicationInsightsManagementClient(
this.creds,
this.subscriptionId,
this.options
this.options,
);
const deployResult = await applicationInsightsManagementClient.components.createOrUpdate(
config.resourceGroupName,
@ -499,7 +499,7 @@ export class AzureResourceMananger {
location: config.location,
applicationType: config.applicationType ?? 'web',
kind: 'web',
}
},
);
if (deployResult._response.status >= 300 || deployResult.provisioningState != 'Succeeded') {
this.logger({
@ -551,7 +551,7 @@ export class AzureResourceMananger {
appinsightsApiKeyResponse = await appinsightsClient.aPIKeys.create(
config.resourceGroupName,
config.name,
apiKeyOptions
apiKeyOptions,
);
const appinsightsApiKey = appinsightsApiKeyResponse.apiKey;
@ -583,7 +583,7 @@ export class AzureResourceMananger {
this.logger({
status: BotProjectDeployLoggerType.PROVISION_ERROR,
message: `! Something went wrong while trying to link Application Insights settings to Bot Service Result: ${JSON.stringify(
botUpdateResult
botUpdateResult,
)}`,
});
throw err;
@ -632,7 +632,7 @@ export class AzureResourceMananger {
failoverPriority: 0,
},
],
}
},
);
if (dbAccountDeployResult._response.status >= 300 || dbAccountDeployResult.provisioningState != 'Succeeded') {
@ -653,7 +653,7 @@ export class AzureResourceMananger {
id: config.databaseName,
},
options: {},
}
},
);
if (dbDeployResult._response.status >= 300) {
@ -697,7 +697,7 @@ export class AzureResourceMananger {
},
},
options: {},
}
},
);
if (containerCreateResult._response.status >= 300) {
@ -710,7 +710,7 @@ export class AzureResourceMananger {
const authKeyResult = await cosmosDBManagementClient.databaseAccounts.listKeys(
config.resourceGroupName,
config.name
config.name,
);
if (authKeyResult._response.status >= 300) {
this.logger({
@ -744,7 +744,7 @@ export class AzureResourceMananger {
* @param config
*/
public async deployBlobStorageResource(
config: BlobStorageConfig
config: BlobStorageConfig,
): Promise<{ name: string; connectionString: string; container: string }> {
try {
this.logger({
@ -770,7 +770,7 @@ export class AzureResourceMananger {
const accountKeysResult = await storageManagementClient.storageAccounts.listKeys(
config.resourceGroupName,
config.name
config.name,
);
const connectionString = accountKeysResult?.keys?.[0].value ?? '';
@ -813,7 +813,7 @@ export class AzureResourceMananger {
family: 'S',
capacity: 1,
},
}
},
);
if (servicePlanResult._response.status >= 300) {
@ -916,7 +916,7 @@ export class AzureResourceMananger {
},
],
},
}
},
);
if (azureFunctionsResult._response.status >= 300) {
@ -926,7 +926,7 @@ export class AzureResourceMananger {
});
throw createCustomizeError(
ProvisionErrors.CREATE_FUNCTIONS_RESOURCE_ERROR,
azureFunctionsResult._response.bodyAsText
azureFunctionsResult._response.bodyAsText,
);
}

Просмотреть файл

@ -12,7 +12,7 @@ export class BackgroundProcessManager {
projectId: string,
processName: string,
initialMessage?: string,
comment?: string
comment?: string,
): string {
const id = uuid();
this.processes[id] = {

Просмотреть файл

@ -51,7 +51,7 @@ export class BotProjectDeploy {
environment: string,
hostname?: string,
luisResource?: string,
absSettings?: any
absSettings?: any,
) {
try {
this.logger(absSettings);
@ -100,7 +100,7 @@ export class BotProjectDeploy {
settings.luis,
luisResource,
this.projPath,
this.logger
this.logger,
);
const qnaConfig = await project.builder.getQnaConfig();
@ -127,14 +127,14 @@ export class BotProjectDeploy {
path.join(pathToArtifacts, 'manifests'),
project.fileStorage,
path.join(pathToArtifacts, 'wwwroot', 'manifests'),
project.fileStorage
project.fileStorage,
);
// Update skill endpoint url in skill manifest.
await this.updateSkillSettings(
profileName,
hostname,
settings.MicrosoftAppId,
path.join(pathToArtifacts, 'wwwroot', 'manifests')
path.join(pathToArtifacts, 'wwwroot', 'manifests'),
);
}
@ -188,7 +188,7 @@ export class BotProjectDeploy {
hostname,
absSettings.subscriptionId,
absSettings.resourceGroup,
linuxFxVersion
linuxFxVersion,
);
}
}
@ -319,7 +319,7 @@ export class BotProjectDeploy {
name: string,
env: string,
hostname?: string,
scmHostDomain?: string
scmHostDomain?: string,
) {
this.logger({
status: BotProjectDeployLoggerType.DEPLOY_INFO,
@ -351,7 +351,7 @@ export class BotProjectDeploy {
const errorMessage = JSON.stringify(err, Object.getOwnPropertyNames(err));
throw createCustomizeError(
AzurePublishErrors.DEPLOY_ZIP_ERROR,
`There was a problem publishing bot assets (zip deploy). ${errorMessage}`
`There was a problem publishing bot assets (zip deploy). ${errorMessage}`,
);
}
}
@ -370,7 +370,7 @@ export class BotProjectDeploy {
hostname: string,
subscriptionId: string,
resourceGroup: string,
linuxFxVersion: string
linuxFxVersion: string,
) {
try {
const updateEndpoint = this.buildUpdateEndpoint(hostname, name, env, subscriptionId, resourceGroup);
@ -379,7 +379,7 @@ export class BotProjectDeploy {
{
properties: { linuxFxVersion: linuxFxVersion },
},
{ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' } }
{ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' } },
);
if (response.status === 200) {
@ -392,7 +392,7 @@ export class BotProjectDeploy {
const errorMessage = JSON.stringify(err, Object.getOwnPropertyNames(err));
throw createCustomizeError(
AzurePublishErrors.DEPLOY_ZIP_ERROR,
`There was a problem updating the bot's settings. ${errorMessage}`
`There was a problem updating the bot's settings. ${errorMessage}`,
);
}
}
@ -402,7 +402,7 @@ export class BotProjectDeploy {
name: string,
env: string,
subscriptionId: string,
resourceGroupName: string
resourceGroupName: string,
) => {
const hostnameResult = hostname ? hostname : name + (env ? '-' + env : '');
return `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.Web/sites/${hostnameResult}/config/web?api-version=2022-03-01`;
@ -553,7 +553,7 @@ export class BotProjectDeploy {
private async getTenantId(accessToken: string, subId: string) {
if (!accessToken) {
throw new Error(
'Error: Missing access token. Please provide a non-expired Azure access token. Tokens can be obtained by running az account get-access-token'
'Error: Missing access token. Please provide a non-expired Azure access token. Tokens can be obtained by running az account get-access-token',
);
}
if (!subId) {

Просмотреть файл

@ -167,7 +167,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
profileName: string,
jobId: string,
resourcekey: string,
customizeConfiguration: DeployResources
customizeConfiguration: DeployResources,
) => {
const { accessToken, name, environment, hostname, luisResource, abs } = customizeConfiguration;
@ -251,7 +251,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
profileName,
jobId,
resourcekey,
customizeConfiguration
customizeConfiguration,
);
} catch (err) {
this.logger('%O', err);
@ -259,7 +259,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
await this.updateHistory(
project.id,
profileName,
publishResultFromStatus(BackgroundProcessManager.getStatus(jobId)).result
publishResultFromStatus(BackgroundProcessManager.getStatus(jobId)).result,
);
BackgroundProcessManager.removeProcess(jobId);
}
@ -408,7 +408,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
project.id,
profileName,
'Accepted for publishing...',
metadata.comment
metadata.comment,
);
// resource key to map to one provision resource
@ -420,8 +420,8 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
throw new Error(
formatMessage(
'There was a problem publishing {projectName}/{profileName}. The profile has not been provisioned yet.',
{ projectName: project.name, profileName }
)
{ projectName: project.name, profileName },
),
);
}
@ -440,8 +440,8 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
throw new Error(
formatMessage(
'There was a problem publishing {projectName}/{profileName}. These required resources have not been provisioned: {missingResourcesText}',
{ projectName: project.name, profileName, missingResourcesText }
)
{ projectName: project.name, profileName, missingResourcesText },
),
);
}
@ -522,7 +522,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
processName: string,
project: IBotProject,
user,
jobId = ''
jobId = '',
): Promise<ProcessStatus> => {
const botId = project.id;
// get status by Job ID first.
@ -554,7 +554,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
const hasLuContent = luResources.some((luResource) => luResource.content?.trim() !== '');
const hasLuisRecognizers = recognizers.some(
(recognizer) => recognizer.content?.$kind === SDKKinds.LuisRecognizer
(recognizer) => recognizer.content?.$kind === SDKKinds.LuisRecognizer,
);
const requiresLUIS = hasLuContent && hasLuisRecognizers;
@ -673,7 +673,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
return !!profile?.hostname;
default:
throw new Error(
formatMessage('Azure resource type {resourceKey} is not handled.', { resourceKey: resource.key })
formatMessage('Azure resource type {resourceKey} is not handled.', { resourceKey: resource.key }),
);
}
};

Просмотреть файл

@ -55,7 +55,7 @@ export class KeyVaultApi {
vaultName: string,
email: string,
objectId: string,
tenantId: string
tenantId: string,
) {
const keyVaultManagementClient = new KeyVaultManagementClient(this.creds, this.subscriptionId);
const setResult = await keyVaultManagementClient.vaults.update(resourceGroupName, vaultName, {
@ -129,7 +129,7 @@ export class KeyVaultApi {
properties: {
MicrosoftAppPassword: `@Microsoft.KeyVault(SecretUri=${secretUri})`,
},
}
},
);
if (updateResult._response.status >= 300) {
this.logger({
@ -149,7 +149,7 @@ export class KeyVaultApi {
properties: {
MicrosoftAppPassword: secretValue,
},
}
},
);
if (updateResult._response.status >= 300) {
this.logger({

Просмотреть файл

@ -24,7 +24,7 @@ type Resources = {
qnaResources: Resource[];
};
export type BuildSettingType<T = {}> = {
export type BuildSettingType<T = NonNullable<unknown>> = {
[K in keyof T]: T[K];
} & {
luis: ILuisConfig;
@ -87,7 +87,7 @@ export async function publishLuisToPrediction(
luisSettings: ILuisConfig,
luisResource: string,
path: string,
logger
logger,
) {
let {
// eslint-disable-next-line prefer-const
@ -153,7 +153,7 @@ export async function publishLuisToPrediction(
const error = JSON.parse(err.error);
if (error?.error?.message && error?.error?.message.indexOf('access token expiry') > 0) {
throw new Error(
`Type: ${error?.error?.code}, Message: ${error?.error?.message}, run az account get-access-token, then replace the accessToken in your configuration`
`Type: ${error?.error?.code}, Message: ${error?.error?.message}, run az account get-access-token, then replace the accessToken in your configuration`,
);
} else {
throw err;
@ -200,7 +200,7 @@ export async function publishLuisToPrediction(
const error = JSON.parse(err.error);
if (error?.error?.message && error?.error?.message.indexOf('access token expiry') > 0) {
throw new Error(
`Type: ${error?.error?.code}, Message: ${error?.error?.message}, run az account get-access-token, then replace the accessToken in your configuration`
`Type: ${error?.error?.code}, Message: ${error?.error?.message}, run az account get-access-token, then replace the accessToken in your configuration`,
);
}
}
@ -210,7 +210,7 @@ export async function publishLuisToPrediction(
throw Error(
`Failed to bind luis prediction resource to luis applications. Please check if your luisResource is set to luis prediction service name in your publish profile.
${luisDebugInfo}.
${luisError}`
${luisError}`,
);
}
}

Просмотреть файл

@ -3,7 +3,7 @@
import { BotProjectProvision, ProvisionConfig } from './provision';
const mockConfig = ({
const mockConfig = {
logger: console.log,
accessToken: 'accessToken',
graphToken: 'graphToken',
@ -18,7 +18,7 @@ const mockConfig = ({
name: 'profileName',
type: 'azurepublish',
subscription: 'test',
} as unknown) as ProvisionConfig;
} as unknown as ProvisionConfig;
const azProvision = new BotProjectProvision(mockConfig);

Просмотреть файл

@ -127,7 +127,7 @@ export class BotProjectProvision {
logErrorMsg('App create', err.message);
throw createCustomizeError(
ProvisionErrors.CREATE_APP_REGISTRATION,
'App create failed! Please file an issue on Github.'
'App create failed! Please file an issue on Github.',
);
} else {
await this.sleep(3000);
@ -170,7 +170,7 @@ export class BotProjectProvision {
logErrorMsg('Add application password', err.message);
throw createCustomizeError(
ProvisionErrors.CREATE_APP_REGISTRATION,
'Add application password failed! Please file an issue on Github.'
'Add application password failed! Please file an issue on Github.',
);
} else {
await this.sleep(3000);
@ -199,13 +199,13 @@ export class BotProjectProvision {
if (!this.accessToken) {
throw createCustomizeError(
ProvisionErrors.GET_TENANTID,
'Error: Missing access token. Please provide a non-expired Azure access token. Tokens can be obtained by running az account get-access-token'
'Error: Missing access token. Please provide a non-expired Azure access token. Tokens can be obtained by running az account get-access-token',
);
}
if (!this.subscriptionId) {
throw createCustomizeError(
ProvisionErrors.GET_TENANTID,
`Error: Missing subscription Id. Please provide a valid Azure subscription id.`
`Error: Missing subscription Id. Please provide a valid Azure subscription id.`,
);
}
try {
@ -222,7 +222,7 @@ export class BotProjectProvision {
} catch (err) {
throw createCustomizeError(
ProvisionErrors.GET_TENANTID,
`Get Tenant Id Failed, details: ${this.getErrorMesssage(err)}`
`Get Tenant Id Failed, details: ${this.getErrorMesssage(err)}`,
);
}
}

Просмотреть файл

@ -11,7 +11,7 @@ export async function copyDir(
srcStorage: IFileStorage,
dstDir: string,
dstStorage: IFileStorage,
pathsToExclude?: Set<string>
pathsToExclude?: Set<string>,
) {
if (!(await srcStorage.exists(srcDir)) || !(await srcStorage.stat(srcDir)).isDir) {
throw new Error(`No such dir ${srcDir}}`);

Просмотреть файл

@ -35,7 +35,7 @@ export const getSubscriptions = async (token: string): Promise<Array<Subscriptio
let message = JSON.stringify(err, Object.getOwnPropertyNames(err));
if (err?.code === 12 && err?.message?.match(/Bearer/gi)) {
message = formatMessage(
'There was an authentication problem retrieving subscriptions. Verify your login session has not expired and you have permission to list subscriptions in this account.'
'There was an authentication problem retrieving subscriptions. Verify your login session has not expired and you have permission to list subscriptions in this account.',
);
}
@ -82,7 +82,7 @@ export const getDeployLocations = async (token: string, subscriptionId: string)
`https://management.azure.com/subscriptions/${subscriptionId}/locations?api-version=2019-10-01`,
{
headers: { Authorization: `Bearer ${token}` },
}
},
);
return result.data.value;
} catch (error) {
@ -98,7 +98,7 @@ export const getDeployLocations = async (token: string, subscriptionId: string)
export const checkWebAppNameAvailability = async (
token: string,
webAppName: string,
subscriptionId: string
subscriptionId: string,
): Promise<ResourceNameAvailability> => {
try {
if (!webAppName) {
@ -125,7 +125,7 @@ export const checkWebAppNameAvailability = async (
const webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId);
const getCheckNameAvailabilityResult = await webSiteManagementClient.checkNameAvailability(
webAppName,
'Microsoft.Web/sites'
'Microsoft.Web/sites',
);
if (getCheckNameAvailabilityResult._response.status >= 300) {
logger({

Просмотреть файл

@ -30,7 +30,7 @@ const Root = styled.div<RootStyleProps>(
grid-template-columns: 1fr;
grid-auto-rows: auto;
}
`
`,
);
export const AzureProvisionWizard = () => {

Просмотреть файл

@ -73,7 +73,7 @@ export const CreateResourcesWizard = React.memo((props: Props) => {
{children}
</a>
),
}
},
),
onRenderContent: () => (
<ChooseResourcesStep enabledResources={enabledResources} onChangeSelection={setEnabledResources} />
@ -84,7 +84,7 @@ export const CreateResourcesWizard = React.memo((props: Props) => {
id: 'review-resources',
title: formatMessage('Review resources to be created'),
subTitle: formatMessage(
'The following resources will be created and provisioned for your bot. Once provisioned, they will be available in the Azure portal.'
'The following resources will be created and provisioned for your bot. Once provisioned, they will be available in the Azure portal.',
),
onRenderContent: () => <ReviewResourcesStep />,
navigationState: { nextText: formatMessage('Done') },

Просмотреть файл

@ -62,7 +62,7 @@ export const HandOffToAdminWizard = React.memo((props: Props) => {
{children}
</a>
),
}
},
),
onRenderContent: () => (
<ChooseResourcesStep enabledResources={resources} onChangeSelection={setEnabledHandOffResources} />
@ -85,7 +85,7 @@ export const HandOffToAdminWizard = React.memo((props: Props) => {
{showHandOff && (
<ProvisionHandoff
developerInstructions={formatMessage(
'If Azure resources and subscription are managed by others, use the following information to request creation of the resources that you need to build and run your bot.'
'If Azure resources and subscription are managed by others, use the following information to request creation of the resources that you need to build and run your bot.',
)}
handoffInstructions={handOffInstructions}
hidden={!showHandOff}

Просмотреть файл

@ -51,7 +51,7 @@ export const CreateResourceInstructionsStep = () => {
<Summary>
<Text>
{formatMessage(
'Select this option when you want to provision new Azure resources and publish a bot. A subscription to'
'Select this option when you want to provision new Azure resources and publish a bot. A subscription to',
)}
</Text>
&nbsp;

Просмотреть файл

@ -49,7 +49,7 @@ export const HandOffInstructionsStep = () => {
<Summary>
<Text>
{formatMessage(
'Select this option to request your Azure admin to provision resources on your behalf, for example, when you dont have proper permissions to use Azure or you want to generate resources from a sovereign cloud.'
'Select this option to request your Azure admin to provision resources on your behalf, for example, when you dont have proper permissions to use Azure or you want to generate resources from a sovereign cloud.',
)}
</Text>
</Summary>
@ -59,7 +59,7 @@ export const HandOffInstructionsStep = () => {
<InstructionDetails>
<Text>
{formatMessage(
'Add resources you need for the bot and generate a resource request to share with your Azure admin.'
'Add resources you need for the bot and generate a resource request to share with your Azure admin.',
)}
</Text>
</InstructionDetails>
@ -69,7 +69,7 @@ export const HandOffInstructionsStep = () => {
<InstructionDetails>
<Text>
{formatMessage(
'Once you get the resource details from your Azure admin, use them to import existing resources.'
'Once you get the resource details from your Azure admin, use them to import existing resources.',
)}
</Text>
</InstructionDetails>

Просмотреть файл

@ -36,14 +36,14 @@ export const ImportInstructionsStep = () => {
<Summary>
<Text>
{formatMessage(
'Select this option if you have access to existing Azure resources and their associated values.'
'Select this option if you have access to existing Azure resources and their associated values.',
)}
</Text>
</Summary>
<Summary>
<Text>
{formatMessage(
'Copy and paste the JSON file containing the values of your existing Azure resources, from the Azure portal. This file includes values for some or all of the following:'
'Copy and paste the JSON file containing the values of your existing Azure resources, from the Azure portal. This file includes values for some or all of the following:',
)}
</Text>
</Summary>

Просмотреть файл

@ -166,8 +166,8 @@ export const ResourceConfigurationStep = (props: Props) => {
</ConfigureResourcesPropertyLabel>
{renderPropertyInfoIcon(
formatMessage(
'A custom resource group name that you choose or create. Resource groups allow you to group Azure resources for access and management.'
)
'A custom resource group name that you choose or create. Resource groups allow you to group Azure resources for access and management.',
),
)}
</Stack>
<ResourceGroupPicker
@ -193,7 +193,7 @@ export const ResourceConfigurationStep = (props: Props) => {
{formatMessage('Operating System')}
</ConfigureResourcesPropertyLabel>
{renderPropertyInfoIcon(
formatMessage('Select the operating system that will host your application service.')
formatMessage('Select the operating system that will host your application service.'),
)}
</Stack>
<OperatingSystemChoiceGroup

Просмотреть файл

@ -119,7 +119,7 @@ export const ReviewResourcesStep = () => {
isPadded: true,
},
],
[]
[],
);
const reviewListItems = React.useMemo(() => {

Просмотреть файл

@ -51,7 +51,7 @@ export const DeployLocationPicker = React.memo((props: Props) => {
placeholder: formatMessage('Select Region'),
errorMessage,
}),
[errorMessage]
[errorMessage],
);
return (
@ -59,7 +59,7 @@ export const DeployLocationPicker = React.memo((props: Props) => {
isLoading={isLoading}
items={sortBy(
deployLocations.map((t) => ({ key: t.name, text: t.displayName })),
[(location) => location.text]
[(location) => location.text],
)}
onSubmit={(option) => props.onChangeDeployLocation(option.key)}
{...{

Просмотреть файл

@ -19,14 +19,8 @@ type Props = {
} & Omit<SearchableDropdownProps, 'items' | 'onSubmit' | 'creationProps'>;
export const ResourceGroupPicker = React.memo((props: Props) => {
const {
onChangeResourceGroup,
accessToken,
subscriptionId,
value,
isNewResourceGroup,
onValidateResourceGroupName,
} = props;
const { onChangeResourceGroup, accessToken, subscriptionId, value, isNewResourceGroup, onValidateResourceGroupName } =
props;
const [resourceGroups, setResourceGroups] = useState<ResourceGroup[]>([]);
const [errorMessage, setErrorMessage] = useState<string>('');
@ -42,8 +36,8 @@ export const ResourceGroupPicker = React.memo((props: Props) => {
if (debouncedNewName && !debouncedNewName.match(/^[-\w._()]+$/)) {
setNewNameErrorMessage(
formatMessage(
'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.'
)
'Resource group names only allow alphanumeric characters, periods, underscores, hyphens and parenthesis and cannot end in a period.',
),
);
} else if (alreadyExists) {
setNewNameErrorMessage(formatMessage('A resource with this name already exists.'));
@ -83,12 +77,12 @@ export const ResourceGroupPicker = React.memo((props: Props) => {
placeholder: formatMessage('Select Resource Group'),
errorMessage,
}),
[errorMessage]
[errorMessage],
);
const creationItem = React.useMemo(
() => ({ key: 'CREATE_NEW_RESOURCE_GROUP', text: formatMessage('Create new resource group') }),
[]
[],
);
return (

Просмотреть файл

@ -31,8 +31,8 @@ export const SubscriptionPicker = React.memo((props: Props) => {
if (subscriptions.length === 0) {
setErrorMessage(
formatMessage(
'Your subscription list is empty, please add your subscription, or login with another account.'
)
'Your subscription list is empty, please add your subscription, or login with another account.',
),
);
}
setSubscriptions(subscriptions);
@ -51,7 +51,7 @@ export const SubscriptionPicker = React.memo((props: Props) => {
placeholder: formatMessage('Select subscription'),
errorMessage,
}),
[errorMessage]
[errorMessage],
);
return (

Просмотреть файл

@ -75,7 +75,7 @@ export const TenantPicker = memo((props: Props) => {
setErrorMessage(
formatMessage('There was a problem loading Azure directories. {errMessage}', {
errMessage: err.message || err.toString(),
})
}),
);
}
})();
@ -101,7 +101,7 @@ export const TenantPicker = memo((props: Props) => {
setErrorMessage(
formatMessage('There was a problem getting the access token for the current Azure directory. {errMessage}', {
errMessage: ex.message || ex.toString(),
})
}),
);
}
};
@ -120,7 +120,7 @@ export const TenantPicker = memo((props: Props) => {
placeholder: formatMessage('Select Azure directory'),
errorMessage,
}),
[errorMessage, tenants]
[errorMessage, tenants],
);
return (

Просмотреть файл

@ -239,7 +239,7 @@ const getNextIteratorValue = (iterator: number, direction: 'forward' | 'backward
const getNextSelectableItem = (
items: IContextualMenuItem[],
selectedIndex: number,
direction: 'forward' | 'backward'
direction: 'forward' | 'backward',
) => {
if (!items.length) {
return undefined;
@ -423,9 +423,10 @@ export const SearchableDropdown = (props: SearchableDropdownProps) => {
*/
const calloutTarget = rootRef.current?.querySelector('.ms-TextField-wrapper');
const createNewItem = React.useMemo(() => creationItem ?? { key: 'CREATE_NEW', text: formatMessage('Create New') }, [
creationItem,
]);
const createNewItem = React.useMemo(
() => creationItem ?? { key: 'CREATE_NEW', text: formatMessage('Create New') },
[creationItem],
);
if (allowCreation) {
filteredItems.unshift(createNewItem);
@ -690,7 +691,7 @@ export const SearchableDropdown = (props: SearchableDropdownProps) => {
* utilize it.
*/
const onRenderTextFieldLabel = () => {
if (!textFieldProps || !textFieldProps.label) {
if (!textFieldProps?.label) {
return;
}

Просмотреть файл

@ -58,5 +58,5 @@ export const SearchableDropdownTextField = React.forwardRef(
onKeyDown={interceptKeyDown}
/>
);
}
},
);

Просмотреть файл

@ -18,7 +18,7 @@ export const substringSearchStrategy = <T, K extends keyof T>(
haystack: T[],
needle: string,
keyParam?: K,
searchFn?: (item: T, query: string) => boolean
searchFn?: (item: T, query: string) => boolean,
): T[] => {
const query = (needle || '').toLocaleLowerCase();

Просмотреть файл

@ -32,17 +32,17 @@ export const UserPersona = (props: Props) => {
const isSignedOut = await logOut();
if (isSignedOut) {
addNotification(
getLogoutNotificationSettings(formatMessage('You have successfully signed out of Azure'), 'info')
getLogoutNotificationSettings(formatMessage('You have successfully signed out of Azure'), 'info'),
);
closeDialog();
} else {
addNotification(
getLogoutNotificationSettings(
formatMessage(
'There was an error attempting to sign out of Azure. To complete sign out, you may need to restart Composer.'
'There was an error attempting to sign out of Azure. To complete sign out, you may need to restart Composer.',
),
'error'
)
'error',
),
);
}
}, [addNotification]);
@ -57,13 +57,13 @@ export const UserPersona = (props: Props) => {
const confirmed = await OpenConfirmModal(
formatMessage('Sign out of Azure'),
formatMessage(
'By signing out of Azure, your new publishing profile will be canceled and this dialog will close. Do you want to continue?'
'By signing out of Azure, your new publishing profile will be canceled and this dialog will close. Do you want to continue?',
),
{
onRenderContent: (subtitle: string) => <div>{subtitle}</div>,
confirmText: formatMessage('Sign out'),
cancelText: formatMessage('Cancel'),
}
},
);
if (confirmed) {
await signoutAndNotify();
@ -75,7 +75,7 @@ export const UserPersona = (props: Props) => {
</div>
);
},
[signoutAndNotify, props.onSignOut]
[signoutAndNotify, props.onSignOut],
);
return <Persona {...props} onRenderSecondaryText={props.onRenderSecondaryText || onRenderSecondaryText} />;
};

Просмотреть файл

@ -45,7 +45,7 @@ export const useHandOffInstructions = () => {
'Provisoning Command:\n' +
'{command}\n\n' +
'Detailed instructions:\nhttps://aka.ms/how-to-complete-provision-handoff',
{ command: provisionComposer }
{ command: provisionComposer },
);
}, [resources, subscriptionId, hostName, deployRegion, resourceGroupName]);
};

Просмотреть файл

@ -7,7 +7,7 @@ const isUsingAdaptiveRuntimeKey = (runtimeKey?: string): boolean =>
runtimeKey === 'csharp-azurewebapp-v2' || !!runtimeKey?.startsWith('adaptive-runtime-');
const parseRuntimeKey = (
runtimeKey?: string
runtimeKey?: string,
): { isUsingAdaptiveRuntime: boolean; runtimeLanguage?: string; runtimeType?: string } => {
const isAdaptive = isUsingAdaptiveRuntimeKey(runtimeKey);

Просмотреть файл

@ -47,10 +47,10 @@ export const useResourceConfiguration = () => {
requireUserLogin(publishConfig?.tenantId, { requireGraph: true }); //use tenantId from import config if present
}, [isAuthenticated]);
const hasErrors = React.useMemo(() => isInvalidResourceGroupName || isInvalidHostName, [
isInvalidHostName,
isInvalidResourceGroupName,
]);
const hasErrors = React.useMemo(
() => isInvalidResourceGroupName || isInvalidHostName,
[isInvalidHostName, isInvalidResourceGroupName],
);
const isValidConfiguration = React.useMemo(
(): boolean =>
@ -63,7 +63,7 @@ export const useResourceConfiguration = () => {
!luisRegion ||
!hostName
),
[currentTenant, subscriptionId, resourceGroupName, hasErrors, deployLocation, luisRegion, hostName]
[currentTenant, subscriptionId, resourceGroupName, hasErrors, deployLocation, luisRegion, hostName],
);
const handleChangeSubscription = React.useCallback((subscriptionId: string) => {
@ -83,7 +83,7 @@ export const useResourceConfiguration = () => {
(isValid: boolean) => {
setIsInvalidResourceGroupName(isValid);
},
[setIsInvalidResourceGroupName]
[setIsInvalidResourceGroupName],
);
const handleChangeDeployLocation = React.useCallback((deployLocationId: string) => {
@ -95,7 +95,7 @@ export const useResourceConfiguration = () => {
setLuisRegion(
(LuisAuthoringSupportLocation.includes(deployLocation)
? deployLocation
: LuisAuthoringSupportLocation[0]) as LuisRegion
: LuisAuthoringSupportLocation[0]) as LuisRegion,
);
}
}, []);

Просмотреть файл

@ -44,7 +44,7 @@ const appInsightsProvisionMethod = (provisionConfig: ProvisionServiceConfig) =>
const applicationInsightsManagementClient = new ApplicationInsightsManagementClient(
tokenCredentials,
provisionConfig.subscriptionId
provisionConfig.subscriptionId,
);
const botServiceClient = new AzureBotService(tokenCredentials, provisionConfig.subscriptionId);
@ -57,7 +57,7 @@ const appInsightsProvisionMethod = (provisionConfig: ProvisionServiceConfig) =>
location: resourceConfig.location,
applicationType: resourceConfig.applicationType ?? 'web',
kind: 'web',
}
},
);
type ApiKeyOptions = {
@ -86,7 +86,7 @@ const appInsightsProvisionMethod = (provisionConfig: ProvisionServiceConfig) =>
appInsightsClient: ApplicationInsightsManagementClient,
botServiceClient: AzureBotService,
apiKeyOptions: ApiKeyOptions,
config: AppInsightsResourceConfig
config: AppInsightsResourceConfig,
) => {
const appComponents = await appInsightsClient.components.get(config.resourceGroupName, config.name);
const appInsightsId = appComponents.appId;
@ -95,7 +95,7 @@ const appInsightsProvisionMethod = (provisionConfig: ProvisionServiceConfig) =>
const appInsightsApiKeyResponse = await appInsightsClient.aPIKeys.create(
config.resourceGroupName,
config.name,
apiKeyOptions
apiKeyOptions,
);
const appInsightsApiKey = appInsightsApiKeyResponse.apiKey;
@ -113,7 +113,7 @@ const appInsightsProvisionMethod = (provisionConfig: ProvisionServiceConfig) =>
return async (
resourceConfig: AppInsightsResourceConfig,
workingSet: ProvisionWorkingSet
workingSet: ProvisionWorkingSet,
): Promise<ProvisionWorkingSet> => {
try {
const deployResult = await createOrUpdateAppInsightsComponent(resourceConfig);
@ -124,7 +124,7 @@ const appInsightsProvisionMethod = (provisionConfig: ProvisionServiceConfig) =>
applicationInsightsManagementClient,
botServiceClient,
apiKeyOptions,
resourceConfig
resourceConfig,
);
const provisionResult = {

Просмотреть файл

@ -45,7 +45,7 @@ const postRequestWithRetry = async (requestUri: string, requestOptions: AxiosReq
} else if (retryCount == 0) {
throw createCustomizeError(
ProvisionErrors.CREATE_APP_REGISTRATION,
'App create failed! Please file an issue on Github.'
'App create failed! Please file an issue on Github.',
);
} else {
await sleep(3000);
@ -93,7 +93,7 @@ const appRegistrationProvisionMethod = (provisionConfig: ProvisionServiceConfig)
return async (
resourceConfig: AppRegistrationResourceConfig,
workingSet: ProvisionWorkingSet
workingSet: ProvisionWorkingSet,
): Promise<ProvisionWorkingSet> => {
const { appName } = resourceConfig;
const { appId, id } = await createApp(appName);

Просмотреть файл

@ -90,7 +90,7 @@ const azureFunctionsProvisionMethod = (provisionConfig: ProvisionServiceConfig):
},
],
},
}
},
);
const hostname = azureFunctionsResult?.hostNames?.[0];

Просмотреть файл

@ -65,7 +65,7 @@ const blobStorageProvisionMethod = (provisionConfig: ProvisionServiceConfig): Pr
const accountKeysResult = await storageManagementClient.storageAccounts.listKeys(
config.resourceGroupName,
config.name
config.name,
);
const connectionString = accountKeysResult?.keys?.[0]?.value ?? '';

Просмотреть файл

@ -64,7 +64,7 @@ const cosmosDbProvisionMethod = (provisionConfig: ProvisionServiceConfig): Provi
failoverPriority: 0,
},
],
}
},
);
};
@ -78,7 +78,7 @@ const cosmosDbProvisionMethod = (provisionConfig: ProvisionServiceConfig): Provi
id: config.databaseName,
},
options: {},
}
},
);
};
@ -115,7 +115,7 @@ const cosmosDbProvisionMethod = (provisionConfig: ProvisionServiceConfig): Provi
},
},
options: {},
}
},
);
};
@ -123,32 +123,31 @@ const cosmosDbProvisionMethod = (provisionConfig: ProvisionServiceConfig): Provi
return await cosmosDBManagementClient.databaseAccounts.listKeys(config.resourceGroupName, config.displayName);
};
const provision = () => async (
config: CosmosDbConfig,
workingSet: ProvisionWorkingSet
): Promise<ProvisionWorkingSet> => {
try {
const { documentEndpoint } = await createDbAccount(config);
await createDb(config);
await createContainer(config);
const { primaryMasterKey } = await getAuthKey(config);
const provision =
() =>
async (config: CosmosDbConfig, workingSet: ProvisionWorkingSet): Promise<ProvisionWorkingSet> => {
try {
const { documentEndpoint } = await createDbAccount(config);
await createDb(config);
await createContainer(config);
const { primaryMasterKey } = await getAuthKey(config);
const provisionResult: CosmosDbProvisionResult = {
authKey: primaryMasterKey,
cosmosDbEndpoint: documentEndpoint,
databaseId: config.databaseName,
containerId: config.containerName,
collectionId: 'botstate-collection',
};
const provisionResult: CosmosDbProvisionResult = {
authKey: primaryMasterKey,
cosmosDbEndpoint: documentEndpoint,
databaseId: config.databaseName,
containerId: config.containerName,
collectionId: 'botstate-collection',
};
return {
...workingSet,
cosmosDb: provisionResult,
};
} catch (err) {
throw createCustomizeError(ProvisionErrors.CREATE_COSMOSDB_ERROR, stringifyError(err));
}
};
return {
...workingSet,
cosmosDb: provisionResult,
};
} catch (err) {
throw createCustomizeError(ProvisionErrors.CREATE_COSMOSDB_ERROR, stringifyError(err));
}
};
return provision();
};

Просмотреть файл

@ -45,7 +45,7 @@ const luisAuthoringProvisionMethod = (provisionConfig: ProvisionServiceConfig):
const cognitiveServicesManagementClient = new CognitiveServicesManagementClient(
tokenCredentials,
provisionConfig.subscriptionId
provisionConfig.subscriptionId,
);
return async (config: LuisAuthoringConfig, workingSet: ProvisionWorkingSet): Promise<ProvisionWorkingSet> => {
@ -65,7 +65,7 @@ const luisAuthoringProvisionMethod = (provisionConfig: ProvisionServiceConfig):
name: config.sku ?? 'F0',
},
location: authoringLocation,
}
},
);
const authoringEndpoint = deployResult.properties?.endpoint ?? '';

Просмотреть файл

@ -44,7 +44,7 @@ const luisPredictionProvisionMethod = (provisionConfig: ProvisionServiceConfig):
const tokenCredentials = new TokenCredentials(provisionConfig.accessToken);
const cognitiveServicesManagementClient = new CognitiveServicesManagementClient(
tokenCredentials,
provisionConfig.subscriptionId
provisionConfig.subscriptionId,
);
return async (config: LuisPredictionConfig, workingSet: ProvisionWorkingSet): Promise<ProvisionWorkingSet> => {
@ -64,7 +64,7 @@ const luisPredictionProvisionMethod = (provisionConfig: ProvisionServiceConfig):
name: config.sku ?? 'S0',
},
location: authoringLocation,
}
},
);
const endpoint = deployResult.properties?.endpoint ?? '';

Просмотреть файл

@ -58,12 +58,12 @@ const qnAProvisionMethod = (provisionConfig: ProvisionServiceConfig): ProvisionM
const tokenCredentials = new TokenCredentials(provisionConfig.accessToken);
const applicationInsightsManagementClient = new ApplicationInsightsManagementClient(
tokenCredentials,
provisionConfig.subscriptionId
provisionConfig.subscriptionId,
);
const webSiteManagementClient = new WebSiteManagementClient(tokenCredentials, provisionConfig.subscriptionId);
const cognitiveServicesManagementClient = new CognitiveServicesManagementClient(
tokenCredentials,
provisionConfig.subscriptionId
provisionConfig.subscriptionId,
);
const createOrUpdateSearchService = async (config: QnAResourceConfig, qnaMakerSearchName: string) => {
@ -102,7 +102,7 @@ const qnAProvisionMethod = (provisionConfig: ProvisionServiceConfig): ProvisionM
const createOrUpdateQnAAccount = async (
config: QnAResourceConfig,
qnaMakerServiceName: string,
qnaEndpoint: string
qnaEndpoint: string,
) => {
return await cognitiveServicesManagementClient.accounts.create(config.resourceGroupName, qnaMakerServiceName, {
kind: 'QnAMaker',
@ -121,7 +121,7 @@ const qnAProvisionMethod = (provisionConfig: ProvisionServiceConfig): ProvisionM
const getSubscriptionKey = async (config: QnAResourceConfig, qnaMakerServiceName: string) => {
const keys = await cognitiveServicesManagementClient.accounts.listKeys(
config.resourceGroupName,
qnaMakerServiceName
qnaMakerServiceName,
);
return keys?.key1 ?? '';
};
@ -132,11 +132,11 @@ const qnAProvisionMethod = (provisionConfig: ProvisionServiceConfig): ProvisionM
servicePlanName: string,
qnaMakerSearchName: string,
azureSearchAdminKey: string,
appInsightsName: string
appInsightsName: string,
) => {
const appInsightsComponent = await applicationInsightsManagementClient.components.get(
config.resourceGroupName,
appInsightsName
appInsightsName,
);
const userAppInsightsKey = appInsightsComponent.instrumentationKey;
const userAppInsightsName = appInsightsName;
@ -236,7 +236,7 @@ const qnAProvisionMethod = (provisionConfig: ProvisionServiceConfig): ProvisionM
servicePlanResult.name,
qnaMakerSearchName,
azureSearchAdminKey,
qnaAppInsightsName
qnaAppInsightsName,
);
// Create qna account

Просмотреть файл

@ -41,7 +41,7 @@ const appServiceProvisionMethod = (provisionConfig: ProvisionServiceConfig) => {
return async (
resourceConfig: ServicePlanResourceConfig,
workingSet: ProvisionWorkingSet
workingSet: ProvisionWorkingSet,
): Promise<ProvisionWorkingSet> => {
const operatingSystem = resourceConfig.operatingSystem ? resourceConfig.operatingSystem : 'windows';
try {
@ -60,7 +60,7 @@ const appServiceProvisionMethod = (provisionConfig: ProvisionServiceConfig) => {
family: 'S',
capacity: 1,
},
}
},
);
return { ...workingSet, appService: { appServicePlanName: appServiceResult.name } };
} catch (err) {

Просмотреть файл

@ -14,7 +14,7 @@ export type WebAppConfig = ResourceConfig & {
location: string;
resourceGroupName: string;
};
export type AppServiceConfig = ResourceDefinition & {};
export type AppServiceConfig = ResourceDefinition & NonNullable<unknown>;
export type BotChannelResult = {
botName: string;

Просмотреть файл

@ -45,7 +45,7 @@ const webAppProvisionMethod = (provisionConfig: ProvisionServiceConfig) => {
return async (
resourceConfig: WebAppResourceConfig,
workingSet: ProvisionWorkingSet
workingSet: ProvisionWorkingSet,
): Promise<ProvisionWorkingSet> => {
const { resourceGroupName, webAppName, operatingSystem, location } = resourceConfig;
try {

Просмотреть файл

@ -34,7 +34,7 @@ const createAzurePublishPlugin = (): PublishPlugin<ProvisionServiceConfig> => {
});
}
return resources;
}, [])
}, []),
);
};
@ -90,7 +90,7 @@ const createAzurePublishPlugin = (): PublishPlugin<ProvisionServiceConfig> => {
processName: string,
project: IBotProject,
_user,
jobId = ''
jobId = '',
): Promise<ProcessStatus> => {
let status = processTracker.get(jobId);
if (!status) {

Просмотреть файл

@ -10,7 +10,7 @@ export type OnProvisionProgress = (status: number, message: string) => void;
export type ProvisionMethod = (
config: ResourceConfig,
workingSet: ProvisionWorkingSet,
onProgress?: OnProvisionProgress
onProgress?: OnProvisionProgress,
) => Promise<ProvisionWorkingSet>;
export type ResourceProvisionService = {

Просмотреть файл

@ -12,9 +12,10 @@ export const handOffToAdminDispatcher = () => {
});
const setRequiredHandOffResources = useRecoilCallback(
({ set }: CallbackInterface) => (resources: ResourcesItem[]) => {
set(requiredHandOffResourcesState, resources);
}
({ set }: CallbackInterface) =>
(resources: ResourcesItem[]) => {
set(requiredHandOffResourcesState, resources);
},
);
return {

Просмотреть файл

@ -21,9 +21,10 @@ export const resourceConfigurationDispatcher = () => {
});
const setResourceGroup = useRecoilCallback(
({ set }: CallbackInterface) => (resourceGroupName: string, isNew: boolean) => {
set(resourceGroupState, { name: resourceGroupName, isNew });
}
({ set }: CallbackInterface) =>
(resourceGroupName: string, isNew: boolean) => {
set(resourceGroupState, { name: resourceGroupName, isNew });
},
);
const setDeployLocation = useRecoilCallback(({ set }: CallbackInterface) => (deployLocation: string) => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
export const createABSService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const azureBotService = new AzureBotService(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
const createAppInsightsService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const applicationInsightsManagementClient = new ApplicationInsightsManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
const createBlobStorageService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const storageManagementClient = new StorageManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
export const createCosmosDBService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const cosmosDBManagementClient = new CosmosDBManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
const createLuisService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const cognitiveServicesManagementClient = new CognitiveServicesManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -8,9 +8,9 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
const createQNAService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const searchManagementClient = new SearchManagementClient(tokenCredentials, subscriptionId);
// @ts-expect-error
// @ts-expect-error types missmatch
const webSiteManagementClient = new WebSiteManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
const createWebAppAzureFunctionService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const webSiteManagementClient = new WebSiteManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -8,7 +8,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
export const createWebAppService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const webSiteManagementClient = new WebSiteManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from '../throwNotImplementedError';
const createWebAppServicePlanService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const webSiteManagementClient = new WebSiteManagementClient(tokenCredentials, subscriptionId);
const checkNameAvailability = async () => {

Просмотреть файл

@ -7,7 +7,7 @@ import { throwNotImplementedError } from './throwNotImplementedError';
const createResourceGroupService = (token: string, subscriptionId: string) => {
const tokenCredentials = new TokenCredentials(token);
// @ts-expect-error
// @ts-expect-error types missmatch
const client = new ResourceManagementClient(tokenCredentials, subscriptionId);
const list = async () => {

Просмотреть файл

@ -22,8 +22,8 @@ module.exports = {
token: accessToken,
profile: profile,
});
}
)
},
),
);
// define this BEFORE turning on the middleware...
@ -45,7 +45,7 @@ module.exports = {
console.log('login complete!');
// Successful authentication, redirect home.
res.redirect('/home');
}
},
);
composer.addAllowedUrl('/logout');
@ -60,7 +60,7 @@ module.exports = {
(user, done) => {
console.log('DESERIALIZE USER!', user);
done(null, JSON.parse(user));
}
},
);
},
};

Просмотреть файл

@ -110,7 +110,7 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
RuntimeLogServer.sendRuntimeLogToSubscribers(
botId,
LocalPublisher.runningBots[botId].result.runtimeLog ?? '',
LocalPublisher.runningBots[botId].result.runtimeError ?? ''
LocalPublisher.runningBots[botId].result.runtimeError ?? '',
);
};
@ -257,7 +257,7 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
// get port, and stop previous bot if exist
try {
// if a port (e.g. --port 5000) is configured in the custom runtime command try to parse and set this port
if (settings.runtime.command && settings.runtime.command.includes('--port')) {
if (settings.runtime?.command?.includes?.('--port')) {
try {
port = Number(/--port (\d+)/.exec(settings.runtime.command)[1]);
} catch (err) {
@ -340,7 +340,7 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
},
(err) => {
reject(`Bot on localhost:${port} not working, error message: ${err.message}`);
}
},
);
} catch (err) {
reject(err);
@ -387,20 +387,18 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
child: ChildProcess,
botId: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
logger: (...args: any[]) => void
logger: (...args: any[]) => void,
) => {
let errOutput = '';
child.stdout &&
child.stdout.on('data', (data: any) => {
const runtimeData = data.toString();
this.appendRuntimeLogs(botId, runtimeData);
logger('%s', data.toString());
});
child.stdout?.on?.('data', (data: any) => {
const runtimeData = data.toString();
this.appendRuntimeLogs(botId, runtimeData);
logger('%s', data.toString());
});
child.stderr &&
child.stderr.on('data', (err: any) => {
errOutput += err.toString();
});
child.stderr?.on?.('data', (err: any) => {
errOutput += err.toString();
});
child.on('exit', (code) => {
if (code !== 0) {

Просмотреть файл

@ -9,7 +9,7 @@ import express, { Request, Response } from 'express';
import WS from 'ws';
import { Debugger } from 'debug';
const { Server: WSServer } = WS
const { Server: WSServer } = WS;
interface WebSocket {
close(): void;
@ -105,7 +105,7 @@ export class RuntimeLogServer {
JSON.stringify({
standardOutput,
standardError,
})
}),
);
}
}

Просмотреть файл

@ -83,7 +83,7 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
const profileName = config.name;
const botId = project.id;
if (this.data[botId] && this.data[botId][profileName]) {
if (this.data?.[botId]?.[profileName]) {
const response = this.data[botId][profileName][this.data[botId][profileName].length - 1];
// return latest status
return response;
@ -100,7 +100,7 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
const profileName = config.name;
const botId = project.id;
const result = [];
if (this.data[botId] && this.data[botId][profileName]) {
if (this.data?.[botId]?.[profileName]) {
this.data[botId][profileName].map((item) => {
result.push({
...item.result,

Просмотреть файл

@ -155,7 +155,7 @@ class MongoStorage implements IFileStorage {
resolve(
files.map((item) => {
return item.path.replace(path, '');
})
}),
);
}
});
@ -270,7 +270,7 @@ class MongoStorage implements IFileStorage {
resolve(
files.map((item) => {
return item.path.replace(path, '');
})
}),
);
}
});

Просмотреть файл

@ -5,8 +5,8 @@ module.exports = {
extends: [
'eslint:recommended',
'plugin:prettier/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'prettier/@typescript-eslint',
],
plugins: ['import', 'notice', 'security', 'lodash'],
env: {

Просмотреть файл

@ -78,7 +78,7 @@ export const FeedModal: React.FC<WorkingModalProps> = (props) => {
setSelectedItem(undefined);
}
},
})
}),
);
useEffect(() => {
@ -276,7 +276,7 @@ export const FeedModal: React.FC<WorkingModalProps> = (props) => {
if (
await confirm(
formatMessage('Delete this feed?'),
formatMessage('Are you sure you want to remove this feed source?')
formatMessage('Are you sure you want to remove this feed source?'),
)
) {
setItems(items.filter((i) => i.key !== selectedItem.key));

Просмотреть файл

@ -42,7 +42,7 @@ const ImportDialog: React.FC<ImportDialogProps> = (props) => {
<form onSubmit={submit}>
<p>
{formatMessage(
'Install a specific package by pasting the name and version number below. The text must be an exact match in order to find the correct package. You can also add and browse feeds to find packages to add.'
'Install a specific package by pasting the name and version number below. The text must be an exact match in order to find the correct package. You can also add and browse feeds to find packages to add.',
)}
</p>
<TextField

Просмотреть файл

@ -22,7 +22,11 @@ export class NpmFeed implements IFeed {
* @param packageSource package source from where to retrieve packages.
* @param data data received in the `objects` field from the http call to the npm registry.
*/
constructor(private composer: IExtensionRegistration, private packageSource?: IPackageSource, private data?) {}
constructor(
private composer: IExtensionRegistration,
private packageSource?: IPackageSource,
private data?,
) {}
/**
* Gets packages from the npm feed based on the provided query.

Просмотреть файл

@ -26,7 +26,10 @@ export class LocalNuGetFeed implements IFeed {
* @param composer Composer registration used for logging.
* @param url Url of the feed, represented usually by the file path to the NuGet file system feed.
*/
constructor(private composer: IExtensionRegistration, private url: string) {}
constructor(
private composer: IExtensionRegistration,
private url: string,
) {}
/**
* Gets packages from local NuGet feed according to query request.
@ -49,6 +52,7 @@ export class LocalNuGetFeed implements IFeed {
// * extract only folders from that list
// * pass each one through the getPackageInfo function, which extracts metadata from the package
// * return a feed in the form that is used by nuget search API
// eslint-disable-next-line security/detect-non-literal-fs-filename
const packages = await readdir(url, { withFileTypes: true });
const feedPromises: Promise<IPackageDefinition>[] = packages
@ -69,6 +73,7 @@ export class LocalNuGetFeed implements IFeed {
let versions;
try {
// eslint-disable-next-line security/detect-non-literal-fs-filename
versions = await readdir(packageDir, { withFileTypes: true });
versions = versions.filter((f) => f.isDirectory()).map((f) => f.name);
if (versions.length === 0) {
@ -77,13 +82,14 @@ export class LocalNuGetFeed implements IFeed {
versions = semverSort.desc(versions);
} catch (err) {
throw new Error(
`Could not find versions of local package ${packageName} at ${rootDir}. For more info about setting up a local feed, see here: https://docs.microsoft.com/en-us/nuget/hosting-packages/local-feeds. Error: ${err}`
`Could not find versions of local package ${packageName} at ${rootDir}. For more info about setting up a local feed, see here: https://docs.microsoft.com/en-us/nuget/hosting-packages/local-feeds. Error: ${err}`,
);
}
// Read from the nuspec file in the latest to get other info.
try {
const pathToNuspec = path.join(packageDir, versions[0], `${packageName}.nuspec`);
// eslint-disable-next-line security/detect-non-literal-fs-filename
const xml = await readFile(pathToNuspec, 'utf8');
const parsed = await parseStringPromise(xml);

Просмотреть файл

@ -25,7 +25,7 @@ export class NuGetFeed implements IFeed {
constructor(
private composer: IExtensionRegistration,
private packageSource?: IPackageSource,
private data?: INuGetSearchResult | INuGetServiceIndex
private data?: INuGetSearchResult | INuGetServiceIndex,
) {}
/**
@ -50,7 +50,7 @@ export class NuGetFeed implements IFeed {
let serviceIndex: INuGetServiceIndex = this.data as INuGetServiceIndex;
// If we don't have a service index provided at construction, get it from the url
if (!serviceIndex || !serviceIndex.resources) {
if (!serviceIndex?.resources) {
const httpResponse = await axios.get(this.packageSource.url);
serviceIndex = httpResponse?.data;
}

Просмотреть файл

@ -201,7 +201,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
// append user specified query to defaultQuery
if (req.query.term) {
packageSource.defaultQuery.query = `${packageSource.defaultQuery.query}+${encodeURIComponent(
req.query.term
req.query.term,
)}`;
}
@ -261,7 +261,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
false, // verbosity: true = verbose
composer.log,
composer.log,
captureErrors
captureErrors,
);
const dryRunMergeResults = await dryrun.merge();
@ -311,7 +311,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
packageName,
version,
source,
currentProject
currentProject,
);
const manifestFile = runtime.identifyManifest(runtimePath, currentProject.name);
@ -325,7 +325,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
false, // verbosity: true = verbose
composer.log,
composer.log,
captureErrors
captureErrors,
);
const dryRunMergeResults = await dryrun.merge();
@ -353,7 +353,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
false, // verbosity: true = verbose
composer.log,
composer.log,
composer.log
composer.log,
);
const mergeResults = await realMerge.merge();
@ -361,7 +361,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
composer.log(
'MERGE RESULTS',
path.join(currentProject.dataDir, 'dialogs/imported'),
JSON.stringify(mergeResults, null, 2)
JSON.stringify(mergeResults, null, 2),
);
const installedComponents = await loadPackageAssets(mergeResults.components.filter(isAdaptiveComponent));
@ -379,7 +379,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
if (
newlyInstalledPlugin &&
!currentProject.settings.runtimeSettings?.components?.find(
(p: { name: string }) => p.name === newlyInstalledPlugin.name
(p: { name: string }) => p.name === newlyInstalledPlugin.name,
)
) {
const newSettings = await currentProject.getEnvSettings();
@ -464,7 +464,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
false, // verbosity: true = verbose
composer.log,
composer.log,
captureErrors
captureErrors,
);
const mergeResults = await merger.merge();
@ -484,7 +484,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
) {
const newSettings = await currentProject.getEnvSettings();
newSettings.runtimeSettings.components = newSettings.runtimeSettings.components.filter(
(p) => p.name !== packageName
(p) => p.name !== packageName,
);
currentProject.updateEnvSettings(newSettings);
}

Просмотреть файл

@ -148,19 +148,19 @@ const Library: React.FC = () => {
recentlyUsedCategory: formatMessage('Recently Used'),
installedCategory: formatMessage('Installed'),
updateConfirmationPrompt: formatMessage(
'Any changes you made to this package will be lost! Are you sure you want to continue?'
'Any changes you made to this package will be lost! Are you sure you want to continue?',
),
updateConfirmationTitle: formatMessage('Update Package'),
conflictConfirmationTitle: formatMessage('Conflicting changes detected'),
conflictConfirmationPrompt: formatMessage(
'This operation will overwrite changes made to previously imported files. Do you want to proceed?'
'This operation will overwrite changes made to previously imported files. Do you want to proceed?',
),
removeConfirmationTitle: formatMessage('Remove Package'),
removeConfirmationPrompt: formatMessage(
'Any changes you made to this package will be lost! In addition, this may leave your bot in a broken state. Are you sure you want to continue?'
'Any changes you made to this package will be lost! In addition, this may leave your bot in a broken state. Are you sure you want to continue?',
),
requireEject: formatMessage(
'To install components, this project must have an ejected runtime. Please navigate to the project settings page, custom runtime section.'
'To install components, this project must have an ejected runtime. Please navigate to the project settings page, custom runtime section.',
),
ejectRuntime: formatMessage('Eject Runtime'),
noComponentsInstalled: formatMessage('No packages installed'),
@ -182,7 +182,7 @@ const Library: React.FC = () => {
packageName: string,
version: string,
isUpdating: boolean,
source: string
source: string,
) => {
return httpClient.post(`${API_ROOT}/projects/${projectId}/import`, {
package: packageName,
@ -303,7 +303,7 @@ const Library: React.FC = () => {
let availversions;
let setversion;
if (selectedItem.versions && selectedItem.versions.length) {
if (selectedItem?.versions?.length) {
availversions = selectedItem.versions;
} else {
availversions = [selectedItem.version];
@ -501,7 +501,7 @@ const Library: React.FC = () => {
} catch (err) {
setApplicationLevelError({
status: err.response.status,
message: err.response && err.response.data.message ? err.response.data.message : err,
message: err?.response?.data?.message ?? err,
summary: strings.libraryError,
});
} finally {
@ -519,7 +519,7 @@ const Library: React.FC = () => {
} catch (err) {
setApplicationLevelError({
status: err.response.status,
message: err.response && err.response.data.message ? err.response.data.message : err,
message: err?.response?.data?.message ?? err,
summary: strings.libraryError,
});
}
@ -563,7 +563,7 @@ const Library: React.FC = () => {
if (err.response) {
setApplicationLevelError({
status: err.response.status,
message: err.response && err.response.data.message ? err.response.data.message : err,
message: err?.response?.data?.message ?? err,
summary: strings.importError,
});
} else {

Просмотреть файл

@ -113,7 +113,7 @@ export const PVADialog: FC = () => {
setBot(bot);
}
},
[bots, env]
[bots, env],
);
useEffect(() => {

Просмотреть файл

@ -62,7 +62,7 @@ describe('publish()', () => {
mockBotProject,
{ comment: 'testing' },
undefined,
mockGetAccessToken
mockGetAccessToken,
);
expect(result.status).toBe(202);
@ -71,7 +71,7 @@ describe('publish()', () => {
expect(innerResult.comment).toBe('testing');
expect(innerResult.eTag).toBe('W/"version"');
expect(innerResult.log).toEqual(
mockDiagnostics.map((diag) => `---\n${JSON.stringify(diag, null, 2)}\n---\n`).join('\n')
mockDiagnostics.map((diag) => `---\n${JSON.stringify(diag, null, 2)}\n---\n`).join('\n'),
);
expect(innerResult.id).toBe('operationId');
expect(innerResult.action).toEqual(null);
@ -87,7 +87,7 @@ describe('publish()', () => {
mockBotProject,
{ comment: 'testing' },
undefined,
mockGetAccessToken
mockGetAccessToken,
);
expect(result.status).toBe(502);
@ -104,7 +104,7 @@ describe('publish()', () => {
mockBotProject,
{ comment: 'testing' },
undefined,
mockGetAccessToken
mockGetAccessToken,
);
expect(result.status).toBe(500);

Просмотреть файл

@ -23,7 +23,7 @@ export const publish = async (
project: IBotProject,
metadata: any,
_user?: UserIdentity,
getAccessToken?
getAccessToken?,
): Promise<PublishResponse> => {
const {
// these are provided by Composer
@ -68,7 +68,7 @@ export const publish = async (
resolve();
});
archive.pipe(botContentWriter);
}
},
);
});
const botContent = Buffer.concat(botContentData);
@ -90,7 +90,7 @@ export const publish = async (
},
});
if (res.status === 202) {
const job = await res.json() as PVAPublishJob;
const job = (await res.json()) as PVAPublishJob;
logger.log('Publish job started: %O', job);
// transform the PVA job to a publish response
@ -134,7 +134,7 @@ export const getStatus = async (
config: PublishConfig,
project: IBotProject,
user?: UserIdentity,
getAccessToken?
getAccessToken?,
): Promise<PublishResponse> => {
const {
// these are provided by Composer
@ -174,7 +174,7 @@ export const getStatus = async (
'If-None-Match': project.eTag || '',
},
});
const job = await res.json() as PVAPublishJob;
const job = (await res.json()) as PVAPublishJob;
logger.log('Got updated status from publish job: %O', job);
// transform the PVA job to a publish response
@ -210,7 +210,7 @@ export const history = async (
config: PublishConfig,
_project: IBotProject,
_user?: UserIdentity,
getAccessToken?
getAccessToken?,
): Promise<PublishResult[]> => {
const {
// these are specific to the PVA publish profile shape
@ -232,7 +232,7 @@ export const history = async (
method: 'GET',
headers: getAuthHeaders(accessToken, tenantId),
});
const jobs = await res.json() as PVAPublishJob[];
const jobs = (await res.json()) as PVAPublishJob[];
// return the first 20
return jobs.map((job) => xformJobToResult(job)).slice(0, 19);
@ -245,7 +245,7 @@ export const pull = async (
config: PublishConfig,
_project: IBotProject,
_user?: UserIdentity,
getAccessToken?
getAccessToken?,
): Promise<PullResponse> => {
const {
// these are specific to the PVA publish profile shape
@ -281,6 +281,7 @@ export const pull = async (
const zipDir = join(process.env.COMPOSER_TEMP_DIR as string, 'pva-publish');
ensureDirSync(zipDir);
const zipPath = join(zipDir, `bot-assets-${Date.now()}.zip`);
// eslint-disable-next-line security/detect-non-literal-fs-filename
const writeStream = createWriteStream(zipPath);
await new Promise((resolve, reject) => {
writeStream.once('finish', resolve);
@ -342,11 +343,7 @@ const ensurePublishProfileHistory = (botProjectId: string, profileName: string)
};
const getOperationIdOfLastJob = (botProjectId: string, profileName: string): string => {
if (
publishHistory[botProjectId] &&
publishHistory[botProjectId][profileName] &&
!!publishHistory[botProjectId][profileName].length
) {
if (publishHistory?.[botProjectId]?.[profileName]?.length) {
const mostRecentJob = publishHistory[botProjectId][profileName][0];
return mostRecentJob.id || '';
}

Просмотреть файл

@ -11,7 +11,7 @@ export async function copyDir(
srcStorage: IFileStorage,
dstDir: string,
dstStorage: IFileStorage,
pathsToExclude?: Set<string>
pathsToExclude?: Set<string>,
) {
if (!(await srcStorage.exists(srcDir)) || !(await srcStorage.stat(srcDir)).isDir) {
throw new Error(`No such dir ${srcDir}}`);

Просмотреть файл

@ -46,7 +46,7 @@ const writeAllLocalFunctionsSettings = async (fullSettings: DialogSetting, port:
'luis:endpointKey',
fullSettings.luis?.endpointKey || fullSettings.luis?.authoringKey,
runtimePath,
log
log,
);
await writeLocalFunctionsSetting('qna:endpointKey', fullSettings.qna?.endpointKey, runtimePath, log);
let skillHostEndpoint;
@ -100,7 +100,7 @@ export default async (composer: any): Promise<void> => {
version: string,
source: string,
project: IBotProject,
isPreview = false
isPreview = false,
): Promise<string> => {
// run dotnet install on the project
const command = `dotnet add ${project.name}.csproj package "${packageName}"${
@ -122,7 +122,7 @@ export default async (composer: any): Promise<void> => {
`dotnet remove ${project.name}.csproj package ${packageName}`,
{
cwd: path.join(runtimePath),
}
},
);
if (installError) {
throw new Error(installError);
@ -139,7 +139,7 @@ export default async (composer: any): Promise<void> => {
runtimePath: string,
project: IBotProject,
settings: DialogSetting,
profileName: string
profileName: string,
): Promise<string> => {
composer.log('BUILD FOR DEPLOY TO AZURE!');
@ -189,7 +189,7 @@ export default async (composer: any): Promise<void> => {
dstStorage: IFileStorage,
srcManifestDir: string,
srcStorage: IFileStorage,
mode = 'azurewebapp' // set default as azurewebapp
mode = 'azurewebapp', // set default as azurewebapp
) => {
// update manifst into runtime wwwroot
if (mode === 'azurewebapp') {
@ -241,7 +241,7 @@ export default async (composer: any): Promise<void> => {
version: string,
source: string,
project: IBotProject,
isPreview = false
isPreview = false,
): Promise<string> => {
// run dotnet install on the project
const command = `dotnet add ${project.name}.csproj package "${packageName}"${
@ -263,7 +263,7 @@ export default async (composer: any): Promise<void> => {
`dotnet remove ${project.name}.csproj package ${packageName}`,
{
cwd: path.join(runtimePath),
}
},
);
if (installError) {
throw new Error(installError);
@ -280,7 +280,7 @@ export default async (composer: any): Promise<void> => {
runtimePath: string,
project: IBotProject,
settings: DialogSetting,
profileName: string
profileName: string,
): Promise<string> => {
composer.log('BUILD FOR DEPLOY TO AZURE!');
@ -347,14 +347,14 @@ export default async (composer: any): Promise<void> => {
version: string,
source: string,
_project: IBotProject,
isPreview = false
isPreview = false,
): Promise<string> => {
// run dotnet install on the project
const { stderr: installError, stdout: installOutput } = await execAsync(
`npm install --loglevel=error --save ${packageName}${version ? '@' + version : ''}`,
{
cwd: path.join(runtimePath),
}
},
);
if (installError) {
throw new Error(installError);
@ -367,7 +367,7 @@ export default async (composer: any): Promise<void> => {
`npm uninstall --loglevel=error --save ${packageName}`,
{
cwd: path.join(runtimePath),
}
},
);
if (installError) {
throw new Error(installError);
@ -381,7 +381,7 @@ export default async (composer: any): Promise<void> => {
runtimePath: string,
project: IBotProject,
settings: DialogSetting,
profileName: string
profileName: string,
): Promise<string> => {
// do stuff
composer.log(`BUILD THIS JS PROJECT in ${runtimePath}`);
@ -425,14 +425,14 @@ export default async (composer: any): Promise<void> => {
version: string,
source: string,
_project: IBotProject,
isPreview = false
isPreview = false,
): Promise<string> => {
// run dotnet install on the project
const { stderr: installError, stdout: installOutput } = await execAsync(
`npm install --loglevel=error --save ${packageName}${version ? '@' + version : ''}`,
{
cwd: path.join(runtimePath),
}
},
);
if (installError) {
throw new Error(installError);
@ -445,7 +445,7 @@ export default async (composer: any): Promise<void> => {
`npm uninstall --loglevel=error --save ${packageName}`,
{
cwd: path.join(runtimePath),
}
},
);
if (installError) {
throw new Error(installError);
@ -459,7 +459,7 @@ export default async (composer: any): Promise<void> => {
runtimePath: string,
project: IBotProject,
settings: DialogSetting,
profileName: string
profileName: string,
): Promise<string> => {
// do stuff
composer.log(`BUILD THIS JS PROJECT in ${runtimePath}`);

Просмотреть файл

@ -46,8 +46,15 @@ export const textField = css`
// copied from Fluent
export const label = css`
font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto,
'Helvetica Neue', sans-serif;
font-family:
'Segoe UI',
'Segoe UI Web (West European)',
'Segoe UI',
-apple-system,
BlinkMacSystemFont,
Roboto,
'Helvetica Neue',
sans-serif;
font-size: 14px;
font-weight: 600;
color: rgb(50, 49, 48);
@ -64,8 +71,15 @@ export const shortTextField = css`
`;
export const output = css`
font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto,
'Helvetica Neue', sans-serif;
font-family:
'Segoe UI',
'Segoe UI Web (West European)',
'Segoe UI',
-apple-system,
BlinkMacSystemFont,
Roboto,
'Helvetica Neue',
sans-serif;
font-size: 14px;
font-weight: 400;
`;