@nymbalhq/media-s3 1.1.0 → 1.2.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.
package/dist/index.d.ts CHANGED
@@ -23,6 +23,19 @@ interface S3MediaStorageOptions extends S3ObjectUrlOptions {
23
23
  }
24
24
  declare const S3_MEDIA_CAPABILITIES: readonly string[];
25
25
  declare const DEFAULT_S3_REGION = "us-east-1";
26
+ /** The connection fields every client of this package is made from. */
27
+ interface S3ClientOptions {
28
+ /** `us-east-1` when not given. */
29
+ region?: string;
30
+ endpoint?: string;
31
+ /** True by default when an endpoint is set: an S3-compatible server rarely has per-bucket hostnames. */
32
+ forcePathStyle?: boolean;
33
+ /** When not given, the AWS SDK's default chain provides them (the environment, a profile, a role). */
34
+ credentials?: {
35
+ accessKeyId: string;
36
+ secretAccessKey: string;
37
+ };
38
+ }
26
39
  /** The public URL of the object stored under `key`: the base, then each segment of the object key percent-encoded. */
27
40
  declare function s3ObjectUrl(options: S3ObjectUrlOptions, key: string): string;
28
41
  /**
@@ -31,10 +44,26 @@ declare function s3ObjectUrl(options: S3ObjectUrlOptions, key: string): string;
31
44
  */
32
45
  declare function createS3MediaStorage(options: S3MediaStorageOptions): MediaStorage;
33
46
 
47
+ interface S3ObjectWriterOptions extends S3ClientOptions {
48
+ bucket: string;
49
+ /** Prepended to every key, its edge slashes trimmed; none when empty. */
50
+ prefix?: string;
51
+ }
52
+ /** Writes whole objects; what it writes is read back only with credentials. */
53
+ interface S3ObjectWriter {
54
+ put(key: string, body: Uint8Array, contentType: string): Promise<void>;
55
+ }
56
+ /**
57
+ * Private objects in a bucket the operator owns, such as the event archive: unlike media storage it answers no URL,
58
+ * and it sets no ACL, so an object is as private as its bucket. Never point it at the public media bucket.
59
+ */
60
+ declare function createS3ObjectWriter(options: S3ObjectWriterOptions): S3ObjectWriter;
61
+
34
62
  /**
35
63
  * The kernel's entry: `infrastructure.media: 's3'`, with the `s3` block as the platform resolved it (its environment
36
64
  * fallbacks and defaults applied). Credentials are never in it: the AWS SDK's default chain provides them.
37
65
  */
38
66
  declare function createAdapter(ctx: AdapterContext): MediaStorage;
39
67
 
40
- export { DEFAULT_S3_REGION, type S3MediaStorageOptions, type S3ObjectUrlOptions, S3_MEDIA_CAPABILITIES, createAdapter, createS3MediaStorage, s3ObjectUrl };
68
+ export { DEFAULT_S3_REGION, S3_MEDIA_CAPABILITIES, createAdapter, createS3MediaStorage, createS3ObjectWriter, s3ObjectUrl };
69
+ export type { S3MediaStorageOptions, S3ObjectUrlOptions, S3ObjectWriter, S3ObjectWriterOptions };
package/dist/index.js CHANGED
@@ -7,6 +7,14 @@ import { boundedHealthCheck } from "@nymbalhq/types";
7
7
  var S3_MEDIA_CAPABILITIES = ["put"];
8
8
  var DEFAULT_S3_REGION = "us-east-1";
9
9
  var trimTrailingSlashes = (s) => s.replace(/\/+$/, "");
