From be05d836eaa5f0e9f6e9af3098d7ddade7225c32 Mon Sep 17 00:00:00 2001 From: Damien Erambert Date: Sun, 31 Jul 2022 21:53:37 +0200 Subject: [PATCH] :construction: working file upload --- lib.js | 131 +++++++++++++++++++++++++++++----------------- package-lock.json | 129 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 5 +- 3 files changed, 214 insertions(+), 51 deletions(-) diff --git a/lib.js b/lib.js index b8cbaac..06b1aab 100644 --- a/lib.js +++ b/lib.js @@ -1,6 +1,11 @@ -const _fetch = require("node-fetch"); +const _fetch = require('node-fetch') const crypto = require("crypto"); +const needle = require('needle'); const { decode } = require("./lib/b64arraybuffer"); +const fs = require('fs'); +const path = require('path'); +const mime = require('mime-types'); + const API_BASE = "https://cohost.org/api/v1"; @@ -15,14 +20,14 @@ const API_BASE = "https://cohost.org/api/v1"; * @param {boolean} [complex=false] Whether to return {headers, body}, or just the body * @returns Response, JSON parsed if parsable, string if not */ -async function fetch(method, endpoint, cookies = "", data, complex = false) { +async function fetch(method, endpoint, cookies = "", data, complex = false, headers = {}) { let url = API_BASE + endpoint + (method == "GET" && data ? "?" + new URLSearchParams(data).toString() : ""); let req = await _fetch(url, { method, headers: { "Content-Type": "application/json", - "Cookie": cookies + "Cookie": cookies, }, body: (method != "GET" && data) ? JSON.stringify(data) : undefined }); @@ -112,54 +117,86 @@ class User { * Represents a cohost Project (e.g. @mog) */ class Project { - constructor(user, data) { - this.user = user; - this.populate(data); - } + constructor(user, data) { + this.user = user; + this.populate(data); + } - /** - * Creates a Project. Docs TBD - */ - static async create(user, data) { - return await fetch( - "POST", - "/project", - user.sessionCookie, - data - ); - } + /** + * Creates a Project. Docs TBD + */ + static async create(user, data) { + return await fetch("POST", "/project", user.sessionCookie, data); + } - /** - * @private - */ - populate(data) { - this.id = data.projectId; - this.handle = data.handle; - this.displayName = data.displayName; - this.dek = data.dek; - this.description = data.description; - this.avatarURL = data.avatarURL; - this.headerURL = data.headerURL; - this.privacy = data.privacy; - this.pronouns = data.pronouns; - this.url = data.url; - this.flags = data.flags; - this.avatarShape = data.avatarShape; - } + /** + * @private + */ + populate(data) { + this.id = data.projectId; + this.handle = data.handle; + this.displayName = data.displayName; + this.dek = data.dek; + this.description = data.description; + this.avatarURL = data.avatarURL; + this.headerURL = data.headerURL; + this.privacy = data.privacy; + this.pronouns = data.pronouns; + this.url = data.url; + this.flags = data.flags; + this.avatarShape = data.avatarShape; + } - /** - * @param {number} [page=0] Page of posts to get, 20 posts per page - * @returns {object[]} - */ - async getPosts(page = 0) { - let res = await fetch( - "GET", - `/project/${encodeURIComponent(this.handle)}/posts?page=${encodeURIComponent(page.toString())}`, - this.user.sessionCookie - ); + /** + * @param {number} [page=0] Page of posts to get, 20 posts per page + * @returns {object[]} + */ + async getPosts(page = 0) { + let res = await fetch( + "GET", + `/project/${encodeURIComponent( + this.handle + )}/posts?page=${encodeURIComponent(page.toString())}`, + this.user.sessionCookie + ); - return res.items.map(x => new Post(this.user, x)); - } + return res.items.map((x) => new Post(this.user, x)); + } + + async uploadAttachment(postId, filename) { + const fileContentType = mime.lookup(filename); + const fileContentLength = fs.statSync(filename).size; + const S3Parameters = await fetch( + "POST", + `/project/${encodeURIComponent( + this.handle + )}/posts/${postId}/attach/start`, + this.user.sessionCookie, + { + filename: path.basename(filename), + content_type: fileContentType, + content_length: fileContentLength, + } + ); + + await needle('post', S3Parameters.url, { + ...S3Parameters.requiredFields, + file: { + file: filename, + content_type: fileContentType + } + }, {multipart: true}); + + const res = fetch( + "POST", + `/project/${encodeURIComponent( + this.handle + )}/posts/${postId}/attach/finish/${S3Parameters.attachmentId}`, + this.user.sessionCookie + ) + + console.log(await res) + } } /** diff --git a/package-lock.json b/package-lock.json index 848077b..fbb1d6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,78 @@ { "name": "cohost", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cohost", - "version": "0.0.1", + "version": "0.0.2", "license": "MIT", "dependencies": { + "mime-types": "^2.1.35", + "needle": "^3.1.0", "node-fetch": "2" } }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/needle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", + "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -31,6 +92,16 @@ } } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -52,6 +123,50 @@ } }, "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "needle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", + "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + } + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -60,6 +175,16 @@ "whatwg-url": "^5.0.0" } }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", diff --git a/package.json b/package.json index 573af73..d73bd6b 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,13 @@ "author": "mogery", "license": "MIT", "dependencies": { + "mime-types": "^2.1.35", + "needle": "^3.1.0", "node-fetch": "2" }, "directories": { "lib": "lib" }, - "devDependencies": {}, "repository": { "type": "git", "url": "git+https://github.com/mogery/cohost.js.git" @@ -24,4 +25,4 @@ "url": "https://github.com/mogery/cohost.js/issues" }, "homepage": "https://github.com/mogery/cohost.js#readme" -} +} \ No newline at end of file