@panorama-industries/effect-vercel-blob 0.0.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -1
  3. package/dist/client.d.ts +8 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +8 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/contracts/blob-client.d.ts +67 -0
  8. package/dist/contracts/blob-client.d.ts.map +1 -0
  9. package/dist/contracts/blob-client.js +11 -0
  10. package/dist/contracts/blob-client.js.map +1 -0
  11. package/dist/contracts/blob-config.d.ts +114 -0
  12. package/dist/contracts/blob-config.d.ts.map +1 -0
  13. package/dist/contracts/blob-config.js +7 -0
  14. package/dist/contracts/blob-config.js.map +1 -0
  15. package/dist/contracts/blob-domain.d.ts +336 -0
  16. package/dist/contracts/blob-domain.d.ts.map +1 -0
  17. package/dist/contracts/blob-domain.js +152 -0
  18. package/dist/contracts/blob-domain.js.map +1 -0
  19. package/dist/contracts/blob-errors.d.ts +125 -0
  20. package/dist/contracts/blob-errors.d.ts.map +1 -0
  21. package/dist/contracts/blob-errors.js +114 -0
  22. package/dist/contracts/blob-errors.js.map +1 -0
  23. package/dist/contracts/blob-signed-urls.d.ts +83 -0
  24. package/dist/contracts/blob-signed-urls.d.ts.map +1 -0
  25. package/dist/contracts/blob-signed-urls.js +10 -0
  26. package/dist/contracts/blob-signed-urls.js.map +1 -0
  27. package/dist/contracts/blob-store.d.ts +153 -0
  28. package/dist/contracts/blob-store.d.ts.map +1 -0
  29. package/dist/contracts/blob-store.js +15 -0
  30. package/dist/contracts/blob-store.js.map +1 -0
  31. package/dist/contracts/blob-uploads.d.ts +101 -0
  32. package/dist/contracts/blob-uploads.d.ts.map +1 -0
  33. package/dist/contracts/blob-uploads.js +17 -0
  34. package/dist/contracts/blob-uploads.js.map +1 -0
  35. package/dist/implementation/blob-client-live.d.ts +37 -0
  36. package/dist/implementation/blob-client-live.d.ts.map +1 -0
  37. package/dist/implementation/blob-client-live.js +213 -0
  38. package/dist/implementation/blob-client-live.js.map +1 -0
  39. package/dist/implementation/blob-config-live.d.ts +49 -0
  40. package/dist/implementation/blob-config-live.d.ts.map +1 -0
  41. package/dist/implementation/blob-config-live.js +82 -0
  42. package/dist/implementation/blob-config-live.js.map +1 -0
  43. package/dist/implementation/blob-live.d.ts +26 -0
  44. package/dist/implementation/blob-live.d.ts.map +1 -0
  45. package/dist/implementation/blob-live.js +26 -0
  46. package/dist/implementation/blob-live.js.map +1 -0
  47. package/dist/implementation/blob-signed-urls-live.d.ts +12 -0
  48. package/dist/implementation/blob-signed-urls-live.d.ts.map +1 -0
  49. package/dist/implementation/blob-signed-urls-live.js +92 -0
  50. package/dist/implementation/blob-signed-urls-live.js.map +1 -0
  51. package/dist/implementation/blob-store-live.d.ts +18 -0
  52. package/dist/implementation/blob-store-live.d.ts.map +1 -0
  53. package/dist/implementation/blob-store-live.js +364 -0
  54. package/dist/implementation/blob-store-live.js.map +1 -0
  55. package/dist/implementation/blob-uploads-live.d.ts +11 -0
  56. package/dist/implementation/blob-uploads-live.d.ts.map +1 -0
  57. package/dist/implementation/blob-uploads-live.js +218 -0
  58. package/dist/implementation/blob-uploads-live.js.map +1 -0
  59. package/dist/index.d.ts +15 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +15 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/internal/blob-errors.d.ts +79 -0
  64. package/dist/internal/blob-errors.d.ts.map +1 -0
  65. package/dist/internal/blob-errors.js +196 -0
  66. package/dist/internal/blob-errors.js.map +1 -0
  67. package/dist/internal/blob-request.d.ts +255 -0
  68. package/dist/internal/blob-request.d.ts.map +1 -0
  69. package/dist/internal/blob-request.js +291 -0
  70. package/dist/internal/blob-request.js.map +1 -0
  71. package/dist/internal/callback.d.ts +70 -0
  72. package/dist/internal/callback.d.ts.map +1 -0
  73. package/dist/internal/callback.js +141 -0
  74. package/dist/internal/callback.js.map +1 -0
  75. package/dist/internal/client-token.d.ts +65 -0
  76. package/dist/internal/client-token.d.ts.map +1 -0
  77. package/dist/internal/client-token.js +80 -0
  78. package/dist/internal/client-token.js.map +1 -0
  79. package/dist/internal/env.d.ts +34 -0
  80. package/dist/internal/env.d.ts.map +1 -0
  81. package/dist/internal/env.js +61 -0
  82. package/dist/internal/env.js.map +1 -0
  83. package/dist/internal/multipart.d.ts +110 -0
  84. package/dist/internal/multipart.d.ts.map +1 -0
  85. package/dist/internal/multipart.js +290 -0
  86. package/dist/internal/multipart.js.map +1 -0
  87. package/dist/internal/presign.d.ts +123 -0
  88. package/dist/internal/presign.d.ts.map +1 -0
  89. package/dist/internal/presign.js +345 -0
  90. package/dist/internal/presign.js.map +1 -0
  91. package/dist/internal/store-id.d.ts +38 -0
  92. package/dist/internal/store-id.d.ts.map +1 -0
  93. package/dist/internal/store-id.js +54 -0
  94. package/dist/internal/store-id.js.map +1 -0
  95. package/dist/internal/urls.d.ts +26 -0
  96. package/dist/internal/urls.d.ts.map +1 -0
  97. package/dist/internal/urls.js +33 -0
  98. package/dist/internal/urls.js.map +1 -0
  99. package/dist/internal/wire.d.ts +55 -0
  100. package/dist/internal/wire.d.ts.map +1 -0
  101. package/dist/internal/wire.js +64 -0
  102. package/dist/internal/wire.js.map +1 -0
  103. package/dist/internal/write-headers.d.ts +56 -0
  104. package/dist/internal/write-headers.d.ts.map +1 -0
  105. package/dist/internal/write-headers.js +82 -0
  106. package/dist/internal/write-headers.js.map +1 -0
  107. package/dist/testing/index.d.ts +2 -0
  108. package/dist/testing/index.d.ts.map +1 -0
  109. package/dist/testing/index.js +2 -0
  110. package/dist/testing/index.js.map +1 -0
  111. package/dist/testing/test-blob-store.d.ts +134 -0
  112. package/dist/testing/test-blob-store.d.ts.map +1 -0
  113. package/dist/testing/test-blob-store.js +718 -0
  114. package/dist/testing/test-blob-store.js.map +1 -0
  115. package/package.json +58 -4
  116. package/src/client.ts +11 -0
  117. package/src/contracts/blob-client.ts +121 -0
  118. package/src/contracts/blob-config.ts +64 -0
  119. package/src/contracts/blob-domain.ts +304 -0
  120. package/src/contracts/blob-errors.ts +161 -0
  121. package/src/contracts/blob-signed-urls.ts +112 -0
  122. package/src/contracts/blob-store.ts +258 -0
  123. package/src/contracts/blob-uploads.ts +151 -0
  124. package/src/implementation/blob-client-live.ts +387 -0
  125. package/src/implementation/blob-config-live.ts +145 -0
  126. package/src/implementation/blob-live.ts +55 -0
  127. package/src/implementation/blob-signed-urls-live.ts +121 -0
  128. package/src/implementation/blob-store-live.ts +528 -0
  129. package/src/implementation/blob-uploads-live.ts +326 -0
  130. package/src/index.ts +18 -0
  131. package/src/internal/blob-errors.ts +325 -0
  132. package/src/internal/blob-request.ts +617 -0
  133. package/src/internal/callback.ts +200 -0
  134. package/src/internal/client-token.ts +132 -0
  135. package/src/internal/env.ts +128 -0
  136. package/src/internal/multipart.ts +526 -0
  137. package/src/internal/presign.ts +477 -0
  138. package/src/internal/store-id.ts +69 -0
  139. package/src/internal/urls.ts +42 -0
  140. package/src/internal/wire.ts +80 -0
  141. package/src/internal/write-headers.ts +118 -0
  142. package/src/testing/index.ts +1 -0
  143. package/src/testing/test-blob-store.ts +1136 -0
