@azure/app-configuration 1.3.2-alpha.20220401.1 → 1.4.0-alpha.20220412.2

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +15 -7
  2. package/dist/index.js +175 -423
  3. package/dist/index.js.map +1 -1
  4. package/dist-esm/src/appConfigCredential.js +24 -30
  5. package/dist-esm/src/appConfigCredential.js.map +1 -1
  6. package/dist-esm/src/appConfigurationClient.js +63 -81
  7. package/dist-esm/src/appConfigurationClient.js.map +1 -1
  8. package/dist-esm/src/generated/src/appConfiguration.js +47 -89
  9. package/dist-esm/src/generated/src/appConfiguration.js.map +1 -1
  10. package/dist-esm/src/generated/src/index.js +0 -1
  11. package/dist-esm/src/generated/src/index.js.map +1 -1
  12. package/dist-esm/src/generated/src/models/index.js +78 -1
  13. package/dist-esm/src/generated/src/models/index.js.map +1 -1
  14. package/dist-esm/src/generated/src/models/mappers.js.map +1 -1
  15. package/dist-esm/src/generated/src/models/parameters.js +7 -8
  16. package/dist-esm/src/generated/src/models/parameters.js.map +1 -1
  17. package/dist-esm/src/internal/helpers.js +35 -18
  18. package/dist-esm/src/internal/helpers.js.map +1 -1
  19. package/dist-esm/src/internal/synctokenpolicy.js +9 -18
  20. package/dist-esm/src/internal/synctokenpolicy.js.map +1 -1
  21. package/dist-esm/src/internal/tracing.js +11 -0
  22. package/dist-esm/src/internal/tracing.js.map +1 -0
  23. package/dist-esm/src/models.js.map +1 -1
  24. package/dist-esm/test/internal/helpers.spec.js +3 -12
  25. package/dist-esm/test/internal/helpers.spec.js.map +1 -1
  26. package/dist-esm/test/internal/http.spec.js +2 -14
  27. package/dist-esm/test/internal/http.spec.js.map +1 -1
  28. package/dist-esm/test/internal/node/throttlingRetryPolicy.spec.js +6 -5
  29. package/dist-esm/test/internal/node/throttlingRetryPolicy.spec.js.map +1 -1
  30. package/dist-esm/test/public/auth.spec.js +1 -1
  31. package/dist-esm/test/public/auth.spec.js.map +1 -1
  32. package/dist-esm/test/public/etags.spec.js +1 -2
  33. package/dist-esm/test/public/etags.spec.js.map +1 -1
  34. package/dist-esm/test/public/index.readonlytests.spec.js +6 -1
  35. package/dist-esm/test/public/index.readonlytests.spec.js.map +1 -1
  36. package/dist-esm/test/public/index.spec.js +23 -8
  37. package/dist-esm/test/public/index.spec.js.map +1 -1
  38. package/dist-esm/test/public/secretReference.spec.js.map +1 -1
  39. package/dist-esm/test/public/throwOrNotThrow.spec.js +1 -1
  40. package/dist-esm/test/public/throwOrNotThrow.spec.js.map +1 -1
  41. package/dist-esm/test/public/tracing.spec.js +34 -0
  42. package/dist-esm/test/public/tracing.spec.js.map +1 -0
  43. package/dist-esm/test/public/utils/testHelpers.js.map +1 -1
  44. package/package.json +12 -4
  45. package/types/app-configuration.d.ts +5 -14
  46. package/dist-esm/src/generated/src/appConfigurationContext.js +0 -46
  47. package/dist-esm/src/generated/src/appConfigurationContext.js.map +0 -1
  48. package/dist-esm/src/internal/tracingHelpers.js +0 -46
  49. package/dist-esm/src/internal/tracingHelpers.js.map +0 -1
  50. package/dist-esm/src/policies/throttlingRetryPolicy.js +0 -126
  51. package/dist-esm/src/policies/throttlingRetryPolicy.js.map +0 -1
  52. package/dist-esm/test/internal/throttlingRetryPolicyTests.spec.js +0 -145
  53. package/dist-esm/test/internal/throttlingRetryPolicyTests.spec.js.map +0 -1
  54. package/dist-esm/test/internal/tracingHelpers.spec.js +0 -112
  55. package/dist-esm/test/internal/tracingHelpers.spec.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"synctokenpolicy.js","sourceRoot":"","sources":["../../../src/internal/synctokenpolicy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n RequestPolicy,\n RequestPolicyOptions,\n BaseRequestPolicy,\n WebResource,\n HttpOperationResponse,\n RequestPolicyFactory,\n} from \"@azure/core-http\";\n\n/**\n * The sync token header, as described here:\n * https://docs.microsoft.com/azure/azure-app-configuration/rest-api-consistency\n * @internal\n */\nexport const SyncTokenHeaderName = \"sync-token\";\n\n/**\n * A policy factory for injecting sync tokens properly into outgoing requests.\n * @param syncTokens - the sync tokens store to be used across requests.\n * @internal\n */\nexport function syncTokenPolicy(syncTokens: SyncTokens): RequestPolicyFactory {\n return {\n create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => {\n return new SyncTokenPolicy(nextPolicy, options, syncTokens);\n },\n };\n}\n\nclass SyncTokenPolicy extends BaseRequestPolicy {\n constructor(\n nextPolicy: RequestPolicy,\n options: RequestPolicyOptions,\n private _syncTokens: SyncTokens\n ) {\n super(nextPolicy, options);\n }\n\n public async sendRequest(webResource: WebResource): Promise<HttpOperationResponse> {\n const syncTokenHeaderValue = this._syncTokens.getSyncTokenHeaderValue();\n\n if (syncTokenHeaderValue != null) {\n webResource.headers.set(SyncTokenHeaderName, syncTokenHeaderValue);\n }\n\n const response = await this._nextPolicy.sendRequest(webResource);\n this._syncTokens.addSyncTokenFromHeaderValue(response.headers.get(SyncTokenHeaderName));\n return response;\n }\n}\n\n/**\n * Sync token tracker (allows for real-time consistency, even in the face of\n * caching and load balancing within App Configuration).\n *\n * (protocol and format described here)\n * https://docs.microsoft.com/azure/azure-app-configuration/rest-api-consistency\n *\n * @internal\n */\nexport class SyncTokens {\n private _currentSyncTokens = new Map<string, SyncToken>();\n\n /**\n * Takes the value from the header named after the constant `SyncTokenHeaderName`\n * and adds it to our list of accumulated sync tokens.\n *\n * If given an empty value (or undefined) it clears the current list of sync tokens.\n * (indicates the service has properly absorbed values into the cluster).\n *\n * @param syncTokenHeaderValue - The full value of the sync token header.\n */\n addSyncTokenFromHeaderValue(syncTokenHeaderValue: string | undefined): void {\n if (syncTokenHeaderValue == null || syncTokenHeaderValue === \"\") {\n // eventually everything gets synced up and we don't have to track\n // these headers anymore\n this._currentSyncTokens.clear();\n return;\n }\n\n const newTokens = syncTokenHeaderValue.split(\",\").map(parseSyncToken);\n\n for (const newToken of newTokens) {\n const existingToken = this._currentSyncTokens.get(newToken.id);\n\n if (!existingToken || existingToken.sequenceNumber < newToken.sequenceNumber) {\n this._currentSyncTokens.set(newToken.id, newToken);\n continue;\n }\n }\n }\n\n /**\n * Gets a properly formatted SyncToken header value.\n */\n getSyncTokenHeaderValue(): string | undefined {\n if (this._currentSyncTokens.size === 0) {\n return undefined;\n }\n\n const syncTokenStrings = [];\n\n for (const syncToken of this._currentSyncTokens.values()) {\n // note that you don't include the 'sn' field here - that's only\n // used for internal tracking of the 'version' for the token itself\n syncTokenStrings.push(`${syncToken.id}=${syncToken.value}`);\n }\n\n return syncTokenStrings.join(\",\");\n }\n}\n\n// An example sync token (from their documentation):\n//\n// jtqGc1I4=MDoyOA==;sn=28\n//\n// Which breaks down to:\n// id: jtqGc1I4\n// value: MDoyOA==\n// sequence number: 28\nconst syncTokenRegex = /^([^=]+)=([^;]+);sn=(\\d+)$/;\n\ninterface SyncToken {\n id: string;\n value: string;\n sequenceNumber: number;\n}\n\n/**\n * Parses a single sync token into it's constituent parts.\n *\n * @param syncToken - A single sync token.\n *\n * @internal\n */\nexport function parseSyncToken(syncToken: string): SyncToken {\n const matches = syncToken.match(syncTokenRegex);\n\n if (matches == null) {\n throw new Error(\n `Failed to parse sync token '${syncToken}' with regex ${syncTokenRegex.source}`\n );\n }\n\n const sequenceNumber = parseInt(matches[3], 10);\n\n if (isNaN(sequenceNumber)) {\n // this should be impossible since our regex restricts to just digits\n // but there's nothing wrong with being thorough.\n throw new Error(`${syncToken}: The sequence number value '${matches[3]}' wasn't a number`);\n }\n\n return {\n id: matches[1],\n value: matches[2],\n sequenceNumber,\n };\n}\n"]}
