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 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
- export { BlobHierarchyItem, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockRestError, MockTableClient, MockTableDatabase, PageSettings, PagedAsyncIterableIterator, bodyToBuffer, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, isReadableStream, toWebResourceLike };
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 = [...entities.values()].map(withMetadata);
1261
+ const allEntitiesWithMetadata = entities.map(withMetadata);
1178
1262
  if (allEntitiesWithMetadata.length > 0) yield await Promise.resolve(allEntitiesWithMetadata);
1179
- })(this.table),
1263
+ })(resultTableEntities),
1180
1264
  next: () => (async function* (entities) {
1181
- for (const entity of entities.values()) yield await Promise.resolve(withMetadata(entity));
1182
- })(this.table).next(),
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.10.0",
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": "ccf4ffe4c50cf43881b91045207eb5814ecf1cd3"
39
+ "gitHead": "e3d27b0dd40f23eebc5236a975406d0ada8e66c4"
38
40
  }