@teamflojo/floimg 0.4.0 → 0.6.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.
@@ -1,17 +1,29 @@
1
- import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
1
+ import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
2
+ import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
2
3
  /**
3
4
  * S3 save provider - saves images to AWS S3 or S3-compatible storage
5
+ *
6
+ * Supports:
7
+ * - AWS S3
8
+ * - Hetzner Object Storage
9
+ * - Cloudflare R2
10
+ * - Any S3-compatible service
4
11
  */
5
12
  export default class S3SaveProvider {
6
13
  name = "s3";
7
14
  s3Client;
8
15
  bucket;
16
+ region;
17
+ endpoint;
9
18
  constructor(config) {
10
19
  this.bucket = config.bucket;
20
+ this.region = config.region;
21
+ this.endpoint = config.endpoint;
11
22
  this.s3Client = new S3Client({
12
23
  region: config.region,
13
24
  endpoint: config.endpoint,
14
25
  credentials: config.credentials,
26
+ forcePathStyle: !!config.endpoint, // Required for S3-compatible services
15
27
  });
16
28
  }
17
29
  async save(input) {
@@ -23,9 +35,7 @@ export default class S3SaveProvider {
23
35
  ...(input.headers && { Metadata: input.headers }),
24
36
  });
25
37
  const result = await this.s3Client.send(command);
26
- const url = input.headers?.endpoint
27
- ? `${input.headers.endpoint}/${this.bucket}/${input.path}`
28
- : `https://${this.bucket}.s3.amazonaws.com/${input.path}`;
38
+ const url = this.getPublicUrl(input.path);
29
39
  return {
30
40
  provider: "s3",
31
41
  location: url,
@@ -38,5 +48,49 @@ export default class S3SaveProvider {
38
48
  },
39
49
  };
40
50
  }
51
+ /**
52
+ * Generate a presigned URL for temporary access to a private object
53
+ *
54
+ * @param key - The S3 object key (path)
55
+ * @param options - Presign options (expiry time)
56
+ * @returns Presigned URL string
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const provider = new S3SaveProvider({ bucket: 'my-bucket', region: 'us-east-1' });
61
+ * const url = await provider.getPresignedUrl('images/photo.png', { expiresIn: 3600 });
62
+ * // Returns: https://my-bucket.s3.us-east-1.amazonaws.com/images/photo.png?X-Amz-...
63
+ * ```
64
+ */
65
+ async getPresignedUrl(key, options) {
66
+ const command = new GetObjectCommand({
67
+ Bucket: this.bucket,
68
+ Key: key,
69
+ });
70
+ const expiresIn = options?.expiresIn ?? 3600; // Default 1 hour
71
+ return getSignedUrl(this.s3Client, command, { expiresIn });
72
+ }
73
+ /**
74
+ * Get the public URL for an object (assumes bucket is publicly readable)
75
+ *
76
+ * @param key - The S3 object key (path)
77
+ * @returns Public URL string
78
+ */
79
+ getPublicUrl(key) {
80
+ if (this.endpoint) {
81
+ // S3-compatible service (Hetzner, R2, etc.)
82
+ // Format: https://endpoint/bucket/key
83
+ return `${this.endpoint}/${this.bucket}/${key}`;
84
+ }
85
+ // AWS S3
86
+ // Format: https://bucket.s3.region.amazonaws.com/key
87
+ return `https://${this.bucket}.s3.${this.region}.amazonaws.com/${key}`;
88
+ }
89
+ /**
90
+ * Get the bucket name
91
+ */
92
+ getBucket() {
93
+ return this.bucket;
94
+ }
41
95
  }
42
96
  //# sourceMappingURL=S3SaveProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"S3SaveProvider.js","sourceRoot":"","sources":["../../../src/providers/save/S3SaveProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAahE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,IAAI,GAAG,IAAI,CAAC;IACJ,QAAQ,CAAW;IACnB,MAAM,CAAS;IAEvB,YAAY,MAA4B;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAKV;QACC,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,KAAK,CAAC,IAAI;YACf,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;YACtB,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;YAC5B,GAAG,CAAE,KAAK,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;SACnD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEjD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,EAAE,QAAQ;YACjC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE;YAC1D,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,qBAAqB,KAAK,CAAC,IAAI,EAAE,CAAC;QAE5D,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,GAAG;YACb,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAC7B,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;YACrB,QAAQ,EAAE;gBACR,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,KAAK,CAAC,IAAI;aAChB;SACF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"S3SaveProvider.js","sourceRoot":"","sources":["../../../src/providers/save/S3SaveProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAkB7D;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,IAAI,GAAG,IAAI,CAAC;IACJ,QAAQ,CAAW;IACnB,MAAM,CAAS;IACf,MAAM,CAAS;IACf,QAAQ,CAAU;IAE1B,YAAY,MAA4B;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,sCAAsC;SAC1E,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAKV;QACC,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,KAAK,CAAC,IAAI;YACf,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;YACtB,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;YAC5B,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEjD,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1C,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,GAAG;YACb,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAC7B,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;YACrB,QAAQ,EAAE;gBACR,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,KAAK,CAAC,IAAI;aAChB;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,eAAe,CAAC,GAAW,EAAE,OAAwB;QACzD,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,GAAG;SACT,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC,iBAAiB;QAE/D,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,GAAW;QACtB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,4CAA4C;YAC5C,sCAAsC;YACtC,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAClD,CAAC;QACD,SAAS;QACT,qDAAqD;QACrD,OAAO,WAAW,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;IACzE,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamflojo/floimg",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Universal image workflow engine for developers and AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -56,6 +56,7 @@
56
56
  "homepage": "https://github.com/TeamFlojo/floimg#readme",
57
57
  "dependencies": {
58
58
  "@aws-sdk/client-s3": "^3.709.0",
59
+ "@aws-sdk/s3-request-presigner": "^3.958.0",
59
60
  "@modelcontextprotocol/sdk": "^1.20.0",
60
61
  "@napi-rs/canvas": "^0.1.80",
61
62
  "@resvg/resvg-js": "^2.6.2",