azure-mock 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +93 -3
- package/dist/index.js +90 -6
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnonymousCredential, AppendBlobClient, BlobAbortCopyFromURLResponse, BlobBatchClient, BlobBatchDeleteBlobsResponse, BlobBeginCopyFromURLResponse, BlobClient, BlobCopyFromURLResponse, BlobCreateSnapshotResponse, BlobDeleteIfExistsResponse, BlobDeleteImmutabilityPolicyResponse, BlobDeleteOptions, BlobDeleteResponse, BlobDownloadResponseModel, BlobDownloadResponseParsed, BlobGetAccountInfoResponse, BlobGetPropertiesResponse, BlobGetTagsResponse, BlobItem, BlobLeaseClient, BlobPrefix, BlobSetHTTPHeadersResponse, BlobSetImmutabilityPolicyResponse, BlobSetLegalHoldResponse, BlobSetMetadataResponse, BlobSetTagsResponse, BlobSetTierResponse, BlobUndeleteResponse, BlobUploadCommonResponse, BlockBlobClient, BlockBlobCommitBlockListResponse, BlockBlobGetBlockListResponse, BlockBlobPutBlobFromUrlResponse, BlockBlobStageBlockFromURLResponse, BlockBlobStageBlockResponse, BlockBlobUploadResponse, ContainerClient, ContainerCreateIfNotExistsResponse, ContainerCreateResponse, ContainerDeleteIfExistsResponse, ContainerDeleteResponse, ContainerFindBlobsByTagsSegmentResponse, ContainerGetAccessPolicyResponse, ContainerGetAccountInfoResponse, ContainerGetPropertiesResponse, ContainerListBlobFlatSegmentResponse, ContainerListBlobHierarchySegmentResponse, ContainerListBlobsOptions, ContainerSetAccessPolicyResponse, ContainerSetMetadataResponse, FilterBlobItem, HttpRequestBody, PageBlobClient, PollOperationState, PollerLikeWithCancellation, StorageSharedKeyCredential } from "@azure/storage-blob";
|
|
2
2
|
import { MapValue } from "type-fest/source/entry";
|
|
3
|
-
import { CreateTableEntityResponse, GetAccessPolicyResponse, GetTableEntityResponse, TableClient, TableDeleteEntityHeaders, TableEntity, TableEntityResult, TableEntityResultPage, TableMergeEntityHeaders, TableSetAccessPolicyHeaders, TableTransactionResponse, UpdateMode } from "@azure/data-tables";
|
|
3
|
+
import { CreateTableEntityResponse, GetAccessPolicyResponse, GetTableEntityResponse, ListTableEntitiesOptions, TableClient, TableDeleteEntityHeaders, TableEntity, TableEntityResult, TableEntityResultPage, TableMergeEntityHeaders, TableSetAccessPolicyHeaders, TableTransactionResponse, UpdateMode } from "@azure/data-tables";
|
|
4
4
|
|
|
5
5
|
//#region src/models/BlobHierarchyItem.d.ts
|
|
6
6
|
type BlobHierarchyItem = (BlobItem & {
|
|
@@ -830,7 +830,7 @@ declare class MockTableClient implements Except<TableClient, "pipeline"> {
|
|
|
830
830
|
deleteTable(): Promise<void>;
|
|
831
831
|
getAccessPolicy(): Promise<GetAccessPolicyResponse>;
|
|
832
832
|
getEntity<T extends object = Record<string, unknown>>(partitionKey: string, rowKey: string): Promise<GetTableEntityResponse<TableEntityResult<T>>>;
|
|
833
|
-
listEntities<T extends object>(): PagedAsyncIterableIterator<TableEntityResult<T>, TableEntityResultPage<T>>;
|
|
833
|
+
listEntities<T extends object>(options?: ListTableEntitiesOptions): PagedAsyncIterableIterator<TableEntityResult<T>, TableEntityResultPage<T>>;
|
|
834
834
|
setAccessPolicy(): Promise<TableSetAccessPolicyHeaders>;
|
|
835
835
|
submitTransaction(): Promise<TableTransactionResponse>;
|
|
836
836
|
updateEntity<T extends object>(entity: TableEntity<T>, mode?: UpdateMode): Promise<TableMergeEntityHeaders>;
|
|
@@ -1522,4 +1522,94 @@ type TransferProgressEvent = {
|
|
|
1522
1522
|
//#region src/util/toWebResourceLike.d.ts
|
|
1523
1523
|
declare const toWebResourceLike: (request: PipelineRequest) => WebResourceLike;
|
|
1524
1524
|
//#endregion
|
|
1525
|
-
|
|
1525
|
+
//#region ../shared/dist/index.d.ts
|
|
1526
|
+
//#region src/models/azure/BinaryOperator.d.ts
|
|
1527
|
+
declare enum BinaryOperator {
|
|
1528
|
+
eq = "eq",
|
|
1529
|
+
ge = "ge",
|
|
1530
|
+
gt = "gt",
|
|
1531
|
+
le = "le",
|
|
1532
|
+
lt = "lt",
|
|
1533
|
+
}
|
|
1534
|
+
//#endregion
|
|
1535
|
+
//#region src/models/shared/Operation.d.ts
|
|
1536
|
+
|
|
1537
|
+
//#endregion
|
|
1538
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/observable-like.d.ts
|
|
1539
|
+
declare global {
|
|
1540
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
|
|
1541
|
+
interface SymbolConstructor {
|
|
1542
|
+
readonly observable: symbol;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
/**
|
|
1547
|
+
@remarks
|
|
1548
|
+
The TC39 observable proposal defines a `closed` property, but some implementations (such as xstream) do not as of 10/08/2021.
|
|
1549
|
+
As well, some guidance on making an `Observable` to not include `closed` property.
|
|
1550
|
+
@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130
|
|
1551
|
+
@see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85
|
|
1552
|
+
@see https://github.com/benlesh/symbol-observable#making-an-object-observable
|
|
1553
|
+
|
|
1554
|
+
@category Observable
|
|
1555
|
+
*/
|
|
1556
|
+
|
|
1557
|
+
//#endregion
|
|
1558
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/optional-keys-of.d.ts
|
|
1559
|
+
/**
|
|
1560
|
+
Extract all optional keys from the given type.
|
|
1561
|
+
|
|
1562
|
+
This is useful when you want to create a new type that contains different type values for the optional keys only.
|
|
1563
|
+
|
|
1564
|
+
@example
|
|
1565
|
+
```
|
|
1566
|
+
import type {OptionalKeysOf, Except} from 'type-fest';
|
|
1567
|
+
|
|
1568
|
+
interface User {
|
|
1569
|
+
name: string;
|
|
1570
|
+
surname: string;
|
|
1571
|
+
|
|
1572
|
+
luckyNumber?: number;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
const REMOVE_FIELD = Symbol('remove field symbol');
|
|
1576
|
+
type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
|
|
1577
|
+
[Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
const update1: UpdateOperation<User> = {
|
|
1581
|
+
name: 'Alice'
|
|
1582
|
+
};
|
|
1583
|
+
|
|
1584
|
+
const update2: UpdateOperation<User> = {
|
|
1585
|
+
name: 'Bob',
|
|
1586
|
+
luckyNumber: REMOVE_FIELD
|
|
1587
|
+
};
|
|
1588
|
+
```
|
|
1589
|
+
|
|
1590
|
+
@category Utilities
|
|
1591
|
+
*/
|
|
1592
|
+
//#endregion
|
|
1593
|
+
//#region src/models/tableFilter/Clause.d.ts
|
|
1594
|
+
interface Clause {
|
|
1595
|
+
key: string;
|
|
1596
|
+
operator: BinaryOperator;
|
|
1597
|
+
value: string;
|
|
1598
|
+
}
|
|
1599
|
+
//#endregion
|
|
1600
|
+
//#region src/util/tableFilter/applyTableFilter.d.ts
|
|
1601
|
+
declare const applyTableFilter: <T extends object>(entities: TableEntity<T>[], filter: string) => TableEntity<T>[];
|
|
1602
|
+
//#endregion
|
|
1603
|
+
//#region src/util/tableFilter/compare.d.ts
|
|
1604
|
+
declare const compare: (operator: BinaryOperator, leftHandSide: string, rightHandSide: string) => boolean;
|
|
1605
|
+
//#endregion
|
|
1606
|
+
//#region src/util/tableFilter/constants.d.ts
|
|
1607
|
+
declare const CLAUSE_REGEX: RegExp;
|
|
1608
|
+
//#endregion
|
|
1609
|
+
//#region src/util/tableFilter/createTableFilterPredicate.d.ts
|
|
1610
|
+
declare const createTableFilterPredicate: <T extends object>(filter: string) => ((entity: TableEntity<T>) => boolean);
|
|
1611
|
+
//#endregion
|
|
1612
|
+
//#region src/util/tableFilter/parseClause.d.ts
|
|
1613
|
+
declare const parseClause: (rawClause: string) => Clause;
|
|
1614
|
+
//#endregion
|
|
1615
|
+
export { BlobHierarchyItem, CLAUSE_REGEX, Clause, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockRestError, MockTableClient, MockTableDatabase, PageSettings, PagedAsyncIterableIterator, applyTableFilter, bodyToBuffer, compare, createTableFilterPredicate, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, isReadableStream, parseClause, toWebResourceLike };
|
package/dist/index.js
CHANGED
|
@@ -5,12 +5,26 @@ const MockContainerDatabase = /* @__PURE__ */ new Map();
|
|
|
5
5
|
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region ../shared/dist/index.js
|
|
8
|
+
let BinaryOperator = /* @__PURE__ */ function(BinaryOperator$1) {
|
|
9
|
+
BinaryOperator$1["eq"] = "eq";
|
|
10
|
+
BinaryOperator$1["ge"] = "ge";
|
|
11
|
+
BinaryOperator$1["gt"] = "gt";
|
|
12
|
+
BinaryOperator$1["le"] = "le";
|
|
13
|
+
BinaryOperator$1["lt"] = "lt";
|
|
14
|
+
return BinaryOperator$1;
|
|
15
|
+
}({});
|
|
8
16
|
var InvalidOperationError = class extends Error {
|
|
9
17
|
constructor(operation, name, message) {
|
|
10
18
|
super(`Invalid operation: ${operation}, name: ${name}, ${message}`);
|
|
11
19
|
this.name = "InvalidOperationError";
|
|
12
20
|
}
|
|
13
21
|
};
|
|
22
|
+
var NotFoundError = class extends Error {
|
|
23
|
+
constructor(name, id) {
|
|
24
|
+
super(`${name} is not found for id: ${id}`);
|
|
25
|
+
this.name = "NotFoundError";
|
|
26
|
+
}
|
|
27
|
+
};
|
|
14
28
|
let Operation = /* @__PURE__ */ function(Operation$1) {
|
|
15
29
|
Operation$1["Create"] = "Create";
|
|
16
30
|
Operation$1["Delete"] = "Delete";
|
|
@@ -29,6 +43,7 @@ const streamToText = async (readable) => {
|
|
|
29
43
|
for await (const chunk of readable) data += chunk.toString();
|
|
30
44
|
return data;
|
|
31
45
|
};
|
|
46
|
+
const uncapitalize = (string) => `${string.charAt(0).toLowerCase()}${string.slice(1)}`;
|
|
32
47
|
const exhaustiveGuard = (value) => {
|
|
33
48
|
throw new InvalidOperationError(Operation.Read, exhaustiveGuard.name, JSON.stringify(value));
|
|
34
49
|
};
|
|
@@ -1111,6 +1126,72 @@ var MockContainerClient = class {
|
|
|
1111
1126
|
//#region src/store/MockTableDatabase.ts
|
|
1112
1127
|
const MockTableDatabase = /* @__PURE__ */ new Map();
|
|
1113
1128
|
|
|
1129
|
+
//#endregion
|
|
1130
|
+
//#region src/util/tableFilter/compare.ts
|
|
1131
|
+
const compare = (operator, leftHandSide, rightHandSide) => {
|
|
1132
|
+
switch (operator) {
|
|
1133
|
+
case BinaryOperator.eq: return leftHandSide === rightHandSide;
|
|
1134
|
+
case BinaryOperator.ge: return leftHandSide >= rightHandSide;
|
|
1135
|
+
case BinaryOperator.gt: return leftHandSide > rightHandSide;
|
|
1136
|
+
case BinaryOperator.le: return leftHandSide <= rightHandSide;
|
|
1137
|
+
case BinaryOperator.lt: return leftHandSide < rightHandSide;
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
//#endregion
|
|
1142
|
+
//#region src/util/tableFilter/constants.ts
|
|
1143
|
+
const CLAUSE_REGEX = /^(?<key>[A-Za-z0-9_]+)\s+(?<operator>eq|gt|ge|lt|le)\s+'(?<value>[^']+)'$/i;
|
|
1144
|
+
|
|
1145
|
+
//#endregion
|
|
1146
|
+
//#region src/util/tableFilter/parseClause.ts
|
|
1147
|
+
const parseClause = (rawClause) => {
|
|
1148
|
+
const match = CLAUSE_REGEX.exec(rawClause.trim());
|
|
1149
|
+
if (!match) throw new NotFoundError(parseClause.name, rawClause);
|
|
1150
|
+
const groups = match.groups;
|
|
1151
|
+
if (!groups) throw new NotFoundError(parseClause.name, rawClause);
|
|
1152
|
+
const { key, operator, value } = groups;
|
|
1153
|
+
return {
|
|
1154
|
+
key,
|
|
1155
|
+
operator,
|
|
1156
|
+
value
|
|
1157
|
+
};
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
//#endregion
|
|
1161
|
+
//#region src/util/tableFilter/createTableFilterPredicate.ts
|
|
1162
|
+
const createTableFilterPredicate = (filter) => {
|
|
1163
|
+
const normalizedFilter = filter.replaceAll(String.raw`(`, "").replaceAll(String.raw`)`, "");
|
|
1164
|
+
const andGroups = normalizedFilter.split(/\s+and\s+/i).filter(Boolean);
|
|
1165
|
+
const orGroups = andGroups.map((group) => group.split(/\s+or\s+/i).filter(Boolean));
|
|
1166
|
+
return (entity) => {
|
|
1167
|
+
for (const group of orGroups) {
|
|
1168
|
+
let isGroupMatched = false;
|
|
1169
|
+
for (const rawClause of group) {
|
|
1170
|
+
const clause = parseClause(rawClause);
|
|
1171
|
+
const normalizedClauseKey = uncapitalize(clause.key);
|
|
1172
|
+
if (!(normalizedClauseKey in entity)) throw new NotFoundError(createTableFilterPredicate.name, JSON.stringify({
|
|
1173
|
+
entity,
|
|
1174
|
+
filter,
|
|
1175
|
+
key: normalizedClauseKey
|
|
1176
|
+
}));
|
|
1177
|
+
if (compare(clause.operator, String(entity[normalizedClauseKey]), clause.value)) {
|
|
1178
|
+
isGroupMatched = true;
|
|
1179
|
+
break;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
if (!isGroupMatched) return false;
|
|
1183
|
+
}
|
|
1184
|
+
return true;
|
|
1185
|
+
};
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
//#endregion
|
|
1189
|
+
//#region src/util/tableFilter/applyTableFilter.ts
|
|
1190
|
+
const applyTableFilter = (entities, filter) => {
|
|
1191
|
+
const predicate = createTableFilterPredicate(filter);
|
|
1192
|
+
return entities.filter(predicate);
|
|
1193
|
+
};
|
|
1194
|
+
|
|
1114
1195
|
//#endregion
|
|
1115
1196
|
//#region src/models/MockTableClient.ts
|
|
1116
1197
|
/**
|
|
@@ -1170,16 +1251,19 @@ var MockTableClient = class {
|
|
|
1170
1251
|
etag: this.getEtag()
|
|
1171
1252
|
});
|
|
1172
1253
|
}
|
|
1173
|
-
listEntities() {
|
|
1254
|
+
listEntities(options) {
|
|
1174
1255
|
const withMetadata = this.withMetadata.bind(this);
|
|
1256
|
+
const filter = options?.queryOptions?.filter;
|
|
1257
|
+
const tableEntities = [...this.table.values()];
|
|
1258
|
+
const resultTableEntities = filter ? applyTableFilter(tableEntities, filter) : tableEntities;
|
|
1175
1259
|
return {
|
|
1176
1260
|
byPage: () => (async function* (entities) {
|
|
1177
|
-
const allEntitiesWithMetadata =
|
|
1261
|
+
const allEntitiesWithMetadata = entities.map(withMetadata);
|
|
1178
1262
|
if (allEntitiesWithMetadata.length > 0) yield await Promise.resolve(allEntitiesWithMetadata);
|
|
1179
|
-
})(
|
|
1263
|
+
})(resultTableEntities),
|
|
1180
1264
|
next: () => (async function* (entities) {
|
|
1181
|
-
for (const entity of entities
|
|
1182
|
-
})(
|
|
1265
|
+
for (const entity of entities) yield await Promise.resolve(withMetadata(entity));
|
|
1266
|
+
})(resultTableEntities).next(),
|
|
1183
1267
|
[Symbol.asyncIterator]() {
|
|
1184
1268
|
return this;
|
|
1185
1269
|
}
|
|
@@ -1237,4 +1321,4 @@ var MockTableClient = class {
|
|
|
1237
1321
|
};
|
|
1238
1322
|
|
|
1239
1323
|
//#endregion
|
|
1240
|
-
export { MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockRestError, MockTableClient, MockTableDatabase, bodyToBuffer, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, isReadableStream, toWebResourceLike };
|
|
1324
|
+
export { CLAUSE_REGEX, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockRestError, MockTableClient, MockTableDatabase, applyTableFilter, bodyToBuffer, compare, createTableFilterPredicate, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, isReadableStream, parseClause, toWebResourceLike };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "azure-mock",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "A library that contains azure mock classes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/Esposter/Esposter#readme",
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "pnpm export:gen && rolldown --config rolldown.config.ts",
|
|
26
|
+
"test": "NODE_OPTIONS=--max-old-space-size=8192 vitest",
|
|
27
|
+
"coverage": "vitest run --coverage",
|
|
26
28
|
"lint": "oxlint && eslint .",
|
|
27
29
|
"lint:fix": "oxlint --fix && eslint --fix .",
|
|
28
30
|
"typecheck": "tsc",
|
|
@@ -34,5 +36,5 @@
|
|
|
34
36
|
"@azure/data-tables": "^13.3.1",
|
|
35
37
|
"@azure/storage-blob": "^12.28.0"
|
|
36
38
|
},
|
|
37
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "e3d27b0dd40f23eebc5236a975406d0ada8e66c4"
|
|
38
40
|
}
|