1
+ {"version":3,"file":"synctokenpolicy.js","sourceRoot":"","sources":["../../../src/internal/synctokenpolicy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n PipelinePolicy,\n PipelineRequest,\n PipelineResponse,\n SendRequest,\n} from \"@azure/core-rest-pipeline\";\n\n/**\n * The sync token header, as described here:\n * https://docs.microsoft.com/azure/azure-app-configuration/rest-api-consistency\n * @internal\n */\nexport const SyncTokenHeaderName = \"sync-token\";\n\n/**\n * A policy factory for injecting sync tokens properly into outgoing requests.\n * @param syncTokens - the sync tokens store to be used across requests.\n * @internal\n */\nexport function syncTokenPolicy(syncTokens: SyncTokens): PipelinePolicy {\n return {\n name: \"Sync Token Policy\",\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n const syncTokenHeaderValue = syncTokens.getSyncTokenHeaderValue();\n\n if (syncTokenHeaderValue) {\n request.headers.set(SyncTokenHeaderName, syncTokenHeaderValue);\n }\n\n const response = await next(request);\n syncTokens.addSyncTokenFromHeaderValue(response.headers.get(SyncTokenHeaderName));\n return response;\n },\n };\n}\n\n/**\n * Sync token tracker (allows for real-time consistency, even in the face of\n * caching and load balancing within App Configuration).\n *\n * (protocol and format described here)\n * https://docs.microsoft.com/azure/azure-app-configuration/rest-api-consistency\n *\n * @internal\n */\nexport class SyncTokens {\n private _currentSyncTokens = new Map<string, SyncToken>();\n\n /**\n * Takes the value from the header named after the constant `SyncTokenHeaderName`\n * and adds it to our list of accumulated sync tokens.\n *\n * If given an empty value (or undefined) it clears the current list of sync tokens.\n * (indicates the service has properly absorbed values into the cluster).\n *\n * @param syncTokenHeaderValue - The full value of the sync token header.\n */\n addSyncTokenFromHeaderValue(syncTokenHeaderValue: string | undefined): void {\n if (syncTokenHeaderValue == null || syncTokenHeaderValue === \"\") {\n // eventually everything gets synced up and we don't have to track\n // these headers anymore\n this._currentSyncTokens.clear();\n return;\n }\n\n const newTokens = syncTokenHeaderValue.split(\",\").map(parseSyncToken);\n\n for (const newToken of newTokens) {\n const existingToken = this._currentSyncTokens.get(newToken.id);\n\n if (!existingToken || existingToken.sequenceNumber < newToken.sequenceNumber) {\n this._currentSyncTokens.set(newToken.id, newToken);\n continue;\n }\n }\n }\n\n /**\n * Gets a properly formatted SyncToken header value.\n */\n getSyncTokenHeaderValue(): string | undefined {\n if (this._currentSyncTokens.size === 0) {\n return undefined;\n }\n\n const syncTokenStrings = [];\n\n for (const syncToken of this._currentSyncTokens.values()) {\n // note that you don't include the 'sn' field here - that's only\n // used for internal tracking of the 'version' for the token itself\n syncTokenStrings.push(`${syncToken.id}=${syncToken.value}`);\n }\n\n return syncTokenStrings.join(\",\");\n }\n}\n\n// An example sync token (from their documentation):\n//\n// jtqGc1I4=MDoyOA==;sn=28\n//\n// Which breaks down to:\n// id: jtqGc1I4\n// value: MDoyOA==\n// sequence number: 28\nconst syncTokenRegex = /^([^=]+)=([^;]+);sn=(\\d+)$/;\n\ninterface SyncToken {\n id: string;\n value: string;\n sequenceNumber: number;\n}\n\n/**\n * Parses a single sync token into it's constituent parts.\n *\n * @param syncToken - A single sync token.\n *\n * @internal\n */\nexport function parseSyncToken(syncToken: string): SyncToken {\n const matches = syncToken.match(syncTokenRegex);\n\n if (matches == null) {\n throw new Error(\n `Failed to parse sync token '${syncToken}' with regex ${syncTokenRegex.source}`\n );\n }\n\n const sequenceNumber = parseInt(matches[3], 10);\n\n if (isNaN(sequenceNumber)) {\n // this should be impossible since our regex restricts to just digits\n // but there's nothing wrong with being thorough.\n throw new Error(`${syncToken}: The sequence number value '${matches[3]}' wasn't a number`);\n }\n\n return {\n id: matches[1],\n value: matches[2],\n sequenceNumber,\n };\n}\n"]}
@@ -0,0 +1,11 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ import { createTracingClient } from "@azure/core-tracing";
4
+ import { packageVersion } from "../appConfigurationClient";
5
+ /** @internal */
6
+ export const tracingClient = createTracingClient({
7
+ namespace: "Microsoft.AppConfiguration",
8
+ packageName: "@azure/app-configuration",
9
+ packageVersion,
10
+ });
11
+ //# sourceMappingURL=tracing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing.js","sourceRoot":"","sources":["../../../src/internal/tracing.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,gBAAgB;AAChB,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC;IAC/C,SAAS,EAAE,4BAA4B;IACvC,WAAW,EAAE,0BAA0B;IACvC,cAAc;CACf,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createTracingClient } from \"@azure/core-tracing\";\nimport { packageVersion } from \"../appConfigurationClient\";\n\n/** @internal */\nexport const tracingClient = createTracingClient({\n namespace: \"Microsoft.AppConfiguration\",\n packageName: \"@azure/app-configuration\",\n packageVersion,\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { OperationOptions, HttpResponse } from \"@azure/core-http\";\nimport { FeatureFlagValue } from \"./featureFlag\";\nimport { SecretReferenceValue } from \"./secretReference\";\n\n/**\n * Fields that uniquely identify a configuration setting\n */\nexport interface ConfigurationSettingId {\n /**\n * The key for this setting.\n * Feature flags must be prefixed with `.appconfig.featureflag/<feature-flag-name>`.\n */\n key: string;\n\n /**\n * The label for this setting. Leaving this undefined means this\n * setting does not have a label.\n */\n label?: string;\n\n /**\n * The etag for this setting\n */\n etag?: string;\n}\n\n/**\n * Necessary fields for updating or creating a new configuration setting\n */\nexport type ConfigurationSettingParam<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingId & {\n /**\n * The content type of the setting's value\n */\n contentType?: string;\n\n /**\n * Tags for this key\n */\n tags?: { [propertyName: string]: string };\n} & (T extends string\n ? {\n /**\n * The setting's value\n */\n value?: string;\n }\n : {\n /**\n * The setting's value\n */\n value: T;\n });\n\n/**\n * Configuration setting with extra metadata from the server, indicating\n * its etag, whether it is currently readOnly and when it was last modified.\n */\nexport type ConfigurationSetting<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingParam<T> & {\n /**\n * Whether or not the setting is read-only\n */\n isReadOnly: boolean;\n\n /**\n * The date when this setting was last modified\n */\n lastModified?: Date;\n};\n\n/**\n * Fields that are hoisted up from the _response field of the object\n * Used in cases where individual HTTP response fields are important for\n * the user to use in common-use cases like handling http status codes 204 or 304.\n */\nexport interface HttpResponseFields {\n /**\n * The HTTP status code for the response\n */\n statusCode: number;\n}\n\n/**\n * Parameters for adding a new configuration setting\n */\nexport type AddConfigurationSettingParam<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingParam<T>;\n\n/**\n * Parameters for creating or updating a new configuration setting\n */\nexport type SetConfigurationSettingParam<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingParam<T>;\n\n/**\n * Standard base response for getting, deleting or updating a configuration setting\n */\nexport type ConfigurationSettingResponse<HeadersT> = ConfigurationSetting &\n HttpResponseField<HeadersT> &\n Pick<HeadersT, Exclude<keyof HeadersT, \"eTag\">>;\n\n/**\n * HTTP response related information - headers and raw body.\n */\nexport interface HttpResponseField<HeadersT> {\n /**\n * The underlying HTTP response.\n */\n _response: HttpResponse & {\n /**\n * The parsed HTTP response headers.\n */\n parsedHeaders: HeadersT;\n\n /**\n * The response body as text (string format)\n */\n bodyAsText: string;\n };\n}\n\n/**\n * Options used to provide if-none-match for an HTTP request\n */\nexport interface HttpOnlyIfChangedField {\n /**\n * Used to perform an operation only if the targeted resource's etag does not match the value\n * provided.\n */\n onlyIfChanged?: boolean;\n}\n\n/**\n * Options used to provide if-match for an HTTP request\n */\nexport interface HttpOnlyIfUnchangedField {\n /**\n * Used to perform an operation only if the targeted resource's etag matches the value provided.\n */\n onlyIfUnchanged?: boolean;\n}\n\n/**\n * Used when the API supports selectively returning fields.\n */\nexport interface OptionalFields {\n /**\n * Which fields to return for each ConfigurationSetting\n */\n fields?: (keyof ConfigurationSetting)[];\n}\n\n/**\n * Sync token header field\n */\nexport interface SyncTokenHeaderField {\n /**\n * Enables real-time consistency between requests by providing the returned value in the next\n * request made to the server.\n */\n syncToken?: string;\n}\n\n/**\n * Options used when adding a ConfigurationSetting.\n */\nexport interface AddConfigurationSettingOptions extends OperationOptions {}\n\n/**\n * Response from adding a ConfigurationSetting.\n */\nexport interface AddConfigurationSettingResponse\n extends ConfigurationSetting,\n SyncTokenHeaderField,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Response from deleting a ConfigurationSetting.\n */\nexport interface DeleteConfigurationSettingResponse\n extends SyncTokenHeaderField,\n HttpResponseFields,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Options for deleting a ConfigurationSetting.\n */\nexport interface DeleteConfigurationSettingOptions\n extends HttpOnlyIfUnchangedField,\n OperationOptions {}\n\n/**\n * Options used when saving a ConfigurationSetting.\n */\nexport interface SetConfigurationSettingOptions\n extends HttpOnlyIfUnchangedField,\n OperationOptions {}\n\n/**\n * Response from setting a ConfigurationSetting.\n */\nexport interface SetConfigurationSettingResponse\n extends ConfigurationSetting,\n SyncTokenHeaderField,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Headers from getting a ConfigurationSetting.\n */\nexport interface GetConfigurationHeaders extends SyncTokenHeaderField {}\n\n/**\n * Response from retrieving a ConfigurationSetting.\n */\nexport interface GetConfigurationSettingResponse\n extends ConfigurationSetting,\n GetConfigurationHeaders,\n HttpResponseFields,\n HttpResponseField<GetConfigurationHeaders> {}\n\n/**\n * Options for getting a ConfigurationSetting.\n */\nexport interface GetConfigurationSettingOptions\n extends OperationOptions,\n HttpOnlyIfChangedField,\n OptionalFields {\n /**\n * Requests the server to respond with the state of the resource at the specified time.\n */\n acceptDateTime?: Date;\n}\n\n/**\n * Common options for 'list' style APIs in AppConfig used to specify wildcards as well as\n * the accept date time header.\n */\nexport interface ListSettingsOptions extends OptionalFields {\n /**\n * Requests the server to respond with the state of the resource at the specified time.\n */\n acceptDateTime?: Date;\n\n /**\n * Filters for keys. There are two types of matching:\n *\n * 1. Exact matching. Up to 5 key names are allowed, separated by commas (',')\n * 2. Wildcard matching. A single wildcard expression can be specified.\n *\n * | Value | Matches |\n * |--------------|---------------------------------------|\n * | omitted or * | Matches any key |\n * | abc | Matches a key named abc |\n * | abc* | Matches key names that start with abc |\n *\n * These characters are reserved and must be prefixed with backslash in order\n * to be specified: * or \\\\ or ,\n */\n keyFilter?: string;\n\n /**\n * Filters for labels. There are two types of matching:\n *\n * 1. Exact matching. Up to 5 labels are allowed, separated by commas (',')\n * 2. Wildcard matching. A single wildcard expression can be specified.\n *\n * | Value | Matches |\n * |--------------|---------------------------------------------------|\n * | omitted or * | Matches any key |\n * | %00 | Matches any key without a label |\n * | prod | Matches a key with label named prod |\n * | prod* | Matches key with label names that start with prod |\n *\n * These characters are reserved and must be prefixed with backslash in order\n * to be specified: * or \\\\ or ,\n */\n labelFilter?: string;\n}\n\n/**\n * Options for listConfigurationSettings that allow for filtering based on keys, labels and other fields.\n * Also provides `fields` which allows you to selectively choose which fields are populated in the\n * result.\n */\nexport interface ListConfigurationSettingsOptions extends OperationOptions, ListSettingsOptions {}\n\n/**\n * An interface that tracks the settings for paged iteration\n */\nexport interface PageSettings {\n /**\n * The token that keeps track of where to continue the iterator\n */\n continuationToken?: string;\n // The appconfig service doesn't currently support letting you select a page size\n // so we're ignoring their setting for now.\n}\n\n/**\n * A page of configuration settings and the corresponding HTTP response\n */\nexport interface ListConfigurationSettingPage\n extends HttpResponseField<SyncTokenHeaderField>,\n PageSettings {\n /**\n * The configuration settings for this page of results.\n */\n items: ConfigurationSetting[];\n}\n\n/**\n * Options for listRevisions that allow for filtering based on keys, labels and other fields.\n * Also provides `fields` which allows you to selectively choose which fields are populated in the\n * result.\n */\nexport interface ListRevisionsOptions extends OperationOptions, ListSettingsOptions {}\n\n/**\n * A page of configuration settings and the corresponding HTTP response\n */\nexport interface ListRevisionsPage extends HttpResponseField<SyncTokenHeaderField>, PageSettings {\n /**\n * The configuration settings for this page of results.\n */\n items: ConfigurationSetting[];\n}\n\n/**\n * Options for setReadOnly\n */\nexport interface SetReadOnlyOptions extends HttpOnlyIfUnchangedField, OperationOptions {}\n\n/**\n * Response when setting a value to read-only.\n */\nexport interface SetReadOnlyResponse\n extends ConfigurationSetting,\n SyncTokenHeaderField,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Options that control how to retry failed requests.\n */\nexport interface RetryOptions {\n /**\n * The maximum number of retry attempts. Defaults to 3.\n */\n maxRetries?: number;\n\n /**\n * The maximum delay in milliseconds allowed before retrying an operation.\n */\n maxRetryDelayInMs?: number;\n}\n"]}
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { OperationOptions } from \"@azure/core-client\";\nimport { FeatureFlagValue } from \"./featureFlag\";\nimport { SecretReferenceValue } from \"./secretReference\";\nimport { CompatResponse } from \"@azure/core-http-compat\";\n/**\n * Fields that uniquely identify a configuration setting\n */\nexport interface ConfigurationSettingId {\n /**\n * The key for this setting.\n * Feature flags must be prefixed with `.appconfig.featureflag/<feature-flag-name>`.\n */\n key: string;\n\n /**\n * The label for this setting. Leaving this undefined means this\n * setting does not have a label.\n */\n label?: string;\n\n /**\n * The etag for this setting\n */\n etag?: string;\n}\n\n/**\n * Necessary fields for updating or creating a new configuration setting\n */\nexport type ConfigurationSettingParam<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingId & {\n /**\n * The content type of the setting's value\n */\n contentType?: string;\n\n /**\n * Tags for this key\n */\n tags?: { [propertyName: string]: string };\n} & (T extends string\n ? {\n /**\n * The setting's value\n */\n value?: string;\n }\n : {\n /**\n * The setting's value\n */\n value: T;\n });\n\n/**\n * Configuration setting with extra metadata from the server, indicating\n * its etag, whether it is currently readOnly and when it was last modified.\n */\nexport type ConfigurationSetting<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingParam<T> & {\n /**\n * Whether or not the setting is read-only\n */\n isReadOnly: boolean;\n\n /**\n * The date when this setting was last modified\n */\n lastModified?: Date;\n};\n\n/**\n * Fields that are hoisted up from the _response field of the object\n * Used in cases where individual HTTP response fields are important for\n * the user to use in common-use cases like handling http status codes 204 or 304.\n */\nexport interface HttpResponseFields {\n /**\n * The HTTP status code for the response\n */\n statusCode: number;\n}\n/**\n * HTTP response related information - headers and raw body.\n */\nexport interface HttpResponseField<HeadersT> {\n /**\n * The underlying HTTP response.\n */\n _response: CompatResponse & {\n /**\n * The parsed HTTP response headers.\n */\n parsedHeaders: HeadersT;\n\n /**\n * The response body as text (string format)\n */\n bodyAsText: string;\n };\n}\n/**\n * Parameters for adding a new configuration setting\n */\nexport type AddConfigurationSettingParam<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingParam<T>;\n\n/**\n * Parameters for creating or updating a new configuration setting\n */\nexport type SetConfigurationSettingParam<\n T extends string | FeatureFlagValue | SecretReferenceValue = string\n> = ConfigurationSettingParam<T>;\n\n/**\n * Standard base response for getting, deleting or updating a configuration setting\n */\nexport type ConfigurationSettingResponse<HeadersT> = ConfigurationSetting &\n HttpResponseField<HeadersT> &\n Pick<HeadersT, Exclude<keyof HeadersT, \"eTag\">>;\n\n/**\n * Options used to provide if-none-match for an HTTP request\n */\nexport interface HttpOnlyIfChangedField {\n /**\n * Used to perform an operation only if the targeted resource's etag does not match the value\n * provided.\n */\n onlyIfChanged?: boolean;\n}\n\n/**\n * Options used to provide if-match for an HTTP request\n */\nexport interface HttpOnlyIfUnchangedField {\n /**\n * Used to perform an operation only if the targeted resource's etag matches the value provided.\n */\n onlyIfUnchanged?: boolean;\n}\n\n/**\n * Used when the API supports selectively returning fields.\n */\nexport interface OptionalFields {\n /**\n * Which fields to return for each ConfigurationSetting\n */\n fields?: (keyof ConfigurationSetting)[];\n}\n\n/**\n * Sync token header field\n */\nexport interface SyncTokenHeaderField {\n /**\n * Enables real-time consistency between requests by providing the returned value in the next\n * request made to the server.\n */\n syncToken?: string;\n}\n\n/**\n * Options used when adding a ConfigurationSetting.\n */\nexport interface AddConfigurationSettingOptions extends OperationOptions {}\n\n/**\n * Response from adding a ConfigurationSetting.\n */\nexport interface AddConfigurationSettingResponse\n extends ConfigurationSetting,\n SyncTokenHeaderField,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Response from deleting a ConfigurationSetting.\n */\nexport interface DeleteConfigurationSettingResponse\n extends SyncTokenHeaderField,\n HttpResponseFields,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Options for deleting a ConfigurationSetting.\n */\nexport interface DeleteConfigurationSettingOptions\n extends HttpOnlyIfUnchangedField,\n OperationOptions {}\n\n/**\n * Options used when saving a ConfigurationSetting.\n */\nexport interface SetConfigurationSettingOptions\n extends HttpOnlyIfUnchangedField,\n OperationOptions {}\n\n/**\n * Response from setting a ConfigurationSetting.\n */\nexport interface SetConfigurationSettingResponse\n extends ConfigurationSetting,\n SyncTokenHeaderField,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Headers from getting a ConfigurationSetting.\n */\nexport interface GetConfigurationHeaders extends SyncTokenHeaderField {}\n\n/**\n * Response from retrieving a ConfigurationSetting.\n */\nexport interface GetConfigurationSettingResponse\n extends ConfigurationSetting,\n GetConfigurationHeaders,\n HttpResponseFields,\n HttpResponseField<GetConfigurationHeaders> {}\n\n/**\n * Options for getting a ConfigurationSetting.\n */\nexport interface GetConfigurationSettingOptions\n extends OperationOptions,\n HttpOnlyIfChangedField,\n OptionalFields {\n /**\n * Requests the server to respond with the state of the resource at the specified time.\n */\n acceptDateTime?: Date;\n}\n\n/**\n * Common options for 'list' style APIs in AppConfig used to specify wildcards as well as\n * the accept date time header.\n */\nexport interface ListSettingsOptions extends OptionalFields {\n /**\n * Requests the server to respond with the state of the resource at the specified time.\n */\n acceptDateTime?: Date;\n\n /**\n * Filters for keys. There are two types of matching:\n *\n * 1. Exact matching. Up to 5 key names are allowed, separated by commas (',')\n * 2. Wildcard matching. A single wildcard expression can be specified.\n *\n * | Value | Matches |\n * |--------------|---------------------------------------|\n * | omitted or * | Matches any key |\n * | abc | Matches a key named abc |\n * | abc* | Matches key names that start with abc |\n *\n * These characters are reserved and must be prefixed with backslash in order\n * to be specified: * or \\\\ or ,\n */\n keyFilter?: string;\n\n /**\n * Filters for labels. There are two types of matching:\n *\n * 1. Exact matching. Up to 5 labels are allowed, separated by commas (',')\n * 2. Wildcard matching. A single wildcard expression can be specified.\n *\n * | Value | Matches |\n * |--------------|---------------------------------------------------|\n * | omitted or * | Matches any key |\n * | %00 | Matches any key without a label |\n * | prod | Matches a key with label named prod |\n * | prod* | Matches key with label names that start with prod |\n *\n * These characters are reserved and must be prefixed with backslash in order\n * to be specified: * or \\\\ or ,\n */\n labelFilter?: string;\n}\n\n/**\n * Options for listConfigurationSettings that allow for filtering based on keys, labels and other fields.\n * Also provides `fields` which allows you to selectively choose which fields are populated in the\n * result.\n */\nexport interface ListConfigurationSettingsOptions extends OperationOptions, ListSettingsOptions {}\n\n/**\n * An interface that tracks the settings for paged iteration\n */\nexport interface PageSettings {\n /**\n * The token that keeps track of where to continue the iterator\n */\n continuationToken?: string;\n // The appconfig service doesn't currently support letting you select a page size\n // so we're ignoring their setting for now.\n}\n\n/**\n * A page of configuration settings and the corresponding HTTP response\n */\nexport interface ListConfigurationSettingPage\n extends HttpResponseField<SyncTokenHeaderField>,\n PageSettings {\n /**\n * The configuration settings for this page of results.\n */\n items: ConfigurationSetting[];\n}\n\n/**\n * Options for listRevisions that allow for filtering based on keys, labels and other fields.\n * Also provides `fields` which allows you to selectively choose which fields are populated in the\n * result.\n */\nexport interface ListRevisionsOptions extends OperationOptions, ListSettingsOptions {}\n\n/**\n * A page of configuration settings and the corresponding HTTP response\n */\nexport interface ListRevisionsPage extends HttpResponseField<SyncTokenHeaderField>, PageSettings {\n /**\n * The configuration settings for this page of results.\n */\n items: ConfigurationSetting[];\n}\n\n/**\n * Options for setReadOnly\n */\nexport interface SetReadOnlyOptions extends HttpOnlyIfUnchangedField, OperationOptions {}\n\n/**\n * Response when setting a value to read-only.\n */\nexport interface SetReadOnlyResponse\n extends ConfigurationSetting,\n SyncTokenHeaderField,\n HttpResponseField<SyncTokenHeaderField> {}\n\n/**\n * Options that control how to retry failed requests.\n */\nexport interface RetryOptions {\n /**\n * The maximum number of retry attempts. Defaults to 3.\n */\n maxRetries?: number;\n\n /**\n * The maximum delay in milliseconds allowed before retrying an operation.\n */\n maxRetryDelayInMs?: number;\n}\n"]}
@@ -3,7 +3,6 @@
3
3
  import { checkAndFormatIfAndIfNoneMatch, formatFiltersAndSelect, extractAfterTokenFromNextLink, quoteETag, makeConfigurationSettingEmpty, transformKeyValue, transformKeyValueResponseWithStatusCode, transformKeyValueResponse, formatFieldsForSelect, serializeAsConfigurationSettingParam, } from "../../src/internal/helpers";
