Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [#4684] ESLint issues in botbuilder-azure #498

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions libraries/botbuilder-azure/eslint.config.cjs

This file was deleted.

3 changes: 1 addition & 2 deletions libraries/botbuilder-azure/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"bcryptjs": "^2.4.3",
"botbuilder": "4.1.6",
"botbuilder-stdlib": "4.1.6",
"eslint-plugin-only-warn": "^1.1.0",
"lodash": "^4.17.20",
"p-map": "^4.0.0"
},
Expand All @@ -49,7 +48,7 @@
"build:rollup": "yarn clean && yarn build && api-extractor run --verbose --local",
"clean": "rimraf _ts3.4 lib tsconfig.tsbuildinfo",
"depcheck": "depcheck --config ../../.depcheckrc",
"lint": "eslint .",
"lint": "eslint . --config ../../eslint.config.cjs",
"postbuild": "downlevel-dts lib _ts3.4/lib --checksum",
"test": "yarn build && nyc mocha tests/",
"test:compat": "api-extractor run --verbose"
Expand Down
8 changes: 4 additions & 4 deletions libraries/botbuilder-azure/src/azureBlobTranscriptStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class AzureBlobTranscriptStore implements TranscriptStore {
this.containerClient = new ContainerClient(
this.settings.storageAccountOrConnectionString,
this.settings.containerName,
pipeline.options
pipeline.options,
);
}

