@effect-app/infra 4.0.0-beta.330 → 4.0.0-beta.331

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @effect-app/infra
2
2
 
3
+ ## 4.0.0-beta.331
4
+
5
+ ### Patch Changes
6
+
7
+ - 65835a6: Create missing Cosmos containers without throughput when the account is serverless (offer read/replace returns 400). Provisioned databases still get autoscale when configured.
8
+ - effect-app@4.0.0-beta.331
9
+
3
10
  ## 4.0.0-beta.330
4
11
 
5
12
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"cosmos-client.d.ts","sourceRoot":"","sources":["../src/cosmos-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AACnF,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAIzC,eAAO,MAAM,gBAAgB,QAAS,MAAM,UAAU,MAAM;;gBACM,CAAA;;iBAGnD,UAAU,CAAC,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC;;AADxE,qBAAa,YAAa,SAAQ,iBAEJ;CAAG;AAEjC,eAAO,MAAM,EAAE,sEAA6C,CAAA;AAE5D,eAAO,MAAM,iBAAiB,cAAe,MAAM,UAAU,MAAM,4CACF,CAAA;AAEjE,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrD;AAED,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IAC7E,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IACjG,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CACnE;AAID,eAAO,MAAM,0BAA0B,OACjC,WAAW,QACT,gBAAgB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,eAC1B,yBAAyB,kBAcvC,CAAA"}
1
+ {"version":3,"file":"cosmos-client.d.ts","sourceRoot":"","sources":["../src/cosmos-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AACnF,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAC3C,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAIzC,eAAO,MAAM,gBAAgB,QAAS,MAAM,UAAU,MAAM;;gBACM,CAAA;;iBAGnD,UAAU,CAAC,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC;;AADxE,qBAAa,YAAa,SAAQ,iBAEJ;CAAG;AAEjC,eAAO,MAAM,EAAE,sEAA6C,CAAA;AAE5D,eAAO,MAAM,iBAAiB,cAAe,MAAM,UAAU,MAAM,4CACF,CAAA;AAEjE,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrD;AAED,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IAC7E,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IACjG,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CACnE;AAeD,eAAO,MAAM,0BAA0B,OACjC,WAAW,QACT,gBAAgB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,eAC1B,yBAAyB,kBAmBvC,CAAA"}
@@ -9,6 +9,16 @@ export class CosmosClient extends Context.Service()("@services/CosmosClient") {
9
9
  export const db = CosmosClient.pipe(Effect.map((_) => _.db));
10
10
  export const CosmosClientLayer = (cosmosUrl, dbName) => Layer.effect(CosmosClient, makeCosmosClient(cosmosUrl, dbName));
11
11
  const isNotFound = (e) => typeof e === "object" && e !== null && "code" in e && e.code === 404;
12
+ const isServerlessOfferError = (error) => {
13
+ const code = typeof error === "object" && error !== null && "code" in error ? error.code : undefined;
14
+ const message = error instanceof Error
15
+ ? error.message
16
+ : typeof error === "object" && error !== null && "message" in error
17
+ ? String(error.message)
18
+ : String(error);
19
+ const badRequest = code === 400 || code === "BadRequest" || code === "400";
20
+ return badRequest && message.toLowerCase().includes("not supported for serverless");
21
+ };
12
22
  export const createContainerIfNotExists = async (db, body, throughput) => {
13
23
  const maxThroughput = throughput?.autoscaleMaxThroughput;
14
24
  if (maxThroughput === undefined) {
@@ -18,7 +28,14 @@ export const createContainerIfNotExists = async (db, body, throughput) => {
18
28
  const exists = await db.container(body.id).read().then(() => true, (e) => isNotFound(e) ? false : Promise.reject(e));
19
29
  if (exists)
20
30
  return;
21
- const { resource: sharedOffer } = await db.readOffer();
22
- await db.containers.createIfNotExists(sharedOffer ? body : { ...body, maxThroughput });
31
+ try {
32
+ const { resource: sharedOffer } = await db.readOffer();
33
+ await db.containers.createIfNotExists(sharedOffer ? body : { ...body, maxThroughput });
34
+ }
35
+ catch (error) {
36
+ if (!isServerlessOfferError(error))
37
+ throw error;
38
+ await db.containers.createIfNotExists(body);
39
+ }
23
40
  };
24
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29zbW9zLWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb3Ntb3MtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBeUIsWUFBWSxJQUFJLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNuRixPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFBO0FBQzdDLE9BQU8sS0FBSyxNQUFNLE1BQU0sbUJBQW1CLENBQUE7QUFDM0MsT0FBTyxLQUFLLEtBQUssTUFBTSxrQkFBa0IsQ0FBQTtBQUV6QyxNQUFNLFVBQVUsR0FBRyxDQUFDLEdBQVcsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBRTVFLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsR0FBVyxFQUFFLE1BQWMsRUFBRSxFQUFFLENBQzlELE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7QUFFbEUsTUFBTSxPQUFPLFlBQWEsU0FBUSxPQUFPLENBQUMsT0FBTyxFQUU3QyxDQUFDLHdCQUF3QixDQUFDO0NBQUc7QUFFakMsTUFBTSxDQUFDLE1BQU0sRUFBRSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7QUFFNUQsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxTQUFpQixFQUFFLE1BQWMsRUFBRSxFQUFFLENBQ3JFLEtBQUssQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBbUJqRSxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQVUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLEdBQUcsQ0FBQTtBQUV2RyxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxLQUFLLEVBQzdDLEVBQWUsRUFDZixJQUF1QyxFQUN2QyxVQUFzQyxFQUN0QyxFQUFFO0lBQ0YsTUFBTSxhQUFhLEdBQUcsVUFBVSxFQUFFLHNCQUFzQixDQUFBO0lBQ3hELElBQUksYUFBYSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMzQyxPQUFNO0lBQ1IsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUNwRCxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQ1YsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUNqRCxDQUFBO0lBQ0QsSUFBSSxNQUFNO1FBQUUsT0FBTTtJQUNsQixNQUFNLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFBO0lBQ3RELE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksRUFBRSxhQUFhLEVBQUUsQ0FBQyxDQUFBO0FBQ3hGLENBQUMsQ0FBQSJ9
41
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29zbW9zLWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb3Ntb3MtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBeUIsWUFBWSxJQUFJLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUNuRixPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFBO0FBQzdDLE9BQU8sS0FBSyxNQUFNLE1BQU0sbUJBQW1CLENBQUE7QUFDM0MsT0FBTyxLQUFLLEtBQUssTUFBTSxrQkFBa0IsQ0FBQTtBQUV6QyxNQUFNLFVBQVUsR0FBRyxDQUFDLEdBQVcsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBRTVFLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsR0FBVyxFQUFFLE1BQWMsRUFBRSxFQUFFLENBQzlELE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7QUFFbEUsTUFBTSxPQUFPLFlBQWEsU0FBUSxPQUFPLENBQUMsT0FBTyxFQUU3QyxDQUFDLHdCQUF3QixDQUFDO0NBQUc7QUFFakMsTUFBTSxDQUFDLE1BQU0sRUFBRSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7QUFFNUQsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxTQUFpQixFQUFFLE1BQWMsRUFBRSxFQUFFLENBQ3JFLEtBQUssQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFF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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "4.0.0-beta.330",
3
+ "version": "4.0.0-beta.331",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -16,7 +16,7 @@
16
16
  "proper-lockfile": "^4.1.2",
17
17
  "pure-rand": "8.4.0",
18
18
  "query-string": "^9.4.0",
19
- "effect-app": "4.0.0-beta.330"
19
+ "effect-app": "4.0.0-beta.331"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@azure/cosmos": "^4.9.3",
@@ -36,6 +36,17 @@ export interface ContainerDb {
36
36
 
37
37
  const isNotFound = (e: unknown) => typeof e === "object" && e !== null && "code" in e && e.code === 404
38
38
 
39
+ const isServerlessOfferError = (error: unknown): boolean => {
40
+ const code = typeof error === "object" && error !== null && "code" in error ? error.code : undefined
41
+ const message = error instanceof Error
42
+ ? error.message
43
+ : typeof error === "object" && error !== null && "message" in error
44
+ ? String(error.message)
45
+ : String(error)
46
+ const badRequest = code === 400 || code === "BadRequest" || code === "400"
47
+ return badRequest && message.toLowerCase().includes("not supported for serverless")
48
+ }
49
+
39
50
  export const createContainerIfNotExists = async (
40
51
  db: ContainerDb,
41
52
  body: ContainerRequest & { id: string },
@@ -51,6 +62,11 @@ export const createContainerIfNotExists = async (
51
62
  (e) => isNotFound(e) ? false : Promise.reject(e)
52
63
  )
53
64
  if (exists) return
54
- const { resource: sharedOffer } = await db.readOffer()
55
- await db.containers.createIfNotExists(sharedOffer ? body : { ...body, maxThroughput })
65
+ try {
66
+ const { resource: sharedOffer } = await db.readOffer()
67
+ await db.containers.createIfNotExists(sharedOffer ? body : { ...body, maxThroughput })
68
+ } catch (error) {
69
+ if (!isServerlessOfferError(error)) throw error
70
+ await db.containers.createIfNotExists(body)
71
+ }
56
72
  }
@@ -3,7 +3,11 @@ import { type ContainerDb, createContainerIfNotExists } from "../src/cosmos-clie
3
3
 
4
4
  const body = { id: "prefix-Orders", partitionKey: { paths: ["/_partitionKey"], version: 2 } }
5
5
 
6
- const fakeDb = (opts: { readonly read: () => Promise<unknown>; readonly sharedOffer: boolean }) => {
6
+ const fakeDb = (opts: {
7
+ readonly read: () => Promise<unknown>
8
+ readonly sharedOffer: boolean
9
+ readonly offerError?: unknown
10
+ }) => {
7
11
  const calls = { created: [] as Array<unknown>, offerReads: 0 }
8
12
  const db: ContainerDb = {
9
13
  container: () => ({ read: opts.read }),
@@ -15,6 +19,7 @@ const fakeDb = (opts: { readonly read: () => Promise<unknown>; readonly sharedOf
15
19
  },
16
20
  readOffer: () => {
17
21
  calls.offerReads++
22
+ if (opts.offerError !== undefined) return Promise.reject(opts.offerError)
18
23
  return Promise.resolve({ resource: opts.sharedOffer ? { id: "offer" } : undefined })
19
24
  }
20
25
  }
@@ -58,4 +63,18 @@ describe("createContainerIfNotExists", () => {
58
63
  })
59
64
  expect(calls.created).toEqual([])
60
65
  })
66
+
67
+ it("creates without throughput when offer reads are rejected as serverless", async () => {
68
+ const { calls, db } = fakeDb({
69
+ read: missing,
70
+ sharedOffer: false,
71
+ offerError: {
72
+ code: 400,
73
+ message: "Reading or replacing offers is not supported for serverless accounts."
74
+ }
75
+ })
76
+ await createContainerIfNotExists(db, body, { autoscaleMaxThroughput: 1000 })
77
+ expect(calls.created).toEqual([body])
78
+ expect(calls.offerReads).toBe(1)
79
+ })
61
80
  })