@geekmidas/storage 9.0.2 → 10.0.0-alpha.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 (69) hide show
  1. package/dist/aws.cjs +159 -4
  2. package/dist/aws.cjs.map +1 -0
  3. package/dist/aws.d.cts +51 -3
  4. package/dist/aws.d.cts.map +1 -0
  5. package/dist/aws.d.mts +51 -3
  6. package/dist/aws.d.mts.map +1 -0
  7. package/dist/aws.mjs +151 -3
  8. package/dist/aws.mjs.map +1 -0
  9. package/dist/chunk-B9dir_RE.mjs +11 -0
  10. package/dist/errors-Bce0CJ11.cjs +109 -0
  11. package/dist/errors-Bce0CJ11.cjs.map +1 -0
  12. package/dist/errors-D5UnAd-X.mjs +79 -0
  13. package/dist/errors-D5UnAd-X.mjs.map +1 -0
  14. package/dist/index.cjs +39 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +66 -2
  17. package/dist/index.d.cts.map +1 -0
  18. package/dist/index.d.mts +66 -2
  19. package/dist/index.d.mts.map +1 -0
  20. package/dist/index.mjs +32 -0
  21. package/dist/index.mjs.map +1 -0
  22. package/dist/{StorageClient-COs9SOsU.d.cts → registry-DBsAUTT3.d.cts} +27 -2
  23. package/dist/registry-DBsAUTT3.d.cts.map +1 -0
  24. package/dist/{StorageClient-DH4tP-Mf.d.mts → registry-DEqSHjx-.d.mts} +27 -2
  25. package/dist/registry-DEqSHjx-.d.mts.map +1 -0
  26. package/dist/s3Url-BfztIltX.d.cts +39 -0
  27. package/dist/s3Url-BfztIltX.d.cts.map +1 -0
  28. package/dist/s3Url-Bo32UTTA.cjs +103 -0
  29. package/dist/s3Url-Bo32UTTA.cjs.map +1 -0
  30. package/dist/s3Url-C8FGPNrG.mjs +52 -0
  31. package/dist/s3Url-C8FGPNrG.mjs.map +1 -0
  32. package/dist/s3Url-COpMIgF9.d.mts +42 -0
  33. package/dist/s3Url-COpMIgF9.d.mts.map +1 -0
  34. package/dist/s3Url.cjs +5 -0
  35. package/dist/s3Url.d.cts +2 -0
  36. package/dist/s3Url.d.mts +2 -0
  37. package/dist/s3Url.mjs +4 -0
  38. package/package.json +16 -3
  39. package/CHANGELOG.md +0 -72
  40. package/dist/AmazonStorageClient-BHpWawGD.d.mts +0 -45
  41. package/dist/AmazonStorageClient-BHpWawGD.d.mts.map +0 -1
  42. package/dist/AmazonStorageClient-BNoY2PL6.d.cts +0 -45
  43. package/dist/AmazonStorageClient-BNoY2PL6.d.cts.map +0 -1
  44. package/dist/AmazonStorageClient-BvoZepKJ.cjs +0 -161
  45. package/dist/AmazonStorageClient-BvoZepKJ.cjs.map +0 -1
  46. package/dist/AmazonStorageClient-Dz-KCJ_4.mjs +0 -127
  47. package/dist/AmazonStorageClient-Dz-KCJ_4.mjs.map +0 -1
  48. package/dist/AmazonStorageClient.cjs +0 -5
  49. package/dist/AmazonStorageClient.d.cts +0 -3
  50. package/dist/AmazonStorageClient.d.mts +0 -3
  51. package/dist/AmazonStorageClient.mjs +0 -4
  52. package/dist/StorageClient-4ADnTPnJ.mjs +0 -11
  53. package/dist/StorageClient-4ADnTPnJ.mjs.map +0 -1
  54. package/dist/StorageClient-BDRVrMJj.cjs +0 -17
  55. package/dist/StorageClient-BDRVrMJj.cjs.map +0 -1
  56. package/dist/StorageClient-COs9SOsU.d.cts.map +0 -1
  57. package/dist/StorageClient-DH4tP-Mf.d.mts.map +0 -1
  58. package/dist/StorageClient.cjs +0 -3
  59. package/dist/StorageClient.d.cts +0 -2
  60. package/dist/StorageClient.d.mts +0 -2
  61. package/dist/StorageClient.mjs +0 -3
  62. package/src/AmazonStorageClient.ts +0 -207
  63. package/src/StorageClient.ts +0 -108
  64. package/src/__tests__/AmazonStorageClient.spec.ts +0 -606
  65. package/src/__tests__/StorageClient.spec.ts +0 -98
  66. package/src/aws.ts +0 -11
  67. package/src/index.ts +0 -1
  68. package/tsconfig.json +0 -9
  69. package/tsdown.config.ts +0 -9
