@homecloud-platform/sdk 0.5.3 → 0.5.5

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/README.md CHANGED
@@ -32,6 +32,11 @@ exports.handler = async (event, context) => {
32
32
  accountId: context.account_id,
33
33
  });
34
34
  await client.so.putJson("my-bucket", "proof/ok.json", { ok: true });
35
+ await client.so.upload("my-bucket", null, {
36
+ body: Buffer.from("..."),
37
+ key: "videos/clip.mp4",
38
+ contentType: "video/mp4",
39
+ });
35
40
  return { ok: true };
36
41
  };
37
42
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homecloud-platform/sdk",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "HomeCloud Functions SDK for Node.js (ADR-033 / ADR-025e)",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
package/src/client.js CHANGED
@@ -375,8 +375,8 @@ class HomeCloud {
375
375
  return data;
376
376
  }
377
377
 
378
- async login(username, password, { mfaCode } = {}) {
379
- const body = { username, password };
378
+ async login(account, username, password, { mfaCode } = {}) {
379
+ const body = { account, username, password };
380
380
  if (mfaCode) body.mfa_code = mfaCode;
381
381
  const data = await this.consoleRequest("POST", "auth/login", {
382
382
  json: body,
package/src/so.js CHANGED
@@ -2,10 +2,38 @@
2
2
 
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
- const os = require("os");
6
5
  const { soObjectPaths } = require("./signing");
7
6
  const { HomeCloudError } = require("./errors");
8
7
 
8
+ const MIME_BY_EXT = {
9
+ ".mp4": "video/mp4",
10
+ ".webm": "video/webm",
11
+ ".mov": "video/quicktime",
12
+ ".mp3": "audio/mpeg",
13
+ ".wav": "audio/wav",
14
+ ".ogg": "audio/ogg",
15
+ ".png": "image/png",
16
+ ".jpg": "image/jpeg",
17
+ ".jpeg": "image/jpeg",
18
+ ".gif": "image/gif",
19
+ ".webp": "image/webp",
20
+ ".pdf": "application/pdf",
21
+ ".json": "application/json",
22
+ ".txt": "text/plain",
23
+ ".html": "text/html",
24
+ ".htm": "text/html",
25
+ ".css": "text/css",
26
+ ".js": "text/javascript",
27
+ ".xml": "application/xml",
28
+ ".csv": "text/csv",
29
+ ".zip": "application/zip",
30
+ };
31
+
32
+ function _guessContentType(name) {
33
+ const ext = path.extname(String(name || "")).toLowerCase();
34
+ return MIME_BY_EXT[ext] || null;
35
+ }
36
+
9
37
  class SoAPI {
10
38
  constructor(client) {
11
39
  this._c = client;
@@ -58,34 +86,56 @@ class SoAPI {
58
86
  return items;
59
87
  }
60
88
 
61
- async upload(bucketName, filePath, { key } = {}) {
89
+ async upload(bucketName, filePath, { key, body, contentType } = {}) {
62
90
  this._c.requireAccessKey();
63
- if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
64
- throw new HomeCloudError(`File not found: ${filePath}`);
91
+ const hasBody = body !== undefined && body !== null;
92
+ if (hasBody && filePath != null && filePath !== "") {
93
+ throw new HomeCloudError("Pass either filePath or body, not both");
94
+ }
95
+ if (!hasBody && (filePath == null || filePath === "")) {
96
+ throw new HomeCloudError("filePath or body is required");
65
97
  }
66
- const objectKey = key || path.basename(filePath);
98
+ if (hasBody && (!key || !String(key).trim())) {
99
+ throw new HomeCloudError("key is required when uploading body");
100
+ }
101
+
102
+ let objectKey;
103
+ let filename;
104
+ let payload;
105
+
106
+ if (hasBody) {
107
+ objectKey = String(key).trim().replace(/^\/+/, "");
108
+ filename = path.basename(objectKey) || "object";
109
+ payload = body;
110
+ } else {
111
+ if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
112
+ throw new HomeCloudError(`File not found: ${filePath}`);
113
+ }
114
+ objectKey = key || path.basename(filePath);
115
+ filename = path.basename(filePath);
116
+ payload = fs.readFileSync(filePath);
117
+ }
118
+
119
+ const mime =
120
+ contentType ||
121
+ _guessContentType(objectKey) ||
122
+ _guessContentType(filename) ||
123
+ "application/octet-stream";
67
124
  const accountId = this._c.accountId;
68
125
  const uploadPath = `/${accountId}/${bucketName}/objects`;
69
- const blob = fs.readFileSync(filePath);
70
126
  const form = new FormData();
71
127
  form.append("key", objectKey);
72
- form.append("file", new Blob([blob]), path.basename(filePath));
128
+ form.append("file", new Blob([payload], { type: mime }), filename);
73
129
  return this._c.dataPlaneRequest("so", "POST", uploadPath, { formData: form });
74
130
  }
75
131
 
76
132
  async putJson(bucketName, objectKey, value) {
77
- const tmp = path.join(
78
- os.tmpdir(),
79
- `hc-sdk-${Date.now()}-${Math.random().toString(16).slice(2)}.json`
80
- );
81
- fs.writeFileSync(tmp, JSON.stringify(value, null, 2), "utf8");
82
- try {
83
- return await this.upload(bucketName, tmp, { key: objectKey });
84
- } finally {
85
- try {
86
- fs.unlinkSync(tmp);
87
- } catch (_) {}
88
- }
133
+ const data = Buffer.from(JSON.stringify(value, null, 2), "utf8");
134
+ return this.upload(bucketName, null, {
135
+ key: objectKey,
136
+ body: data,
137
+ contentType: "application/json",
138
+ });
89
139
  }
90
140
 
91
141
  async delete(bucketName, objectKey) {