4
4
  import { assert } from "chai";
5
5
  import { featureFlagContentType, secretReferenceContentType, } from "../../src";
6
- import { HttpHeaders } from "@azure/core-http";
7
6
  describe("helper methods", () => {
8
7
  it("checkAndFormatIfAndIfNoneMatch", () => {
9
8
  const key = "ignored";
@@ -118,20 +117,12 @@ describe("helper methods", () => {
118
117
  },
119
118
  method: "GET",
120
119
  withCredentials: false,
121
- headers: new HttpHeaders(),
120
+ headers: {},
122
121
  timeout: 0,
123
122
  requestId: "",
124
- clone: function () {
125
- return this;
126
- },
127
- // eslint-disable-next-line @typescript-eslint/no-empty-function
128
- validateRequestProperties: () => { },
129
- prepare: function () {
130
- return this;
131
- },
132
123
  },
133
124
  status: 204,
134
- headers: new HttpHeaders(),
125
+ headers: {},
135
126
  bodyAsText: "",
136
127
  parsedHeaders: {},
137
128
  },
@@ -164,7 +155,7 @@ describe("helper methods", () => {
164
155
  });
165
156
  });
166
157
  it("transformKeyValueResponseWithStatusCode", () => {
167
- const configurationSetting = transformKeyValueResponseWithStatusCode(Object.assign({ key: "hello", locked: true }, fakeHttp204Response));
158
+ const configurationSetting = transformKeyValueResponseWithStatusCode(Object.assign({ key: "hello", locked: true }, fakeHttp204Response), 204);
168
159
  const actualKeys = Object.keys(configurationSetting).sort();
169
160
  // _response is explictly set to not enumerate, even in our copied object.
170
161
  assert.deepEqual(actualKeys, ["isReadOnly", "key", "statusCode", "value"]);
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.spec.js","sourceRoot":"","sources":["../../../test/internal/helpers.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n checkAndFormatIfAndIfNoneMatch,\n formatFiltersAndSelect,\n extractAfterTokenFromNextLink,\n quoteETag,\n makeConfigurationSettingEmpty,\n transformKeyValue,\n transformKeyValueResponseWithStatusCode,\n transformKeyValueResponse,\n formatFieldsForSelect,\n serializeAsConfigurationSettingParam,\n} from \"../../src/internal/helpers\";\nimport { assert } from \"chai\";\nimport {\n ConfigurationSetting,\n ConfigurationSettingParam,\n featureFlagContentType,\n HttpResponseField,\n HttpResponseFields,\n secretReferenceContentType,\n} from \"../../src\";\nimport { HttpHeaders } from \"@azure/core-http\";\nimport { FeatureFlagValue } from \"../../src/featureFlag\";\nimport { SecretReferenceValue } from \"../../src/secretReference\";\n\ndescribe(\"helper methods\", () => {\n it(\"checkAndFormatIfAndIfNoneMatch\", () => {\n const key = \"ignored\";\n\n assert.deepEqual(\n {\n ifMatch: undefined,\n ifNoneMatch: undefined,\n },\n checkAndFormatIfAndIfNoneMatch({ key }, {})\n );\n\n assert.deepEqual(\n {\n ifMatch: '\"hello\"',\n ifNoneMatch: undefined,\n },\n checkAndFormatIfAndIfNoneMatch(\n { key, etag: \"hello\" },\n {\n onlyIfUnchanged: true,\n }\n )\n );\n\n assert.deepEqual(\n {\n ifNoneMatch: '\"hello\"',\n ifMatch: undefined,\n },\n checkAndFormatIfAndIfNoneMatch(\n { key, etag: \"hello\" },\n {\n onlyIfChanged: true,\n }\n )\n );\n });\n\n it(\"checkAndFormatIfAndIfNoneMatch - mutually exclusive\", () => {\n const key = \"ignored\";\n\n assert.throws(\n () =>\n checkAndFormatIfAndIfNoneMatch(\n { key, etag: \"won't get used\" },\n {\n onlyIfChanged: true,\n onlyIfUnchanged: true,\n }\n ),\n /onlyIfChanged and onlyIfUnchanged are mutually-exclusive/\n );\n });\n\n describe(\"quoteETag\", () => {\n it(\"undefined\", () => {\n assert.equal(undefined, quoteETag(undefined));\n\n assert.equal('\"etagishere\"', quoteETag(\"etagishere\"));\n\n assert.equal(\"'etagishere'\", quoteETag(\"'etagishere'\"));\n\n assert.equal(\"*\", quoteETag(\"*\"));\n });\n });\n\n describe(\"formatWildcards\", () => {\n it(\"undefined\", () => {\n const result = formatFiltersAndSelect({\n keyFilter: undefined,\n labelFilter: undefined,\n });\n\n assert.ok(!result.key);\n assert.ok(!result.label);\n });\n\n it(\"single values only\", () => {\n const result = formatFiltersAndSelect({\n keyFilter: \"key1\",\n labelFilter: \"label1\",\n });\n\n assert.equal(\"key1\", result.key);\n assert.equal(\"label1\", result.label);\n });\n\n it(\"multiple values\", () => {\n const result = formatFiltersAndSelect({\n keyFilter: \"key1,key2\",\n labelFilter: \"label1,label2\",\n });\n\n assert.equal(\"key1,key2\", result.key);\n assert.equal(\"label1,label2\", result.label);\n });\n\n it(\"fields map properly\", () => {\n const result = formatFiltersAndSelect({\n fields: [\"isReadOnly\", \"value\"],\n });\n\n assert.deepEqual([\"locked\", \"value\"], result.select);\n });\n });\n\n describe(\"extractAfterTokenFromNextLink\", () => {\n it(\"token is extracted and properly unescaped\", () => {\n const token = extractAfterTokenFromNextLink(\"/kv?key=someKey&api-version=1.0&after=bGlah%3D\");\n assert.equal(\"bGlah=\", token);\n });\n });\n\n describe(\"serializeAsConfigurationSettingParam\", () => {\n [`[]`, \"Hello World\"].forEach((value) => {\n // These values are unexpected for feature flag or secret reference config setting\n // These tests make sure the latest version supports such settings where the value is unexpected\n // as well because the older versions of the SDK support such cases.\n // These tests make sure the SDK is not broken for the users with such use cases.\n it(`serializer doesn't throw on ${value} as feature flag value`, () => {\n const featureFlag: ConfigurationSetting<FeatureFlagValue> = {\n contentType: featureFlagContentType,\n key: \"key\",\n isReadOnly: false,\n value: { conditions: { clientFilters: [] }, enabled: true },\n };\n featureFlag.value = value as any;\n assert.deepEqual(\n serializeAsConfigurationSettingParam(featureFlag),\n featureFlag as unknown as ConfigurationSettingParam<string>,\n \"setting was modified\"\n );\n });\n\n it(`serializer doesn't throw on ${value} as secret reference value`, () => {\n const setting: ConfigurationSetting<SecretReferenceValue> = {\n contentType: secretReferenceContentType,\n key: \"key\",\n isReadOnly: false,\n value: { secretId: \"abc\" },\n };\n setting.value = value as any;\n assert.deepEqual(\n serializeAsConfigurationSettingParam(setting),\n setting as any,\n \"setting was modified\"\n );\n });\n });\n });\n\n const fakeHttp204Response: HttpResponseField<any> = {\n _response: {\n request: {\n url: \"unused\",\n abortSignal: {\n aborted: true,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n addEventListener: () => {},\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n removeEventListener: () => {},\n },\n method: \"GET\",\n withCredentials: false,\n headers: new HttpHeaders(),\n timeout: 0,\n requestId: \"\",\n clone: function () {\n return this;\n },\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n validateRequestProperties: () => {},\n prepare: function () {\n return this;\n },\n },\n status: 204,\n headers: new HttpHeaders(),\n bodyAsText: \"\",\n parsedHeaders: {},\n },\n };\n\n it(\"makeConfigurationSettingEmpty\", () => {\n const response: ConfigurationSetting & HttpResponseField<any> & HttpResponseFields = {\n key: \"mykey\",\n statusCode: 204,\n isReadOnly: false,\n ...fakeHttp204Response,\n };\n\n makeConfigurationSettingEmpty(response);\n\n // key isn't touched\n assert.equal(\"mykey\", response.key);\n\n for (const name of getAllConfigurationSettingFieldsMinusKey()) {\n assert.ok(!response[name], name);\n }\n\n // These point is these properties are untouched and won't throw\n // since they're the only properties the user is allowed to touch on these\n // \"body empty\" objects.\n assert.equal(204, response._response.status);\n assert.equal(204, response.statusCode);\n });\n\n it(\"transformKeyValue\", () => {\n const configurationSetting = transformKeyValue({\n key: \"hello\",\n locked: true,\n });\n\n assert.deepEqual(configurationSetting, {\n // the 'locked' property should not be present in the object since\n // it should be 'renamed' to readOnly\n isReadOnly: true,\n key: \"hello\",\n value: undefined,\n });\n });\n\n it(\"transformKeyValueResponseWithStatusCode\", () => {\n const configurationSetting = transformKeyValueResponseWithStatusCode({\n key: \"hello\",\n locked: true,\n ...fakeHttp204Response,\n });\n\n const actualKeys = Object.keys(configurationSetting).sort();\n\n // _response is explictly set to not enumerate, even in our copied object.\n assert.deepEqual(actualKeys, [\"isReadOnly\", \"key\", \"statusCode\", \"value\"]);\n\n // now make it enumerable so we can do our comparison\n Object.defineProperty(configurationSetting, \"_response\", {\n enumerable: true,\n });\n\n assert.deepEqual(configurationSetting, {\n isReadOnly: true,\n key: \"hello\",\n value: undefined,\n statusCode: 204,\n _response: fakeHttp204Response._response,\n });\n });\n\n it(\"transformKeyValueResponse\", () => {\n const configurationSetting = transformKeyValueResponse({\n key: \"hello\",\n locked: true,\n ...fakeHttp204Response,\n });\n\n const actualKeys = Object.keys(configurationSetting).sort();\n\n // _response is explictly set to not enumerate, even in our copied object.\n assert.deepEqual(actualKeys, [\"isReadOnly\", \"key\", \"value\"]);\n\n // now make it enumerable so we can do our comparison\n Object.defineProperty(configurationSetting, \"_response\", {\n enumerable: true,\n });\n\n assert.deepEqual(configurationSetting, {\n isReadOnly: true,\n key: \"hello\",\n value: undefined,\n _response: fakeHttp204Response._response,\n });\n });\n\n it(\"normalizeFilterFields\", () => {\n const fields = getAllConfigurationSettingFields();\n\n assert.deepEqual(formatFieldsForSelect(fields)!.sort(), [\n \"content_type\",\n \"etag\",\n \"key\",\n \"label\",\n \"last_modified\",\n \"locked\", // isReadOnly maps to this\n \"tags\",\n \"value\",\n ]);\n\n assert.ok(formatFieldsForSelect(undefined) === undefined);\n assert.deepEqual(formatFieldsForSelect([]), []);\n });\n\n /**\n * Gets all the properties from ConfigurationSetting, sorted ascending.\n *\n * @returns All property names, sorted ascending.\n */\n function getAllConfigurationSettingFields(): (keyof ConfigurationSetting)[] {\n const configObjectWithAllFieldsRequired: Required<ConfigurationSetting> = {\n contentType: \"\",\n etag: \"\",\n key: \"\",\n label: \"\",\n lastModified: new Date(),\n isReadOnly: true,\n tags: {},\n value: \"\",\n };\n\n return Object.keys(configObjectWithAllFieldsRequired).sort() as (keyof ConfigurationSetting)[];\n }\n\n function getAllConfigurationSettingFieldsMinusKey(): Exclude<\n keyof ConfigurationSetting,\n \"key\"\n >[] {\n const keys = getAllConfigurationSettingFields().filter((key) => key !== \"key\");\n\n return keys as Exclude<keyof ConfigurationSetting, \"key\">[];\n }\n});\n"]}
1
+ {"version":3,"file":"helpers.spec.js","sourceRoot":"","sources":["../../../test/internal/helpers.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,EACtB,6BAA6B,EAC7B,SAAS,EACT,6BAA6B,EAC7B,iBAAiB,EACjB,uCAAuC,EACvC,yBAAyB,EACzB,qBAAqB,EACrB,oCAAoC,GACrC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAGL,sBAAsB,EAGtB,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AAKnB,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,GAAG,GAAG,SAAS,CAAC;QAEtB,MAAM,CAAC,SAAS,CACd;YACE,OAAO,EAAE,SAAS;YAClB,WAAW,EAAE,SAAS;SACvB,EACD,8BAA8B,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAC5C,CAAC;QAEF,MAAM,CAAC,SAAS,CACd;YACE,OAAO,EAAE,SAAS;YAClB,WAAW,EAAE,SAAS;SACvB,EACD,8BAA8B,CAC5B,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,EACtB;YACE,eAAe,EAAE,IAAI;SACtB,CACF,CACF,CAAC;QAEF,MAAM,CAAC,SAAS,CACd;YACE,WAAW,EAAE,SAAS;YACtB,OAAO,EAAE,SAAS;SACnB,EACD,8BAA8B,CAC5B,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,EACtB;YACE,aAAa,EAAE,IAAI;SACpB,CACF,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,SAAS,CAAC;QAEtB,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CACH,8BAA8B,CAC5B,EAAE,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAC/B;YACE,aAAa,EAAE,IAAI;YACnB,eAAe,EAAE,IAAI;SACtB,CACF,EACH,0DAA0D,CAC3D,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;YACnB,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;YAE9C,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;YAEtD,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;YAExD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;YACnB,MAAM,MAAM,GAAG,sBAAsB,CAAC;gBACpC,SAAS,EAAE,SAAS;gBACpB,WAAW,EAAE,SAAS;aACvB,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,MAAM,GAAG,sBAAsB,CAAC;gBACpC,SAAS,EAAE,MAAM;gBACjB,WAAW,EAAE,QAAQ;aACtB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,MAAM,GAAG,sBAAsB,CAAC;gBACpC,SAAS,EAAE,WAAW;gBACtB,WAAW,EAAE,eAAe;aAC7B,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,MAAM,GAAG,sBAAsB,CAAC;gBACpC,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;aAChC,CAAC,CAAC;YAEH,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC7C,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,KAAK,GAAG,6BAA6B,CAAC,gDAAgD,CAAC,CAAC;YAC9F,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;QACpD,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACtC,kFAAkF;YAClF,gGAAgG;YAChG,oEAAoE;YACpE,iFAAiF;YACjF,EAAE,CAAC,+BAA+B,KAAK,wBAAwB,EAAE,GAAG,EAAE;gBACpE,MAAM,WAAW,GAA2C;oBAC1D,WAAW,EAAE,sBAAsB;oBACnC,GAAG,EAAE,KAAK;oBACV,UAAU,EAAE,KAAK;oBACjB,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;iBAC5D,CAAC;gBACF,WAAW,CAAC,KAAK,GAAG,KAAY,CAAC;gBACjC,MAAM,CAAC,SAAS,CACd,oCAAoC,CAAC,WAAW,CAAC,EACjD,WAA2D,EAC3D,sBAAsB,CACvB,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,+BAA+B,KAAK,4BAA4B,EAAE,GAAG,EAAE;gBACxE,MAAM,OAAO,GAA+C;oBAC1D,WAAW,EAAE,0BAA0B;oBACvC,GAAG,EAAE,KAAK;oBACV,UAAU,EAAE,KAAK;oBACjB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;iBAC3B,CAAC;gBACF,OAAO,CAAC,KAAK,GAAG,KAAY,CAAC;gBAC7B,MAAM,CAAC,SAAS,CACd,oCAAoC,CAAC,OAAO,CAAC,EAC7C,OAAc,EACd,sBAAsB,CACvB,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,mBAAmB,GAA2B;QAClD,SAAS,EAAE;YACT,OAAO,EAAE;gBACP,GAAG,EAAE,QAAQ;gBACb,WAAW,EAAE;oBACX,OAAO,EAAE,IAAI;oBACb,gEAAgE;oBAChE,gBAAgB,EAAE,GAAG,EAAE,GAAE,CAAC;oBAC1B,gEAAgE;oBAChE,mBAAmB,EAAE,GAAG,EAAE,GAAE,CAAC;iBAC9B;gBACD,MAAM,EAAE,KAAK;gBACb,eAAe,EAAE,KAAK;gBACtB,OAAO,EAAE,EAAqB;gBAC9B,OAAO,EAAE,CAAC;gBACV,SAAS,EAAE,EAAE;aACd;YACD,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAqB;YAC9B,UAAU,EAAE,EAAE;YACd,aAAa,EAAE,EAAE;SAClB;KACF,CAAC;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,QAAQ,mBACZ,GAAG,EAAE,OAAO,EACZ,UAAU,EAAE,GAAG,EACf,UAAU,EAAE,KAAK,IACd,mBAAmB,CACvB,CAAC;QAEF,6BAA6B,CAAC,QAAQ,CAAC,CAAC;QAExC,oBAAoB;QACpB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;QAEpC,KAAK,MAAM,IAAI,IAAI,wCAAwC,EAAE,EAAE;YAC7D,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;SAClC;QAED,gEAAgE;QAChE,0EAA0E;QAC1E,wBAAwB;QACxB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;YAC7C,GAAG,EAAE,OAAO;YACZ,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,CAAC,oBAAoB,EAAE;YACrC,kEAAkE;YAClE,qCAAqC;YACrC,UAAU,EAAE,IAAI;YAChB,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,SAAS;SACN,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,oBAAoB,GAAG,uCAAuC,iBAEhE,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,IAAI,IACT,mBAAmB,GAExB,GAAG,CACJ,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,CAAC;QAE5D,0EAA0E;QAC1E,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAE3E,qDAAqD;QACrD,MAAM,CAAC,cAAc,CAAC,oBAAoB,EAAE,WAAW,EAAE;YACvD,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,CAAC,oBAAoB,EAAE;YACrC,UAAU,EAAE,IAAI;YAChB,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,mBAAmB,CAAC,SAAS;SAC9B,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,oBAAoB,GAAG,yBAAyB,iBACpD,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,IAAI,IACT,mBAAmB,EACtB,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,CAAC;QAE5D,0EAA0E;QAC1E,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QAE7D,qDAAqD;QACrD,MAAM,CAAC,cAAc,CAAC,oBAAoB,EAAE,WAAW,EAAE;YACvD,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,CAAC,oBAAoB,EAAE;YACrC,UAAU,EAAE,IAAI;YAChB,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,mBAAmB,CAAC,SAAS;SAC9B,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,MAAM,GAAG,gCAAgC,EAAE,CAAC;QAElD,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,MAAM,CAAE,CAAC,IAAI,EAAE,EAAE;YACtD,cAAc;YACd,MAAM;YACN,KAAK;YACL,OAAO;YACP,eAAe;YACf,QAAQ;YACR,MAAM;YACN,OAAO;SACR,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,CAAC;QAC1D,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH;;;;OAIG;IACH,SAAS,gCAAgC;QACvC,MAAM,iCAAiC,GAAmC;YACxE,WAAW,EAAE,EAAE;YACf,IAAI,EAAE,EAAE;YACR,GAAG,EAAE,EAAE;YACP,KAAK,EAAE,EAAE;YACT,YAAY,EAAE,IAAI,IAAI,EAAE;YACxB,UAAU,EAAE,IAAI;YAChB,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,EAAE;SACV,CAAC;QAEF,OAAO,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,IAAI,EAAoC,CAAC;IACjG,CAAC;IAED,SAAS,wCAAwC;QAI/C,MAAM,IAAI,GAAG,gCAAgC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC;QAE/E,OAAO,IAAoD,CAAC;IAC9D,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n checkAndFormatIfAndIfNoneMatch,\n formatFiltersAndSelect,\n extractAfterTokenFromNextLink,\n quoteETag,\n makeConfigurationSettingEmpty,\n transformKeyValue,\n transformKeyValueResponseWithStatusCode,\n transformKeyValueResponse,\n formatFieldsForSelect,\n serializeAsConfigurationSettingParam,\n} from \"../../src/internal/helpers\";\nimport { assert } from \"chai\";\nimport {\n ConfigurationSetting,\n ConfigurationSettingParam,\n featureFlagContentType,\n HttpResponseField,\n HttpResponseFields,\n secretReferenceContentType,\n} from \"../../src\";\nimport { FeatureFlagValue } from \"../../src/featureFlag\";\nimport { SecretReferenceValue } from \"../../src/secretReference\";\nimport { HttpHeadersLike } from \"@azure/core-http-compat\";\n\ndescribe(\"helper methods\", () => {\n it(\"checkAndFormatIfAndIfNoneMatch\", () => {\n const key = \"ignored\";\n\n assert.deepEqual(\n {\n ifMatch: undefined,\n ifNoneMatch: undefined,\n },\n checkAndFormatIfAndIfNoneMatch({ key }, {})\n );\n\n assert.deepEqual(\n {\n ifMatch: '\"hello\"',\n ifNoneMatch: undefined,\n },\n checkAndFormatIfAndIfNoneMatch(\n { key, etag: \"hello\" },\n {\n onlyIfUnchanged: true,\n }\n )\n );\n\n assert.deepEqual(\n {\n ifNoneMatch: '\"hello\"',\n ifMatch: undefined,\n },\n checkAndFormatIfAndIfNoneMatch(\n { key, etag: \"hello\" },\n {\n onlyIfChanged: true,\n }\n )\n );\n });\n\n it(\"checkAndFormatIfAndIfNoneMatch - mutually exclusive\", () => {\n const key = \"ignored\";\n\n assert.throws(\n () =>\n checkAndFormatIfAndIfNoneMatch(\n { key, etag: \"won't get used\" },\n {\n onlyIfChanged: true,\n onlyIfUnchanged: true,\n }\n ),\n /onlyIfChanged and onlyIfUnchanged are mutually-exclusive/\n );\n });\n\n describe(\"quoteETag\", () => {\n it(\"undefined\", () => {\n assert.equal(undefined, quoteETag(undefined));\n\n assert.equal('\"etagishere\"', quoteETag(\"etagishere\"));\n\n assert.equal(\"'etagishere'\", quoteETag(\"'etagishere'\"));\n\n assert.equal(\"*\", quoteETag(\"*\"));\n });\n });\n\n describe(\"formatWildcards\", () => {\n it(\"undefined\", () => {\n const result = formatFiltersAndSelect({\n keyFilter: undefined,\n labelFilter: undefined,\n });\n\n assert.ok(!result.key);\n assert.ok(!result.label);\n });\n\n it(\"single values only\", () => {\n const result = formatFiltersAndSelect({\n keyFilter: \"key1\",\n labelFilter: \"label1\",\n });\n\n assert.equal(\"key1\", result.key);\n assert.equal(\"label1\", result.label);\n });\n\n it(\"multiple values\", () => {\n const result = formatFiltersAndSelect({\n keyFilter: \"key1,key2\",\n labelFilter: \"label1,label2\",\n });\n\n assert.equal(\"key1,key2\", result.key);\n assert.equal(\"label1,label2\", result.label);\n });\n\n it(\"fields map properly\", () => {\n const result = formatFiltersAndSelect({\n fields: [\"isReadOnly\", \"value\"],\n });\n\n assert.deepEqual([\"locked\", \"value\"], result.select);\n });\n });\n\n describe(\"extractAfterTokenFromNextLink\", () => {\n it(\"token is extracted and properly unescaped\", () => {\n const token = extractAfterTokenFromNextLink(\"/kv?key=someKey&api-version=1.0&after=bGlah%3D\");\n assert.equal(\"bGlah=\", token);\n });\n });\n\n describe(\"serializeAsConfigurationSettingParam\", () => {\n [`[]`, \"Hello World\"].forEach((value) => {\n // These values are unexpected for feature flag or secret reference config setting\n // These tests make sure the latest version supports such settings where the value is unexpected\n // as well because the older versions of the SDK support such cases.\n // These tests make sure the SDK is not broken for the users with such use cases.\n it(`serializer doesn't throw on ${value} as feature flag value`, () => {\n const featureFlag: ConfigurationSetting<FeatureFlagValue> = {\n contentType: featureFlagContentType,\n key: \"key\",\n isReadOnly: false,\n value: { conditions: { clientFilters: [] }, enabled: true },\n };\n featureFlag.value = value as any;\n assert.deepEqual(\n serializeAsConfigurationSettingParam(featureFlag),\n featureFlag as unknown as ConfigurationSettingParam<string>,\n \"setting was modified\"\n );\n });\n\n it(`serializer doesn't throw on ${value} as secret reference value`, () => {\n const setting: ConfigurationSetting<SecretReferenceValue> = {\n contentType: secretReferenceContentType,\n key: \"key\",\n isReadOnly: false,\n value: { secretId: \"abc\" },\n };\n setting.value = value as any;\n assert.deepEqual(\n serializeAsConfigurationSettingParam(setting),\n setting as any,\n \"setting was modified\"\n );\n });\n });\n });\n\n const fakeHttp204Response: HttpResponseField<any> = {\n _response: {\n request: {\n url: \"unused\",\n abortSignal: {\n aborted: true,\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n addEventListener: () => {},\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n removeEventListener: () => {},\n },\n method: \"GET\",\n withCredentials: false,\n headers: {} as HttpHeadersLike,\n timeout: 0,\n requestId: \"\",\n },\n status: 204,\n headers: {} as HttpHeadersLike,\n bodyAsText: \"\",\n parsedHeaders: {},\n },\n };\n\n it(\"makeConfigurationSettingEmpty\", () => {\n const response: ConfigurationSetting & HttpResponseField<any> & HttpResponseFields = {\n key: \"mykey\",\n statusCode: 204,\n isReadOnly: false,\n ...fakeHttp204Response,\n };\n\n makeConfigurationSettingEmpty(response);\n\n // key isn't touched\n assert.equal(\"mykey\", response.key);\n\n for (const name of getAllConfigurationSettingFieldsMinusKey()) {\n assert.ok(!response[name], name);\n }\n\n // These point is these properties are untouched and won't throw\n // since they're the only properties the user is allowed to touch on these\n // \"body empty\" objects.\n assert.equal(204, response._response.status);\n assert.equal(204, response.statusCode);\n });\n\n it(\"transformKeyValue\", () => {\n const configurationSetting = transformKeyValue({\n key: \"hello\",\n locked: true,\n });\n\n assert.deepEqual(configurationSetting, {\n // the 'locked' property should not be present in the object since\n // it should be 'renamed' to readOnly\n isReadOnly: true,\n key: \"hello\",\n value: undefined,\n } as unknown);\n });\n\n it(\"transformKeyValueResponseWithStatusCode\", () => {\n const configurationSetting = transformKeyValueResponseWithStatusCode(\n {\n key: \"hello\",\n locked: true,\n ...fakeHttp204Response,\n },\n 204\n );\n\n const actualKeys = Object.keys(configurationSetting).sort();\n\n // _response is explictly set to not enumerate, even in our copied object.\n assert.deepEqual(actualKeys, [\"isReadOnly\", \"key\", \"statusCode\", \"value\"]);\n\n // now make it enumerable so we can do our comparison\n Object.defineProperty(configurationSetting, \"_response\", {\n enumerable: true,\n });\n\n assert.deepEqual(configurationSetting, {\n isReadOnly: true,\n key: \"hello\",\n value: undefined,\n statusCode: 204,\n _response: fakeHttp204Response._response,\n } as unknown);\n });\n\n it(\"transformKeyValueResponse\", () => {\n const configurationSetting = transformKeyValueResponse({\n key: \"hello\",\n locked: true,\n ...fakeHttp204Response,\n });\n\n const actualKeys = Object.keys(configurationSetting).sort();\n\n // _response is explictly set to not enumerate, even in our copied object.\n assert.deepEqual(actualKeys, [\"isReadOnly\", \"key\", \"value\"]);\n\n // now make it enumerable so we can do our comparison\n Object.defineProperty(configurationSetting, \"_response\", {\n enumerable: true,\n });\n\n assert.deepEqual(configurationSetting, {\n isReadOnly: true,\n key: \"hello\",\n value: undefined,\n _response: fakeHttp204Response._response,\n } as unknown);\n });\n\n it(\"normalizeFilterFields\", () => {\n const fields = getAllConfigurationSettingFields();\n\n assert.deepEqual(formatFieldsForSelect(fields)!.sort(), [\n \"content_type\",\n \"etag\",\n \"key\",\n \"label\",\n \"last_modified\",\n \"locked\", // isReadOnly maps to this\n \"tags\",\n \"value\",\n ]);\n\n assert.ok(formatFieldsForSelect(undefined) === undefined);\n assert.deepEqual(formatFieldsForSelect([]), []);\n });\n\n /**\n * Gets all the properties from ConfigurationSetting, sorted ascending.\n *\n * @returns All property names, sorted ascending.\n */\n function getAllConfigurationSettingFields(): (keyof ConfigurationSetting)[] {\n const configObjectWithAllFieldsRequired: Required<ConfigurationSetting> = {\n contentType: \"\",\n etag: \"\",\n key: \"\",\n label: \"\",\n lastModified: new Date(),\n isReadOnly: true,\n tags: {},\n value: \"\",\n };\n\n return Object.keys(configObjectWithAllFieldsRequired).sort() as (keyof ConfigurationSetting)[];\n }\n\n function getAllConfigurationSettingFieldsMinusKey(): Exclude<\n keyof ConfigurationSetting,\n \"key\"\n >[] {\n const keys = getAllConfigurationSettingFields().filter((key) => key !== \"key\");\n\n return keys as Exclude<keyof ConfigurationSetting, \"key\">[];\n }\n});\n"]}
@@ -2,13 +2,11 @@
2
2
  // Licensed under the MIT license.