@@ -0,0 +1,79 @@
1
+ //#region src/errors.ts
2
+ /**
3
+ * Storage errors — shared by every implementation, not just S3.
4
+ *
5
+ * A `gs://` or Azure client hits the same three problems as the S3 one: the
6
+ * string is not a URL, it is a URL for a different provider, or it addresses no
7
+ * bucket. Each carries the provider-specific detail as a field, so the type is
8
+ * common while the specifics stay accurate.
9
+ *
10
+ * Messages state the rule, which is constant, and never interpolate the value.
11
+ * An interpolated message cannot be matched on, reads differently every time it
12
+ * is thrown, and carries user input into every log line that touches it.
13
+ */
14
+ /** Base for anything wrong with a storage URL, so callers may catch broadly. */
15
+ var StorageUrlError = class extends Error {
16
+ /** The URL that could not be used. */
17
+ url;
18
+ constructor(url, message) {
19
+ super(message);
20
+ this.url = url;
21
+ this.name = new.target.name;
22
+ }
23
+ };
24
+ /** The string is not a URL at all. */
25
+ var MalformedStorageUrl = class extends StorageUrlError {
26
+ constructor(url) {
27
+ super(url, "Not a valid URL");
28
+ }
29
+ };
30
+ /**
31
+ * A URL, but for a different provider — a `gs://` URL reaching the S3 client,
32
+ * or the reverse. The usual cause is a construct resolving against the wrong
33
+ * target, which is worth distinguishing from a malformed string.
34
+ */
35
+ var UnexpectedStorageScheme = class extends StorageUrlError {
36
+ /** The scheme this client handles, e.g. `'s3:'`. */
37
+ expected;
38
+ /** The scheme the URL actually carried, e.g. `'gs:'`. */
39
+ actual;
40
+ constructor(url, expected, actual) {
41
+ super(url, "Storage URL is for a different provider");
42
+ this.expected = expected;
43
+ this.actual = actual;
44
+ }
45
+ };
46
+ /**
47
+ * A well-formed URL that addresses no bucket.
48
+ *
49
+ * "Bucket" is the term S3 and GCS share; Azure calls the same thing a
50
+ * container. One error covers all three — the word in the message is the
51
+ * common one rather than a new abstraction nobody uses.
52
+ */
53
+ var MissingStorageBucket = class extends StorageUrlError {
54
+ constructor(url) {
55
+ super(url, "Storage URL must address a bucket");
56
+ }
57
+ };
58
+ /**
59
+ * No driver is registered for the URL's scheme.
60
+ *
61
+ * Usually means the build pinned a driver for a different target, or an entry
62
+ * point registered nothing at all — so the registered schemes are carried
63
+ * alongside, since "what *is* available" is the actionable half.
64
+ */
65
+ var UnregisteredStorageScheme = class extends StorageUrlError {
66
+ /** The scheme that had no driver, e.g. `'gs:'`. */
67
+ scheme;
68
+ /** What is registered, so the caller can see what was pinned instead. */
69
+ registered;
70
+ constructor(url, scheme, registered) {
71
+ super(url, "No storage driver is registered for this URL scheme");
72
+ this.scheme = scheme;
73
+ this.registered = registered;
74
+ }
75
+ };
76
+
77
+ //#endregion
78
+ export { MalformedStorageUrl, MissingStorageBucket, StorageUrlError, UnexpectedStorageScheme, UnregisteredStorageScheme };
79
+ //# sourceMappingURL=errors-D5UnAd-X.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-D5UnAd-X.mjs","names":["url: string","message: string","expected: string","actual: string","scheme: string","registered: readonly string[]"],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Storage errors — shared by every implementation, not just S3.\n *\n * A `gs://` or Azure client hits the same three problems as the S3 one: the\n * string is not a URL, it is a URL for a different provider, or it addresses no\n * bucket. Each carries the provider-specific detail as a field, so the type is\n * common while the specifics stay accurate.\n *\n * Messages state the rule, which is constant, and never interpolate the value.\n * An interpolated message cannot be matched on, reads differently every time it\n * is thrown, and carries user input into every log line that touches it.\n */\n\n/** Base for anything wrong with a storage URL, so callers may catch broadly. */\nexport abstract class StorageUrlError extends Error {\n\t/** The URL that could not be used. */\n\treadonly url: string;\n\n\tconstructor(url: string, message: string) {\n\t\tsuper(message);\n\t\tthis.url = url;\n\t\tthis.name = new.target.name;\n\t}\n}\n\n/** The string is not a URL at all. */\nexport class MalformedStorageUrl extends StorageUrlError {\n\tconstructor(url: string) {\n\t\tsuper(url, 'Not a valid URL');\n\t}\n}\n\n/**\n * A URL, but for a different provider — a `gs://` URL reaching the S3 client,\n * or the reverse. The usual cause is a construct resolving against the wrong\n * target, which is worth distinguishing from a malformed string.\n */\nexport class UnexpectedStorageScheme extends StorageUrlError {\n\t/** The scheme this client handles, e.g. `'s3:'`. */\n\treadonly expected: string;\n\t/** The scheme the URL actually carried, e.g. `'gs:'`. */\n\treadonly actual: string;\n\n\tconstructor(url: string, expected: string, actual: string) {\n\t\tsuper(url, 'Storage URL is for a different provider');\n\t\tthis.expected = expected;\n\t\tthis.actual = actual;\n\t}\n}\n\n/**\n * A well-formed URL that addresses no bucket.\n *\n * \"Bucket\" is the term S3 and GCS share; Azure calls the same thing a\n * container. One error covers all three — the word in the message is the\n * common one rather than a new abstraction nobody uses.\n */\nexport class MissingStorageBucket extends StorageUrlError {\n\tconstructor(url: string) {\n\t\tsuper(url, 'Storage URL must address a bucket');\n\t}\n}\n\n/**\n * No driver is registered for the URL's scheme.\n *\n * Usually means the build pinned a driver for a different target, or an entry\n * point registered nothing at all — so the registered schemes are carried\n * alongside, since \"what *is* available\" is the actionable half.\n */\nexport class UnregisteredStorageScheme extends StorageUrlError {\n\t/** The scheme that had no driver, e.g. `'gs:'`. */\n\treadonly scheme: string;\n\t/** What is registered, so the caller can see what was pinned instead. */\n\treadonly registered: readonly string[];\n\n\tconstructor(url: string, scheme: string, registered: readonly string[]) {\n\t\tsuper(url, 'No storage driver is registered for this URL scheme');\n\t\tthis.scheme = scheme;\n\t\tthis.registered = registered;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,IAAsB,kBAAtB,cAA8C,MAAM;;CAEnD,AAAS;CAET,YAAYA,KAAaC,SAAiB;AACzC,QAAM,QAAQ;AACd,OAAK,MAAM;AACX,OAAK,OAAO,IAAI,OAAO;CACvB;AACD;;AAGD,IAAa,sBAAb,cAAyC,gBAAgB;CACxD,YAAYD,KAAa;AACxB,QAAM,KAAK,kBAAkB;CAC7B;AACD;;;;;;AAOD,IAAa,0BAAb,cAA6C,gBAAgB;;CAE5D,AAAS;;CAET,AAAS;CAET,YAAYA,KAAaE,UAAkBC,QAAgB;AAC1D,QAAM,KAAK,0CAA0C;AACrD,OAAK,WAAW;AAChB,OAAK,SAAS;CACd;AACD;;;;;;;;AASD,IAAa,uBAAb,cAA0C,gBAAgB;CACzD,YAAYH,KAAa;AACxB,QAAM,KAAK,oCAAoC;CAC/C;AACD;;;;;;;;AASD,IAAa,4BAAb,cAA+C,gBAAgB;;CAE9D,AAAS;;CAET,AAAS;CAET,YAAYA,KAAaI,QAAgBC,YAA+B;AACvE,QAAM,KAAK,sDAAsD;AACjE,OAAK,SAAS;AACd,OAAK,aAAa;CAClB;AACD"}
package/dist/index.cjs CHANGED
@@ -0,0 +1,39 @@
1
+ const require_errors = require('./errors-Bce0CJ11.cjs');
2
+
3
+ //#region src/registry.ts
4
+ const drivers = /* @__PURE__ */ new Map();
5
+ /** Make a driver available to {@link createStorageClient}. Idempotent. */
6
+ function registerStorageDriver(driver) {
7
+ drivers.set(driver.scheme, driver);
8
+ }
9
+ /** Which schemes are currently registered — the useful half of a failure. */
10
+ function registeredStorageSchemes() {
11
+ return [...drivers.keys()].sort();
12
+ }
13
+ /**
14
+ * Build a client for a URL.
15
+ *
16
+ * @throws {UnregisteredStorageScheme} when no driver handles the scheme, which
17
+ * in practice means the build pinned a different one, or nothing registered.
18
+ */
19
+ function createStorageClient(url) {
20
+ const scheme = schemeOf(url);
21
+ const driver = drivers.get(scheme);
22
+ if (!driver) throw new require_errors.UnregisteredStorageScheme(url, scheme, registeredStorageSchemes());
23
+ return driver.create(url);
24
+ }
25
+ function schemeOf(url) {
26
+ const separator = url.indexOf(":");
27
+ return separator === -1 ? "" : url.slice(0, separator + 1);
28
+ }
29
+
30
+ //#endregion
31
+ exports.MalformedStorageUrl = require_errors.MalformedStorageUrl;
32
+ exports.MissingStorageBucket = require_errors.MissingStorageBucket;
33
+ exports.StorageUrlError = require_errors.StorageUrlError;
34
+ exports.UnexpectedStorageScheme = require_errors.UnexpectedStorageScheme;
35
+ exports.UnregisteredStorageScheme = require_errors.UnregisteredStorageScheme;
36
+ exports.createStorageClient = createStorageClient;
37
+ exports.registerStorageDriver = registerStorageDriver;
38
+ exports.registeredStorageSchemes = registeredStorageSchemes;
39
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["driver: StorageDriver","url: string","UnregisteredStorageScheme"],"sources":["../src/registry.ts"],"sourcesContent":["/**\n * Driver registry — how a storage URL becomes a client without the caller\n * naming a cloud.\n *\n * A construct declares that it needs object storage and receives one URL. It\n * must not import `AmazonStorageClient` to use it: that would name a provider in\n * the neutral layer and drag the AWS SDK into an app that only ever talks to\n * GCS. So the protocol selects the driver, and whoever assembles the\n * application decides which drivers exist — a generated handler registering the\n * one its target needs, or a dev entry registering several.\n *\n * Registration is explicit rather than an import side effect, because a\n * side-effecting module is exactly what a bundler is entitled to drop.\n */\n\nimport { UnregisteredStorageScheme } from './errors';\nimport type { StorageClient } from './StorageClient';\n\n/**\n * Builds a client from a URL it recognises.\n *\n * The driver owns parsing: the shape of an `s3://` URL is S3's business, and a\n * `gs://` driver shares nothing with it beyond this signature.\n */\nexport interface StorageDriver {\n\t/** The URL scheme this driver handles, including the colon — e.g. `'s3:'`. */\n\treadonly scheme: string;\n\tcreate(url: string): StorageClient;\n}\n\nconst drivers = new Map<string, StorageDriver>();\n\n/** Make a driver available to {@link createStorageClient}. Idempotent. */\nexport function registerStorageDriver(driver: StorageDriver): void {\n\tdrivers.set(driver.scheme, driver);\n}\n\n/** Which schemes are currently registered — the useful half of a failure. */\nexport function registeredStorageSchemes(): string[] {\n\treturn [...drivers.keys()].sort();\n}\n\n/**\n * Build a client for a URL.\n *\n * @throws {UnregisteredStorageScheme} when no driver handles the scheme, which\n * in practice means the build pinned a different one, or nothing registered.\n */\nexport function createStorageClient(url: string): StorageClient {\n\tconst scheme = schemeOf(url);\n\tconst driver = drivers.get(scheme);\n\n\tif (!driver) {\n\t\tthrow new UnregisteredStorageScheme(\n\t\t\turl,\n\t\t\tscheme,\n\t\t\tregisteredStorageSchemes(),\n\t\t);\n\t}\n\n\treturn driver.create(url);\n}\n\nfunction schemeOf(url: string): string {\n\tconst separator = url.indexOf(':');\n\treturn separator === -1 ? '' : url.slice(0, separator + 1);\n}\n"],"mappings":";;;AA8BA,MAAM,0BAAU,IAAI;;AAGpB,SAAgB,sBAAsBA,QAA6B;AAClE,SAAQ,IAAI,OAAO,QAAQ,OAAO;AAClC;;AAGD,SAAgB,2BAAqC;AACpD,QAAO,CAAC,GAAG,QAAQ,MAAM,AAAC,EAAC,MAAM;AACjC;;;;;;;AAQD,SAAgB,oBAAoBC,KAA4B;CAC/D,MAAM,SAAS,SAAS,IAAI;CAC5B,MAAM,SAAS,QAAQ,IAAI,OAAO;AAElC,MAAK,OACJ,OAAM,IAAIC,yCACT,KACA,QACA,0BAA0B;AAI5B,QAAO,OAAO,OAAO,IAAI;AACzB;AAED,SAAS,SAASD,KAAqB;CACtC,MAAM,YAAY,IAAI,QAAQ,IAAI;AAClC,QAAO,cAAc,KAAK,KAAK,IAAI,MAAM,GAAG,YAAY,EAAE;AAC1D"}
package/dist/index.d.cts CHANGED
@@ -1,2 +1,66 @@
1
- import { StorageClient } from "./StorageClient-COs9SOsU.cjs";
2
- export { StorageClient };
1
+ import { StorageClient, StorageDriver, createStorageClient, registerStorageDriver, registeredStorageSchemes } from "./registry-DBsAUTT3.cjs";
2
+
3
+ //#region src/errors.d.ts
4
+
5
+ /**
6
+ * Storage errors — shared by every implementation, not just S3.
7
+ *
8
+ * A `gs://` or Azure client hits the same three problems as the S3 one: the
9
+ * string is not a URL, it is a URL for a different provider, or it addresses no
10
+ * bucket. Each carries the provider-specific detail as a field, so the type is
11
+ * common while the specifics stay accurate.
12
+ *
13
+ * Messages state the rule, which is constant, and never interpolate the value.
14
+ * An interpolated message cannot be matched on, reads differently every time it
15
+ * is thrown, and carries user input into every log line that touches it.
16
+ */
17
+ /** Base for anything wrong with a storage URL, so callers may catch broadly. */
18
+ declare abstract class StorageUrlError extends Error {
19
+ /** The URL that could not be used. */
20
+ readonly url: string;
21
+ constructor(url: string, message: string);
22
+ }
23
+ /** The string is not a URL at all. */
24
+ declare class MalformedStorageUrl extends StorageUrlError {
25
+ constructor(url: string);
26
+ }
27
+ /**
28
+ * A URL, but for a different provider — a `gs://` URL reaching the S3 client,
29
+ * or the reverse. The usual cause is a construct resolving against the wrong
30
+ * target, which is worth distinguishing from a malformed string.
31
+ */
32
+ declare class UnexpectedStorageScheme extends StorageUrlError {
33
+ /** The scheme this client handles, e.g. `'s3:'`. */
34
+ readonly expected: string;
35
+ /** The scheme the URL actually carried, e.g. `'gs:'`. */
36
+ readonly actual: string;
37
+ constructor(url: string, expected: string, actual: string);
38
+ }
39
+ /**
40
+ * A well-formed URL that addresses no bucket.
41
+ *
42
+ * "Bucket" is the term S3 and GCS share; Azure calls the same thing a
43
+ * container. One error covers all three — the word in the message is the
44
+ * common one rather than a new abstraction nobody uses.
45
+ */
46
+ declare class MissingStorageBucket extends StorageUrlError {
47
+ constructor(url: string);
48
+ }
49
+ /**
50
+ * No driver is registered for the URL's scheme.
51
+ *
52
+ * Usually means the build pinned a driver for a different target, or an entry
53
+ * point registered nothing at all — so the registered schemes are carried
54
+ * alongside, since "what *is* available" is the actionable half.
55
+ */
56
+ declare class UnregisteredStorageScheme extends StorageUrlError {
57
+ /** The scheme that had no driver, e.g. `'gs:'`. */
58
+ readonly scheme: string;
59
+ /** What is registered, so the caller can see what was pinned instead. */
60
+ readonly registered: readonly string[];
61
+ constructor(url: string, scheme: string, registered: readonly string[]);
62
+ }
63
+ //# sourceMappingURL=errors.d.ts.map
64
+ //#endregion
65
+ export { MalformedStorageUrl, MissingStorageBucket, StorageClient, StorageDriver, StorageUrlError, UnexpectedStorageScheme, UnregisteredStorageScheme, createStorageClient, registerStorageDriver, registeredStorageSchemes };
66
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts"],"sourcesContent":[],"mappings":";;;;;;;AAcA;AAYA;AAWA;AAoBA;AAaA;;;;;;uBAxDsB,eAAA,SAAwB,KAAK;;;;;;cAYtC,mBAAA,SAA4B,eAAe;;;;;;;;cAW3C,uBAAA,SAAgC,eAAe;;;;;;;;;;;;;;cAoB/C,oBAAA,SAA6B,eAAe;;;;;;;;;;cAa5C,yBAAA,SAAkC,eAAe"}
package/dist/index.d.mts CHANGED
@@ -1,2 +1,66 @@
1
- import { StorageClient } from "./StorageClient-DH4tP-Mf.mjs";
2
- export { StorageClient };
1
+ import { StorageClient, StorageDriver, createStorageClient, registerStorageDriver, registeredStorageSchemes } from "./registry-DEqSHjx-.mjs";
2
+
3
+ //#region src/errors.d.ts
4
+
5
+ /**
6
+ * Storage errors — shared by every implementation, not just S3.
7
+ *
8
+ * A `gs://` or Azure client hits the same three problems as the S3 one: the
9
+ * string is not a URL, it is a URL for a different provider, or it addresses no
10
+ * bucket. Each carries the provider-specific detail as a field, so the type is
11
+ * common while the specifics stay accurate.
12
+ *
13
+ * Messages state the rule, which is constant, and never interpolate the value.
14
+ * An interpolated message cannot be matched on, reads differently every time it
15
+ * is thrown, and carries user input into every log line that touches it.
16
+ */
17
+ /** Base for anything wrong with a storage URL, so callers may catch broadly. */
18
+ declare abstract class StorageUrlError extends Error {
19
+ /** The URL that could not be used. */
20
+ readonly url: string;
21
+ constructor(url: string, message: string);
22
+ }
23
+ /** The string is not a URL at all. */
24
+ declare class MalformedStorageUrl extends StorageUrlError {
25
+ constructor(url: string);
26
+ }
27
+ /**
28
+ * A URL, but for a different provider — a `gs://` URL reaching the S3 client,
29
+ * or the reverse. The usual cause is a construct resolving against the wrong
30
+ * target, which is worth distinguishing from a malformed string.
31
+ */
32
+ declare class UnexpectedStorageScheme extends StorageUrlError {
33
+ /** The scheme this client handles, e.g. `'s3:'`. */
34
+ readonly expected: string;
35
+ /** The scheme the URL actually carried, e.g. `'gs:'`. */
36
+ readonly actual: string;
37
+ constructor(url: string, expected: string, actual: string);
38
+ }
39
+ /**
40
+ * A well-formed URL that addresses no bucket.
41
+ *
42
+ * "Bucket" is the term S3 and GCS share; Azure calls the same thing a
43
+ * container. One error covers all three — the word in the message is the
44
+ * common one rather than a new abstraction nobody uses.
45
+ */
46
+ declare class MissingStorageBucket extends StorageUrlError {
47
+ constructor(url: string);
48
+ }
49
+ /**
50
+ * No driver is registered for the URL's scheme.
51
+ *
52
+ * Usually means the build pinned a driver for a different target, or an entry
53
+ * point registered nothing at all — so the registered schemes are carried
54
+ * alongside, since "what *is* available" is the actionable half.
55
+ */
56
+ declare class UnregisteredStorageScheme extends StorageUrlError {
57
+ /** The scheme that had no driver, e.g. `'gs:'`. */
58
+ readonly scheme: string;
59
+ /** What is registered, so the caller can see what was pinned instead. */
60
+ readonly registered: readonly string[];
61
+ constructor(url: string, scheme: string, registered: readonly string[]);
62
+ }
63
+ //# sourceMappingURL=errors.d.ts.map
64
+ //#endregion
65
+ export { MalformedStorageUrl, MissingStorageBucket, StorageClient, StorageDriver, StorageUrlError, UnexpectedStorageScheme, UnregisteredStorageScheme, createStorageClient, registerStorageDriver, registeredStorageSchemes };
66
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts"],"sourcesContent":[],"mappings":";;;;;;;AAcA;AAYA;AAWA;AAoBA;AAaA;;;;;;uBAxDsB,eAAA,SAAwB,KAAK;;;;;;cAYtC,mBAAA,SAA4B,eAAe;;;;;;;;cAW3C,uBAAA,SAAgC,eAAe;;;;;;;;;;;;;;cAoB/C,oBAAA,SAA6B,eAAe;;;;;;;;;;cAa5C,yBAAA,SAAkC,eAAe"}
package/dist/index.mjs CHANGED
@@ -0,0 +1,32 @@
1
+ import { MalformedStorageUrl, MissingStorageBucket, StorageUrlError, UnexpectedStorageScheme, UnregisteredStorageScheme } from "./errors-D5UnAd-X.mjs";
2
+
3
+ //#region src/registry.ts
4
+ const drivers = /* @__PURE__ */ new Map();
5
+ /** Make a driver available to {@link createStorageClient}. Idempotent. */
6
+ function registerStorageDriver(driver) {
7
+ drivers.set(driver.scheme, driver);
8
+ }
9
+ /** Which schemes are currently registered — the useful half of a failure. */
10
+ function registeredStorageSchemes() {
11
+ return [...drivers.keys()].sort();
12
+ }
13
+ /**
14
+ * Build a client for a URL.
15
+ *
16
+ * @throws {UnregisteredStorageScheme} when no driver handles the scheme, which
17
+ * in practice means the build pinned a different one, or nothing registered.
18
+ */
19
+ function createStorageClient(url) {
20
+ const scheme = schemeOf(url);
21
+ const driver = drivers.get(scheme);
22
+ if (!driver) throw new UnregisteredStorageScheme(url, scheme, registeredStorageSchemes());
23
+ return driver.create(url);
24
+ }
25
+ function schemeOf(url) {
26
+ const separator = url.indexOf(":");
27
+ return separator === -1 ? "" : url.slice(0, separator + 1);
28
+ }
29
+
30
+ //#endregion
31
+ export { MalformedStorageUrl, MissingStorageBucket, StorageUrlError, UnexpectedStorageScheme, UnregisteredStorageScheme, createStorageClient, registerStorageDriver, registeredStorageSchemes };
32
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["driver: StorageDriver","url: string"],"sources":["../src/registry.ts"],"sourcesContent":["/**\n * Driver registry — how a storage URL becomes a client without the caller\n * naming a cloud.\n *\n * A construct declares that it needs object storage and receives one URL. It\n * must not import `AmazonStorageClient` to use it: that would name a provider in\n * the neutral layer and drag the AWS SDK into an app that only ever talks to\n * GCS. So the protocol selects the driver, and whoever assembles the\n * application decides which drivers exist — a generated handler registering the\n * one its target needs, or a dev entry registering several.\n *\n * Registration is explicit rather than an import side effect, because a\n * side-effecting module is exactly what a bundler is entitled to drop.\n */\n\nimport { UnregisteredStorageScheme } from './errors';\nimport type { StorageClient } from './StorageClient';\n\n/**\n * Builds a client from a URL it recognises.\n *\n * The driver owns parsing: the shape of an `s3://` URL is S3's business, and a\n * `gs://` driver shares nothing with it beyond this signature.\n */\nexport interface StorageDriver {\n\t/** The URL scheme this driver handles, including the colon — e.g. `'s3:'`. */\n\treadonly scheme: string;\n\tcreate(url: string): StorageClient;\n}\n\nconst drivers = new Map<string, StorageDriver>();\n\n/** Make a driver available to {@link createStorageClient}. Idempotent. */\nexport function registerStorageDriver(driver: StorageDriver): void {\n\tdrivers.set(driver.scheme, driver);\n}\n\n/** Which schemes are currently registered — the useful half of a failure. */\nexport function registeredStorageSchemes(): string[] {\n\treturn [...drivers.keys()].sort();\n}\n\n/**\n * Build a client for a URL.\n *\n * @throws {UnregisteredStorageScheme} when no driver handles the scheme, which\n * in practice means the build pinned a different one, or nothing registered.\n */\nexport function createStorageClient(url: string): StorageClient {\n\tconst scheme = schemeOf(url);\n\tconst driver = drivers.get(scheme);\n\n\tif (!driver) {\n\t\tthrow new UnregisteredStorageScheme(\n\t\t\turl,\n\t\t\tscheme,\n\t\t\tregisteredStorageSchemes(),\n\t\t);\n\t}\n\n\treturn driver.create(url);\n}\n\nfunction schemeOf(url: string): string {\n\tconst separator = url.indexOf(':');\n\treturn separator === -1 ? '' : url.slice(0, separator + 1);\n}\n"],"mappings":";;;AA8BA,MAAM,0BAAU,IAAI;;AAGpB,SAAgB,sBAAsBA,QAA6B;AAClE,SAAQ,IAAI,OAAO,QAAQ,OAAO;AAClC;;AAGD,SAAgB,2BAAqC;AACpD,QAAO,CAAC,GAAG,QAAQ,MAAM,AAAC,EAAC,MAAM;AACjC;;;;;;;AAQD,SAAgB,oBAAoBC,KAA4B;CAC/D,MAAM,SAAS,SAAS,IAAI;CAC5B,MAAM,SAAS,QAAQ,IAAI,OAAO;AAElC,MAAK,OACJ,OAAM,IAAI,0BACT,KACA,QACA,0BAA0B;AAI5B,QAAO,OAAO,OAAO,IAAI;AACzB;AAED,SAAS,SAASA,KAAqB;CACtC,MAAM,YAAY,IAAI,QAAQ,IAAI;AAClC,QAAO,cAAc,KAAK,KAAK,IAAI,MAAM,GAAG,YAAY,EAAE;AAC1D"}
@@ -95,5 +95,30 @@ interface File {
95
95
  }
