azure-mock 2.34.1 → 2.35.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,9 +1,10 @@
1
+ import { HttpHeadersLike, WebResourceLike } from "@azure/core-http-compat";
1
2
  import { MapValue } from "@esposter/shared";
2
- import { WebResourceLike } from "@azure/core-http-compat";
3
3
  import { PipelineRequest } from "@azure/core-rest-pipeline";
4
4
  import { AnonymousCredential, AppendBlobClient, BlobAbortCopyFromURLResponse, BlobBatchClient, BlobBatchDeleteBlobsResponse, BlobBeginCopyFromURLResponse, BlobClient, BlobCopyFromURLResponse, BlobCreateSnapshotResponse, BlobDeleteIfExistsResponse, BlobDeleteImmutabilityPolicyResponse, BlobDeleteOptions, BlobDeleteResponse, BlobDownloadResponseModel, BlobDownloadResponseParsed, BlobGenerateSasUrlOptions, 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, ContainerGenerateSasUrlOptions, ContainerGetAccessPolicyResponse, ContainerGetAccountInfoResponse, ContainerGetPropertiesResponse, ContainerListBlobFlatSegmentResponse, ContainerListBlobHierarchySegmentResponse, ContainerListBlobsOptions, ContainerSetAccessPolicyResponse, ContainerSetMetadataResponse, FilterBlobItem, HttpRequestBody, PageBlobClient, PollOperationState, PollerLikeWithCancellation, StorageSharedKeyCredential } from "@azure/storage-blob";
5
5
  import { BinaryOperator, Clause } from "@esposter/db-schema";
6
6
  import { EventGridEvent, EventGridPublisherClient } from "@azure/eventgrid";
7
+ import { ServiceBusMessage, ServiceBusMessageBatch, ServiceBusSender } from "@azure/service-bus";
7
8
  import { CreateTableEntityResponse, GetAccessPolicyResponse, GetTableEntityResponse, ListTableEntitiesOptions, TableClient, TableDeleteEntityHeaders, TableEntity, TableEntityResult, TableEntityResultPage, TableMergeEntityHeaders, TableSetAccessPolicyHeaders, TableTransactionResponse, UpdateMode } from "@azure/data-tables";
8
9
  import { QueueClearMessagesResponse, QueueClient, QueueCreateIfNotExistsResponse, QueueCreateOptions, QueueCreateResponse, QueueDeleteIfExistsResponse, QueueDeleteMessageResponse, QueueDeleteResponse, QueueGenerateSasUrlOptions, QueueGetAccessPolicyResponse, QueueGetPropertiesResponse, QueueItem, QueuePeekMessagesOptions, QueuePeekMessagesResponse, QueueReceiveMessageOptions, QueueReceiveMessageResponse, QueueSendMessageOptions, QueueSendMessageResponse, QueueServiceProperties, QueueSetAccessPolicyResponse, QueueSetMetadataResponse, QueueUpdateMessageResponse, SignedIdentifier } from "@azure/storage-queue";
9
10
  import { AutocompleteResult, CountDocumentsOptions, DeleteDocumentsOptions, GetDocumentOptions, IndexDocumentsBatch, IndexDocumentsOptions, IndexDocumentsResult, MergeDocumentsOptions, MergeOrUploadDocumentsOptions, NarrowedModel, SearchClient, SearchDocumentsResult, SearchOptions, SelectFields, SuggestDocumentsResult, SuggestOptions, UploadDocumentsOptions } from "@azure/search-documents";
@@ -11,6 +12,12 @@ declare const MOCK_BLOB_BASE_URL = "https://mockaccount.blob.core.windows.net";
11
12
  declare const MOCK_QUEUE_BASE_URL = "https://mockaccount.queue.core.windows.net";
12
13
  declare const MOCK_SEARCH_BASE_URL = "https://mockaccount.search.windows.net";
13
14
  declare const MOCK_TABLE_BASE_URL = "https://mockaccount.table.core.windows.net";
15
+ interface MockResponse {
16
+ headers: HttpHeadersLike;
17
+ parsedHeaders: Record<string, never>;
18
+ request: WebResourceLike;
19
+ status: number;
20
+ }
14
21
  declare class MockRestError extends Error {
15
22
  statusCode: number;
16
23
  constructor(message: string, statusCode: number);
@@ -45,10 +52,15 @@ interface PagedAsyncIterableIterator<TElement, TPage = TElement[], TPageSettings
45
52
  */
46
53
  next: () => Promise<IteratorResult<TElement>>;
47
54
  }
55
+ declare const createMockResponse: (status: number, url?: string) => MockResponse;
56
+ declare const getMockSasUrl: (url: string, permissions: undefined | {
57
+ toString: () => string;
58
+ }, resourceType?: string) => string;
48
59
  declare const MockContainerDatabase: Map<string, Map<string, Buffer>>;
49
60
  declare const MockEventGridDatabase: Map<string, EventGridEvent<unknown>[]>;
50
61
  declare const MockQueueDatabase: Map<string, string[]>;
51
62
  declare const MockSearchDatabase: Map<string, object[]>;