Expand Down Expand Up @@ -137,7 +137,7 @@ export class AzureBlobTranscriptStore implements TranscriptStore {
channelId: string,
conversationId: string,
continuationToken?: string,
startDate?: Date
startDate?: Date,
): Promise<PagedResult<Activity>> {
if (!channelId) {
throw new Error('Missing channelId');
Expand Down Expand Up @@ -174,7 +174,7 @@ export class AzureBlobTranscriptStore implements TranscriptStore {
const fromIdx =
startDate != null
? blobItems.findIndex(
(blobItem) => blobItem?.properties?.createdOn && blobItem?.properties?.createdOn >= startDate
(blobItem) => blobItem?.properties?.createdOn && blobItem?.properties?.createdOn >= startDate,
)
: 0;

Expand All @@ -193,7 +193,7 @@ export class AzureBlobTranscriptStore implements TranscriptStore {
const activity = (await StreamConsumers.json(readableStreamBody)) as any;
return { ...activity, timestamp: new Date(activity.timestamp) } as Activity;
},
{ concurrency: this.concurrency }
{ concurrency: this.concurrency },
);

activities.forEach((activity) => {
Expand Down
12 changes: 6 additions & 6 deletions libraries/botbuilder-azure/src/blobStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const ResolvePromisesSerial = (values, promise) =>
.map((value) => () => promise(value))
.reduce(
(promise, func) => promise.then((result) => func().then(Array.prototype.concat.bind(result))),
Promise.resolve([])
Promise.resolve([]),
);

/**
Expand Down Expand Up @@ -155,7 +155,7 @@ export class BlobStorage implements Storage {
this.containerClient = new ContainerClient(
this.settings.storageAccountOrConnectionString,
this.settings.containerName,
pipeline.options
pipeline.options,
);

this.useEmulator = settings.storageAccountOrConnectionString === 'UseDevelopmentStorage=true;';
Expand Down Expand Up @@ -194,7 +194,7 @@ export class BlobStorage implements Storage {
// If blob does not exist, return an empty DocumentStoreItem.
return { document: {} } as DocumentStoreItem;
}
})
}),
)
.then((items: DocumentStoreItem[]) => {
if (items !== null && items.length > 0) {
Expand Down Expand Up @@ -257,7 +257,7 @@ export class BlobStorage implements Storage {
// depending on the payload's size. The default maximum size for a single blob upload is 128MB.
// An 'InvalidBlockList' error is commonly caused due to concurrently uploading an object larger than 128MB in size.
const promise: (b: any) => Promise<BlockBlobUploadResponse> = (
blob: any
blob: any,
): Promise<BlockBlobUploadResponse> => {
const blockBlobClient = this.containerClient.getBlockBlobClient(blob.id);
const uploadBlobResponse = blockBlobClient.upload(blob.data, blob.data.length, blob.options);
Expand Down Expand Up @@ -301,7 +301,7 @@ export class BlobStorage implements Storage {
sanitizedKeys.map(async (key: string) => {
const blockBlobClient = this.containerClient.getBlockBlobClient(key);
return await blockBlobClient.deleteIfExists();
})
}),
);
})
.then(() => {
Expand All @@ -328,7 +328,7 @@ export class BlobStorage implements Storage {
// The number of path segments comprising the blob name cannot exceed 254
const validKey: string = segments.reduce(
(acc: any, curr: any, index: number) => [acc, curr].join(index < 255 ? '/' : ''),
base
base,
);

// Reserved URL characters must be escaped.
Expand Down
6 changes: 3 additions & 3 deletions libraries/botbuilder-azure/src/cosmosDbKeyEscape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export namespace CosmosDbKeyEscape {

return map;
},
new Map()
new Map(),
);

/**
Expand All @@ -43,7 +43,7 @@ export namespace CosmosDbKeyEscape {
const keySplitted: string[] = key.split('');

const firstIllegalCharIndex: number = keySplitted.findIndex((c: string): boolean =>
illegalKeys.some((i: string) => i === c)
illegalKeys.some((i: string) => i === c),
);

// If there are no illegal characters return immediately and avoid any further processing/allocations
Expand All @@ -54,7 +54,7 @@ export namespace CosmosDbKeyEscape {
const sanitizedKey = keySplitted.reduce(
(result: string, c: string) =>
result + (illegalKeyCharacterReplacementMap.has(c) ? illegalKeyCharacterReplacementMap.get(c) : c),
''
'',
);

return truncateKey(`${sanitizedKey}${keySuffix || ''}`, compatibilityMode);
Expand Down
163 changes: 78 additions & 85 deletions libraries/botbuilder-azure/src/cosmosDbPartitionedStorage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/ban-types */
/**
* @module botbuilder-azure
*/
Expand All @@ -13,7 +12,7 @@ import { DoOnce } from './doOnce';
import { Storage, StoreItems } from 'botbuilder';
import { TokenCredential } from '@azure/core-auth';

// eslint-disable-next-line @typescript-eslint/no-var-requires
// eslint-disable-next-line @typescript-eslint/no-require-imports
const pjson: Record<'name' | 'version', string> = require('../package.json');

const _doOnce: DoOnce<Container> = new DoOnce<Container>();
Expand Down Expand Up @@ -173,7 +172,7 @@ export class CosmosDbPartitionedStorage implements Storage {
const suffixEscaped = CosmosDbKeyEscape.escapeKey(cosmosDbStorageOptions.keySuffix);
if (cosmosDbStorageOptions.keySuffix !== suffixEscaped) {
throw new ReferenceError(
`Cannot use invalid Row Key characters: ${cosmosDbStorageOptions.keySuffix} in keySuffix`
`Cannot use invalid Row Key characters: ${cosmosDbStorageOptions.keySuffix} in keySuffix`,
);
}
}
Expand Down Expand Up @@ -202,43 +201,41 @@ export class CosmosDbPartitionedStorage implements Storage {
const storeItems: StoreItems = {};

await Promise.all(
keys.map(
async (k: string): Promise<void> => {
try {
const escapedKey = CosmosDbKeyEscape.escapeKey(
k,
this.cosmosDbStorageOptions.keySuffix,
this.cosmosDbStorageOptions.compatibilityMode
);
keys.map(async (k: string): Promise<void> => {
try {
const escapedKey = CosmosDbKeyEscape.escapeKey(
k,
this.cosmosDbStorageOptions.keySuffix,
this.cosmosDbStorageOptions.compatibilityMode,
);

const readItemResponse = await this.container
.item(escapedKey, this.getPartitionKey(escapedKey))
.read<DocumentStoreItem>();
const documentStoreItem = readItemResponse.resource;
if (documentStoreItem) {
storeItems[documentStoreItem.realId] = documentStoreItem.document;
storeItems[documentStoreItem.realId].eTag = documentStoreItem._etag;
}
} catch (err) {
// When an item is not found a CosmosException is thrown, but we want to
// return an empty collection so in this instance we catch and do not rethrow.
// Throw for any other exception.
if (err.code === 404) {
// no-op
}
// Throw unique error for 400s
else if (err.code === 400) {
this.throwInformativeError(
`Error reading from container. You might be attempting to read from a non-partitioned
const readItemResponse = await this.container
.item(escapedKey, this.getPartitionKey(escapedKey))
.read<DocumentStoreItem>();
const documentStoreItem = readItemResponse.resource;
if (documentStoreItem) {
storeItems[documentStoreItem.realId] = documentStoreItem.document;
storeItems[documentStoreItem.realId].eTag = documentStoreItem._etag;
}
} catch (err) {
// When an item is not found a CosmosException is thrown, but we want to
// return an empty collection so in this instance we catch and do not rethrow.
// Throw for any other exception.
if (err.code === 404) {
// no-op
}
// Throw unique error for 400s
else if (err.code === 400) {
this.throwInformativeError(
`Error reading from container. You might be attempting to read from a non-partitioned
container or a container that does not use '/id' as the partitionKeyPath`,
err
);
} else {
this.throwInformativeError('Error reading from container', err);
}
err,
);
} else {
this.throwInformativeError('Error reading from container', err);
}
}
)
}),
);

return storeItems;
Expand All @@ -259,38 +256,36 @@ export class CosmosDbPartitionedStorage implements Storage {
await this.initialize();

await Promise.all(
Object.entries(changes).map(
async ([key, { eTag, ...change }]): Promise<void> => {
const document = new DocumentStoreItem({
id: CosmosDbKeyEscape.escapeKey(
key,
this.cosmosDbStorageOptions.keySuffix,
this.cosmosDbStorageOptions.compatibilityMode
),
realId: key,
document: change,
});
Object.entries(changes).map(async ([key, { eTag, ...change }]): Promise<void> => {
const document = new DocumentStoreItem({
id: CosmosDbKeyEscape.escapeKey(
key,
this.cosmosDbStorageOptions.keySuffix,
this.cosmosDbStorageOptions.compatibilityMode,
),
realId: key,
document: change,
});

const accessCondition =
eTag !== '*' && eTag != null && eTag.length > 0
? { accessCondition: { type: 'IfMatch', condition: eTag } }
: undefined;

try {
await this.container.items.upsert(document, accessCondition);
} catch (err) {
// This check could potentially be performed before even attempting to upsert the item
// so that a request wouldn't be made to Cosmos if it's expected to fail.
// However, performing the check here ensures that this custom exception is only thrown
// if Cosmos returns an error first.
// This way, the nesting limit is not imposed on the Bot Framework side
// and no exception will be thrown if the limit is eventually changed on the Cosmos side.
this.checkForNestingError(change, err);

this.throwInformativeError('Error upserting document', err);
}
const accessCondition =
eTag !== '*' && eTag != null && eTag.length > 0
? { accessCondition: { type: 'IfMatch', condition: eTag } }
: undefined;

try {
await this.container.items.upsert(document, accessCondition);
} catch (err) {
// This check could potentially be performed before even attempting to upsert the item
// so that a request wouldn't be made to Cosmos if it's expected to fail.
// However, performing the check here ensures that this custom exception is only thrown
// if Cosmos returns an error first.
// This way, the nesting limit is not imposed on the Bot Framework side
// and no exception will be thrown if the limit is eventually changed on the Cosmos side.
this.checkForNestingError(change, err);

this.throwInformativeError('Error upserting document', err);
}
)
}),
);
}

Expand All @@ -303,25 +298,23 @@ export class CosmosDbPartitionedStorage implements Storage {
await this.initialize();

await Promise.all(
keys.map(
async (k: string): Promise<void> => {
const escapedKey = CosmosDbKeyEscape.escapeKey(
k,
this.cosmosDbStorageOptions.keySuffix,
this.cosmosDbStorageOptions.compatibilityMode
);
try {
await this.container.item(escapedKey, this.getPartitionKey(escapedKey)).delete();
} catch (err) {
// If trying to delete a document that doesn't exist, do nothing. Otherwise, throw
if (err.code === 404) {
// no-op
} else {
this.throwInformativeError('Unable to delete document', err);
}
keys.map(async (k: string): Promise<void> => {
const escapedKey = CosmosDbKeyEscape.escapeKey(
k,
this.cosmosDbStorageOptions.keySuffix,
this.cosmosDbStorageOptions.compatibilityMode,
);
try {
await this.container.item(escapedKey, this.getPartitionKey(escapedKey)).delete();
} catch (err) {
// If trying to delete a document that doesn't exist, do nothing. Otherwise, throw
if (err.code === 404) {
// no-op
} else {
this.throwInformativeError('Unable to delete document', err);
}
}
)
}),
);
}

Expand Down Expand Up @@ -350,7 +343,7 @@ export class CosmosDbPartitionedStorage implements Storage {
const dbAndContainerKey = `${this.cosmosDbStorageOptions.databaseId}-${this.cosmosDbStorageOptions.containerId}`;
this.container = await _doOnce.waitFor(
dbAndContainerKey,
async (): Promise<Container> => await this.getOrCreateContainer()
async (): Promise<Container> => await this.getOrCreateContainer(),
);
}
}
Expand All @@ -372,7 +365,7 @@ export class CosmosDbPartitionedStorage implements Storage {
} else if (paths.indexOf(DocumentStoreItem.partitionKeyPath) === -1) {
// We are not supporting custom Partition Key Paths.
new Error(
`Custom Partition Key Paths are not supported. ${this.cosmosDbStorageOptions.containerId} has a custom Partition Key Path of ${paths[0]}.`
`Custom Partition Key Paths are not supported. ${this.cosmosDbStorageOptions.containerId} has a custom Partition Key Path of ${paths[0]}.`,
);
}
} else {
Expand Down
Loading
Loading