96
96
  //# sourceMappingURL=StorageClient.d.ts.map
97
97
  //#endregion
98
- export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField };
99
- //# sourceMappingURL=StorageClient-COs9SOsU.d.cts.map
98
+ //#region src/registry.d.ts
99
+ /**
100
+ * Builds a client from a URL it recognises.
101
+ *
102
+ * The driver owns parsing: the shape of an `s3://` URL is S3's business, and a
103
+ * `gs://` driver shares nothing with it beyond this signature.
104
+ */
105
+ interface StorageDriver {
106
+ /** The URL scheme this driver handles, including the colon — e.g. `'s3:'`. */
107
+ readonly scheme: string;
108
+ create(url: string): StorageClient;
109
+ }
110
+ /** Make a driver available to {@link createStorageClient}. Idempotent. */
111
+ declare function registerStorageDriver(driver: StorageDriver): void;
112
+ /** Which schemes are currently registered — the useful half of a failure. */
113
+ declare function registeredStorageSchemes(): string[];
114
+ /**
115
+ * Build a client for a URL.
116
+ *
117
+ * @throws {UnregisteredStorageScheme} when no driver handles the scheme, which
118
+ * in practice means the build pinned a different one, or nothing registered.
119
+ */
120
+ declare function createStorageClient(url: string): StorageClient;
121
+ //# sourceMappingURL=registry.d.ts.map
122
+ //#endregion
123
+ export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageDriver, StorageProvider, createStorageClient, registerStorageDriver, registeredStorageSchemes };
124
+ //# sourceMappingURL=registry-DBsAUTT3.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-DBsAUTT3.d.cts","names":[],"sources":["../src/StorageClient.ts","../src/registry.ts"],"sourcesContent":[],"mappings":";;;UACiB,eAAA;;EAAA,SAAA,EAEL,IAFK;AAKjB;AAMiB,aANL,eAAA;EAMkB,KAAA,GAAA,kCAAA;EAAA,GACV,GAAA,+BAAA;EAAe,KACjB,GAAA,iCAAA;;AAS0C,UAX3C,aAAA,CAW2C;EAAO,SAU7C,QAAA,EApBF,eAoBE;EAAI,SAAuB,KAAA,CAAA,EAnB/B,KAmB+B;EAAO;;;;;;;;EAmC3B,YAAzB,CAAA,MAAA,EA7CkB,eA6ClB,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA7CwD,OA6CxD,CAAA,MAAA,CAAA;EAAO;AAMkB;AAG7B;AAMA;AAKA;AAKA;;;uBA5DsB,2BAA2B;ECThC;AASjB;AAKA;AAUA;;4BDT2B,QAAQ;;;;;;;8BAQN,0BAA0B;;;;;;;qCAStC,8BAEb;;;;;;;oBAQM,sCAEN,QAAQ;;;;;;uBAMU;;UAGL,eAAA;;;;;KAML,WAAA;;;;KAKA,iBAAA;;UAEH;;UAGQ,IAAA;;;;;;;;;;;;;;;;;;;;;;;;AAzBb,UC5Ca,aAAA,CD4Cb;EAAO;EAMkB,SAAA,MAAA,EAAA,MAAA;EAGZ,MAAA,CAAA,GAAA,EAAA,MAAe,CAAA,EClDV,aDkDU;AAMhC;AAKA;AAKiB,iBC5DD,qBAAA,CD4DK,MAAA,EC5DyB,aD4DzB,CAAA,EAAA,IAAA;;iBCvDL,wBAAA,CAAA;;AAdhB;AASA;AAKA;AAUA;;iBAAgB,mBAAA,eAAkC"}
@@ -95,5 +95,30 @@ interface File {
95
95
  }