@@ -0,0 +1,118 @@
1
+ import { Duration } from "effect";
2
+
3
+ import type { BlobAccess } from "../contracts/blob-domain.ts";
4
+
5
+ /** Header carrying each write option, as the SDK's `putOptionHeaderMap`. */
6
+ export const writeOptionHeaders = {
7
+ cacheControlMaxAge: "x-cache-control-max-age",
8
+ addRandomSuffix: "x-add-random-suffix",
9
+ allowOverwrite: "x-allow-overwrite",
10
+ contentType: "x-content-type",
11
+ access: "x-vercel-blob-access",
12
+ ifMatch: "x-if-match",
13
+ } as const;
14
+
15
+ /** A write option an endpoint may accept; `access` is always sent and needs no listing. */
16
+ export type WriteOption = Exclude<keyof typeof writeOptionHeaders, "access">;
17
+
18
+ /**
19
+ * Write options as any write operation receives them. `CreateBlobOptions`, `PutOptions` and the
20
+ * client upload options are all assignable to it.
21
+ */
22
+ export interface WriteHeaderOptions {
23
+ readonly access: BlobAccess;
24
+ readonly addRandomSuffix?: boolean | undefined;
25
+ readonly allowOverwrite?: boolean | undefined;
26
+ readonly contentType?: string | undefined;
27
+ readonly cacheControlMaxAge?: Duration.Input | undefined;
28
+ readonly ifMatch?: string | undefined;
29
+ }
30
+
31
+ /** The `allowedOptions` each SDK write method passes to `createPutHeaders`. */
32
+ export const allowedWriteOptions = {
33
+ /** `put` (single and multipart), `createMultipartUpload`. */
34
+ put: ["cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "contentType", "ifMatch"],
35
+ /** `uploadPart` and `completeMultipartUpload`: no `ifMatch`. */
36
+ multipartPart: ["cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "contentType"],
37
+ /** `putImage`: the optimizer decides the media type. */
38
+ putImage: ["cacheControlMaxAge", "addRandomSuffix", "allowOverwrite", "ifMatch"],
39
+ /** Every browser (client token) write: the token fixes the rest. */
40
+ client: ["contentType"],
41
+ } as const satisfies Record<string, ReadonlyArray<WriteOption>>;
42
+
43
+ /**
44
+ * The cache lifetime in whole seconds, as sent in `x-cache-control-max-age`. Note that a bare
45
+ * number is a `Duration.Input` in milliseconds.
46
+ */
47
+ export const cacheControlMaxAgeSeconds = (maxAge: Duration.Input): number =>
48
+ Math.floor(Duration.toSeconds(maxAge));
49
+
50
+ /**
51
+ * Port of the SDK's `createPutHeaders`: the headers for the write options that `allowedOptions`
52
+ * lists, plus `x-vercel-blob-access` always.
53
+ *
54
+ * Booleans are sent as `1`/`0`. `ifMatch` (when allowed and non-empty) implies
55
+ * `x-allow-overwrite: 1` unless `allowOverwrite` is set explicitly; the option types already rule
56
+ * out `ifMatch` with `allowOverwrite: false`. An empty `contentType` is not sent.
57
+ */
58
+ export const writeHeaders = (
59
+ allowedOptions: ReadonlyArray<WriteOption>,
60
+ options: WriteHeaderOptions,
61
+ ): Record<string, string> => {
62
+ const headers: Record<string, string> = {};
63
+ headers[writeOptionHeaders.access] = options.access;
64
+
65
+ if (allowedOptions.includes("contentType") && options.contentType) {
66
+ headers[writeOptionHeaders.contentType] = options.contentType;
67
+ }
68
+
69
+ if (allowedOptions.includes("addRandomSuffix") && options.addRandomSuffix !== undefined) {
70
+ headers[writeOptionHeaders.addRandomSuffix] = options.addRandomSuffix ? "1" : "0";
71
+ }
72
+
73
+ if (allowedOptions.includes("ifMatch") && options.ifMatch) {
74
+ headers[writeOptionHeaders.ifMatch] = options.ifMatch;
75
+ if (allowedOptions.includes("allowOverwrite") && options.allowOverwrite === undefined) {
76
+ headers[writeOptionHeaders.allowOverwrite] = "1";
77
+ }
78
+ }
79
+
80
+ if (allowedOptions.includes("allowOverwrite") && options.allowOverwrite !== undefined) {
81
+ headers[writeOptionHeaders.allowOverwrite] = options.allowOverwrite ? "1" : "0";
82
+ }
83
+
84
+ if (allowedOptions.includes("cacheControlMaxAge") && options.cacheControlMaxAge !== undefined) {
85
+ headers[writeOptionHeaders.cacheControlMaxAge] = String(
86
+ cacheControlMaxAgeSeconds(options.cacheControlMaxAge),
87
+ );
88
+ }
89
+
90
+ return headers;
91
+ };
92
+
93
+ /**
94
+ * The write headers of `copy` and `rename`, which the SDK builds by hand: every option is sent when
95
+ * set, and `ifMatch` (checked against the source) does not imply `x-allow-overwrite`.
96
+ */
97
+ export const copyWriteHeaders = (options: WriteHeaderOptions): Record<string, string> => {
98
+ const headers: Record<string, string> = {};
99
+ headers[writeOptionHeaders.access] = options.access;
100
+ if (options.addRandomSuffix !== undefined) {
101
+ headers[writeOptionHeaders.addRandomSuffix] = options.addRandomSuffix ? "1" : "0";
102
+ }
103
+ if (options.allowOverwrite !== undefined) {
104
+ headers[writeOptionHeaders.allowOverwrite] = options.allowOverwrite ? "1" : "0";
105
+ }
106
+ if (options.contentType) {
107
+ headers[writeOptionHeaders.contentType] = options.contentType;
108
+ }
109
+ if (options.cacheControlMaxAge !== undefined) {
110
+ headers[writeOptionHeaders.cacheControlMaxAge] = String(
111
+ cacheControlMaxAgeSeconds(options.cacheControlMaxAge),
112
+ );
113
+ }
114
+ if (options.ifMatch) {
115
+ headers[writeOptionHeaders.ifMatch] = options.ifMatch;
116
+ }
117
+ return headers;
118
+ };
@@ -0,0 +1 @@
1
+ export * from "./test-blob-store.ts";