Simple API wrapper

This commit is contained in:
Danny McGee
2024-03-07 19:26:01 -05:00
parent 326424347f
commit 9b34a82323
5 changed files with 58 additions and 50 deletions
+12 -20
View File
@@ -10,12 +10,12 @@
"license": "MIT",
"dependencies": {
"@fortawesome/fontawesome-pro": "^6.4.2",
"axios": "^1.6.7",
"lit": "^2.8.0",
"lodash": "^4.17.21",
"react": "18.2.0",
"react-dom": "18.2.0",
"tslib": "^2.3.0",
"uuid": "^9.0.1"
"tslib": "^2.3.0"
},
"devDependencies": {
"@nx/js": "16.9.1",
@@ -4976,8 +4976,7 @@
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dev": true
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/available-typed-arrays": {
"version": "1.0.5",
@@ -4992,12 +4991,11 @@
}
},
"node_modules/axios": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz",
"integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==",
"dev": true,
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
"dependencies": {
"follow-redirects": "^1.15.0",
"follow-redirects": "^1.15.4",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
@@ -5606,7 +5604,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -5950,7 +5947,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
"engines": {
"node": ">=0.4.0"
}
@@ -6531,10 +6527,9 @@
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
"dev": true,
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
"funding": [
{
"type": "individual",
@@ -6591,7 +6586,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@@ -8041,7 +8035,6 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -8050,7 +8043,6 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"dependencies": {
"mime-db": "1.52.0"
},
@@ -8834,8 +8826,7 @@
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/psl": {
"version": "1.9.0",
@@ -10202,6 +10193,7 @@
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"dev": true,
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
+2 -2
View File
@@ -42,11 +42,11 @@
},
"dependencies": {
"@fortawesome/fontawesome-pro": "^6.4.2",
"axios": "^1.6.7",
"lit": "^2.8.0",
"lodash": "^4.17.21",
"react": "18.2.0",
"react-dom": "18.2.0",
"tslib": "^2.3.0",
"uuid": "^9.0.1"
"tslib": "^2.3.0"
}
}
+14 -28
View File
@@ -1,4 +1,4 @@
import { drag, on } from "@storyteller/framework";
import { drag, on, provide } from "@storyteller/framework";
import * as studio from "@storyteller/studio";
import {
type SceneSavedEvent,
@@ -9,6 +9,7 @@ import {
import { ButtonElement } from "@storyteller/studio-ui/button";
import {
SceneHierarchyElement,
StorytellerApi,
StudioURLParams,
} from "@storyteller/studio-web";
import { match } from "@storyteller/utility";
@@ -17,7 +18,6 @@ import { customElement, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { createRef, ref } from "lit/directives/ref.js";
import { styleMap } from "lit/directives/style-map.js";
import { v4 as uuid } from "uuid";
import "@storyteller/studio-ui/button";
import "@storyteller/studio-ui/icon";
@@ -40,6 +40,10 @@ import "./blocking.element";
import "./app.element.scss";
@customElement("app-root")
@provide({
token: StorytellerApi,
provide() { return this.api; }
})
export class AppElement extends LitElement {
@state() showHelp = false;
@state() showInspector = false;
@@ -49,6 +53,7 @@ export class AppElement extends LitElement {
@state() inspectorWidth = 320;
@state() hierarchyHeight?: number;
private api = new StorytellerApi();
#enableAnimTimeline = false; // TODO
#addToSceneButtonRef = createRef<ButtonElement>();
@@ -63,34 +68,15 @@ export class AppElement extends LitElement {
@on("scene-saved")
async onSceneSaved({ detail: scene }: SceneSavedEvent): Promise<void> {
const file = new File([scene], "scene.scn.ron", { type: "text/ron" });
const formData = new FormData();
formData.append("uuid_idempotency_token", uuid());
formData.append("file", file);
try {
const response = await fetch("https://api.fakeyou.com/v1/engine/create_scene", {
method: "POST",
credentials: "include",
headers: { "Accept": "text/plain" },
body: formData,
});
const file = new File([scene], "scene.scn.ron", { type: "text/ron" });
const token = await this.api.createScene(file);
if (response.ok) {
const resultJson: {
success: boolean;
media_file_token: string;
} = await response.json();
if (resultJson.success) {
this.dispatchEvent(new CustomEvent("scene-uploaded", {
detail: resultJson.media_file_token,
bubbles: true,
composed: true,
}));
}
}
this.dispatchEvent(new CustomEvent("scene-uploaded", {
detail: token,
bubbles: true,
composed: true,
}));
}
catch (err) {
console.error(err);
+1
View File
@@ -6,6 +6,7 @@ export * from "./lib/inspector/inspector.types";
export * from "./lib/loading.element";
export * from "./lib/scene-data-provider.element";
export * from "./lib/scene-hierarchy.element";
export * from "./lib/storyteller-api";
export * from "./lib/studio.element";
export * from "./lib/transform-toolbar.element";
export * from "./lib/url-params";
+29
View File
@@ -0,0 +1,29 @@
import axios from "axios";
export type MediaToken = string;
export class StorytellerApi {
#api = axios.create({
baseURL: "https://api.fakeyou.com",
withCredentials: true,
});
async createScene(file: File): Promise<MediaToken> {
type Response = {
success: boolean;
media_file_token: MediaToken;
}
const response = await this.#api.postForm<Response>("v1/engine/create_scene", {
uuid_idempotency_token: crypto.randomUUID(),
file,
}, {
headers: { Accept: "text/plain" },
});
if (response.status === 200 && response.data.success)
return response.data.media_file_token;
throw new Error(`API responded with status ${response.status}: "${response.statusText}"`);
}
}