96
96
  //# sourceMappingURL=StorageClient.d.ts.map
97
97
  //#endregion
98
- export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField };
99
- //# sourceMappingURL=StorageClient-DH4tP-Mf.d.mts.map
98
+ //#region src/registry.d.ts
99
+ /**
100
+ * Builds a client from a URL it recognises.
101
+ *
102
+ * The driver owns parsing: the shape of an `s3://` URL is S3's business, and a
103
+ * `gs://` driver shares nothing with it beyond this signature.
104
+ */
105
+ interface StorageDriver {
106
+ /** The URL scheme this driver handles, including the colon — e.g. `'s3:'`. */
107
+ readonly scheme: string;
108
+ create(url: string): StorageClient;
109
+ }
110
+ /** Make a driver available to {@link createStorageClient}. Idempotent. */
111
+ declare function registerStorageDriver(driver: StorageDriver): void;
112
+ /** Which schemes are currently registered — the useful half of a failure. */
113
+ declare function registeredStorageSchemes(): string[];
114
+ /**
115
+ * Build a client for a URL.
116
+ *
117
+ * @throws {UnregisteredStorageScheme} when no driver handles the scheme, which
118
+ * in practice means the build pinned a different one, or nothing registered.
119
+ */
120
+ declare function createStorageClient(url: string): StorageClient;
121
+ //# sourceMappingURL=registry.d.ts.map
122
+ //#endregion
123
+ export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageDriver, StorageProvider, createStorageClient, registerStorageDriver, registeredStorageSchemes };
124
+ //# sourceMappingURL=registry-DEqSHjx-.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-DEqSHjx-.d.mts","names":[],"sources":["../src/StorageClient.ts","../src/registry.ts"],"sourcesContent":[],"mappings":";;;UACiB,eAAA;;EAAA,SAAA,EAEL,IAFK;AAKjB;AAMiB,aANL,eAAA;EAMkB,KAAA,GAAA,kCAAA;EAAA,GACV,GAAA,+BAAA;EAAe,KACjB,GAAA,iCAAA;;AAS0C,UAX3C,aAAA,CAW2C;EAAO,SAU7C,QAAA,EApBF,eAoBE;EAAI,SAAuB,KAAA,CAAA,EAnB/B,KAmB+B;EAAO;;;;;;;;EAmC3B,YAAzB,CAAA,MAAA,EA7CkB,eA6ClB,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA7CwD,OA6CxD,CAAA,MAAA,CAAA;EAAO;AAMkB;AAG7B;AAMA;AAKA;AAKA;;;uBA5DsB,2BAA2B;ECThC;AASjB;AAKA;AAUA;;4BDT2B,QAAQ;;;;;;;8BAQN,0BAA0B;;;;;;;qCAStC,8BAEb;;;;;;;oBAQM,sCAEN,QAAQ;;;;;;uBAMU;;UAGL,eAAA;;;;;KAML,WAAA;;;;KAKA,iBAAA;;UAEH;;UAGQ,IAAA;;;;;;;;;;;;;;;;;;;;;;;;AAzBb,UC5Ca,aAAA,CD4Cb;EAAO;EAMkB,SAAA,MAAA,EAAA,MAAA;EAGZ,MAAA,CAAA,GAAA,EAAA,MAAe,CAAA,EClDV,aDkDU;AAMhC;AAKA;AAKiB,iBC5DD,qBAAA,CD4DK,MAAA,EC5DyB,aD4DzB,CAAA,EAAA,IAAA;;iBCvDL,wBAAA,CAAA;;AAdhB;AASA;AAKA;AAUA;;iBAAgB,mBAAA,eAAkC"}
@@ -0,0 +1,39 @@
1
+ declare namespace s3Url_d_exports {
2
+ export { S3Address, build, parse };
3
+ }
4
+ /**
5
+ * The `s3://` URL codec — how an S3 bucket is addressed as a single string.
6
+ *
7
+ * It lives beside the client rather than in a neutral package because `bucket`,
8
+ * `region`, and `forcePathStyle` are S3's vocabulary. The neutral layer only
9
+ * knows that a construct provides *one URL*; what that URL says is between the
10
+ * component that composes it and the client that parses it. A `gs://` codec
11
+ * would sit beside its own client and share nothing with this one.
12
+ *
13
+ * Both directions live here so they cannot drift: `parse(build(x))` is `x`.
14
+ */
15
+ /** What an S3 URL addresses. Credentials are deliberately absent — see below. */
16
+ interface S3Address {
17
+ bucket: string;
18
+ /** Read off the bucket, never inherited: a bucket may live in another region. */
19
+ region?: string;
20
+ /** Set for S3-compatible backends such as MinIO. */
21
+ endpoint?: string;
22
+ /** MinIO and most S3-compatible servers need path-style addressing. */
23
+ forcePathStyle?: boolean;
24
+ }
25
+ /**
26
+ * Compose an address into a URL.
27
+ *
28
+ * Credentials never appear. The AWS SDK resolves them from its own chain — an
29
+ * execution role when deployed, `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`
30
+ * locally — so the URL stays safe to log and identical across environments that
31
+ * differ only in who is calling.
32
+ */
33
+ declare function build(address: S3Address): string;
34
+ /** Parse a URL back into an address. Throws if it is not an `s3://` URL. */
35
+ declare function parse(url: string): S3Address;
36
+ //# sourceMappingURL=s3Url.d.ts.map
37
+ //#endregion
38
+ export { S3Address, build, parse, s3Url_d_exports };
39
+ //# sourceMappingURL=s3Url-BfztIltX.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3Url-BfztIltX.d.cts","names":[],"sources":["../src/s3Url.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;UAmBiB,SAAA;;;;;EAAA,QAAA,CAAA,EAAA,MAAS;EAoBV;EAYA,cAAK,CAAA,EAAA,OAAe;;;;;;;;;;iBAZpB,KAAA,UAAe;;iBAYf,KAAA,eAAoB"}
@@ -0,0 +1,103 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
16
+ key = keys[i];
17
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
18
+ get: ((k) => from[k]).bind(null, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
25
+ value: mod,
26
+ enumerable: true
27
+ }) : target, mod));
28
+
29
+ //#endregion
30
+ const require_errors = require('./errors-Bce0CJ11.cjs');
31
+
32
+ //#region src/s3Url.ts
33
+ var s3Url_exports = {};
34
+ __export(s3Url_exports, {
35
+ build: () => build,
36
+ parse: () => parse
37
+ });
38
+ const SCHEME = "s3:";
39
+ /**
40
+ * Compose an address into a URL.
41
+ *
42
+ * Credentials never appear. The AWS SDK resolves them from its own chain — an
43
+ * execution role when deployed, `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`
44
+ * locally — so the URL stays safe to log and identical across environments that
45
+ * differ only in who is calling.
46
+ */
47
+ function build(address) {
48
+ const { bucket, region, endpoint, forcePathStyle } = address;
49
+ if (!bucket) throw new require_errors.MissingStorageBucket("");
50
+ const url = new URL(`${SCHEME}//${bucket}`);
51
+ if (region) url.searchParams.set("region", region);
52
+ if (endpoint) url.searchParams.set("endpoint", endpoint);
53
+ if (forcePathStyle) url.searchParams.set("forcePathStyle", "true");
54
+ return url.toString();
55
+ }
56
+ /** Parse a URL back into an address. Throws if it is not an `s3://` URL. */
57
+ function parse(url) {
58
+ let parsed;
59
+ try {
60
+ parsed = new URL(url);
61
+ } catch {
62
+ throw new require_errors.MalformedStorageUrl(url);
63
+ }
64
+ if (parsed.protocol !== SCHEME) throw new require_errors.UnexpectedStorageScheme(url, SCHEME, parsed.protocol);
65
+ const bucket = parsed.hostname;
66
+ if (!bucket) throw new require_errors.MissingStorageBucket(url);
67
+ const region = parsed.searchParams.get("region") ?? void 0;
68
+ const endpoint = parsed.searchParams.get("endpoint") ?? void 0;
69
+ const forcePathStyle = parsed.searchParams.get("forcePathStyle") === "true" ? true : void 0;
70
+ return {
71
+ bucket,
72
+ ...region ? { region } : {},
73
+ ...endpoint ? { endpoint } : {},
74
+ ...forcePathStyle ? { forcePathStyle } : {}
75
+ };
76
+ }
77
+
78
+ //#endregion
79
+ Object.defineProperty(exports, '__toESM', {
80
+ enumerable: true,
81
+ get: function () {
82
+ return __toESM;
83
+ }
84
+ });
85
+ Object.defineProperty(exports, 'build', {
86
+ enumerable: true,
87
+ get: function () {
88
+ return build;
89
+ }
90
+ });
91
+ Object.defineProperty(exports, 'parse', {
92
+ enumerable: true,
93
+ get: function () {
94
+ return parse;
95
+ }
96
+ });
97
+ Object.defineProperty(exports, 's3Url_exports', {
98
+ enumerable: true,
99
+ get: function () {
100
+ return s3Url_exports;
101
+ }
102
+ });
103
+ //# sourceMappingURL=s3Url-Bo32UTTA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3Url-Bo32UTTA.cjs","names":["address: S3Address","MissingStorageBucket","url: string","parsed: URL","MalformedStorageUrl","UnexpectedStorageScheme"],"sources":["../src/s3Url.ts"],"sourcesContent":["/**\n * The `s3://` URL codec — how an S3 bucket is addressed as a single string.\n *\n * It lives beside the client rather than in a neutral package because `bucket`,\n * `region`, and `forcePathStyle` are S3's vocabulary. The neutral layer only\n * knows that a construct provides *one URL*; what that URL says is between the\n * component that composes it and the client that parses it. A `gs://` codec\n * would sit beside its own client and share nothing with this one.\n *\n * Both directions live here so they cannot drift: `parse(build(x))` is `x`.\n */\n\nimport {\n\tMalformedStorageUrl,\n\tMissingStorageBucket,\n\tUnexpectedStorageScheme,\n} from './errors';\n\n/** What an S3 URL addresses. Credentials are deliberately absent — see below. */\nexport interface S3Address {\n\tbucket: string;\n\t/** Read off the bucket, never inherited: a bucket may live in another region. */\n\tregion?: string;\n\t/** Set for S3-compatible backends such as MinIO. */\n\tendpoint?: string;\n\t/** MinIO and most S3-compatible servers need path-style addressing. */\n\tforcePathStyle?: boolean;\n}\n\nconst SCHEME = 's3:';\n\n/**\n * Compose an address into a URL.\n *\n * Credentials never appear. The AWS SDK resolves them from its own chain — an\n * execution role when deployed, `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`\n * locally — so the URL stays safe to log and identical across environments that\n * differ only in who is calling.\n */\nexport function build(address: S3Address): string {\n\tconst { bucket, region, endpoint, forcePathStyle } = address;\n\tif (!bucket) throw new MissingStorageBucket('');\n\n\tconst url = new URL(`${SCHEME}//${bucket}`);\n\tif (region) url.searchParams.set('region', region);\n\tif (endpoint) url.searchParams.set('endpoint', endpoint);\n\tif (forcePathStyle) url.searchParams.set('forcePathStyle', 'true');\n\treturn url.toString();\n}\n\n/** Parse a URL back into an address. Throws if it is not an `s3://` URL. */\nexport function parse(url: string): S3Address {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\tthrow new MalformedStorageUrl(url);\n\t}\n\n\tif (parsed.protocol !== SCHEME) {\n\t\tthrow new UnexpectedStorageScheme(url, SCHEME, parsed.protocol);\n\t}\n\n\tconst bucket = parsed.hostname;\n\tif (!bucket) throw new MissingStorageBucket(url);\n\n\tconst region = parsed.searchParams.get('region') ?? undefined;\n\tconst endpoint = parsed.searchParams.get('endpoint') ?? undefined;\n\tconst forcePathStyle =\n\t\tparsed.searchParams.get('forcePathStyle') === 'true' ? true : undefined;\n\n\treturn {\n\t\tbucket,\n\t\t...(region ? { region } : {}),\n\t\t...(endpoint ? { endpoint } : {}),\n\t\t...(forcePathStyle ? { forcePathStyle } : {}),\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAM,SAAS;;;;;;;;;AAUf,SAAgB,MAAMA,SAA4B;CACjD,MAAM,EAAE,QAAQ,QAAQ,UAAU,gBAAgB,GAAG;AACrD,MAAK,OAAQ,OAAM,IAAIC,oCAAqB;CAE5C,MAAM,MAAM,IAAI,KAAK,EAAE,OAAO,IAAI,OAAO;AACzC,KAAI,OAAQ,KAAI,aAAa,IAAI,UAAU,OAAO;AAClD,KAAI,SAAU,KAAI,aAAa,IAAI,YAAY,SAAS;AACxD,KAAI,eAAgB,KAAI,aAAa,IAAI,kBAAkB,OAAO;AAClE,QAAO,IAAI,UAAU;AACrB;;AAGD,SAAgB,MAAMC,KAAwB;CAC7C,IAAIC;AACJ,KAAI;AACH,WAAS,IAAI,IAAI;CACjB,QAAO;AACP,QAAM,IAAIC,mCAAoB;CAC9B;AAED,KAAI,OAAO,aAAa,OACvB,OAAM,IAAIC,uCAAwB,KAAK,QAAQ,OAAO;CAGvD,MAAM,SAAS,OAAO;AACtB,MAAK,OAAQ,OAAM,IAAIJ,oCAAqB;CAE5C,MAAM,SAAS,OAAO,aAAa,IAAI,SAAS;CAChD,MAAM,WAAW,OAAO,aAAa,IAAI,WAAW;CACpD,MAAM,iBACL,OAAO,aAAa,IAAI,iBAAiB,KAAK,SAAS;AAExD,QAAO;EACN;EACA,GAAI,SAAS,EAAE,OAAQ,IAAG,CAAE;EAC5B,GAAI,WAAW,EAAE,SAAU,IAAG,CAAE;EAChC,GAAI,iBAAiB,EAAE,eAAgB,IAAG,CAAE;CAC5C;AACD"}
@@ -0,0 +1,52 @@
1
+ import { __export } from "./chunk-B9dir_RE.mjs";
2
+ import { MalformedStorageUrl, MissingStorageBucket, UnexpectedStorageScheme } from "./errors-D5UnAd-X.mjs";
3
+
4
+ //#region src/s3Url.ts
5
+ var s3Url_exports = {};
6
+ __export(s3Url_exports, {
7
+ build: () => build,
8
+ parse: () => parse
9
+ });
10
+ const SCHEME = "s3:";
11
+ /**
12
+ * Compose an address into a URL.
13
+ *
14
+ * Credentials never appear. The AWS SDK resolves them from its own chain — an
15
+ * execution role when deployed, `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`
16
+ * locally — so the URL stays safe to log and identical across environments that
17
+ * differ only in who is calling.
18
+ */
19
+ function build(address) {
20
+ const { bucket, region, endpoint, forcePathStyle } = address;
21
+ if (!bucket) throw new MissingStorageBucket("");
22
+ const url = new URL(`${SCHEME}//${bucket}`);
23
+ if (region) url.searchParams.set("region", region);
24
+ if (endpoint) url.searchParams.set("endpoint", endpoint);
25
+ if (forcePathStyle) url.searchParams.set("forcePathStyle", "true");
26
+ return url.toString();
27
+ }
28
+ /** Parse a URL back into an address. Throws if it is not an `s3://` URL. */
29
+ function parse(url) {
30
+ let parsed;
31
+ try {
32
+ parsed = new URL(url);
33
+ } catch {
34
+ throw new MalformedStorageUrl(url);
35
+ }
36
+ if (parsed.protocol !== SCHEME) throw new UnexpectedStorageScheme(url, SCHEME, parsed.protocol);
37
+ const bucket = parsed.hostname;
38
+ if (!bucket) throw new MissingStorageBucket(url);
39
+ const region = parsed.searchParams.get("region") ?? void 0;
40
+ const endpoint = parsed.searchParams.get("endpoint") ?? void 0;
41
+ const forcePathStyle = parsed.searchParams.get("forcePathStyle") === "true" ? true : void 0;
42
+ return {
43
+ bucket,
44
+ ...region ? { region } : {},
45
+ ...endpoint ? { endpoint } : {},
46
+ ...forcePathStyle ? { forcePathStyle } : {}
47
+ };
48
+ }
49
+
50
+ //#endregion
51
+ export { build, parse, s3Url_exports };
52
+ //# sourceMappingURL=s3Url-C8FGPNrG.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3Url-C8FGPNrG.mjs","names":["address: S3Address","url: string","parsed: URL"],"sources":["../src/s3Url.ts"],"sourcesContent":["/**\n * The `s3://` URL codec — how an S3 bucket is addressed as a single string.\n *\n * It lives beside the client rather than in a neutral package because `bucket`,\n * `region`, and `forcePathStyle` are S3's vocabulary. The neutral layer only\n * knows that a construct provides *one URL*; what that URL says is between the\n * component that composes it and the client that parses it. A `gs://` codec\n * would sit beside its own client and share nothing with this one.\n *\n * Both directions live here so they cannot drift: `parse(build(x))` is `x`.\n */\n\nimport {\n\tMalformedStorageUrl,\n\tMissingStorageBucket,\n\tUnexpectedStorageScheme,\n} from './errors';\n\n/** What an S3 URL addresses. Credentials are deliberately absent — see below. */\nexport interface S3Address {\n\tbucket: string;\n\t/** Read off the bucket, never inherited: a bucket may live in another region. */\n\tregion?: string;\n\t/** Set for S3-compatible backends such as MinIO. */\n\tendpoint?: string;\n\t/** MinIO and most S3-compatible servers need path-style addressing. */\n\tforcePathStyle?: boolean;\n}\n\nconst SCHEME = 's3:';\n\n/**\n * Compose an address into a URL.\n *\n * Credentials never appear. The AWS SDK resolves them from its own chain — an\n * execution role when deployed, `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`\n * locally — so the URL stays safe to log and identical across environments that\n * differ only in who is calling.\n */\nexport function build(address: S3Address): string {\n\tconst { bucket, region, endpoint, forcePathStyle } = address;\n\tif (!bucket) throw new MissingStorageBucket('');\n\n\tconst url = new URL(`${SCHEME}//${bucket}`);\n\tif (region) url.searchParams.set('region', region);\n\tif (endpoint) url.searchParams.set('endpoint', endpoint);\n\tif (forcePathStyle) url.searchParams.set('forcePathStyle', 'true');\n\treturn url.toString();\n}\n\n/** Parse a URL back into an address. Throws if it is not an `s3://` URL. */\nexport function parse(url: string): S3Address {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\tthrow new MalformedStorageUrl(url);\n\t}\n\n\tif (parsed.protocol !== SCHEME) {\n\t\tthrow new UnexpectedStorageScheme(url, SCHEME, parsed.protocol);\n\t}\n\n\tconst bucket = parsed.hostname;\n\tif (!bucket) throw new MissingStorageBucket(url);\n\n\tconst region = parsed.searchParams.get('region') ?? undefined;\n\tconst endpoint = parsed.searchParams.get('endpoint') ?? undefined;\n\tconst forcePathStyle =\n\t\tparsed.searchParams.get('forcePathStyle') === 'true' ? true : undefined;\n\n\treturn {\n\t\tbucket,\n\t\t...(region ? { region } : {}),\n\t\t...(endpoint ? { endpoint } : {}),\n\t\t...(forcePathStyle ? { forcePathStyle } : {}),\n\t};\n}\n"],"mappings":";;;;;;;;;AA6BA,MAAM,SAAS;;;;;;;;;AAUf,SAAgB,MAAMA,SAA4B;CACjD,MAAM,EAAE,QAAQ,QAAQ,UAAU,gBAAgB,GAAG;AACrD,MAAK,OAAQ,OAAM,IAAI,qBAAqB;CAE5C,MAAM,MAAM,IAAI,KAAK,EAAE,OAAO,IAAI,OAAO;AACzC,KAAI,OAAQ,KAAI,aAAa,IAAI,UAAU,OAAO;AAClD,KAAI,SAAU,KAAI,aAAa,IAAI,YAAY,SAAS;AACxD,KAAI,eAAgB,KAAI,aAAa,IAAI,kBAAkB,OAAO;AAClE,QAAO,IAAI,UAAU;AACrB;;AAGD,SAAgB,MAAMC,KAAwB;CAC7C,IAAIC;AACJ,KAAI;AACH,WAAS,IAAI,IAAI;CACjB,QAAO;AACP,QAAM,IAAI,oBAAoB;CAC9B;AAED,KAAI,OAAO,aAAa,OACvB,OAAM,IAAI,wBAAwB,KAAK,QAAQ,OAAO;CAGvD,MAAM,SAAS,OAAO;AACtB,MAAK,OAAQ,OAAM,IAAI,qBAAqB;CAE5C,MAAM,SAAS,OAAO,aAAa,IAAI,SAAS;CAChD,MAAM,WAAW,OAAO,aAAa,IAAI,WAAW;CACpD,MAAM,iBACL,OAAO,aAAa,IAAI,iBAAiB,KAAK,SAAS;AAExD,QAAO;EACN;EACA,GAAI,SAAS,EAAE,OAAQ,IAAG,CAAE;EAC5B,GAAI,WAAW,EAAE,SAAU,IAAG,CAAE;EAChC,GAAI,iBAAiB,EAAE,eAAgB,IAAG,CAAE;CAC5C;AACD"}