10
+ function s3Client(options) {
11
+ return new S3Client({
12
+ region: options.region ?? DEFAULT_S3_REGION,
13
+ forcePathStyle: options.forcePathStyle ?? options.endpoint !== void 0,
14
+ ...options.endpoint !== void 0 && { endpoint: options.endpoint },
15
+ ...options.credentials !== void 0 && { credentials: options.credentials }
16
+ });
17
+ }
10
18
  function objectKey(prefix, key) {
11
19
  const trimmed = (prefix ?? "").replace(/^\/+|\/+$/g, "");
12
20
  return trimmed === "" ? key : `${trimmed}/${key}`;
@@ -23,12 +31,7 @@ function s3ObjectUrl(options, key) {
23
31
  return `${baseUrl(options)}/${path}`;
24
32
  }
25
33
  function createS3MediaStorage(options) {
26
- const client = new S3Client({
27
- region: options.region ?? DEFAULT_S3_REGION,
28
- forcePathStyle: options.forcePathStyle ?? options.endpoint !== void 0,
29
- ...options.endpoint !== void 0 && { endpoint: options.endpoint },
30
- ...options.credentials !== void 0 && { credentials: options.credentials }
31
- });
34
+ const client = s3Client(options);
32
35
  return {
33
36
  capabilities: () => S3_MEDIA_CAPABILITIES,
34
37
  async put(key, body, contentType) {
@@ -62,6 +65,24 @@ function createS3MediaStorage(options) {
62
65
  };
63
66
  }
64
67
 
68
+ // src/s3-object-writer.ts
69
+ import { PutObjectCommand as PutObjectCommand2 } from "@aws-sdk/client-s3";
70
+ function createS3ObjectWriter(options) {
71
+ const client = s3Client(options);
72
+ return {
73
+ async put(key, body, contentType) {
74
+ await client.send(
75
+ new PutObjectCommand2({
76
+ Bucket: options.bucket,
77
+ Key: objectKey(options.prefix, key),
78
+ Body: body,
79
+ ContentType: contentType
80
+ })
81
+ );
82
+ }
83
+ };
84
+ }
85
+
65
86
  // src/index.ts
66
87
  var optionalString = (value) => typeof value === "string" && value !== "" ? value : void 0;
67
88
  function createAdapter(ctx) {
@@ -93,6 +114,7 @@ export {
93
114
  S3_MEDIA_CAPABILITIES,
94
115
  createAdapter,
95
116
  createS3MediaStorage,
117
+ createS3ObjectWriter,
96
118
  s3ObjectUrl
97
119
  };
98
120
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/s3-media-storage.ts"],"sourcesContent":["import { ConfigError, type AdapterContext, type MediaStorage } from '@nymbalhq/types'\nimport { createS3MediaStorage, type S3MediaStorageOptions } from './s3-media-storage.js'\n\nexport {\n createS3MediaStorage,\n DEFAULT_S3_REGION,\n S3_MEDIA_CAPABILITIES,\n s3ObjectUrl,\n type S3MediaStorageOptions,\n type S3ObjectUrlOptions,\n} from './s3-media-storage.js'\n\nconst optionalString = (value: unknown): string | undefined =>\n typeof value === 'string' && value !== '' ? value : undefined\n\n/**\n * The kernel's entry: `infrastructure.media: 's3'`, with the `s3` block as the platform resolved it (its environment\n * fallbacks and defaults applied). Credentials are never in it: the AWS SDK's default chain provides them.\n */\nexport function createAdapter(ctx: AdapterContext): MediaStorage {\n if (ctx.slot !== 'media') {\n throw new ConfigError(`@nymbalhq/media-s3 serves media, not ${ctx.slot}`, {\n code: 'adapter.wrong_slot',\n context: { slot: ctx.slot },\n })\n }\n const bucket = optionalString(ctx.config['bucket'])\n if (bucket === undefined) {\n throw new ConfigError('@nymbalhq/media-s3 needs a bucket', {\n code: 'config.invalid',\n context: { slot: ctx.slot },\n })\n }\n const options: S3MediaStorageOptions = { bucket }\n for (const field of ['region', 'endpoint', 'prefix', 'publicUrl'] as const) {\n const value = optionalString(ctx.config[field])\n if (value !== undefined) options[field] = value\n }\n if (typeof ctx.config['forcePathStyle'] === 'boolean') {\n options.forcePathStyle = ctx.config['forcePathStyle']\n }\n return createS3MediaStorage(options)\n}\n","import { HeadBucketCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3'\nimport { boundedHealthCheck, type HealthReport, type MediaStorage } from '@nymbalhq/types'\n\n/** Where the URL of an object starts, and where its key starts in the bucket. */\nexport interface S3ObjectUrlOptions {\n bucket: string\n /** `us-east-1` when not given. */\n region?: string\n /** An S3-compatible API (MinIO, R2); its objects are served path-style under it. */\n endpoint?: string\n /** Prepended to every key, its edge slashes trimmed; none when empty. */\n prefix?: string\n /** Where the bucket's objects are served from (a CDN), when not the bucket's own URL. */\n publicUrl?: string\n}\n\nexport interface S3MediaStorageOptions extends S3ObjectUrlOptions {\n /** True by default when an endpoint is set: an S3-compatible server rarely has per-bucket hostnames. */\n forcePathStyle?: boolean\n /** For tests only: a store gets its credentials from the AWS SDK's default chain. */\n credentials?: { accessKeyId: string; secretAccessKey: string }\n}\n\nexport const S3_MEDIA_CAPABILITIES: readonly string[] = ['put']\n\nexport const DEFAULT_S3_REGION = 'us-east-1'\n\nconst trimTrailingSlashes = (s: string): string => s.replace(/\\/+$/, '')\n\n/** The object's key in the bucket. Only the prefix is normalised: the key stays verbatim, so distinct keys stay distinct objects. */\nfunction objectKey(prefix: string | undefined, key: string): string {\n const trimmed = (prefix ?? '').replace(/^\\/+|\\/+$/g, '')\n return trimmed === '' ? key : `${trimmed}/${key}`\n}\n\nfunction baseUrl(options: S3ObjectUrlOptions): string {\n if (options.publicUrl !== undefined) return trimTrailingSlashes(options.publicUrl)\n if (options.endpoint !== undefined) {\n return `${trimTrailingSlashes(options.endpoint)}/${options.bucket}`\n }\n return `https://${options.bucket}.s3.${options.region ?? DEFAULT_S3_REGION}.amazonaws.com`\n}\n\n/** The public URL of the object stored under `key`: the base, then each segment of the object key percent-encoded. */\nexport function s3ObjectUrl(options: S3ObjectUrlOptions, key: string): string {\n const path = objectKey(options.prefix, key).split('/').map(encodeURIComponent).join('/')\n return `${baseUrl(options)}/${path}`\n}\n\n/**\n * Media stored as objects in a bucket the operator owns: it never creates buckets or sets policies, so the bucket (or\n * the `publicUrl` in front of it) must already serve its objects publicly.\n */\nexport function createS3MediaStorage(options: S3MediaStorageOptions): MediaStorage {\n const client = new S3Client({\n region: options.region ?? DEFAULT_S3_REGION,\n forcePathStyle: options.forcePathStyle ?? options.endpoint !== undefined,\n ...(options.endpoint !== undefined && { endpoint: options.endpoint }),\n ...(options.credentials !== undefined && { credentials: options.credentials }),\n })\n return {\n capabilities: () => S3_MEDIA_CAPABILITIES,\n async put(key, body, contentType) {\n await client.send(\n new PutObjectCommand({\n Bucket: options.bucket,\n Key: objectKey(options.prefix, key),\n Body: body,\n ContentType: contentType,\n }),\n )\n return { url: s3ObjectUrl(options, key) }\n },\n // HeadBucket reads the bucket's existence and our access to it; aborted at the bound, retries included.\n healthCheck(): Promise<HealthReport> {\n return boundedHealthCheck(\n async (signal) => {\n await client.send(new HeadBucketCommand({ Bucket: options.bucket }), {\n abortSignal: signal,\n })\n return { status: 'healthy', detail: options.bucket }\n },\n {\n redact: [\n options.credentials?.accessKeyId ?? '',\n options.credentials?.secretAccessKey ?? '',\n ],\n },\n )\n },\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/s3-media-storage.ts","../src/s3-object-writer.ts"],"sourcesContent":["import { ConfigError, type AdapterContext, type MediaStorage } from '@nymbalhq/types'\nimport { createS3MediaStorage, type S3MediaStorageOptions } from './s3-media-storage.js'\n\nexport {\n createS3MediaStorage,\n DEFAULT_S3_REGION,\n S3_MEDIA_CAPABILITIES,\n s3ObjectUrl,\n type S3MediaStorageOptions,\n type S3ObjectUrlOptions,\n} from './s3-media-storage.js'\nexport {\n createS3ObjectWriter,\n type S3ObjectWriter,\n type S3ObjectWriterOptions,\n} from './s3-object-writer.js'\n\nconst optionalString = (value: unknown): string | undefined =>\n typeof value === 'string' && value !== '' ? value : undefined\n\n/**\n * The kernel's entry: `infrastructure.media: 's3'`, with the `s3` block as the platform resolved it (its environment\n * fallbacks and defaults applied). Credentials are never in it: the AWS SDK's default chain provides them.\n */\nexport function createAdapter(ctx: AdapterContext): MediaStorage {\n if (ctx.slot !== 'media') {\n throw new ConfigError(`@nymbalhq/media-s3 serves media, not ${ctx.slot}`, {\n code: 'adapter.wrong_slot',\n context: { slot: ctx.slot },\n })\n }\n const bucket = optionalString(ctx.config['bucket'])\n if (bucket === undefined) {\n throw new ConfigError('@nymbalhq/media-s3 needs a bucket', {\n code: 'config.invalid',\n context: { slot: ctx.slot },\n })\n }\n const options: S3MediaStorageOptions = { bucket }\n for (const field of ['region', 'endpoint', 'prefix', 'publicUrl'] as const) {\n const value = optionalString(ctx.config[field])\n if (value !== undefined) options[field] = value\n }\n if (typeof ctx.config['forcePathStyle'] === 'boolean') {\n options.forcePathStyle = ctx.config['forcePathStyle']\n }\n return createS3MediaStorage(options)\n}\n","import { HeadBucketCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3'\nimport { boundedHealthCheck, type HealthReport, type MediaStorage } from '@nymbalhq/types'\n\n/** Where the URL of an object starts, and where its key starts in the bucket. */\nexport interface S3ObjectUrlOptions {\n bucket: string\n /** `us-east-1` when not given. */\n region?: string\n /** An S3-compatible API (MinIO, R2); its objects are served path-style under it. */\n endpoint?: string\n /** Prepended to every key, its edge slashes trimmed; none when empty. */\n prefix?: string\n /** Where the bucket's objects are served from (a CDN), when not the bucket's own URL. */\n publicUrl?: string\n}\n\nexport interface S3MediaStorageOptions extends S3ObjectUrlOptions {\n /** True by default when an endpoint is set: an S3-compatible server rarely has per-bucket hostnames. */\n forcePathStyle?: boolean\n /** For tests only: a store gets its credentials from the AWS SDK's default chain. */\n credentials?: { accessKeyId: string; secretAccessKey: string }\n}\n\nexport const S3_MEDIA_CAPABILITIES: readonly string[] = ['put']\n\nexport const DEFAULT_S3_REGION = 'us-east-1'\n\nconst trimTrailingSlashes = (s: string): string => s.replace(/\\/+$/, '')\n\n/** The connection fields every client of this package is made from. */\nexport interface S3ClientOptions {\n /** `us-east-1` when not given. */\n region?: string\n endpoint?: string\n /** True by default when an endpoint is set: an S3-compatible server rarely has per-bucket hostnames. */\n forcePathStyle?: boolean\n /** When not given, the AWS SDK's default chain provides them (the environment, a profile, a role). */\n credentials?: { accessKeyId: string; secretAccessKey: string }\n}\n\nexport function s3Client(options: S3ClientOptions): S3Client {\n return new S3Client({\n region: options.region ?? DEFAULT_S3_REGION,\n forcePathStyle: options.forcePathStyle ?? options.endpoint !== undefined,\n ...(options.endpoint !== undefined && { endpoint: options.endpoint }),\n ...(options.credentials !== undefined && { credentials: options.credentials }),\n })\n}\n\n/** The object's key in the bucket. Only the prefix is normalised: the key stays verbatim, so distinct keys stay distinct objects. */\nexport function objectKey(prefix: string | undefined, key: string): string {\n const trimmed = (prefix ?? '').replace(/^\\/+|\\/+$/g, '')\n return trimmed === '' ? key : `${trimmed}/${key}`\n}\n\nfunction baseUrl(options: S3ObjectUrlOptions): string {\n if (options.publicUrl !== undefined) return trimTrailingSlashes(options.publicUrl)\n if (options.endpoint !== undefined) {\n return `${trimTrailingSlashes(options.endpoint)}/${options.bucket}`\n }\n return `https://${options.bucket}.s3.${options.region ?? DEFAULT_S3_REGION}.amazonaws.com`\n}\n\n/** The public URL of the object stored under `key`: the base, then each segment of the object key percent-encoded. */\nexport function s3ObjectUrl(options: S3ObjectUrlOptions, key: string): string {\n const path = objectKey(options.prefix, key).split('/').map(encodeURIComponent).join('/')\n return `${baseUrl(options)}/${path}`\n}\n\n/**\n * Media stored as objects in a bucket the operator owns: it never creates buckets or sets policies, so the bucket (or\n * the `publicUrl` in front of it) must already serve its objects publicly.\n */\nexport function createS3MediaStorage(options: S3MediaStorageOptions): MediaStorage {\n const client = s3Client(options)\n return {\n capabilities: () => S3_MEDIA_CAPABILITIES,\n async put(key, body, contentType) {\n await client.send(\n new PutObjectCommand({\n Bucket: options.bucket,\n Key: objectKey(options.prefix, key),\n Body: body,\n ContentType: contentType,\n }),\n )\n return { url: s3ObjectUrl(options, key) }\n },\n // HeadBucket reads the bucket's existence and our access to it; aborted at the bound, retries included.\n healthCheck(): Promise<HealthReport> {\n return boundedHealthCheck(\n async (signal) => {\n await client.send(new HeadBucketCommand({ Bucket: options.bucket }), {\n abortSignal: signal,\n })\n return { status: 'healthy', detail: options.bucket }\n },\n {\n redact: [\n options.credentials?.accessKeyId ?? '',\n options.credentials?.secretAccessKey ?? '',\n ],\n },\n )\n },\n }\n}\n","import { PutObjectCommand } from '@aws-sdk/client-s3'\nimport { objectKey, s3Client, type S3ClientOptions } from './s3-media-storage.js'\n\nexport interface S3ObjectWriterOptions extends S3ClientOptions {\n bucket: string\n /** Prepended to every key, its edge slashes trimmed; none when empty. */\n prefix?: string\n}\n\n/** Writes whole objects; what it writes is read back only with credentials. */\nexport interface S3ObjectWriter {\n put(key: string, body: Uint8Array, contentType: string): Promise<void>\n}\n\n/**\n * Private objects in a bucket the operator owns, such as the event archive: unlike media storage it answers no URL,\n * and it sets no ACL, so an object is as private as its bucket. Never point it at the public media bucket.\n */\nexport function createS3ObjectWriter(options: S3ObjectWriterOptions): S3ObjectWriter {\n const client = s3Client(options)\n return {\n async put(key, body, contentType) {\n await client.send(\n new PutObjectCommand({\n Bucket: options.bucket,\n Key: objectKey(options.prefix, key),\n Body: body,\n ContentType: contentType,\n }),\n )\n },\n }\n}\n"],"mappings":"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","names":["PutObjectCommand","PutObjectCommand"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nymbalhq/media-s3",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "S3 media storage for Nymbal: `infrastructure.media: 's3'`, on AWS or any S3-compatible bucket",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,19 +29,20 @@
29
29
  "recipes"
30
30
  ],
31
31
  "dependencies": {
32
- "@nymbalhq/types": "1.1.0"
32
+ "@nymbalhq/types": "1.2.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@aws-sdk/client-s3": "^3.600.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@aws-sdk/client-s3": "^3.1153.0",
39
- "tsup": "^8.3.5",
40
- "typescript": "^5.6.3"
39
+ "@typescript/native": "npm:typescript@^7.0.2",
40
+ "tsup": "^9.0.0",
41
+ "typescript": "npm:@typescript/typescript6@^6.0.2"
41
42
  },
42
43
  "scripts": {
43
44
  "build": "tsup",
44
45
  "dev": "tsup --watch",
45
- "typecheck": "tsc -p tsconfig.json --noEmit"
46
+ "typecheck": "tsc -p tsconfig.json --noEmit --rootDir ../.."
46
47
  }
47
48
  }