63
+ declare const MockServiceBusDatabase: Map<string, ServiceBusMessage[]>;
52
64
  declare const MockTableDatabase: Map<string, Map<string, TableEntity>>;
53
65
  type BlobHierarchyItem = (BlobItem & {
54
66
  kind: "blob";
@@ -171,8 +183,8 @@ const update2: UpdateOperation<User> = {
171
183
  @category Utilities
172
184
  */
173
185
  type OptionalKeysOf<Type extends object> = Type extends unknown // For distributing `Type`
174
- ? (keyof { [Key in keyof Type as IsOptionalKeyOf<Type, Key> extends false ? never : Key]: never }) & keyof Type // Intersect with `keyof Type` to ensure result of `OptionalKeysOf<Type>` is always assignable to `keyof Type`
175
- : never;
186
+ ? (keyof { [Key in keyof Type as IsOptionalKeyOf<Type, Key> extends false ? never : Key]: never; }) & keyof Type // Intersect with `keyof Type` to ensure result of `OptionalKeysOf<Type>` is always assignable to `keyof Type`
187
+ : never; // Should never happen
176
188
  /**
177
189
  Extract all required keys from the given type.
178
190
 
@@ -204,7 +216,7 @@ const validator3 = createValidation<User>('luckyNumber', value => value > 0);
204
216
  @category Utilities
205
217
  */
206
218
  type RequiredKeysOf<Type extends object> = Type extends unknown // For distributing `Type`
207
- ? Exclude<keyof Type, OptionalKeysOf<Type>> : never;
219
+ ? Exclude<keyof Type, OptionalKeysOf<Type>> : never; // Should never happen
208
220
  /**
209
221
  Returns a boolean for whether the given type is `never`.
210
222
 
@@ -410,7 +422,7 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
410
422
  @see {@link SimplifyDeep}
411
423
  @category Object
412
424
  */
413
- type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
425
+ type Simplify<T> = { [KeyType in keyof T]: T[KeyType]; } & {};
414
426
  /**
415
427
  Returns a boolean for whether the two given types are equal.
416
428
 
@@ -531,7 +543,7 @@ type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
531
543
  @see {@link PickIndexSignature}
532
544
  @category Object
533
545
  */
534
- type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType] };
546
+ type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType]; };
535
547
  /**
536
548
  Pick only index signatures from the given object type, leaving out all explicitly defined properties.
537
549
 
@@ -577,9 +589,9 @@ type ExampleIndexSignature = PickIndexSignature<Example>;
577
589
  @see {@link OmitIndexSignature}
578
590
  @category Object
579
591
  */
580
- type PickIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType] };
592
+ type PickIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType]; };
581
593
  // Merges two objects without worrying about index signatures.
582
- type SimpleMerge<Destination, Source> = Simplify<{ [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key] } & Source>;
594
+ type SimpleMerge<Destination, Source> = Simplify<{ [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key]; } & Source>;
583
595
  /**
584
596
  Merge two types into a new type. Keys of the second type overrides keys of the first type.
585
597
 
@@ -643,10 +655,9 @@ Note: If you want a merge type that more accurately reflects the runtime behavio
643
655
  @category Object
644
656
  */
645
657
  type Merge<Destination, Source> = Destination extends unknown // For distributing `Destination`
646
- ? Source extends unknown // For distributing `Source`
647
- ? If<IsEqual<Destination, Source>, Destination, _Merge<Destination, Source>> : never // Should never happen
648
- : never;
649
- // Should never happen
658
+ ? Source extends unknown // For distributing `Source`
659
+ ? If<IsEqual<Destination, Source>, Destination, _Merge<Destination, Source>> : never // Should never happen
660
+ : never; // Should never happen
650
661
  type _Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
651
662
  /**
652
663
  Merges user specified options with default options.
@@ -700,36 +711,9 @@ type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOp
700
711
  // Types of property 'leavesOnly' are incompatible. Type 'string' is not assignable to type 'boolean'.
701
712
  ```
702
713
  */
