@cfworker/cosmos 1.12.1 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,10 +44,14 @@ import { CosmosClient } from '@cfworker/cosmos';
44
44
 
45
45
  // 🚨️ Do not commit your Cosmos DB master key to source control!
46
46
  // Use a bundler like Rollup, Parcel, or Webpack to interpolate your master key at build-time.
47
- const masterKey = '...top secret master key copied from the azure portal...';
47
+ const accountKey = '...top secret master key copied from the azure portal...';
48
48
  const endpoint = 'https://xxxxxxxxxxxx.documents.azure.com';
49
49
 
50
- const client = new CosmosClient({ endpoint, masterKey });
50
+ const client = new CosmosClient({ endpoint, accountKey });
51
+
52
+ // or
53
+
54
+ const client = new CosmosClient({ connectionString });
51
55
  ```
52
56
 
53
57
  ### Specify consistency level
@@ -58,7 +62,7 @@ You may override the default value when constructing the CosmosClient.
58
62
  ```ts
59
63
  const consistencyLevel = 'Eventual';
60
64
 
61
- const client = new CosmosClient({ endpoint, masterKey, consistencyLevel });
65
+ const client = new CosmosClient({ endpoint, accountKey, consistencyLevel });
62
66
  ```
63
67
 
64
68
  Most methods on CosmosClient accept a `consistencyLevel` argument to enable overriding the client's consistency level on a case-by-case basis.
@@ -76,7 +80,7 @@ You may specify default values for these arguments when constructing the CosmosC
76
80
  const dbId = 'my-db';
77
81
  const collId = 'my-coll';
78
82
 
79
- const client = new CosmosClient({ endpoint, masterKey, dbId, collId });
83
+ const client = new CosmosClient({ endpoint, accountKey, dbId, collId });
80
84
  ```
81
85
 
82
86
  ### Authenticating with resource tokens
package/dist/client.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { FeedResponse, ItemResponse } from './response.js';
2
2
  import { RetryPolicy } from './retry.js';
3
3
  import { SessionContainer } from './session.js';