3
3
  // Copyright (c) Microsoft Corporation.
4
4
  // Licensed under the MIT License.
5
- import { parseSyncToken, SyncTokens } from "../../src/internal/synctokenpolicy";
5
+ import { SyncTokens, parseSyncToken } from "../../src/internal/synctokenpolicy";
6
6
  import { assert } from "chai";
7
7
  import { AppConfigurationClient } from "../../src";
8
8
  import nock from "nock";
9
- import { getUserAgentPrefix, packageVersion, } from "../../src/appConfigurationClient";
10
- import { createAppConfigurationClientForTests, assertThrowsRestError, startRecorder, } from "../public/utils/testHelpers";
11
- import * as chai from "chai";
9
+ import { assertThrowsRestError, createAppConfigurationClientForTests, startRecorder, } from "../public/utils/testHelpers";
12
10
  describe("http request related tests", function () {
13
11
  describe("unit tests", () => {
14
12
  describe("parseSyncToken", () => {
@@ -25,16 +23,6 @@ describe("http request related tests", function () {
25
23
  }
26
24
  });
27
25
  });
28
- it("useragent", () => {
29
- describe("with user prefix", () => {
30
- const prefix = getUserAgentPrefix("MyCustomUserAgent");
31
- chai.assert.match(prefix, new RegExp(`^MyCustomUserAgent azsdk-js-app-configuration/${packageVersion}+ core-http/[^ ]+.+$`), `Using a custom user agent`);
32
- });
33
- describe("without user prefix", () => {
34
- const prefix = getUserAgentPrefix(undefined);
35
- chai.assert.match(prefix, new RegExp(`^azsdk-js-app-configuration/${packageVersion}+ core-http/[^ ]+.+$`), `Using the default user agent`);
36
- });
37
- });
38
26
  describe("syncTokens", () => {
39
27
  it("basic", () => {
40
28
  const syncTokens = new SyncTokens();
@@ -1 +1 @@
1
- {"version":3,"file":"http.spec.js","sourceRoot":"","sources":["../../../test/internal/http.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { parseSyncToken, SyncTokens } from \"../../src/internal/synctokenpolicy\";\nimport { assert } from \"chai\";\nimport { AppConfigurationClient } from \"../../src\";\nimport nock from \"nock\";\nimport {\n getUserAgentPrefix,\n InternalAppConfigurationClientOptions,\n packageVersion,\n} from \"../../src/appConfigurationClient\";\nimport {\n createAppConfigurationClientForTests,\n assertThrowsRestError,\n startRecorder,\n} from \"../public/utils/testHelpers\";\n\nimport * as chai from \"chai\";\nimport { Recorder } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\n\ndescribe(\"http request related tests\", function () {\n describe(\"unit tests\", () => {\n describe(\"parseSyncToken\", () => {\n it(\"can parse various sync tokens\", () => {\n assert.deepEqual(parseSyncToken(\"theid=thevalue;sn=1\"), {\n id: \"theid\",\n value: \"thevalue\",\n sequenceNumber: 1,\n });\n });\n\n it(\"throws on invalid sync tokens\", () => {\n for (const invalidToken of [\"invalid token\", \"missing=sequencenumber\", \"key=value;\"]) {\n assert.throws(\n () => parseSyncToken(invalidToken),\n new RegExp(`Failed to parse sync token '${invalidToken}' with regex .+$`)\n );\n }\n });\n });\n\n it(\"useragent\", () => {\n describe(\"with user prefix\", () => {\n const prefix = getUserAgentPrefix(\"MyCustomUserAgent\");\n\n chai.assert.match(\n prefix,\n new RegExp(\n `^MyCustomUserAgent azsdk-js-app-configuration/${packageVersion}+ core-http/[^ ]+.+$`\n ),\n `Using a custom user agent`\n );\n });\n\n describe(\"without user prefix\", () => {\n const prefix = getUserAgentPrefix(undefined);\n\n chai.assert.match(\n prefix,\n new RegExp(`^azsdk-js-app-configuration/${packageVersion}+ core-http/[^ ]+.+$`),\n `Using the default user agent`\n );\n });\n });\n\n describe(\"syncTokens\", () => {\n it(\"basic\", () => {\n const syncTokens = new SyncTokens();\n syncTokens.addSyncTokenFromHeaderValue(\"a=value;sn=0\");\n\n // note that 'sn' is purposefully not serialized\n assert.equal(\"a=value\", syncTokens.getSyncTokenHeaderValue());\n\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2;sn=0\");\n assert.equal(\"a=value,b=value2\", splitAndSort(syncTokens.getSyncTokenHeaderValue()));\n\n // now we'll rev the sequence number field - it should overwrite the original value\n // for b\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2.1;sn=1\");\n assert.equal(\"a=value,b=value2.1\", splitAndSort(syncTokens.getSyncTokenHeaderValue()));\n\n // sending in an older version of an existing key should do nothing\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2.1;sn=0\");\n // note that 'b' didn't change\n assert.equal(\"a=value,b=value2.1\", splitAndSort(syncTokens.getSyncTokenHeaderValue()));\n\n // and sending in multiple values acts the same as passing them in one\n // at a time.\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2.2;sn=100,c=value3;sn=1\");\n assert.equal(\n \"a=value,b=value2.2,c=value3\",\n splitAndSort(syncTokens.getSyncTokenHeaderValue())\n );\n\n // and if we get back undefined (ie, the header wasn't there) then it\n // resets the entire thing\n // (sync tokens are temporary in nature and expire as things are committed\n // and moved out of cache)\n syncTokens.addSyncTokenFromHeaderValue(undefined);\n assert.ok(!syncTokens.getSyncTokenHeaderValue());\n });\n });\n });\n\n describe(\"custom client ID\", () => {\n let client: AppConfigurationClient;\n let recorder: Recorder;\n\n beforeEach(function (this: Context) {\n recorder = startRecorder(this);\n client = createAppConfigurationClientForTests() || this.skip();\n });\n\n afterEach(async function () {\n await recorder.stop();\n });\n\n it(\"custom client request ID\", async () => {\n const iterator = client.listConfigurationSettings({\n requestOptions: {\n customHeaders: {\n \"x-ms-client-request-id\": \"this is my custom client request id\",\n },\n },\n });\n\n await iterator.next();\n });\n\n it(\"default client request ID\", async () => {\n const iterator = client.listConfigurationSettings();\n await iterator.next();\n });\n });\n\n // these tests are only testing that the requests and responses are\n // properly extracting and sending the sync token header (which is\n // why they appear to not do much of anything meaningful with what\n // they send or reply back with).\n describe(\"request/reply tests for sync token headers\", () => {\n let client: AppConfigurationClient;\n let syncTokens: SyncTokens;\n let scope: nock.Scope;\n\n beforeEach(function (this: Context) {\n if (nock == null || nock.recorder == null) {\n this.skip();\n return;\n }\n\n syncTokens = new SyncTokens();\n\n client =\n createAppConfigurationClientForTests<InternalAppConfigurationClientOptions>({\n syncTokens: syncTokens,\n }) || this.skip();\n\n nock.recorder.clear();\n nock.restore();\n nock.cleanAll();\n if (!nock.isActive()) {\n nock.activate();\n }\n scope = nock(/.*/);\n });\n\n afterEach(function (this: Context) {\n if (nock == null || nock.recorder == null) {\n return;\n }\n\n if (!this.currentTest?.isPending()) {\n assert.ok(scope.isDone());\n }\n nock.recorder.clear();\n nock.restore();\n nock.cleanAll();\n });\n\n it(\"policy is setup properly to send sync tokens\", async function () {\n syncTokens.addSyncTokenFromHeaderValue(`hello=world;sn=1`);\n\n const policyScope = nock(/.*/, {\n reqheaders: {\n \"sync-token\": \"hello=world\",\n },\n })\n .get(/.*/)\n .reply(418);\n\n await assertThrowsRestError(\n async () =>\n client.getConfigurationSetting({\n key: \"doesntmatter\",\n }),\n 418\n );\n\n assert.ok(policyScope.isDone());\n });\n\n it(\"addConfigurationSetting\", async () => {\n scope.put(/.*/).reply(200, \"\", { \"sync-token\": \"addConfigurationSetting=value;sn=1\" });\n\n await client.addConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"addConfigurationSetting=value\");\n });\n\n it(\"getConfigurationSetting\", async () => {\n scope.get(/.*/).reply(200, \"\", { \"sync-token\": \"getConfigurationSetting=value;sn=1\" });\n\n await client.getConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"getConfigurationSetting=value\");\n });\n\n it(\"setConfigurationSetting\", async () => {\n scope.put(/.*/).reply(200, \"\", { \"sync-token\": \"setConfigurationSetting=value;sn=1\" });\n\n await client.setConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"setConfigurationSetting=value\");\n });\n\n it(\"deleteConfigurationSetting\", async () => {\n scope.delete(/.*/).reply(200, \"\", { \"sync-token\": \"deleteConfigurationSetting=value;sn=1\" });\n\n await client.deleteConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"deleteConfigurationSetting=value\");\n });\n\n it(\"listConfigurationSetting\", async () => {\n scope.get(/.*/).reply(200, \"\", { \"sync-token\": \"listConfigurationSetting=value;sn=1\" });\n\n const iterator = client.listConfigurationSettings({\n keyFilter: \"doesntmatter\",\n });\n\n await iterator.next();\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"listConfigurationSetting=value\");\n });\n\n it(\"listRevisions\", async () => {\n scope.get(/.*/).reply(200, \"\", { \"sync-token\": \"listRevisions=value;sn=1\" });\n\n const iterator = client.listRevisions({\n keyFilter: \"doesntmatter\",\n });\n\n await iterator.next();\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"listRevisions=value\");\n });\n\n it(\"setReadOnly (clear and set)\", async () => {\n scope.put(/.*/).reply(200, \"\", { \"sync-token\": \"setReadOnly=value;sn=1\" });\n\n scope.delete(/.*/).reply(200, \"\", { \"sync-token\": \"clearReadOnly=value;sn=1\" });\n\n await client.setReadOnly(\n {\n key: \"doesntmatter\",\n },\n true\n );\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"setReadOnly=value\");\n\n syncTokens.addSyncTokenFromHeaderValue(undefined); // clear out any previous sync tokens\n\n await client.setReadOnly(\n {\n key: \"doesntmatter\",\n },\n false\n );\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"clearReadOnly=value\");\n });\n });\n\n describe(\"syncToken\", async () => {\n it(\"update sync token\", async () => {\n const syncTokens = new SyncTokens();\n syncTokens.addSyncTokenFromHeaderValue(\"a=value;sn=0\");\n const client = new AppConfigurationClient(\n \"Endpoint=https://endpoint.azconfig.io;Id=abc;Secret=123\",\n { syncTokens } as InternalAppConfigurationClientOptions\n );\n assert.equal(\n syncTokens[\"_currentSyncTokens\"].size,\n 1,\n \"Unexpected number of syncTokens before the `update` call\"\n );\n client.updateSyncToken(\"b=value;sn=3\");\n assert.equal(\n syncTokens[\"_currentSyncTokens\"].size,\n 2,\n \"Unexpected number of syncTokens after the `update` call\"\n );\n assert.deepEqual(\n syncTokens[\"_currentSyncTokens\"].get(\"a\"),\n { id: \"a\", value: \"value\", sequenceNumber: 0 },\n \"Unexpected object present for key `a`\"\n );\n assert.deepEqual(\n syncTokens[\"_currentSyncTokens\"].get(\"b\"),\n { id: \"b\", value: \"value\", sequenceNumber: 3 },\n \"Unexpected object present for key `b`\"\n );\n });\n });\n});\n\nfunction splitAndSort(syncTokens: string | undefined): string {\n if (!syncTokens) {\n throw new Error(\"Undefined can't be split and sorted\");\n }\n\n return syncTokens.split(\",\").sort().join(\",\");\n}\n"]}
1
+ {"version":3,"file":"http.spec.js","sourceRoot":"","sources":["../../../test/internal/http.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EACL,qBAAqB,EACrB,oCAAoC,EACpC,aAAa,GACd,MAAM,6BAA6B,CAAC;AAKrC,QAAQ,CAAC,4BAA4B,EAAE;IACrC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;YAC9B,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;gBACvC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,qBAAqB,CAAC,EAAE;oBACtD,EAAE,EAAE,OAAO;oBACX,KAAK,EAAE,UAAU;oBACjB,cAAc,EAAE,CAAC;iBAClB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;gBACvC,KAAK,MAAM,YAAY,IAAI,CAAC,eAAe,EAAE,wBAAwB,EAAE,YAAY,CAAC,EAAE;oBACpF,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,EAClC,IAAI,MAAM,CAAC,+BAA+B,YAAY,kBAAkB,CAAC,CAC1E,CAAC;iBACH;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;YAC1B,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACf,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;gBACpC,UAAU,CAAC,2BAA2B,CAAC,cAAc,CAAC,CAAC;gBAEvD,gDAAgD;gBAChD,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,uBAAuB,EAAE,CAAC,CAAC;gBAE9D,UAAU,CAAC,2BAA2B,CAAC,eAAe,CAAC,CAAC;gBACxD,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,YAAY,CAAC,UAAU,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;gBAErF,mFAAmF;gBACnF,QAAQ;gBACR,UAAU,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,CAAC;gBAC1D,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,YAAY,CAAC,UAAU,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;gBAEvF,mEAAmE;gBACnE,UAAU,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,CAAC;gBAC1D,8BAA8B;gBAC9B,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,YAAY,CAAC,UAAU,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;gBAEvF,sEAAsE;gBACtE,aAAa;gBACb,UAAU,CAAC,2BAA2B,CAAC,iCAAiC,CAAC,CAAC;gBAC1E,MAAM,CAAC,KAAK,CACV,6BAA6B,EAC7B,YAAY,CAAC,UAAU,CAAC,uBAAuB,EAAE,CAAC,CACnD,CAAC;gBAEF,qEAAqE;gBACrE,0BAA0B;gBAC1B,0EAA0E;gBAC1E,0BAA0B;gBAC1B,UAAU,CAAC,2BAA2B,CAAC,SAAS,CAAC,CAAC;gBAClD,MAAM,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,uBAAuB,EAAE,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,IAAI,MAA8B,CAAC;QACnC,IAAI,QAAkB,CAAC;QAEvB,UAAU,CAAC;YACT,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,GAAG,oCAAoC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,KAAK;YACb,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,yBAAyB,CAAC;gBAChD,cAAc,EAAE;oBACd,aAAa,EAAE;wBACb,wBAAwB,EAAE,qCAAqC;qBAChE;iBACF;aACF,CAAC,CAAC;YAEH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,yBAAyB,EAAE,CAAC;YACpD,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,mEAAmE;IACnE,kEAAkE;IAClE,kEAAkE;IAClE,iCAAiC;IACjC,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;QAC1D,IAAI,MAA8B,CAAC;QACnC,IAAI,UAAsB,CAAC;QAC3B,IAAI,KAAiB,CAAC;QAEtB,UAAU,CAAC;YACT,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE;gBACzC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACZ,OAAO;aACR;YAED,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;YAE9B,MAAM;gBACJ,oCAAoC,CAAwC;oBAC1E,UAAU,EAAE,UAAU;iBACvB,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAEpB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;gBACpB,IAAI,CAAC,QAAQ,EAAE,CAAC;aACjB;YACD,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC;;YACR,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE;gBACzC,OAAO;aACR;YAED,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,SAAS,EAAE,CAAA,EAAE;gBAClC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;aAC3B;YACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK;YACtD,UAAU,CAAC,2BAA2B,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE;gBAC7B,UAAU,EAAE;oBACV,YAAY,EAAE,aAAa;iBAC5B;aACF,CAAC;iBACC,GAAG,CAAC,IAAI,CAAC;iBACT,KAAK,CAAC,GAAG,CAAC,CAAC;YAEd,MAAM,qBAAqB,CACzB,KAAK,IAAI,EAAE,CACT,MAAM,CAAC,uBAAuB,CAAC;gBAC7B,GAAG,EAAE,cAAc;aACpB,CAAC,EACJ,GAAG,CACJ,CAAC;YAEF,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACvC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,oCAAoC,EAAE,CAAC,CAAC;YAEvF,MAAM,MAAM,CAAC,uBAAuB,CAAC;gBACnC,GAAG,EAAE,cAAc;aACpB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,+BAA+B,CAAC,CAAC;QACtF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACvC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,oCAAoC,EAAE,CAAC,CAAC;YAEvF,MAAM,MAAM,CAAC,uBAAuB,CAAC;gBACnC,GAAG,EAAE,cAAc;aACpB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,+BAA+B,CAAC,CAAC;QACtF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACvC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,oCAAoC,EAAE,CAAC,CAAC;YAEvF,MAAM,MAAM,CAAC,uBAAuB,CAAC;gBACnC,GAAG,EAAE,cAAc;aACpB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,+BAA+B,CAAC,CAAC;QACtF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,uCAAuC,EAAE,CAAC,CAAC;YAE7F,MAAM,MAAM,CAAC,0BAA0B,CAAC;gBACtC,GAAG,EAAE,cAAc;aACpB,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,kCAAkC,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACxC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,qCAAqC,EAAE,CAAC,CAAC;YAExF,MAAM,QAAQ,GAAG,MAAM,CAAC,yBAAyB,CAAC;gBAChD,SAAS,EAAE,cAAc;aAC1B,CAAC,CAAC;YAEH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACtB,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,gCAAgC,CAAC,CAAC;QACvF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;YAC7B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAE7E,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC;gBACpC,SAAS,EAAE,cAAc;aAC1B,CAAC,CAAC;YAEH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACtB,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,qBAAqB,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAE3E,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAEhF,MAAM,MAAM,CAAC,WAAW,CACtB;gBACE,GAAG,EAAE,cAAc;aACpB,EACD,IAAI,CACL,CAAC;YAEF,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,mBAAmB,CAAC,CAAC;YAExE,UAAU,CAAC,2BAA2B,CAAC,SAAS,CAAC,CAAC,CAAC,qCAAqC;YAExF,MAAM,MAAM,CAAC,WAAW,CACtB;gBACE,GAAG,EAAE,cAAc;aACpB,EACD,KAAK,CACN,CAAC;YAEF,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,qBAAqB,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QAC/B,EAAE,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;YACjC,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;YACpC,UAAU,CAAC,2BAA2B,CAAC,cAAc,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,IAAI,sBAAsB,CACvC,yDAAyD,EACzD,EAAE,UAAU,EAA2C,CACxD,CAAC;YACF,MAAM,CAAC,KAAK,CACV,UAAU,CAAC,oBAAoB,CAAC,CAAC,IAAI,EACrC,CAAC,EACD,0DAA0D,CAC3D,CAAC;YACF,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CACV,UAAU,CAAC,oBAAoB,CAAC,CAAC,IAAI,EACrC,CAAC,EACD,yDAAyD,CAC1D,CAAC;YACF,MAAM,CAAC,SAAS,CACd,UAAU,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EACzC,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,EAC9C,uCAAuC,CACxC,CAAC;YACF,MAAM,CAAC,SAAS,CACd,UAAU,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EACzC,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,EAC9C,uCAAuC,CACxC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAS,YAAY,CAAC,UAA8B;IAClD,IAAI,CAAC,UAAU,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;KACxD;IAED,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { SyncTokens, parseSyncToken } from \"../../src/internal/synctokenpolicy\";\nimport { assert } from \"chai\";\nimport { AppConfigurationClient } from \"../../src\";\nimport nock from \"nock\";\nimport { InternalAppConfigurationClientOptions } from \"../../src/appConfigurationClient\";\nimport {\n assertThrowsRestError,\n createAppConfigurationClientForTests,\n startRecorder,\n} from \"../public/utils/testHelpers\";\n\nimport { Recorder } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\n\ndescribe(\"http request related tests\", function () {\n describe(\"unit tests\", () => {\n describe(\"parseSyncToken\", () => {\n it(\"can parse various sync tokens\", () => {\n assert.deepEqual(parseSyncToken(\"theid=thevalue;sn=1\"), {\n id: \"theid\",\n value: \"thevalue\",\n sequenceNumber: 1,\n });\n });\n\n it(\"throws on invalid sync tokens\", () => {\n for (const invalidToken of [\"invalid token\", \"missing=sequencenumber\", \"key=value;\"]) {\n assert.throws(\n () => parseSyncToken(invalidToken),\n new RegExp(`Failed to parse sync token '${invalidToken}' with regex .+$`)\n );\n }\n });\n });\n\n describe(\"syncTokens\", () => {\n it(\"basic\", () => {\n const syncTokens = new SyncTokens();\n syncTokens.addSyncTokenFromHeaderValue(\"a=value;sn=0\");\n\n // note that 'sn' is purposefully not serialized\n assert.equal(\"a=value\", syncTokens.getSyncTokenHeaderValue());\n\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2;sn=0\");\n assert.equal(\"a=value,b=value2\", splitAndSort(syncTokens.getSyncTokenHeaderValue()));\n\n // now we'll rev the sequence number field - it should overwrite the original value\n // for b\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2.1;sn=1\");\n assert.equal(\"a=value,b=value2.1\", splitAndSort(syncTokens.getSyncTokenHeaderValue()));\n\n // sending in an older version of an existing key should do nothing\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2.1;sn=0\");\n // note that 'b' didn't change\n assert.equal(\"a=value,b=value2.1\", splitAndSort(syncTokens.getSyncTokenHeaderValue()));\n\n // and sending in multiple values acts the same as passing them in one\n // at a time.\n syncTokens.addSyncTokenFromHeaderValue(\"b=value2.2;sn=100,c=value3;sn=1\");\n assert.equal(\n \"a=value,b=value2.2,c=value3\",\n splitAndSort(syncTokens.getSyncTokenHeaderValue())\n );\n\n // and if we get back undefined (ie, the header wasn't there) then it\n // resets the entire thing\n // (sync tokens are temporary in nature and expire as things are committed\n // and moved out of cache)\n syncTokens.addSyncTokenFromHeaderValue(undefined);\n assert.ok(!syncTokens.getSyncTokenHeaderValue());\n });\n });\n });\n\n describe(\"custom client ID\", () => {\n let client: AppConfigurationClient;\n let recorder: Recorder;\n\n beforeEach(function (this: Context) {\n recorder = startRecorder(this);\n client = createAppConfigurationClientForTests() || this.skip();\n });\n\n afterEach(async function () {\n await recorder.stop();\n });\n\n it(\"custom client request ID\", async () => {\n const iterator = client.listConfigurationSettings({\n requestOptions: {\n customHeaders: {\n \"x-ms-client-request-id\": \"this is my custom client request id\",\n },\n },\n });\n\n await iterator.next();\n });\n\n it(\"default client request ID\", async () => {\n const iterator = client.listConfigurationSettings();\n await iterator.next();\n });\n });\n\n // these tests are only testing that the requests and responses are\n // properly extracting and sending the sync token header (which is\n // why they appear to not do much of anything meaningful with what\n // they send or reply back with).\n describe(\"request/reply tests for sync token headers\", () => {\n let client: AppConfigurationClient;\n let syncTokens: SyncTokens;\n let scope: nock.Scope;\n\n beforeEach(function (this: Context) {\n if (nock == null || nock.recorder == null) {\n this.skip();\n return;\n }\n\n syncTokens = new SyncTokens();\n\n client =\n createAppConfigurationClientForTests<InternalAppConfigurationClientOptions>({\n syncTokens: syncTokens,\n }) || this.skip();\n\n nock.recorder.clear();\n nock.restore();\n nock.cleanAll();\n if (!nock.isActive()) {\n nock.activate();\n }\n scope = nock(/.*/);\n });\n\n afterEach(function (this: Context) {\n if (nock == null || nock.recorder == null) {\n return;\n }\n\n if (!this.currentTest?.isPending()) {\n assert.ok(scope.isDone());\n }\n nock.recorder.clear();\n nock.restore();\n nock.cleanAll();\n });\n\n it(\"policy is setup properly to send sync tokens\", async function () {\n syncTokens.addSyncTokenFromHeaderValue(`hello=world;sn=1`);\n\n const policyScope = nock(/.*/, {\n reqheaders: {\n \"sync-token\": \"hello=world\",\n },\n })\n .get(/.*/)\n .reply(418);\n\n await assertThrowsRestError(\n async () =>\n client.getConfigurationSetting({\n key: \"doesntmatter\",\n }),\n 418\n );\n\n assert.ok(policyScope.isDone());\n });\n\n it(\"addConfigurationSetting\", async () => {\n scope.put(/.*/).reply(200, \"\", { \"sync-token\": \"addConfigurationSetting=value;sn=1\" });\n\n await client.addConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"addConfigurationSetting=value\");\n });\n\n it(\"getConfigurationSetting\", async () => {\n scope.get(/.*/).reply(200, \"\", { \"sync-token\": \"getConfigurationSetting=value;sn=1\" });\n\n await client.getConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"getConfigurationSetting=value\");\n });\n\n it(\"setConfigurationSetting\", async () => {\n scope.put(/.*/).reply(200, \"\", { \"sync-token\": \"setConfigurationSetting=value;sn=1\" });\n\n await client.setConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"setConfigurationSetting=value\");\n });\n\n it(\"deleteConfigurationSetting\", async () => {\n scope.delete(/.*/).reply(200, \"\", { \"sync-token\": \"deleteConfigurationSetting=value;sn=1\" });\n\n await client.deleteConfigurationSetting({\n key: \"doesntmatter\",\n });\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"deleteConfigurationSetting=value\");\n });\n\n it(\"listConfigurationSetting\", async () => {\n scope.get(/.*/).reply(200, \"\", { \"sync-token\": \"listConfigurationSetting=value;sn=1\" });\n\n const iterator = client.listConfigurationSettings({\n keyFilter: \"doesntmatter\",\n });\n\n await iterator.next();\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"listConfigurationSetting=value\");\n });\n\n it(\"listRevisions\", async () => {\n scope.get(/.*/).reply(200, \"\", { \"sync-token\": \"listRevisions=value;sn=1\" });\n\n const iterator = client.listRevisions({\n keyFilter: \"doesntmatter\",\n });\n\n await iterator.next();\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"listRevisions=value\");\n });\n\n it(\"setReadOnly (clear and set)\", async () => {\n scope.put(/.*/).reply(200, \"\", { \"sync-token\": \"setReadOnly=value;sn=1\" });\n\n scope.delete(/.*/).reply(200, \"\", { \"sync-token\": \"clearReadOnly=value;sn=1\" });\n\n await client.setReadOnly(\n {\n key: \"doesntmatter\",\n },\n true\n );\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"setReadOnly=value\");\n\n syncTokens.addSyncTokenFromHeaderValue(undefined); // clear out any previous sync tokens\n\n await client.setReadOnly(\n {\n key: \"doesntmatter\",\n },\n false\n );\n\n assert.equal(syncTokens.getSyncTokenHeaderValue(), \"clearReadOnly=value\");\n });\n });\n\n describe(\"syncToken\", async () => {\n it(\"update sync token\", async () => {\n const syncTokens = new SyncTokens();\n syncTokens.addSyncTokenFromHeaderValue(\"a=value;sn=0\");\n const client = new AppConfigurationClient(\n \"Endpoint=https://endpoint.azconfig.io;Id=abc;Secret=123\",\n { syncTokens } as InternalAppConfigurationClientOptions\n );\n assert.equal(\n syncTokens[\"_currentSyncTokens\"].size,\n 1,\n \"Unexpected number of syncTokens before the `update` call\"\n );\n client.updateSyncToken(\"b=value;sn=3\");\n assert.equal(\n syncTokens[\"_currentSyncTokens\"].size,\n 2,\n \"Unexpected number of syncTokens after the `update` call\"\n );\n assert.deepEqual(\n syncTokens[\"_currentSyncTokens\"].get(\"a\"),\n { id: \"a\", value: \"value\", sequenceNumber: 0 },\n \"Unexpected object present for key `a`\"\n );\n assert.deepEqual(\n syncTokens[\"_currentSyncTokens\"].get(\"b\"),\n { id: \"b\", value: \"value\", sequenceNumber: 3 },\n \"Unexpected object present for key `b`\"\n );\n });\n });\n});\n\nfunction splitAndSort(syncTokens: string | undefined): string {\n if (!syncTokens) {\n throw new Error(\"Undefined can't be split and sorted\");\n }\n\n return syncTokens.split(\",\").sort().join(\",\");\n}\n"]}
@@ -4,7 +4,7 @@ import chai from "chai";
4
4
  import { AppConfigurationClient } from "../../../src";
5
5
  import { AbortController } from "@azure/abort-controller";
6
6
  import nock from "nock";
7
- import { generateUuid } from "@azure/core-http";
7
+ import { v4 as generateUuid } from "uuid";
8
8
  describe("Should not retry forever", () => {
9
9
  let client;
10
10
  const connectionString = "Endpoint=https://myappconfig.azconfig.io;Id=key:ai/u/fake;Secret=abcd=";
@@ -20,7 +20,7 @@ describe("Should not retry forever", () => {
20
20
  }, ["retry-after-ms", retryAfterMs]);
21
21
  }
22
22
  beforeEach(() => {
23
- client = new AppConfigurationClient(connectionString);
23
+ client = new AppConfigurationClient(connectionString, { retryOptions: { maxRetries: 3 } });
24
24
  });
25
25
  afterEach(async function () {
26
26
  nock.restore();
@@ -66,9 +66,10 @@ describe("Should not retry forever", () => {
66
66
  }
67
67
  catch (error) {
68
68
  errorWasThrown = true;
69
- chai.assert.equal(error.name, "RestError", "Unexpected error thrown");
70
- chai.assert.equal(JSON.parse(error.message).status, 429, "Unexpected error thrown");
71
- chai.assert.equal(JSON.parse(error.message).title, "Resource utilization has surpassed the assigned quota", "Unexpected error thrown");
69
+ const err = error;
70
+ chai.assert.equal(err.name, "RestError", "Unexpected error thrown");
71
+ chai.assert.equal(JSON.parse(err.message).status, 429, "Unexpected error thrown");
72
+ chai.assert.equal(JSON.parse(err.message).title, "Resource utilization has surpassed the assigned quota", "Unexpected error thrown");
72
73
  }
73
74
  chai.assert.equal(errorWasThrown, true, "Error was not thrown");
74
75
  chai.assert.equal(nock.pendingMocks().length, responseCount - 1 - 3, // one attempt + three retries
@@ -1 +1 @@
1
- {"version":3,"file":"throttlingRetryPolicy.spec.js","sourceRoot":"","sources":["../../../../test/internal/node/throttlingRetryPolicy.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport chai from \"chai\";\nimport { AppConfigurationClient } from \"../../../src\";\nimport { AbortController } from \"@azure/abort-controller\";\nimport nock from \"nock\";\nimport { generateUuid } from \"@azure/core-http\";\n\ndescribe(\"Should not retry forever\", () => {\n let client: AppConfigurationClient;\n const connectionString = \"Endpoint=https://myappconfig.azconfig.io;Id=key:ai/u/fake;Secret=abcd=\";\n\n function mockErrorResponse(retryAfterMs: string, persistence: boolean = true): void {\n if (!nock.isActive()) {\n nock.activate();\n }\n nock(\"https://myappconfig.azconfig.io:443\").persist(persistence).put(/.*/g).reply(\n 429,\n {\n type: \"https://azconfig.io/errors/too-many-requests\",\n title: \"Resource utilization has surpassed the assigned quota\",\n policy: \"Total Requests\",\n status: 429,\n },\n [\"retry-after-ms\", retryAfterMs]\n );\n }\n\n beforeEach(() => {\n client = new AppConfigurationClient(connectionString);\n });\n\n afterEach(async function () {\n nock.restore();\n nock.cleanAll();\n nock.enableNetConnect();\n });\n\n it(\"simulate the service throttling - honors the abort signal passed\", async () => {\n mockErrorResponse(\"123456\");\n const key = generateUuid();\n const numberOfSettings = 200;\n const promises = [];\n let errorWasThrown = false;\n try {\n for (let index = 0; index < numberOfSettings; index++) {\n promises.push(\n client.addConfigurationSetting(\n {\n key: key + \"-\" + index,\n value: \"added\",\n },\n {\n abortSignal: AbortController.timeout(1000),\n }\n )\n );\n }\n await Promise.all(promises);\n } catch (error) {\n errorWasThrown = true;\n chai.assert.equal((error as any).name, \"AbortError\", \"Unexpected error thrown\");\n }\n chai.assert.equal(errorWasThrown, true, \"Error was not thrown\");\n });\n\n it(\"should not retry forever without abortSignal\", async () => {\n const responseCount = 10;\n for (let index = 0; index < responseCount; index++) {\n mockErrorResponse(\"100\", false);\n }\n const key = generateUuid();\n let errorWasThrown = false;\n\n chai.assert.equal(\n nock.pendingMocks().length,\n responseCount,\n \"unexpected pending mocks before making the request\"\n );\n try {\n await client.addConfigurationSetting({\n key: key,\n value: \"added\",\n });\n } catch (error) {\n errorWasThrown = true;\n chai.assert.equal(error.name, \"RestError\", \"Unexpected error thrown\");\n chai.assert.equal(JSON.parse(error.message).status, 429, \"Unexpected error thrown\");\n chai.assert.equal(\n JSON.parse(error.message).title,\n \"Resource utilization has surpassed the assigned quota\",\n \"Unexpected error thrown\"\n );\n }\n chai.assert.equal(errorWasThrown, true, \"Error was not thrown\");\n chai.assert.equal(\n nock.pendingMocks().length,\n responseCount - 1 - 3, // one attempt + three retries\n \"unexpected pending mocks after the test was run\"\n );\n });\n});\n"]}
1
+ {"version":3,"file":"throttlingRetryPolicy.spec.js","sourceRoot":"","sources":["../../../../test/internal/node/throttlingRetryPolicy.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport chai from \"chai\";\nimport { AppConfigurationClient } from \"../../../src\";\nimport { AbortController } from \"@azure/abort-controller\";\nimport nock from \"nock\";\nimport { v4 as generateUuid } from \"uuid\";\nimport { RestError } from \"@azure/core-rest-pipeline\";\n\ndescribe(\"Should not retry forever\", () => {\n let client: AppConfigurationClient;\n const connectionString = \"Endpoint=https://myappconfig.azconfig.io;Id=key:ai/u/fake;Secret=abcd=\";\n\n function mockErrorResponse(retryAfterMs: string, persistence: boolean = true): void {\n if (!nock.isActive()) {\n nock.activate();\n }\n nock(\"https://myappconfig.azconfig.io:443\").persist(persistence).put(/.*/g).reply(\n 429,\n {\n type: \"https://azconfig.io/errors/too-many-requests\",\n title: \"Resource utilization has surpassed the assigned quota\",\n policy: \"Total Requests\",\n status: 429,\n },\n [\"retry-after-ms\", retryAfterMs]\n );\n }\n\n beforeEach(() => {\n client = new AppConfigurationClient(connectionString, { retryOptions: { maxRetries: 3 } });\n });\n\n afterEach(async function () {\n nock.restore();\n nock.cleanAll();\n nock.enableNetConnect();\n });\n\n it(\"simulate the service throttling - honors the abort signal passed\", async () => {\n mockErrorResponse(\"123456\");\n const key = generateUuid();\n const numberOfSettings = 200;\n const promises = [];\n let errorWasThrown = false;\n try {\n for (let index = 0; index < numberOfSettings; index++) {\n promises.push(\n client.addConfigurationSetting(\n {\n key: key + \"-\" + index,\n value: \"added\",\n },\n {\n abortSignal: AbortController.timeout(1000),\n }\n )\n );\n }\n await Promise.all(promises);\n } catch (error) {\n errorWasThrown = true;\n chai.assert.equal((error as any).name, \"AbortError\", \"Unexpected error thrown\");\n }\n chai.assert.equal(errorWasThrown, true, \"Error was not thrown\");\n });\n\n it(\"should not retry forever without abortSignal\", async () => {\n const responseCount = 10;\n for (let index = 0; index < responseCount; index++) {\n mockErrorResponse(\"100\", false);\n }\n const key = generateUuid();\n let errorWasThrown = false;\n\n chai.assert.equal(\n nock.pendingMocks().length,\n responseCount,\n \"unexpected pending mocks before making the request\"\n );\n try {\n await client.addConfigurationSetting({\n key: key,\n value: \"added\",\n });\n } catch (error) {\n errorWasThrown = true;\n const err = error as RestError;\n chai.assert.equal(err.name, \"RestError\", \"Unexpected error thrown\");\n chai.assert.equal(JSON.parse(err.message).status, 429, \"Unexpected error thrown\");\n chai.assert.equal(\n JSON.parse(err.message).title,\n \"Resource utilization has surpassed the assigned quota\",\n \"Unexpected error thrown\"\n );\n }\n chai.assert.equal(errorWasThrown, true, \"Error was not thrown\");\n chai.assert.equal(\n nock.pendingMocks().length,\n responseCount - 1 - 3, // one attempt + three retries\n \"unexpected pending mocks after the test was run\"\n );\n });\n});\n"]}
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
3
  import { AppConfigurationClient } from "../../src";
4
- import { startRecorder, getTokenAuthenticationCredential, } from "./utils/testHelpers";
4
+ import { getTokenAuthenticationCredential, startRecorder, } from "./utils/testHelpers";
5
5
  import { assert } from "chai";
6
6
  describe("Authentication", () => {
7
7
  let credsAndEndpoint;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.spec.js","sourceRoot":"","sources":["../../../test/public/auth.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EACL,aAAa,EACb,gCAAgC,GAEjC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAI9B,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAI,gBAAkC,CAAC;IACvC,IAAI,QAAkB,CAAC;IAEvB,UAAU,CAAC;QACT,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAC/B,gBAAgB,GAAG,gCAAgC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK;QACb,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,4BAA4B,EAAE,KAAK;QACpC,MAAM,MAAM,GAAG,IAAI,sBAAsB,CACvC,gBAAgB,CAAC,QAAQ,EACzB,gBAAgB,CAAC,UAAU,CAC5B,CAAC;QAEF,4DAA4D;QAC5D,uCAAuC;QACvC,MAAM,MAAM,CAAC,uBAAuB,CAAC;YACnC,GAAG,EAAE,6BAA6B,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;YACzE,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,IAAI,sBAAsB,CAAC,8BAA8B,CAAC,EAChE,6HAA6H,CAC9H,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,IAAI,sBAAsB,CAAC,SAAgB,CAAC,EAClD,6HAA6H,CAC9H,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AppConfigurationClient } from \"../../src\";\nimport {\n startRecorder,\n getTokenAuthenticationCredential,\n CredsAndEndpoint,\n} from \"./utils/testHelpers\";\nimport { assert } from \"chai\";\nimport { Recorder } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\n\ndescribe(\"Authentication\", () => {\n let credsAndEndpoint: CredsAndEndpoint;\n let recorder: Recorder;\n\n beforeEach(function (this: Context) {\n recorder = startRecorder(this);\n credsAndEndpoint = getTokenAuthenticationCredential() || this.skip();\n });\n\n afterEach(async function () {\n await recorder.stop();\n });\n it(\"token authentication works\", async function () {\n const client = new AppConfigurationClient(\n credsAndEndpoint.endpoint,\n credsAndEndpoint.credential\n );\n\n // it doesn't matter if any data comes in so long as we were\n // able to connect and call the service\n await client.addConfigurationSetting({\n key: `token-authentication-test-${recorder.newDate(\"label-1\").valueOf()}`,\n value: \"hello\",\n });\n });\n});\n\ndescribe(\"AppConfigurationClient constructor error cases\", () => {\n it(\"invalid connection string gives a decent error message\", () => {\n assert.throws(\n () => new AppConfigurationClient(\"an invalid connection string\"),\n /Invalid connection string\\. Valid connection strings should match the regex 'Endpoint=\\(\\.\\*\\);Id=\\(\\.\\*\\);Secret=\\(\\.\\*\\)'/\n );\n });\n\n it(\"undefined connection string gives a decent error message\", () => {\n assert.throws(\n () => new AppConfigurationClient(undefined as any),\n /Invalid connection string\\. Valid connection strings should match the regex 'Endpoint=\\(\\.\\*\\);Id=\\(\\.\\*\\);Secret=\\(\\.\\*\\)'/\n );\n });\n});\n"]}
1
+ {"version":3,"file":"auth.spec.js","sourceRoot":"","sources":["../../../test/public/auth.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAEL,gCAAgC,EAChC,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAI9B,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAI,gBAAkC,CAAC;IACvC,IAAI,QAAkB,CAAC;IAEvB,UAAU,CAAC;QACT,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAC/B,gBAAgB,GAAG,gCAAgC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK;QACb,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,4BAA4B,EAAE,KAAK;QACpC,MAAM,MAAM,GAAG,IAAI,sBAAsB,CACvC,gBAAgB,CAAC,QAAQ,EACzB,gBAAgB,CAAC,UAAU,CAC5B,CAAC;QAEF,4DAA4D;QAC5D,uCAAuC;QACvC,MAAM,MAAM,CAAC,uBAAuB,CAAC;YACnC,GAAG,EAAE,6BAA6B,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;YACzE,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,IAAI,sBAAsB,CAAC,8BAA8B,CAAC,EAChE,6HAA6H,CAC9H,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,IAAI,sBAAsB,CAAC,SAAgB,CAAC,EAClD,6HAA6H,CAC9H,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AppConfigurationClient } from \"../../src\";\nimport {\n CredsAndEndpoint,\n getTokenAuthenticationCredential,\n startRecorder,\n} from \"./utils/testHelpers\";\nimport { assert } from \"chai\";\nimport { Recorder } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\n\ndescribe(\"Authentication\", () => {\n let credsAndEndpoint: CredsAndEndpoint;\n let recorder: Recorder;\n\n beforeEach(function (this: Context) {\n recorder = startRecorder(this);\n credsAndEndpoint = getTokenAuthenticationCredential() || this.skip();\n });\n\n afterEach(async function () {\n await recorder.stop();\n });\n it(\"token authentication works\", async function () {\n const client = new AppConfigurationClient(\n credsAndEndpoint.endpoint,\n credsAndEndpoint.credential\n );\n\n // it doesn't matter if any data comes in so long as we were\n // able to connect and call the service\n await client.addConfigurationSetting({\n key: `token-authentication-test-${recorder.newDate(\"label-1\").valueOf()}`,\n value: \"hello\",\n });\n });\n});\n\ndescribe(\"AppConfigurationClient constructor error cases\", () => {\n it(\"invalid connection string gives a decent error message\", () => {\n assert.throws(\n () => new AppConfigurationClient(\"an invalid connection string\"),\n /Invalid connection string\\. Valid connection strings should match the regex 'Endpoint=\\(\\.\\*\\);Id=\\(\\.\\*\\);Secret=\\(\\.\\*\\)'/\n );\n });\n\n it(\"undefined connection string gives a decent error message\", () => {\n assert.throws(\n () => new AppConfigurationClient(undefined as any),\n /Invalid connection string\\. Valid connection strings should match the regex 'Endpoint=\\(\\.\\*\\);Id=\\(\\.\\*\\);Secret=\\(\\.\\*\\)'/\n );\n });\n});\n"]}
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { startRecorder, createAppConfigurationClientForTests, deleteKeyCompletely, assertThrowsRestError, } from "./utils/testHelpers";
3
+ import { assertThrowsRestError, createAppConfigurationClientForTests, deleteKeyCompletely, startRecorder, } from "./utils/testHelpers";
4
4
  import { assert } from "chai";
5
5
  describe("etags", () => {
6
6
  let client;
@@ -64,7 +64,6 @@ describe("etags", () => {
64
64
  });
65
65
  // to keep 'key' a required field we fill this out (but set all the other properties to undefined)
66
66
  assert.equal(response.key, key);
67
- assert.equal(response._response.status, 304);
68
67
  assert.equal(response.statusCode, 304);
69
68
  assert.ok(!response.contentType);
70
69
  assert.ok(!response.etag);
@@ -1 +1 @@
1
- {"version":3,"file":"etags.spec.js","sourceRoot":"","sources":["../../../test/public/etags.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AppConfigurationClient } from \"../../src\";\nimport {\n startRecorder,\n createAppConfigurationClientForTests,\n deleteKeyCompletely,\n assertThrowsRestError,\n} from \"./utils/testHelpers\";\nimport { assert } from \"chai\";\nimport { Recorder } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\n\ndescribe(\"etags\", () => {\n let client: AppConfigurationClient;\n let recorder: Recorder;\n let key: string;\n\n beforeEach(async function (this: Context) {\n recorder = startRecorder(this);\n key = recorder.getUniqueName(\"etags\");\n client = createAppConfigurationClientForTests() || this.skip();\n await client.addConfigurationSetting({\n key: key,\n value: \"some value\",\n });\n });\n\n afterEach(async function () {\n await deleteKeyCompletely([key], client);\n await recorder.stop();\n });\n\n // etag usage is 'opt-in' via the onlyIfChanged/onlyIfUnchanged options for certain calls\n // by default no etags are used.\n it(\"Get and set by default doesn't use etags\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n // by default - ignores the etag in 'addedSetting.etag' so last one in\n // wins\n addedSetting.value = \"some new value!\";\n await client.setConfigurationSetting(addedSetting);\n });\n\n it(\"Get and set, enabling etag checking using onlyIfUnchanged\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n addedSetting.value = \"some new value!\";\n\n // etag of the remote setting matches what we have so we're okay to update\n const newlyUpdatedSetting = await client.setConfigurationSetting(addedSetting, {\n onlyIfUnchanged: true,\n });\n assert.equal(newlyUpdatedSetting.value, addedSetting.value);\n\n const badEtagSetting = {\n ...addedSetting,\n etag: \"bogus\",\n };\n\n // trying to save with a non-matching etag (when we specifically said to only save if\n // nothing has changed) will result in a 412 (precondition failed)\n await assertThrowsRestError(\n () => client.setConfigurationSetting(badEtagSetting, { onlyIfUnchanged: true }),\n 412\n );\n });\n\n it(\"set with an old etag will throw RestError\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n addedSetting.value = \"some new value!\";\n\n // sneaky process B comes in and does an update (ie, does NOT\n // enable the etag)\n await client.setConfigurationSetting({\n ...addedSetting,\n value: \"sneaky user updated the field\",\n });\n\n // the value (and thus the etag) was changed behind our backs\n // so now this update (with the original etag) will throw.\n await assertThrowsRestError(\n () =>\n client.setConfigurationSetting(addedSetting, {\n onlyIfUnchanged: true,\n }),\n 412,\n \"Old etag will result in a failed update and error\"\n );\n });\n\n it(\"get using ifNoneMatch to only get the setting if it's changed (ie: safe GET)\", async () => {\n const originalSetting = await client.setConfigurationSetting({\n key: key,\n value: \"world\",\n });\n\n // only get the setting if it changed (it hasn't)\n const response = await client.getConfigurationSetting(originalSetting, {\n onlyIfChanged: true,\n });\n\n // to keep 'key' a required field we fill this out (but set all the other properties to undefined)\n assert.equal(response.key, key);\n assert.equal(response._response.status, 304);\n assert.equal(response.statusCode, 304);\n\n assert.ok(!response.contentType);\n assert.ok(!response.etag);\n assert.ok(!response.label);\n assert.ok(!response.lastModified);\n assert.ok(!response.isReadOnly);\n assert.ok(!response.tags);\n assert.ok(!response.value);\n\n // let's update it and then try again\n await client.setConfigurationSetting({ key: key, value: \"new world\" });\n\n const updatedSetting = await client.getConfigurationSetting({ key });\n\n assert.notEqual(\n originalSetting.etag,\n updatedSetting.etag,\n \"New content, new update, etags shouldn't match\"\n );\n\n assert.equal(200, updatedSetting.statusCode);\n\n // only get the setting if it changed (it has!)\n const configurationSetting = await client.getConfigurationSetting(originalSetting, {\n onlyIfChanged: true,\n });\n\n // now our retrieved setting matches what's on the server\n assert.equal(\"new world\", configurationSetting.value);\n assert.equal(updatedSetting.etag, configurationSetting.etag);\n });\n\n it(\"(set|clear)readonly using etags\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n const badEtagSetting = {\n ...addedSetting,\n etag: \"bogus\",\n };\n\n // etag won't match so we get a precondition failed\n await assertThrowsRestError(\n () =>\n client.setReadOnly(badEtagSetting, true, {\n onlyIfUnchanged: true,\n }),\n 412\n );\n\n let actualSetting = await client.getConfigurationSetting(badEtagSetting);\n // should not be read-only since it didn't match\n assert.ok(!actualSetting.isReadOnly);\n\n // and now that the etag matches we should be able to set the\n // key's value to read-onlly\n await client.setReadOnly(addedSetting, true, { onlyIfUnchanged: true });\n actualSetting = await client.getConfigurationSetting(addedSetting);\n assert.ok(actualSetting.isReadOnly);\n\n // now let's try to clear it (using a bogus etag so it won't match)\n await assertThrowsRestError(\n () =>\n client.setReadOnly(badEtagSetting, false, {\n onlyIfUnchanged: true,\n }),\n 412\n );\n\n // ...still readOnly\n actualSetting = await client.getConfigurationSetting(addedSetting);\n assert.ok(actualSetting.isReadOnly);\n\n // now we'll use the right etag (from the setting we just retrieved)\n await client.setReadOnly(actualSetting, false, {\n onlyIfUnchanged: true,\n });\n\n // and now it's no longer readOnly\n actualSetting = await client.getConfigurationSetting(addedSetting);\n assert.ok(!actualSetting.isReadOnly);\n });\n\n it(\"delete using etags\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n const badEtagSetting = {\n ...addedSetting,\n etag: \"bogus\",\n };\n\n await assertThrowsRestError(\n () => client.deleteConfigurationSetting(badEtagSetting, { onlyIfUnchanged: true }),\n 412\n );\n\n // obviously the setting is still there (or else this would throw)\n await client.getConfigurationSetting({ key });\n\n // this time we'll pass in the proper setting with the right etag\n await client.deleteConfigurationSetting(addedSetting, { onlyIfUnchanged: true });\n\n // and now the setting isn't found\n await assertThrowsRestError(() => client.getConfigurationSetting({ key }), 404);\n });\n});\n"]}
1
+ {"version":3,"file":"etags.spec.js","sourceRoot":"","sources":["../../../test/public/etags.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AppConfigurationClient } from \"../../src\";\nimport {\n assertThrowsRestError,\n createAppConfigurationClientForTests,\n deleteKeyCompletely,\n startRecorder,\n} from \"./utils/testHelpers\";\nimport { assert } from \"chai\";\nimport { Recorder } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\n\ndescribe(\"etags\", () => {\n let client: AppConfigurationClient;\n let recorder: Recorder;\n let key: string;\n\n beforeEach(async function (this: Context) {\n recorder = startRecorder(this);\n key = recorder.getUniqueName(\"etags\");\n client = createAppConfigurationClientForTests() || this.skip();\n await client.addConfigurationSetting({\n key: key,\n value: \"some value\",\n });\n });\n\n afterEach(async function () {\n await deleteKeyCompletely([key], client);\n await recorder.stop();\n });\n\n // etag usage is 'opt-in' via the onlyIfChanged/onlyIfUnchanged options for certain calls\n // by default no etags are used.\n it(\"Get and set by default doesn't use etags\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n // by default - ignores the etag in 'addedSetting.etag' so last one in\n // wins\n addedSetting.value = \"some new value!\";\n await client.setConfigurationSetting(addedSetting);\n });\n\n it(\"Get and set, enabling etag checking using onlyIfUnchanged\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n addedSetting.value = \"some new value!\";\n\n // etag of the remote setting matches what we have so we're okay to update\n const newlyUpdatedSetting = await client.setConfigurationSetting(addedSetting, {\n onlyIfUnchanged: true,\n });\n assert.equal(newlyUpdatedSetting.value, addedSetting.value);\n\n const badEtagSetting = {\n ...addedSetting,\n etag: \"bogus\",\n };\n\n // trying to save with a non-matching etag (when we specifically said to only save if\n // nothing has changed) will result in a 412 (precondition failed)\n await assertThrowsRestError(\n () => client.setConfigurationSetting(badEtagSetting, { onlyIfUnchanged: true }),\n 412\n );\n });\n\n it(\"set with an old etag will throw RestError\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n addedSetting.value = \"some new value!\";\n\n // sneaky process B comes in and does an update (ie, does NOT\n // enable the etag)\n await client.setConfigurationSetting({\n ...addedSetting,\n value: \"sneaky user updated the field\",\n });\n\n // the value (and thus the etag) was changed behind our backs\n // so now this update (with the original etag) will throw.\n await assertThrowsRestError(\n () =>\n client.setConfigurationSetting(addedSetting, {\n onlyIfUnchanged: true,\n }),\n 412,\n \"Old etag will result in a failed update and error\"\n );\n });\n\n it(\"get using ifNoneMatch to only get the setting if it's changed (ie: safe GET)\", async () => {\n const originalSetting = await client.setConfigurationSetting({\n key: key,\n value: \"world\",\n });\n\n // only get the setting if it changed (it hasn't)\n const response = await client.getConfigurationSetting(originalSetting, {\n onlyIfChanged: true,\n });\n\n // to keep 'key' a required field we fill this out (but set all the other properties to undefined)\n assert.equal(response.key, key);\n assert.equal(response.statusCode, 304);\n\n assert.ok(!response.contentType);\n assert.ok(!response.etag);\n assert.ok(!response.label);\n assert.ok(!response.lastModified);\n assert.ok(!response.isReadOnly);\n assert.ok(!response.tags);\n assert.ok(!response.value);\n\n // let's update it and then try again\n await client.setConfigurationSetting({ key: key, value: \"new world\" });\n\n const updatedSetting = await client.getConfigurationSetting({ key });\n\n assert.notEqual(\n originalSetting.etag,\n updatedSetting.etag,\n \"New content, new update, etags shouldn't match\"\n );\n\n assert.equal(200, updatedSetting.statusCode);\n\n // only get the setting if it changed (it has!)\n const configurationSetting = await client.getConfigurationSetting(originalSetting, {\n onlyIfChanged: true,\n });\n\n // now our retrieved setting matches what's on the server\n assert.equal(\"new world\", configurationSetting.value);\n assert.equal(updatedSetting.etag, configurationSetting.etag);\n });\n\n it(\"(set|clear)readonly using etags\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n const badEtagSetting = {\n ...addedSetting,\n etag: \"bogus\",\n };\n\n // etag won't match so we get a precondition failed\n await assertThrowsRestError(\n () =>\n client.setReadOnly(badEtagSetting, true, {\n onlyIfUnchanged: true,\n }),\n 412\n );\n\n let actualSetting = await client.getConfigurationSetting(badEtagSetting);\n // should not be read-only since it didn't match\n assert.ok(!actualSetting.isReadOnly);\n\n // and now that the etag matches we should be able to set the\n // key's value to read-onlly\n await client.setReadOnly(addedSetting, true, { onlyIfUnchanged: true });\n actualSetting = await client.getConfigurationSetting(addedSetting);\n assert.ok(actualSetting.isReadOnly);\n\n // now let's try to clear it (using a bogus etag so it won't match)\n await assertThrowsRestError(\n () =>\n client.setReadOnly(badEtagSetting, false, {\n onlyIfUnchanged: true,\n }),\n 412\n );\n\n // ...still readOnly\n actualSetting = await client.getConfigurationSetting(addedSetting);\n assert.ok(actualSetting.isReadOnly);\n\n // now we'll use the right etag (from the setting we just retrieved)\n await client.setReadOnly(actualSetting, false, {\n onlyIfUnchanged: true,\n });\n\n // and now it's no longer readOnly\n actualSetting = await client.getConfigurationSetting(addedSetting);\n assert.ok(!actualSetting.isReadOnly);\n });\n\n it(\"delete using etags\", async () => {\n const addedSetting = await client.getConfigurationSetting({ key });\n\n const badEtagSetting = {\n ...addedSetting,\n etag: \"bogus\",\n };\n\n await assertThrowsRestError(\n () => client.deleteConfigurationSetting(badEtagSetting, { onlyIfUnchanged: true }),\n 412\n );\n\n // obviously the setting is still there (or else this would throw)\n await client.getConfigurationSetting({ key });\n\n // this time we'll pass in the proper setting with the right etag\n await client.deleteConfigurationSetting(addedSetting, { onlyIfUnchanged: true });\n\n // and now the setting isn't found\n await assertThrowsRestError(() => client.getConfigurationSetting({ key }), 404);\n });\n});\n"]}
@@ -1,7 +1,8 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { createAppConfigurationClientForTests, assertThrowsRestError, deleteKeyCompletely, assertThrowsAbortError, startRecorder, } from "./utils/testHelpers";
3
+ import { assertThrowsAbortError, assertThrowsRestError, createAppConfigurationClientForTests, deleteKeyCompletely, startRecorder, } from "./utils/testHelpers";
4
4
  import { assert } from "chai";
5
+ import { isPlaybackMode } from "@azure-tools/test-recorder";
5
6
  describe("AppConfigurationClient (set|clear)ReadOnly", () => {
6
7
  let client;
7
8
  let recorder;
@@ -41,6 +42,10 @@ describe("AppConfigurationClient (set|clear)ReadOnly", () => {
41
42
  }), 409, "Delete should fail because the setting is read-only");
42
43
  });
43
44
  it("accepts operation options", async function () {
45
+ // Recorder checks for the recording and complains before core-rest-pipeline could throw the AbortError (Recorder v2 should help here)
46
+ // eslint-disable-next-line @typescript-eslint/no-invalid-this
47
+ if (isPlaybackMode())
48
+ this.skip();
44
49
  await client.getConfigurationSetting({
45
50
  key: testConfigSetting.key,
46
51
  label: testConfigSetting.label,