703
- type ApplyDefaultOptions<Options extends object, Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>, SpecifiedOptions extends Options> = _ApplyDefaultOptions<Options, Defaults, SpecifiedOptions> extends infer Result extends Required<Options> // `extends Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
704
- ? Result : never;
705
- type _ApplyDefaultOptions<Options, Defaults, SpecifiedOptions> = If<IsAny<SpecifiedOptions>, Defaults, If<IsNever<SpecifiedOptions>, Defaults, Merge<Defaults, { [Key in keyof SpecifiedOptions as undefined extends Required<Options>[Key & keyof Options] ? Key : undefined extends SpecifiedOptions[Key] ? never : Key]: SpecifiedOptions[Key] }>>>;
706
- /**
707
- Collapses literal types in a union into their corresponding primitive types, when possible. For example, `CollapseLiterals<'foo' | 'bar' | (string & {})>` returns `string`.
708
-
709
- Note: This doesn't collapse literals within tagged types. For example, `CollapseLiterals<Tagged<'foo' | (string & {}), 'Tag'>>` returns `("foo" & Tag<"Tag", never>) | (string & Tag<"Tag", never>)` and not `string & Tag<"Tag", never>`.
710
-
711
- Use-case: For collapsing unions created using {@link LiteralUnion}.
712
-
713
- @example
714
- ```
715
- import type {LiteralUnion} from 'type-fest';
716
-
717
- type A = CollapseLiterals<'foo' | 'bar' | (string & {})>;
718
- //=> string
719
-
720
- type B = CollapseLiterals<LiteralUnion<1 | 2 | 3, number>>;
721
- //=> number
722
-
723
- type C = CollapseLiterals<LiteralUnion<'onClick' | 'onChange', `on${string}`>>;
724
- //=> `on${string}`
725
-
726
- type D = CollapseLiterals<'click' | 'change' | (`on${string}` & {})>;
727
- //=> 'click' | 'change' | `on${string}`
728
-
729
- type E = CollapseLiterals<LiteralUnion<'foo' | 'bar', string> | null | undefined>;
730
- //=> string | null | undefined
731
- ```
732
- */
714
+ type ApplyDefaultOptions<Options extends object, Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>, SpecifiedOptions extends Options> = _ApplyDefaultOptions<Options, Defaults, SpecifiedOptions> extends (infer Result extends Required<Options> // `extends Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
715
+ ) ? Result : never;
716
+ type _ApplyDefaultOptions<Options, Defaults, SpecifiedOptions> = If<IsAny<SpecifiedOptions>, Defaults, If<IsNever<SpecifiedOptions>, Defaults, Merge<Defaults, { [Key in keyof SpecifiedOptions as undefined extends Required<Options>[Key & keyof Options] ? Key : undefined extends SpecifiedOptions[Key] ? never : Key]: SpecifiedOptions[Key]; }>>>;
733
717
  /**
734
718
  Filter out keys from an object.
735
719
 
@@ -760,10 +744,12 @@ type Filtered = Filter<'bar', 'foo'>;
760
744
  type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType);
761
745
  type ExceptOptions = {
762
746
  /**
763
- Disallow assigning non-specified properties.
764
- Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`.
765
- @default false
766
- */
747
+ Disallow assigning non-specified properties.
748
+
749
+ Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`.
750
+
751
+ @default false
752
+ */
767
753
  requireExactProps?: boolean;
768
754
  };
769
755
  type DefaultExceptOptions = {
@@ -825,7 +811,7 @@ type PostPayloadFixed = Except<UserData, 'email'>;
825
811
  @category Object
826
812
  */
827
813
  type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {}> = _Except<ObjectType, KeysType, ApplyDefaultOptions<ExceptOptions, DefaultExceptOptions, Options>>;
828
- type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = { [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType] } & (Options['requireExactProps'] extends true ? Partial<Record<KeysType, never>> : {});
814
+ type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = { [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType]; } & (Options['requireExactProps'] extends true ? Partial<Record<KeysType, never>> : {});
829
815
  declare class MockBlobClient implements Except<BlobClient, "accountName"> {
830
816
  connectionString: string;
831
817
  containerName: string;
@@ -1004,6 +990,26 @@ declare class MockSearchClient<TModel extends object = Record<string, unknown>>
1004
990
  suggest<TFields extends SelectFields<TModel> = never>(_searchText: string, _suggesterName: string, _options?: SuggestOptions<TModel, TFields>): Promise<SuggestDocumentsResult<TModel, TFields>>;
1005
991
  uploadDocuments(documents: TModel[], _options?: UploadDocumentsOptions): Promise<IndexDocumentsResult>;
1006
992
  }
993
+ /**
994
+ * An in-memory mock of the Azure ServiceBusSender.
995
+ * It uses a Map to simulate a Service Bus queue and correctly implements the ServiceBusSender interface.
996
+ *
997
+ * @example
998
+ * const mockServiceBusSender = new MockServiceBusSender("hello world");
999
+ * await mockServiceBusSender.scheduleMessages({ body: "hello world" }, new Date());
1000
+ */
1001
+ declare class MockServiceBusSender implements ServiceBusSender {
1002
+ entityPath: string;
1003
+ identifier: string;
1004
+ isClosed: boolean;
1005
+ get queue(): MapValue<typeof MockServiceBusDatabase>;
1006
+ constructor(queueName: string);
1007
+ cancelScheduledMessages(): Promise<void>;
1008
+ close(): Promise<void>;
1009
+ createMessageBatch(): Promise<ServiceBusMessageBatch>;
1010
+ scheduleMessages(messages: ServiceBusMessage | ServiceBusMessage[], scheduledEnqueueTimeUtc: Date): Promise<never[]>;
1011
+ sendMessages(messages: ServiceBusMessage | ServiceBusMessage[] | ServiceBusMessageBatch): Promise<void>;
1012
+ }
1007
1013
  /**
1008
1014
  * An in-memory mock of the Azure TableClient.
1009
1015
  * It uses a Map to simulate table storage and correctly implements the TableClient interface.
@@ -1049,10 +1055,7 @@ declare const bodyToBuffer: (body: HttpRequestBody) => Promise<Buffer>;
1049
1055
  * @returns A formatted XML string.
1050
1056
  */
1051
1057
  declare const getAzureErrorXml: (errorCode: string, errorMessage: string) => string;
1052
- declare const getBlobItemXml: ({
1053
- name,
1054
- properties
1055
- }: BlobItem) => string;
1058
+ declare const getBlobItemXml: ({ name, properties }: BlobItem) => string;
1056
1059
  declare const getBlobPrefixXml: (name: string) => string;
1057
1060
  /**
1058
1061
  * Generates a standard Azure Storage list blobs XML response body.
@@ -1067,4 +1070,4 @@ declare const applyFilter: <T extends Record<string, unknown>>(documents: T[], c
1067
1070
  declare const compare: <T>(operator: BinaryOperator, leftHandSide: T, rightHandSide: null | T) => boolean;
1068
1071
  declare const createFilterPredicate: (filter: string) => ((document: Record<string, unknown>) => boolean);
1069
1072
  declare const isNullClause: (clause: Clause<Record<string, unknown>>) => boolean;
1070
- export { BlobHierarchyItem, MOCK_BLOB_BASE_URL, MOCK_QUEUE_BASE_URL, MOCK_SEARCH_BASE_URL, MOCK_TABLE_BASE_URL, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockEventGridDatabase, MockEventGridPublisherClient, MockQueueClient, MockQueueDatabase, MockRestError, MockSearchClient, MockSearchDatabase, MockTableClient, MockTableDatabase, MockWebPubSubServiceClient, PageSettings, PagedAsyncIterableIterator, applyFilter, bodyToBuffer, compare, createFilterPredicate, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, isNullClause, isReadableStream, toWebResourceLike };
1073
+ export { BlobHierarchyItem, MOCK_BLOB_BASE_URL, MOCK_QUEUE_BASE_URL, MOCK_SEARCH_BASE_URL, MOCK_TABLE_BASE_URL, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockEventGridDatabase, MockEventGridPublisherClient, MockQueueClient, MockQueueDatabase, MockResponse, MockRestError, MockSearchClient, MockSearchDatabase, MockServiceBusDatabase, MockServiceBusSender, MockTableClient, MockTableDatabase, MockWebPubSubServiceClient, PageSettings, PagedAsyncIterableIterator, applyFilter, bodyToBuffer, compare, createFilterPredicate, createMockResponse, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, getMockSasUrl, isNullClause, isReadableStream, toWebResourceLike };
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { ID_SEPARATOR, InvalidOperationError, Operation, exhaustiveGuard, getResultAsync, html, noop, streamToText, takeOne } from "@esposter/shared";
2
1
  import { toHttpHeadersLike } from "@azure/core-http-compat";
2
+ import { ID_SEPARATOR, InvalidOperationError, Operation, exhaustiveGuard, getOrCreate, getResultAsync, html, noop, streamToText, takeOne } from "@esposter/shared";
3
3
  import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
4
4
  import { AnonymousCredential } from "@azure/storage-blob";
5
5
  import { Readable } from "node:stream";
6
6
  import { MAX_QUEUE_VISIBILITY_TIMEOUT_MS, deserializeClause, deserializeKey, getTableNullClause, serializeClauses } from "@esposter/db";
7
- import { BinaryOperator } from "@esposter/db-schema";
7
+ import { AZURE_MAX_PAGE_SIZE, BinaryOperator } from "@esposter/db-schema";
8
8
  var __create = Object.create;
9
9
  var __defProp = Object.defineProperty;
10
10
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -38,22 +38,6 @@ var MockRestError = class extends Error {
38
38
  this.statusCode = statusCode;
39
39
  }
40
40
  };
41
- const MockContainerDatabase = /* @__PURE__ */ new Map();
42
- const MockEventGridDatabase = /* @__PURE__ */ new Map();
43
- const MockQueueDatabase = /* @__PURE__ */ new Map();
44
- const MockSearchDatabase = /* @__PURE__ */ new Map();
45
- const MockTableDatabase = /* @__PURE__ */ new Map();
46
- /**
47
- * Generates a standard Azure Storage error XML response body.
48
- * @param errorCode The official Azure error code (e.g., "BlobNotFound").
49
- * @param errorMessage The user-friendly error message.
50
- * @returns A formatted XML string.
51
- */
52
- const getAzureErrorXml = (errorCode, errorMessage) => html`<?xml version="1.0" encoding="utf-8"?>
53
- <Error>
54
- <code>${errorCode}</code>
55
- <Message>${errorMessage}</Message>
56
- </Error>`;
57
41
  const toWebResourceLike = (request) => ({
58
42
  abortSignal: request.abortSignal,
59
43
  agent: request.agent,
@@ -79,6 +63,30 @@ const toWebResourceLike = (request) => ({
79
63
  validateRequestProperties: noop,
80
64
  withCredentials: request.withCredentials
81
65
  });
66
+ const createMockResponse = (status, url = "") => ({
67
+ headers: toHttpHeadersLike(createHttpHeaders()),
68
+ parsedHeaders: {},
69
+ request: toWebResourceLike(createPipelineRequest({ url })),
70
+ status
71
+ });
72
+ const getMockSasUrl = (url, permissions, resourceType) => `${url}?sv=2025-11-05&${resourceType ? `sr=${resourceType}&` : ""}sig=mock-signature&st=1970-01-01T00:00:00Z&se=2099-12-31T23:59:59Z&sp=${permissions?.toString() ?? "r"}`;
73
+ const MockContainerDatabase = /* @__PURE__ */ new Map();
74
+ const MockEventGridDatabase = /* @__PURE__ */ new Map();
75
+ const MockQueueDatabase = /* @__PURE__ */ new Map();
76
+ const MockSearchDatabase = /* @__PURE__ */ new Map();
77
+ const MockServiceBusDatabase = /* @__PURE__ */ new Map();
78
+ const MockTableDatabase = /* @__PURE__ */ new Map();
79
+ /**
80
+ * Generates a standard Azure Storage error XML response body.
81
+ * @param errorCode The official Azure error code (e.g., "BlobNotFound").
82
+ * @param errorMessage The user-friendly error message.
83
+ * @returns A formatted XML string.
84
+ */
85
+ const getAzureErrorXml = (errorCode, errorMessage) => html`<?xml version="1.0" encoding="utf-8"?>
86
+ <Error>
87
+ <code>${errorCode}</code>
88
+ <Message>${errorMessage}</Message>
89
+ </Error>`;
82
90
  var MockBlobBatchClient = class {
83
91
  url;
84
92
  constructor(url) {
@@ -111,6 +119,7 @@ var MockBlobBatchClient = class {
111
119
  statusMessage
112
120
  });
113
121
  subResponsesFailedCount++;
122
+ continue;
114
123
  }
115
124
  const containerName = takeOne(pathSegments);
116
125
  const blobName = pathSegments.slice(1).join("/");
@@ -146,13 +155,11 @@ var MockBlobBatchClient = class {
146
155
  }
147
156
  return Promise.resolve({
148
157
  _response: {
158
+ ...createMockResponse(202, this.url),
149
159
  headers: toHttpHeadersLike(createHttpHeaders({
150
160
  "content-type": "multipart/mixed",
151
161
  "x-ms-request-id": crypto.randomUUID()
152
- })),
153
- parsedHeaders: {},
154
- request: toWebResourceLike(createPipelineRequest({ url: this.url })),
155
- status: 202
162
+ }))
156
163
  },
157
164
  subResponses,
158
165
  subResponsesFailedCount,
@@ -160,12 +167,7 @@ var MockBlobBatchClient = class {
160
167
  });
161
168
  }
162
169
  getContainer(containerName) {
163
- let container = MockContainerDatabase.get(containerName);
164
- if (!container) {
165
- container = /* @__PURE__ */ new Map();
166
- MockContainerDatabase.set(containerName, container);
167
- }
168
- return container;
170
+ return getOrCreate(MockContainerDatabase, containerName, () => /* @__PURE__ */ new Map());
169
171
  }
170
172
  };
171
173
  var MockBlobClient = class {
@@ -175,12 +177,7 @@ var MockBlobClient = class {
175
177
  name;
176
178
  url;
177
179
  get container() {
178
- let container = MockContainerDatabase.get(this.containerName);
179
- if (!container) {
180
- container = /* @__PURE__ */ new Map();
181
- MockContainerDatabase.set(this.containerName, container);
182
- }
183
- return container;
180
+ return getOrCreate(MockContainerDatabase, this.containerName, () => /* @__PURE__ */ new Map());
184
181
  }
185
182
  constructor(connectionString, containerName, blobName) {
186
183
  this.connectionString = connectionString;
@@ -201,12 +198,7 @@ var MockBlobClient = class {
201
198
  const sourceData = sourceContainer.get(sourceBlobName);
202
199
  if (!sourceData) throw new MockRestError("Source blob not found", 404);
203
200
  this.container.set(this.name, Buffer.from(sourceData));
204
- const response = { _response: {
205
- headers: toHttpHeadersLike(createHttpHeaders()),
206
- parsedHeaders: {},
207
- request: toWebResourceLike(createPipelineRequest({ url: `${this.url}?comp=copy` })),
208
- status: 202
209
- } };
201
+ const response = { _response: createMockResponse(202, `${this.url}?comp=copy`) };
210
202
  return Promise.resolve({
211
203
  cancelOperation: () => Promise.resolve(),
212
204
  getOperationState: () => ({
@@ -228,23 +220,13 @@ var MockBlobClient = class {
228
220
  delete() {
229
221
  if (!this.container.has(this.name)) throw new MockRestError("The specified blob does not exist.", 404);
230
222
  this.container.delete(this.name);
231
- return Promise.resolve({ _response: {
232
- headers: toHttpHeadersLike(createHttpHeaders()),
233
- parsedHeaders: {},
234
- request: toWebResourceLike(createPipelineRequest({ url: "" })),
235
- status: 200
236
- } });
223
+ return Promise.resolve({ _response: createMockResponse(200) });
237
224
  }
238
225
  deleteIfExists() {
239
226
  const succeeded = this.container.has(this.name);
240
227
  if (succeeded) this.container.delete(this.name);
241
228
  return Promise.resolve({
242
- _response: {
243
- headers: toHttpHeadersLike(createHttpHeaders()),
244
- parsedHeaders: {},
245
- request: toWebResourceLike(createPipelineRequest({ url: "" })),
246
- status: succeeded ? 200 : 404
247
- },
229
+ _response: createMockResponse(succeeded ? 200 : 404),
248
230
  succeeded
249
231
  });
250
232
  }
@@ -254,12 +236,7 @@ var MockBlobClient = class {
254
236
  download() {
255
237
  const buffer = this.container.get(this.name);
256
238
  return Promise.resolve({
257
- _response: {
258
- headers: toHttpHeadersLike(createHttpHeaders()),
259
- parsedHeaders: {},
260
- request: toWebResourceLike(createPipelineRequest({ url: "" })),
261
- status: buffer ? 200 : 404
262
- },
239
+ _response: createMockResponse(buffer ? 200 : 404),
263
240
  readableStreamBody: buffer ? Readable.from(buffer) : void 0
264
241
  });
265
242
  }
@@ -278,8 +255,7 @@ var MockBlobClient = class {
278
255
  throw new Error("Method not implemented.");
279
256
  }
280
257
  generateSasUrl(options) {
281
- const sp = options.permissions?.toString() ?? "r";
282
- return Promise.resolve(`${MOCK_BLOB_BASE_URL}/${this.containerName}/${this.name}?sv=2025-11-05&sr=b&sig=mock-signature&st=1970-01-01T00:00:00Z&se=2099-12-31T23:59:59Z&sp=${sp}`);
258
+ return Promise.resolve(getMockSasUrl(this.url, options.permissions, "b"));
283
259
  }
284
260
  generateUserDelegationSasStringToSign() {
285
261
  throw new Error("Method not implemented.");
@@ -388,12 +364,7 @@ var MockBlockBlobClient = class extends MockBlobClient {
388
364
  }
389
365
  async upload(body, _contentLength) {
390
366
  this.container.set(this.name, await bodyToBuffer(body));
391
- return { _response: {
392
- headers: toHttpHeadersLike(createHttpHeaders()),
393
- parsedHeaders: {},
394
- request: toWebResourceLike(createPipelineRequest({ url: "" })),
395
- status: 201
396
- } };
367
+ return { _response: createMockResponse(201) };
397
368
  }
398
369
  uploadBrowserData() {
399
370
  throw new Error("Method not implemented.");
@@ -448,12 +419,7 @@ var MockContainerClient = class {
448
419
  credential = new AnonymousCredential();
449
420
  url;
450
421
  get container() {
451
- let container = MockContainerDatabase.get(this.containerName);
452
- if (!container) {
453
- container = /* @__PURE__ */ new Map();
454
- MockContainerDatabase.set(this.containerName, container);
455
- }
456
- return container;
422
+ return getOrCreate(MockContainerDatabase, this.containerName, () => /* @__PURE__ */ new Map());
457
423
  }
458
424
  constructor(connectionString, containerName) {
459
425
  this.connectionString = connectionString;
@@ -472,12 +438,7 @@ var MockContainerClient = class {
472
438
  deleteBlob(blobName) {
473
439
  if (!this.container.has(blobName)) throw new MockRestError("The specified blob does not exist.", 404);
474
440
  this.container.delete(blobName);
475
- return Promise.resolve({ _response: {
476
- headers: toHttpHeadersLike(createHttpHeaders()),
477
- parsedHeaders: {},
478
- request: toWebResourceLike(createPipelineRequest({ url: `${this.url}/${blobName}` })),
479
- status: 200
480
- } });
441
+ return Promise.resolve({ _response: createMockResponse(200, `${this.url}/${blobName}`) });
481
442
  }
482
443
  deleteIfExists() {
483
444
  throw new Error("Method not implemented.");
@@ -492,8 +453,7 @@ var MockContainerClient = class {
492
453
  throw new Error("Method not implemented.");
493
454
  }
494
455
  generateSasUrl(options) {
495
- const sp = options.permissions?.toString() ?? "r";
496
- return Promise.resolve(`${MOCK_BLOB_BASE_URL}/${this.containerName}?sv=2025-11-05&sr=c&sig=mock-signature&st=1970-01-01T00:00:00Z&se=2099-12-31T23:59:59Z&sp=${sp}`);
456
+ return Promise.resolve(getMockSasUrl(this.url, options.permissions, "c"));
497
457
  }
498
458
  generateUserDelegationSasStringToSign() {
499
459
  throw new Error("Method not implemented.");
@@ -545,18 +505,15 @@ var MockContainerClient = class {
545
505
  }
546
506
  if (allBlobItems.length > 0 || allBlobPrefixes.length > 0) yield await Promise.resolve({
547
507
  _response: {
508
+ ...createMockResponse(200),
548
509
  bodyAsText: getListBlobsXml(this.containerName, `${allBlobItemXml.join("")}${allBlobPrefixXml.join("")}`),
549
- headers: toHttpHeadersLike(createHttpHeaders()),
550
510
  parsedBody: {
551
511
  containerName: this.containerName,
552
512
  marker: "",
553
513
  prefix: options?.prefix ?? "",
554
514
  segment: { blobItems: allBlobItems },
555
515
  serviceEndpoint: ""
556
- },
557
- parsedHeaders: {},
558
- request: toWebResourceLike(createPipelineRequest({ url: "" })),
559
- status: 200
516
+ }
560
517
  },
561
518
  containerName: this.containerName,
562
519
  marker: "",
@@ -583,18 +540,15 @@ var MockContainerClient = class {
583
540
  }
584
541
  if (allBlobItems.length > 0) yield await Promise.resolve({
585
542
  _response: {
543
+ ...createMockResponse(200),
586
544
  bodyAsText: getListBlobsXml(this.containerName, allBlobItemXml.join("")),
587
- headers: toHttpHeadersLike(createHttpHeaders()),
588
545
  parsedBody: {
589
546
  containerName: this.containerName,
590
547
  marker: "",
591
548
  prefix: "",
592
549
  segment: { blobItems: allBlobItems },
593
550
  serviceEndpoint: ""
594
- },
595
- parsedHeaders: {},
596
- request: toWebResourceLike(createPipelineRequest({ url: "" })),
597
- status: 200
551
+ }
598
552
  },
599
553
  containerName: this.containerName,
600
554
  marker: "",
@@ -690,9 +644,7 @@ var MockEventGridPublisherClient = class {
690
644
  this.inputSchema = topicType;
691
645
  }
692
646
  send(newEvents) {
693
- const events = MockEventGridDatabase.get(this.endpointUrl) ?? [];
694
- events.push(...newEvents);
695
- MockEventGridDatabase.set(this.endpointUrl, events);
647
+ getOrCreate(MockEventGridDatabase, this.endpointUrl, () => []).push(...newEvents);
696
648
  return Promise.resolve();
697
649
  }
698
650
  };
@@ -711,12 +663,7 @@ var MockQueueClient = class {
711
663
  name;
712
664
  url;
713
665
  get queue() {
714
- let messages = MockQueueDatabase.get(this.name);
715
- if (!messages) {
716
- messages = [];
717
- MockQueueDatabase.set(this.name, messages);
718
- }
719
- return messages;
666
+ return getOrCreate(MockQueueDatabase, this.name, () => []);
720
667
  }
721
668
  constructor(connectionString, queueName) {
722
669
  this.connectionString = connectionString;
@@ -748,8 +695,7 @@ var MockQueueClient = class {
748
695
  throw new Error("Method not implemented.");
749
696
  }
750
697
  generateSasUrl(options) {
751
- const sp = options.permissions?.toString() ?? "r";
752
- return `${MOCK_QUEUE_BASE_URL}/${this.name}?sv=2025-11-05&sig=mock-signature&st=1970-01-01T00:00:00Z&se=2099-12-31T23:59:59Z&sp=${sp}`;
698
+ return getMockSasUrl(this.url, options.permissions);
753
699
  }
754
700
  generateUserDelegationSasUrl() {
755
701
  throw new Error("Method not implemented.");
@@ -779,12 +725,9 @@ var MockQueueClient = class {
779
725
  }));
780
726
  return Promise.resolve({
781
727
  _response: {
728
+ ...createMockResponse(200, this.url),
782
729
  bodyAsText: "",
783
- headers: toHttpHeadersLike(createHttpHeaders()),
784
- parsedBody: peekedMessageItems,
785
- parsedHeaders: {},
786
- request: toWebResourceLike(createPipelineRequest({ url: this.url })),
787
- status: 200
730
+ parsedBody: peekedMessageItems
788
731
  },
789
732
  peekedMessageItems
790
733
  });
@@ -801,12 +744,9 @@ var MockQueueClient = class {
801
744
  }));
802
745
  return Promise.resolve({
803
746
  _response: {
747
+ ...createMockResponse(200, this.url),
804
748
  bodyAsText: "",
805
- headers: toHttpHeadersLike(createHttpHeaders()),
806
- parsedBody: receivedMessageItems,
807
- parsedHeaders: {},
808
- request: toWebResourceLike(createPipelineRequest({ url: this.url })),
809
- status: 200
749
+ parsedBody: receivedMessageItems
810
750
  },
811
751
  receivedMessageItems
812
752
  });
@@ -828,12 +768,9 @@ var MockQueueClient = class {
828
768
  }];
829
769
  return Promise.resolve({
830
770
  _response: {
771
+ ...createMockResponse(200, this.url),
831
772
  bodyAsText: "",
832
- headers: toHttpHeadersLike(createHttpHeaders()),
833
- parsedBody: enqueuedMessages,
834
- parsedHeaders: {},
835
- request: toWebResourceLike(createPipelineRequest({ url: this.url })),
836
- status: 200
773
+ parsedBody: enqueuedMessages
837
774
  },
838
775
  expiresOn,
839
776
  insertedOn,
@@ -973,12 +910,7 @@ var MockSearchClient = class {
973
910
  indexName;
974
911
  serviceVersion = "";
975
912
  get documents() {
976
- let documents = MockSearchDatabase.get(this.indexName);
977
- if (!documents) {
978
- documents = [];
979
- MockSearchDatabase.set(this.indexName, documents);
980
- }
981
- return documents;
913
+ return getOrCreate(MockSearchDatabase, this.indexName, () => []);
982
914
  }
983
915
  constructor(indexName) {
984
916
  this.indexName = indexName;
@@ -1031,6 +963,48 @@ var MockSearchClient = class {
1031
963
  }
1032
964
  };
1033
965
  /**
966
+ * An in-memory mock of the Azure ServiceBusSender.
967
+ * It uses a Map to simulate a Service Bus queue and correctly implements the ServiceBusSender interface.
968
+ *
969
+ * @example
970
+ * const mockServiceBusSender = new MockServiceBusSender("hello world");
971
+ * await mockServiceBusSender.scheduleMessages({ body: "hello world" }, new Date());
972
+ */
973
+ var MockServiceBusSender = class {
974
+ entityPath;
975
+ identifier;
976
+ isClosed = false;
977
+ get queue() {
978
+ return getOrCreate(MockServiceBusDatabase, this.entityPath, () => []);
979
+ }
980
+ constructor(queueName) {
981
+ this.entityPath = queueName;
982
+ this.identifier = queueName;
983
+ }
984
+ cancelScheduledMessages() {
985
+ throw new Error("Method not implemented.");
986
+ }
987
+ close() {
988
+ this.isClosed = true;
989
+ return Promise.resolve();
990
+ }
991
+ createMessageBatch() {
992
+ throw new Error("Method not implemented.");
993
+ }
994
+ scheduleMessages(messages, scheduledEnqueueTimeUtc) {
995
+ for (const message of Array.isArray(messages) ? messages : [messages]) this.queue.push({
996
+ ...message,
997
+ scheduledEnqueueTimeUtc
998
+ });
999
+ return Promise.resolve([]);
1000
+ }
1001
+ sendMessages(messages) {
1002
+ if (!Array.isArray(messages) && "tryAddMessage" in messages) throw new Error("Method not implemented.");
1003
+ this.queue.push(...Array.isArray(messages) ? messages : [messages]);
1004
+ return Promise.resolve();
1005
+ }
1006
+ };
1007
+ /**
1034
1008
  * An in-memory mock of the Azure TableClient.
1035
1009
  * It uses a Map to simulate table storage and correctly implements the TableClient interface.
1036
1010
  *
@@ -1043,12 +1017,7 @@ var MockTableClient = class {
1043
1017
  tableName;
1044
1018
  url;
1045
1019
  get table() {
1046
- let table = MockTableDatabase.get(this.tableName);
1047
- if (!table) {
1048
- table = /* @__PURE__ */ new Map();
1049
- MockTableDatabase.set(this.tableName, table);
1050
- }
1051
- return table;
1020
+ return getOrCreate(MockTableDatabase, this.tableName, () => /* @__PURE__ */ new Map());
1052
1021
  }
1053
1022
  constructor(_url, tableName) {
1054
1023
  this.tableName = tableName;
@@ -1096,6 +1065,7 @@ var MockTableClient = class {
1096
1065
  return {
1097
1066
  byPage: ({ maxPageSize } = {}) => (async function* (entities) {
1098
1067
  if (maxPageSize !== void 0 && maxPageSize <= 0) throw new RangeError("maxPageSize must be greater than 0.");
1068
+ else if (maxPageSize !== void 0 && maxPageSize > AZURE_MAX_PAGE_SIZE) throw new MockRestError("One of the request inputs is not valid.", 400);
1099
1069
  const allEntitiesWithMetadata = entities.map((e) => withMetadata(e));
1100
1070
  if (allEntitiesWithMetadata.length === 0) return;
1101
1071
  else if (!maxPageSize) {
@@ -1209,4 +1179,4 @@ const applyFilter = (documents, clauses) => {
1209
1179
  const predicate = createFilterPredicate(serializeClauses(clauses));
1210
1180
  return documents.filter((document) => predicate(document));
1211
1181
  };
1212
- export { MOCK_BLOB_BASE_URL, MOCK_QUEUE_BASE_URL, MOCK_SEARCH_BASE_URL, MOCK_TABLE_BASE_URL, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockEventGridDatabase, MockEventGridPublisherClient, MockQueueClient, MockQueueDatabase, MockRestError, MockSearchClient, MockSearchDatabase, MockTableClient, MockTableDatabase, MockWebPubSubServiceClient, applyFilter, bodyToBuffer, compare, createFilterPredicate, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, isNullClause, isReadableStream, toWebResourceLike };
1182
+ export { MOCK_BLOB_BASE_URL, MOCK_QUEUE_BASE_URL, MOCK_SEARCH_BASE_URL, MOCK_TABLE_BASE_URL, MockBlobBatchClient, MockBlobClient, MockBlockBlobClient, MockContainerClient, MockContainerDatabase, MockEventGridDatabase, MockEventGridPublisherClient, MockQueueClient, MockQueueDatabase, MockRestError, MockSearchClient, MockSearchDatabase, MockServiceBusDatabase, MockServiceBusSender, MockTableClient, MockTableDatabase, MockWebPubSubServiceClient, applyFilter, bodyToBuffer, compare, createFilterPredicate, createMockResponse, getAzureErrorXml, getBlobItemXml, getBlobPrefixXml, getListBlobsXml, getMockSasUrl, isNullClause, isReadableStream, toWebResourceLike };