4
- import { Collection, ConsistencyLevel, Database, Document, IndexingDirective, IndexingPolicy, OfferType, PartitionKeyDefinition, Resource } from './types.js';
5
- export interface CosmosClientConfig {
6
- endpoint: string;
7
- masterKey: string;
4
+ import { Collection, ConnectionInfo, ConsistencyLevel, Database, Document, IndexingDirective, IndexingPolicy, OfferType, PartitionKeyDefinition, Resource } from './types.js';
5
+ export declare type CosmosClientConfig = (ConnectionInfo & CosmosClientConfigBase) | ({
6
+ connectionString: string;
7
+ } & CosmosClientConfigBase);
8
+ interface CosmosClientConfigBase {
8
9
  retryPolicy?: RetryPolicy;
9
10
  consistencyLevel?: ConsistencyLevel;
10
11
  dbId?: string;
package/dist/client.js CHANGED
@@ -2,13 +2,19 @@ import { FeedResponse, ItemResponse } from './response.js';
2
2
  import { defaultRetryPolicy } from './retry.js';
3
3
  import { DefaultSessionContainer } from './session.js';
4
4
  import { getSigner } from './signer.js';
5
- import { assertArg, escapeNonASCII, uri } from './util.js';
5
+ import { assertArg, escapeNonASCII, parseConnectionString, uri } from './util.js';
6
6
  export class CosmosClient {
7
7
  constructor(config) {
8
8
  this.requestCharges = 0;
9
9
  this.retries = { count: 0, delayMs: 0 };
10
- this.endpoint = config.endpoint;
11
- this.signer = getSigner(config.masterKey);
10
+ let { endpoint, masterKey } = 'connectionString' in config
11
+ ? parseConnectionString(config.connectionString)
12
+ : config;
13
+ if (endpoint.endsWith('/')) {
14
+ endpoint = endpoint.slice(0, -1);
15
+ }
16
+ this.endpoint = endpoint;
17
+ this.signer = getSigner(masterKey);
12
18
  this.retryPolicy = config.retryPolicy ?? defaultRetryPolicy;
13
19
  this.consistencyLevel = config.consistencyLevel ?? 'Session';
14
20
  this.dbId = config.dbId;
@@ -16,7 +22,7 @@ export class CosmosClient {
16
22
  this.enableCrossPartitionQueries =
17
23
  config.enableCrossPartitionQueries ?? true;
18
24
  this.sessions = config.sessions ?? new DefaultSessionContainer();
19
- this.systemFetch = config.fetch ?? fetch.bind(self);
25
+ this.systemFetch = config.fetch ?? fetch.bind(globalThis);
20
26
  }
21
27
  async getDatabases(args = {}) {
22
28
  const url = this.endpoint + `/dbs`;
package/dist/signer.d.ts CHANGED
@@ -9,4 +9,4 @@ export declare class Signer {
9
9
  resourceId: string;
10
10
  };
11
11
  }
12
- export declare function getSigner(masterkey: string): Signer;
12
+ export declare function getSigner(masterKey: string): Signer;
package/dist/signer.js CHANGED
@@ -35,9 +35,9 @@ export class Signer {
35
35
  }
36
36
  }
37
37
  const signers = {};
38
- export function getSigner(masterkey) {
39
- if (!signers[masterkey]) {
40
- signers[masterkey] = new Signer(masterkey);
38
+ export function getSigner(masterKey) {
39
+ if (!signers[masterKey]) {
40
+ signers[masterKey] = new Signer(masterKey);
41
41
  }
42
- return signers[masterkey];
42
+ return signers[masterKey];
43
43
  }
package/dist/types.d.ts CHANGED
@@ -56,3 +56,7 @@ export interface Collection extends PersistedResource {
56
56
  _udfs: 'udfs/';
57
57
  _conflicts: 'conflicts/';
58
58
  }
59
+ export interface ConnectionInfo {
60
+ endpoint: string;
61
+ masterKey: string;
62
+ }
package/dist/util.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ConnectionInfo } from './types';
1
2
  export declare function escapeNonASCII(s: string): string;
2
3
  export declare function assertArg(name: string, value: any): asserts value;
3
4
  export declare function uri(strings: TemplateStringsArray, ...values: any[]): string;
5
+ export declare function parseConnectionString(connString: string): ConnectionInfo;
package/dist/util.js CHANGED
@@ -13,3 +13,24 @@ export function uri(strings, ...values) {
13
13
  }
14
14
  return s;
15
15
  }
16
+ export function parseConnectionString(connString) {
17
+ const props = {};
18
+ connString.split(';').forEach(kv => {
19
+ const pos = kv.indexOf('=');
20
+ if (pos < 1) {
21
+ return;
22
+ }
23
+ const key = kv.slice(0, pos);
24
+ const val = kv.slice(pos + 1);
25
+ if (key && val) {
26
+ props[key] = val;
27
+ }
28
+ });
29
+ if (!props.AccountEndpoint || !props.AccountKey) {
30
+ throw new Error('Invalid connection string');
31
+ }
32
+ return {
33
+ endpoint: props.AccountEndpoint,
34
+ masterKey: props.AccountKey
35
+ };
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfworker/cosmos",
3
- "version": "1.12.1",
3
+ "version": "1.13.1",
4
4
  "description": "Azure Cosmos DB client for Cloudflare Workers and service workers",
5
5
  "keywords": [
6
6
  "azure",
@@ -42,11 +42,11 @@
42
42
  "base64-arraybuffer": "^1.0.2"
43
43
  },
44
44
  "devDependencies": {
45
- "@cfworker/dev": "^1.13.1",
45
+ "@cfworker/dev": "^1.14.0",
46
46
  "@types/chai": "^4.3.0",
47
47
  "@types/mocha": "^9.1.0",
48
- "chai": "^4.3.4",
49
- "mocha": "^9.1.4",
48
+ "chai": "^4.3.6",
49
+ "mocha": "^9.2.1",
50
50
  "typescript": "^4.5.5"
51
51
  }
52
52
  }
package/src/client.ts CHANGED
@@ -4,6 +4,7 @@ import { DefaultSessionContainer, SessionContainer } from './session.js';
4
4
  import { getSigner, Signer } from './signer.js';
5
5
  import {
6
6
  Collection,
7
+ ConnectionInfo,
7
8
  ConsistencyLevel,
8
9
  Database,
9
10
  Document,
@@ -13,21 +14,25 @@ import {
13
14
  PartitionKeyDefinition,
14
15
  Resource
15
16
  } from './types.js';
16
- import { assertArg, escapeNonASCII, uri } from './util.js';
17
-
18
- export interface CosmosClientConfig {
19
- /**
20
- * Cosmos DB endpoint.
21
- * @example
22
- * "https://xxxxxxxxxx.documents.azure.com"
23
- */
24
- endpoint: string;
25
-
26
- /**
27
- * Cosmos DB master key.
28
- */
29
- masterKey: string;
30
-
17
+ import {
18
+ assertArg,
19
+ escapeNonASCII,
20
+ parseConnectionString,
21
+ uri
22
+ } from './util.js';
23
+
24
+ export type CosmosClientConfig =
25
+ | (ConnectionInfo & CosmosClientConfigBase)
26
+ | ({
27
+ /**
28
+ * Cosmos DB connection string.
29
+ * @example
30
+ * "AccountEndpoint=https://xxxxxxxxxx.documents.azure.com:443/;AccountKey=xxxxxxxxxx;"
31
+ */
32
+ connectionString: string;
33
+ } & CosmosClientConfigBase);
34
+
35
+ interface CosmosClientConfigBase {
31
36
  /**
32
37
  * The retry policy to use when requests are throttled.
33
38
  */
@@ -79,8 +84,15 @@ export class CosmosClient {
79
84
  public retries = { count: 0, delayMs: 0 };
80
85
 
81
86
  constructor(config: CosmosClientConfig) {
82
- this.endpoint = config.endpoint;
83
- this.signer = getSigner(config.masterKey);
87
+ let { endpoint, masterKey } =
88
+ 'connectionString' in config
89
+ ? parseConnectionString(config.connectionString)
90
+ : config;
91
+ if (endpoint.endsWith('/')) {
92
+ endpoint = endpoint.slice(0, -1);
93
+ }
94
+ this.endpoint = endpoint;
95
+ this.signer = getSigner(masterKey);
84
96
  this.retryPolicy = config.retryPolicy ?? defaultRetryPolicy;
85
97
  this.consistencyLevel = config.consistencyLevel ?? 'Session';
86
98
  this.dbId = config.dbId;
@@ -88,7 +100,7 @@ export class CosmosClient {
88
100
  this.enableCrossPartitionQueries =
89
101
  config.enableCrossPartitionQueries ?? true;
90
102
  this.sessions = config.sessions ?? new DefaultSessionContainer();
91
- this.systemFetch = config.fetch ?? fetch.bind(self);
103
+ this.systemFetch = config.fetch ?? fetch.bind(globalThis);
92
104
  }
93
105
 
94
106
  public async getDatabases(
package/src/signer.ts CHANGED
@@ -55,9 +55,9 @@ export class Signer {
55
55
 
56
56
  const signers: Record<string, Signer> = {};
57
57
 
58
- export function getSigner(masterkey: string) {
59
- if (!signers[masterkey]) {
60
- signers[masterkey] = new Signer(masterkey);
58
+ export function getSigner(masterKey: string) {
59
+ if (!signers[masterKey]) {
60
+ signers[masterKey] = new Signer(masterKey);
61
61
  }
62
- return signers[masterkey];
62
+ return signers[masterKey];
63
63
  }
package/src/types.ts CHANGED
@@ -66,3 +66,17 @@ export interface Collection extends PersistedResource {
66
66
  _udfs: 'udfs/';
67
67
  _conflicts: 'conflicts/';
68
68
  }
69
+
70
+ export interface ConnectionInfo {
71
+ /**
72
+ * Cosmos DB endpoint.
73
+ * @example
74
+ * "https://xxxxxxxxxx.documents.azure.com"
75
+ */
76
+ endpoint: string;
77
+
78
+ /**
79
+ * Cosmos DB key.
80
+ */
81
+ masterKey: string;
82
+ }
package/src/util.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ConnectionInfo } from './types';
2
+
1
3
  /**
2
4
  * Escape non-ASCII characters as \uXXXX
3
5
  */
@@ -29,3 +31,29 @@ export function uri(strings: TemplateStringsArray, ...values: any[]) {
29
31
  }
30
32
  return s;
31
33
  }
34
+
35
+ /**
36
+ * Parses a connection string for Cosmos DB.
37
+ * @param connString Cosmos DB connection string.
38
+ */
39
+ export function parseConnectionString(connString: string): ConnectionInfo {
40
+ const props: Record<string, string> = {};
41
+ connString.split(';').forEach(kv => {
42
+ const pos = kv.indexOf('=');
43
+ if (pos < 1) {
44
+ return;
45
+ }
46
+ const key = kv.slice(0, pos);
47
+ const val = kv.slice(pos + 1);
48
+ if (key && val) {
49
+ props[key] = val;
50
+ }
51
+ });
52
+ if (!props.AccountEndpoint || !props.AccountKey) {
53
+ throw new Error('Invalid connection string');
54
+ }
55
+ return {
56
+ endpoint: props.AccountEndpoint,
57
+ masterKey: props.AccountKey
58
+ };
59
+ }