Compare commits

...
Author SHA1 Message Date
ArEnSc 14e954f6a3 Merge branch 'main' into feature/apis 2025-04-17 22:49:19 -04:00
Michael Chung ee2b5fb8b0 Added the apis to the api folder it loads correctly now 2025-04-17 22:47:29 -04:00
bflatastic ad5ea26a81 commented out test component it was pushing the ui down 2025-04-18 08:59:53 +07:00
bflatastic 6121d118f0 reduced topbar right side gap 2025-04-18 08:54:40 +07:00
bflatastic 28ca7be96c activity update 2025-04-18 08:50:55 +07:00
Brandon Thomas a2a7f7d274 could also be a bearer token issue 2025-04-17 21:39:45 -04:00
Brandon Thomas e1255a55a0 specific error message for cookie expiration 2025-04-17 21:30:16 -04:00
9f629ee5e2 Nx working test (#524)
It works now.

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Tanish Manku <tanish2k09.dev@gmail.com>
Co-authored-by: Michael Chung <michaelchung@michaels-mbp-2.home>
2025-04-17 16:32:30 -04:00
BFlat 6a82fcb6e0 Revert "shared component starting with toaster" (#522)
Reverts storytold/storyteller-rust#521

it was causing an application error on build.
2025-04-17 17:21:05 +07:00
BFlat 35eac53b9d shared component starting with toaster (#521)
- share the toaster component between both editor2d and editor 3d
2025-04-17 17:14:02 +07:00
82 changed files with 1035 additions and 471 deletions
@@ -2,4 +2,5 @@ pub mod credentials;
pub mod image_gen;
pub mod job;
pub mod upload;
pub mod sentinel_refresh;
pub mod sentinel_refresh;
mod sora_error;
@@ -0,0 +1,48 @@
use std::error::Error;
use std::fmt::{Display, Formatter};
#[derive(Debug)]
pub enum SoraError {
/// Unauthorized, cookie and/or bearer token expired. We'll need to ask for a refreshed login.
///
/// Example message, e.g. from the upload endpoint:
/// {
/// "error": {
/// "message": "Your authentication token has expired. Please try signing in again.",
/// "type": "invalid_request_error",
/// "param": null,
/// "code": "token_expired"
/// }
/// }
UnauthorizedCookieOrBearerExpired,
/// Another error occurred.
OtherBadStatus(anyhow::Error),
/// Reqwest Error
ReqwestError(reqwest::Error),
}
impl Error for SoraError {}
impl Display for SoraError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
SoraError::UnauthorizedCookieOrBearerExpired => {
write!(f, "Unauthorized: cookie and/or bearer token expired")
}
SoraError::OtherBadStatus(err) => {
write!(f, "Other error: {}", err)
}
SoraError::ReqwestError(err) => {
write!(f, "Reqwest error: {}", err)
}
}
}
}
impl From<reqwest::Error> for SoraError {
fn from(err: reqwest::Error) -> SoraError {
SoraError::ReqwestError(err)
}
}
@@ -3,6 +3,7 @@ use errors::AnyhowResult;
use reqwest::multipart::{Form, Part};
use reqwest::Client;
use serde::Deserialize;
use crate::sora_error::SoraError;
const SORA_UPLOAD_MEDIA_URL: &str = "https://sora.com/backend/uploads";
@@ -25,6 +26,17 @@ Response:
"size_bytes": 118501,
"thumbnail_url": "https://videos.openai.com/vg-assets/assets%2Fclient_upload%2Fmedia%2Fuser-9wf6JFdgRSJLjvSJ53LNAbV8%2Fmedia_01jqt9vt20erx9zvryf3v1pecx.jpg?st=2025-04-02T02%3A39%3A01Z&se=2025-04-08T03%3A39%3A01Z&sks=b&skt=2025-04-02T02%3A39%3A01Z&ske=2025-04-08T03%3A39%3A01Z&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skoid=3d249c53-07fa-4ba4-9b65-0bf8eb4ea46a&skv=2019-02-02&sv=2018-11-09&sr=b&sp=r&spr=https%2Chttp&sig=9aU9xKI0BkhRtrTb0RD05%2BT6prBnmXk1I7nV2nTsFbY%3D&az=oaivgprodscus"
}
Error response:
Failed to upload scene media to Sora: Upload failed with status 401 Unauthorized: {
"error": {
"message": "Your authentication token has expired. Please try signing in again.",
"type": "invalid_request_error",
"param": null,
"code": "token_expired"
}
}
*/
#[derive(Debug, Deserialize)]
@@ -50,7 +62,13 @@ pub (crate) struct SoraMediaUploadRequest<'a> {
pub credentials: &'a SoraCredentials,
}
pub (crate) async fn upload_media_http_request(file_bytes: Vec<u8>, filename: String, mime_type: &str, credentials: &SoraCredentials) -> AnyhowResult<SoraMediaUploadResponse> {
pub (crate) async fn upload_media_http_request(
file_bytes: Vec<u8>,
filename: String,
mime_type: &str,
credentials: &SoraCredentials,
) -> Result<SoraMediaUploadResponse, SoraError> {
// Create multipart form
let part = Part::bytes(file_bytes) // NB: Reqwest needs to own the bytes.
.file_name(filename) // NB: Reqwest needs to own the bytes
@@ -70,12 +88,29 @@ pub (crate) async fn upload_media_http_request(file_bytes: Vec<u8>, filename: St
// Check response status
if !response.status().is_success() {
let status = response.status();
let text = response.text().await?;
return Err(anyhow::anyhow!("Upload failed with status {}: {}", status, text));
let error = classify_error(response).await;
return Err(error);
}
// Parse response
let upload_response = response.json::<SoraMediaUploadResponse>().await?;
Ok(upload_response)
}
async fn classify_error(response: reqwest::Response) -> SoraError {
let status = response.status();
let message = match response.text().await {
Ok(text) => text,
Err(err) => return SoraError::ReqwestError(err),
};
let cookie_expired =
message.contains("Your authentication token has expired. Please try signing in again.")
|| message.contains("token_expired");
if cookie_expired {
SoraError::UnauthorizedCookieOrBearerExpired
} else {
SoraError::OtherBadStatus(anyhow::anyhow!("Upload failed with status {}: {}", status, message))
}
}
+17
View File
@@ -27,4 +27,21 @@ Run dev server:
nx dev editor3d
```
```
call when starting on main or a new branch:
./clean_modules
The names for @frontend and @storyteller come from the package.json file in the libs folder.
import { Login } from "@frontend/login";
import { api } from "@storyteller/api";
building:
npx nx build editor3d
npx nx build editor2d
dev:
npx nx dev editor3d
npx nx dev editor2d
```
+8 -1
View File
@@ -4,7 +4,14 @@
"version": "0.0.0",
"type": "module",
"nx": {
"name": "editor2d"
"name": "editor2d",
"targets": {
"build": {
"dependsOn": [
"^build"
]
}
}
},
"scripts": {
"dev": "echo 'editor2d' && vite",
@@ -30,7 +30,7 @@ export const TopBar = ({ pageName }: Props) => {
<header className="fixed left-0 top-0 z-[60] w-full border-b border-white/5 bg-ui-background">
<nav
className="mx-auto grid h-[56px] w-screen grid-cols-3 items-center justify-between px-3"
aria-label="Global"
aria-label="navigation"
>
<div className="flex gap-4">
<a href="/">
@@ -52,7 +52,7 @@ export const TopBar = ({ pageName }: Props) => {
<SceneTitleInput pageName={pageName} />
</div>
<div className="flex justify-end gap-5">
<div className="flex justify-end gap-3.5">
<div className="flex gap-2">
<Button
variant="secondary"
@@ -27,9 +27,14 @@ import { PromptBox } from "./comps/PromptBox";
import { OnboardingHelper } from "./comps/OnboardingHelper";
import { FocalLengthDisplay } from "./comps/FocalLengthDisplay/FocalLengthDisplay";
import { Login } from "@frontend/login";
// import { api } from "@storyteller/api";
// import { AnalyticsApi } from "@storyteller/api";
export const PageEditor = () => {
useSignals();
//console.log(api());
//To prevent the click event from propagating to the canvas: TODO: HANDLE THIS BETTER?
const handleOverlayClick = (event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
@@ -83,6 +88,7 @@ export const PageEditor = () => {
return (
<div className="w-screen">
<TopBar pageName="Edit Scene" />
{/* <Login /> */}
<OnboardingHelper />
<div
className="relative flex w-screen"
@@ -4,8 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PopoverMenu } from "~/components/reusable/Popover/Popover";
import { CompletedCard } from "./CompletedCard";
import { InProgressCard } from "./InProgressCard";
import { H3, P, Tooltip } from "~/components";
import { activeImageGenerationJobs, toasts, userMovies } from "~/signals";
import { Tooltip } from "~/components";
import { useEffect, useState } from "react";
import { JobsApi } from "~/Classes/ApiManager/JobsApi";
import { toast } from "sonner";
@@ -146,6 +145,7 @@ export function Activity() {
} catch (error) {
toast.error("Error Fetching Recent Jobs");
console.error("Failed to fetch recent jobs:", error);
setLoading(false);
}
};
await fetchJobs();
@@ -173,13 +173,13 @@ export function Activity() {
align="end"
triggerIcon={
<div>
{jobs && jobs.length > 0 ? (
{jobs.length > 0 ? (
<FontAwesomeIcon icon={faSpinnerThird} className="animate-spin" />
) : (
<FontAwesomeIcon icon={faBell} />
)}
{jobs && jobs.length > 0 && (
<div className="bg-blue-500 absolute -right-1 -top-1 h-3 w-3 animate-pulse rounded-full" />
{jobs.length > 0 && (
<div className="absolute -right-1 -top-1 h-3 w-3 animate-pulse rounded-full bg-brand-primary-400" />
)}
</div>
}
@@ -194,24 +194,19 @@ export function Activity() {
</div>
)}
{!userMovies.value && !activeImageGenerationJobs.value ? (
<div className="flex h-48 w-full flex-col justify-center gap-4 p-4 text-center align-middle">
<FontAwesomeIcon
icon={faSpinnerThird}
spin
size="2x"
className="text-gray-400"
/>
<H3 className="text-gray-300">Retrieving Activities</H3>
{loading ? (
<div className="flex h-48 w-full items-center justify-center gap-3 p-4 text-center align-middle">
<FontAwesomeIcon icon={faSpinnerThird} className="animate-spin" />
<h3 className="text-lg font-medium text-gray-300">
Loading activities...
</h3>
</div>
) : userMovies.value &&
userMovies.value.length === 0 &&
!activeImageGenerationJobs.value ? (
<div className="flex h-48 w-full flex-col justify-center gap-4 p-4 text-center align-middle">
<H3 className="text-gray-300">No activities yet</H3>
<P className="text-gray-400">
Try generating something new from the featured scenes
</P>
) : jobs.length === 0 && completedItems.length === 0 ? (
<div className="flex h-48 w-full items-center justify-center gap-3 p-4 text-center align-middle">
<FontAwesomeIcon icon={faBell} />
<h3 className="text-lg font-medium text-gray-300">
No activities yet
</h3>
</div>
) : (
<div>
+8 -2
View File
@@ -4,7 +4,14 @@
"sideEffects": false,
"type": "module",
"nx": {
"name": "editor3d"
"name": "editor3d",
"targets": {
"build": {
"dependsOn": [
"^build"
]
}
}
},
"scripts": {
"build": "remix vite:build",
@@ -21,7 +28,6 @@
"test": "jest"
},
"dependencies": {
"@storyteller/api": "file:../../libs/api",
"@awesome.me/kit-fde2be5eb0": "^1.0.7",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
@@ -2,8 +2,11 @@
set -euxo pipefail
echo "Install packages"
npm install
echo "Build Editor 3D"
nx build editor3d
nx build editor3d --verbose
echo "Change to project dir"
pushd apps/editor3d/
+14 -17
View File
@@ -1,34 +1,31 @@
{
"include": [
"env.d.ts",
"**/*.ts",
"**/*.tsx",
"netlify-edge-plugin.ts"
],
"extends": "../../tsconfig.base.json",
"include": ["env.d.ts", "**/*.ts", "**/*.tsx", "netlify-edge-plugin.ts"],
"compilerOptions": {
"lib": [
"DOM",
"DOM.Iterable",
"ESNext"
],
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "node",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"target": "ESNext",
"strict": true,
"allowJs": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"~/*": [
"./app/*"
]
"~/*": ["apps/editor3d/app/*"]
},
// Vite takes care of building everything, not tsc.
"noEmit": true
}
},
"references": [
{
"path": "../../libs/api"
},
{
"path": "../../libs/login"
}
]
}
+9
View File
@@ -14,6 +14,15 @@ export default defineConfig({
// 'kalidokit': `${path.resolve(__dirname, 'src')}/`,
// },
//},
//resolve: {
// alias: [
// {
// find: /@frontend\/login/,
// //replacement: path.resolve(__dirname, 'node_modules', '@frontend', 'login'),
// replacement: path.resolve(__dirname, '../', '../', 'libs', 'login'),
// },
// ],
//},
//rollupOptions: {
// // make sure to externalize deps that shouldn't be bundled
// // into your library
+1
View File
@@ -3,6 +3,7 @@
set -euxo pipefail
echo "Removing Node Modules..."
npx nx reset
rm -rf ./node_modules/
rm -rf ./apps/editor2d/node_modules/
rm -rf ./apps/editor3d/node_modules/
+16
View File
@@ -1 +1,17 @@
export * from './lib/api.js';
export * from "./lib/AnalyticsApi.js";
export * from "./lib/BillingApi.js";
export * from "./lib/CommentsApi.js";
export * from "./lib/EngineApi.js";
export * from "./lib/FeaturedItemsApi.js";
export * from "./lib/JobsApi.js";
export * from "./lib/MediaFilesApi.js";
export * from "./lib/MediaUploadApi.js";
export * from "./lib/MiscApi.js";
export * from "./lib/ModerationApi.js";
export * from "./lib/PromptsApi.js";
export * from "./lib/TtsApi.js";
export * from "./lib/UserBookmarksApi.js";
export * from "./lib/UsersApi.js";
export * from "./lib/VideoApi.js";
export * from "./lib/WeightsApi.js";
@@ -1,4 +1,4 @@
import { ApiManager, ApiResponse } from "./ApiManager";
import { ApiManager, ApiResponse } from "./ApiManager.js";
export class AnalyticsApi extends ApiManager {
public PostAnalytics({
@@ -1,5 +1,5 @@
// import { bool } from "@techstark/opencv-js";
import { API_TARGETS } from "../enums/Api";
import { API_TARGETS } from "./enums/Api.js";
type NonNullableObject<T extends object> = NonNullable<T>;
@@ -1,6 +1,6 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { Subscription } from "../models/Billing";
import { LoyaltyProgram } from "../enums/Billing";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { Subscription } from "./models/Billing.js";
import { LoyaltyProgram } from "./enums/Billing.js";
export class BillingApi extends ApiManager {
public async ListActiveSubscriptions(): Promise<
@@ -1,7 +1,7 @@
// libs/api-client/src/JobsApi.ts
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { Job, JobPreview } from "../models/Job";
import { JobState } from "../models/JobState";
import { ApiManager, ApiResponse } from "../../../api/src/lib/ApiManager.js";
import { Job, JobPreview } from "./models/Job.js";
import { JobState } from "./models/JobState.js";
export class JobsApi extends ApiManager {
public GetPreviewStatusByJobToken({
+364
View File
@@ -0,0 +1,364 @@
import { MediaFile } from "./models/MediaFile.js";
import { Pagination, PaginationInfinite } from "./models/Pagination.js";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { Visibility } from "./enums/Visibility.js";
import {
FilterEngineCategories,
FilterMediaClasses,
FilterMediaType,
} from "./enums/QueryFilters.js";
interface ListMediaQuery {
sort_ascending?: boolean;
page_size?: number;
cursor?: string;
cursor_is_reversed?: boolean;
filter_media_classes?: FilterMediaClasses[];
filter_media_type?: FilterMediaType[];
filter_engine_categories?: FilterEngineCategories[];
}
interface ListUserMediaQuery {
username: string;
sort_ascending?: boolean;
page_size?: number;
page_index?: number;
filter_media_classes?: FilterMediaClasses[];
filter_media_type?: FilterMediaType[];
filter_engine_categories?: FilterEngineCategories[];
}
interface SearchFeaturedMediaQuery {
search_term: string;
filter_media_classes?: FilterMediaClasses[];
filter_media_type?: FilterMediaType[];
filter_engine_categories?: FilterEngineCategories[];
}
export class MediaFilesApi extends ApiManager {
public async DeleteMediaFileByToken({
mediaFileToken,
asMod = true,
setDelete = true,
}: {
mediaFileToken: string;
asMod?: boolean;
setDelete?: boolean;
}): Promise<ApiResponse<MediaFile>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/file/${mediaFileToken}`;
const body = { as_mod: asMod, set_delete: setDelete };
return await this.delete<
{
as_mod: boolean;
set_delete: boolean;
},
{
success?: boolean;
BadInput?: string;
}
>({ endpoint, body })
.then((response) => ({
success: response.success ?? false,
errorMessage: response.BadInput,
}))
.catch((err) => {
return {
success: false,
errorMessage: err.message,
};
});
}
public async ListMediaFilesByTokens({
mediaTokens,
}: {
mediaTokens: string[];
}): Promise<ApiResponse<MediaFile[]>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/batch`;
return await this.get<{
success: boolean;
media_files: MediaFile[];
error_reason?: string;
}>({ endpoint, query: { tokens: mediaTokens.join(",") } })
.then((response) => ({
success: response.success,
data: response.media_files,
}))
.catch((err) => {
return { success: false, errorMessage: err.message };
});
}
public async GetMediaFileByToken({
mediaFileToken,
}: {
mediaFileToken: string;
}): Promise<ApiResponse<MediaFile>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/file/${mediaFileToken}`;
return await this.get<{
success: boolean;
media_file: MediaFile;
}>({ endpoint })
.then((response) => ({
success: response.success,
data: response.media_file,
}))
.catch((err) => {
return {
success: false,
errorMessage: err.message,
};
});
}
public async ListMediaFiles(
query: ListMediaQuery,
): Promise<ApiResponse<MediaFile[], PaginationInfinite>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/list`;
const queryWithStrings = {
...query,
filter_media_classes: query.filter_media_classes
? query.filter_media_classes.join(",")
: undefined,
filter_media_type: query.filter_media_type
? query.filter_media_type.join(",")
: undefined,
filter_engine_categories: query.filter_engine_categories
? query.filter_engine_categories.join(",")
: undefined,
};
return await this.get<{
success: boolean;
results: MediaFile[];
pagination?: PaginationInfinite;
}>({ endpoint, query: queryWithStrings })
.then((response) => ({
success: response.success,
data: response.results ?? [],
pagination: response.pagination,
}))
.catch((err) => {
return {
success: false,
errorMessage: err.message,
};
});
}
public async ListFeaturedMediaFiles(
query: ListMediaQuery,
): Promise<ApiResponse<MediaFile[], PaginationInfinite>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/list_featured`;
const queryWithStrings = {
...query,
filter_media_classes: query.filter_media_classes
? query.filter_media_classes.join(",")
: undefined,
filter_media_type: query.filter_media_type
? query.filter_media_type.join(",")
: undefined,
filter_engine_categories: query.filter_engine_categories
? query.filter_engine_categories.join(",")
: undefined,
};
return await this.get<{
success: boolean;
results: MediaFile[];
pagination: PaginationInfinite;
}>({ endpoint, query: queryWithStrings })
.then((response) => ({
success: true,
data: response.results,
pagination: response.pagination,
}))
.catch((err) => {
return {
success: false,
errorMessage: err.message,
};
});
}
public async ListUserMediaFiles(
query: ListUserMediaQuery,
): Promise<ApiResponse<MediaFile[], Pagination>> {
const userName = query.username;
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/list/user/${userName}`;
const queryWithStrings = {
...query,
include_user_uploads: true,
filter_media_classes: query.filter_media_classes
? query.filter_media_classes.join(",")
: undefined,
filter_media_type: query.filter_media_type
? query.filter_media_type.join(",")
: undefined,
filter_engine_categories: query.filter_engine_categories
? query.filter_engine_categories.join(",")
: undefined,
};
return await this.get<{
success: boolean;
results: MediaFile[];
pagination?: Pagination;
}>({ endpoint, query: queryWithStrings })
.then((response) => ({
success: response.success,
data: response.results ?? [],
pagination: response.pagination,
}))
.catch((err) => {
return {
success: false,
errorMessage: err.message,
};
});
}
public async SearchFeaturedMediaFiles(
query: SearchFeaturedMediaQuery,
): Promise<ApiResponse<MediaFile[], Pagination>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/search_featured`;
const queryWithStrings = {
search_term: query.search_term,
filter_media_classes: query.filter_media_classes
? query.filter_media_classes.join(",")
: undefined,
filter_media_type: query.filter_media_type
? query.filter_media_type.join(",")
: undefined,
filter_engine_categories: query.filter_engine_categories
? query.filter_engine_categories.join(",")
: undefined,
};
return await this.get<{
success: boolean;
results: MediaFile[];
pagination: Pagination;
}>({ endpoint, query: queryWithStrings })
.then((response) => ({
success: true,
data: response.results,
pagination: response.pagination,
}))
.catch((err) => ({
success: false,
errorMessage: err.message,
}));
}
public async SearchUserMediaFiles(
query: SearchFeaturedMediaQuery,
): Promise<ApiResponse<MediaFile[], Pagination>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/search_session`;
const queryWithStrings = {
search_term: query.search_term,
filter_media_classes: query.filter_media_classes
? query.filter_media_classes.join(",")
: undefined,
filter_media_type: query.filter_media_type
? query.filter_media_type.join(",")
: undefined,
filter_engine_categories: query.filter_engine_categories
? query.filter_engine_categories.join(",")
: undefined,
};
return await this.get<{
success: boolean;
results: MediaFile[];
pagination: Pagination;
}>({ endpoint, query: queryWithStrings })
.then((response) => ({
success: true,
data: response.results,
pagination: response.pagination,
}))
.catch((err) => ({
success: false,
errorMessage: err.message,
}));
}
public async RenameMediaFileByToken({
mediaToken,
name,
}: {
mediaToken: string;
name: string;
}): Promise<ApiResponse<undefined>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/rename/${mediaToken}`;
const body = { name };
return await this.post<
{ name: string },
{
success?: boolean;
BadInput?: string;
}
>({ endpoint, body })
.then((response) => ({
success: response.success ?? false,
errorMessage: response.BadInput,
}))
.catch((err) => {
return { success: false, errorMessage: err.message };
});
}
public async UpdateCoverImage({
mediaFileToken,
imageToken,
}: {
mediaFileToken: string;
imageToken: string;
}): Promise<ApiResponse<undefined>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/cover_image/${mediaFileToken}`;
return await this.post<
{ cover_image_media_file_token: string },
{
success?: boolean;
BadInput?: string;
}
>({ endpoint, body: { cover_image_media_file_token: imageToken } })
.then((response) => ({
success: response.success ?? false,
errorMessage: response.BadInput,
}))
.catch((err) => {
return {
success: false,
errorMessage: err.message,
};
});
}
public async UpdateVisibility({
mediaFileToken,
visibility,
}: {
mediaFileToken: string;
visibility: Visibility;
}): Promise<ApiResponse<undefined>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/media_files/visibility/${mediaFileToken}`;
return await this.post<
{ creator_set_visibility: string },
{
success?: boolean;
BadInput?: string;
}
>({ endpoint, body: { creator_set_visibility: visibility } })
.then((response) => ({
success: response.success ?? false,
errorMessage: response.BadInput,
}))
.catch((err) => {
return {
success: false,
errorMessage: err.message,
};
});
}
}
@@ -1,9 +1,9 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { FilterEngineCategories } from "../enums/QueryFilters";
import { Visibility } from "../enums/Visibility";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { FilterEngineCategories } from "./enums/QueryFilters.js";
import { Visibility } from "./enums/Visibility.js";
import { EIntermediateFile } from "./enums/EIntermediateFile.js";
export class MediaUploadApi extends ApiManager {
private sessionToken: string = "";
private sessionToken = "";
private async getSessionTokenForUploadStudioShot() {
const endpoint = `${this.ApiTargets.BaseApi}/v1/session_token`;
@@ -336,11 +336,6 @@ export class MediaUploadApi extends ApiManager {
const fileName = `${maybe_title}-${uuid}`;
return this.Upload({ endpoint, blob, fileName, uuid, options }); // token comes back and send it VST
}
}
@@ -1,5 +1,5 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { StatusAlert } from "../models/StatusAlert";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { StatusAlert } from "./models/StatusAlert.js";
export class MiscApi extends ApiManager {
public GetStatusAlertCheck(): Promise<ApiResponse<StatusAlert>> {
@@ -1,5 +1,5 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { Prompts } from "../models/Prompts";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { Prompts } from "./models/Prompts.js";
export class PromptsApi extends ApiManager {
public GetPromptsByToken({
@@ -1,4 +1,4 @@
import { ApiManager } from "../apis/ApiManager";
import { ApiManager } from "./ApiManager.js";
import { v4 as uuidv4 } from "uuid";
export interface Coordinates {
@@ -1,6 +1,6 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { GenerateTtsAudioErrorType } from "../enums/Tts";
import { Visibility } from "../enums/Visibility";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { GenerateTtsAudioErrorType } from "./enums/Tts.js";
import { Visibility } from "./enums/Visibility.js";
export interface GenerateTtsAudioRequest {
creator_set_visibility?: Visibility;
@@ -1,10 +1,10 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import {
UserBookmarkBatch,
UserBookmarkByEntity,
UserBookmarkByUser,
} from "../models/UserBookmark";
import { Pagination } from "../models/Pagination";
} from "./models/UserBookmark.js";
import { Pagination } from "./models/Pagination.js";
export enum ScopedEntityTypes {
USER = "user",
@@ -1,4 +1,4 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { ApiManager, ApiResponse } from "./ApiManager.js";
export interface UserRating {
entity_token: string;
@@ -1,5 +1,5 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { UserInfo } from "../models/Users";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { UserInfo } from "./models/Users.js";
export class UsersApi extends ApiManager {
public GetSession(): Promise<
@@ -1,5 +1,5 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { Visibility } from "../enums/Visibility";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { Visibility } from "./enums/Visibility.js";
interface GenerateVideoStyleTransferRequest {
creator_set_visibility: string;
@@ -1,4 +1,4 @@
import { ApiManager, ApiResponse } from "./ApiManager";
import { ApiManager, ApiResponse } from "./ApiManager.js";
interface VoiceConversionParams {
autoPredictF0?: boolean;
@@ -1,6 +1,6 @@
import { ApiManager, ApiResponse } from "./ApiManager";
import { Pagination } from "../models/Pagination";
import { ZsDataset } from "../models/Dataset";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { Pagination } from "./models/Pagination.js";
import { ZsDataset } from "./models/Dataset.js";
interface VoiceDesignerParams {
text: string;
@@ -1,12 +1,12 @@
import { ApiManager, ApiResponse } from "./ApiManager";
import { Weight } from "../models/Weight";
import { Pagination, PaginationInfinite } from "../models/Pagination";
import { ApiManager, ApiResponse } from "./ApiManager.js";
import { Weight } from "./models/Weight.js";
import { Pagination, PaginationInfinite } from "./models/Pagination.js";
import {
FilterEngineCategories,
FilterMediaClasses,
FilterMediaType,
} from "../enums/QueryFilters";
import { Visibility } from "../enums/Visibility";
} from "./enums/QueryFilters.js";
import { Visibility } from "./enums/Visibility.js";
export enum ScopedWeightType {
HIFIGAN_TT2 = "hifigan_tt2",
@@ -0,0 +1,4 @@
export enum EIntermediateFile {
"true",
"false"
}
@@ -2,7 +2,7 @@ import {
LoyaltyProgram,
SubscriptionNamespace,
SubscriptionProduct,
} from "../enums/Billing";
} from "../enums/Billing.js";
export interface ActiveSubscriptions {
// user's list of subscriptions
@@ -1,4 +1,4 @@
import { JobStatus } from "../enums/Job";
import { JobStatus } from "../enums/Job.js";
export interface Job {
created_at: string;
@@ -1,4 +1,4 @@
import { USER_FEATURE_FLAGS } from "../enums/UserFeatures";
import { USER_FEATURE_FLAGS } from "../../libs/api/src/lib/enums/UserFeatures";
export interface CoreInfo {
default_avatar: {
+12
View File
@@ -0,0 +1,12 @@
{
"presets": [
[
"@nx/react/babel",
{
"runtime": "automatic",
"useBuiltIns": "usage"
}
]
],
"plugins": []
}
+36
View File
@@ -0,0 +1,36 @@
{
"extends": [
"plugin:@nx/react",
"../../.eslintrc.json"
],
"ignorePatterns": [
"!**/*",
"**/vite.config.*.timestamp*",
"**/vitest.config.*.timestamp*"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {}
},
{
"files": [
"*.ts",
"*.tsx"
],
"rules": {}
},
{
"files": [
"*.js",
"*.jsx"
],
"rules": {}
}
]
}
+7
View File
@@ -0,0 +1,7 @@
# @frontend/login
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test @frontend/login` to execute the unit tests via [Vitest](https://vitest.dev/).
+17
View File
@@ -0,0 +1,17 @@
{
"name": "@frontend/login",
"version": "0.0.1",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"development": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
}
}
}
+2
View File
@@ -0,0 +1,2 @@
export * from './lib/login';
@@ -0,0 +1,7 @@
/*
* Replace this with your own classes
*
* e.g.
* .container {
* }
*/
@@ -0,0 +1,12 @@
import { render } from '@testing-library/react';
import Login from './login';
describe('Login', () => {
it('should render successfully', () => {
const { baseElement } = render(<Login />);
expect(baseElement).toBeTruthy();
});
});
+15
View File
@@ -0,0 +1,15 @@
import styles from './login.module.css';
export function Login() {
return (
<div className={styles['container']}>
<h1>Welcome to Login!</h1>
</div>
);
}
export default Login;
+1
View File
@@ -0,0 +1 @@
// This file should be used to export ONLY server-code from the library.
+3
View File
@@ -0,0 +1,3 @@
import { installGlobals } from '@remix-run/node';
import "@testing-library/jest-dom/matchers";
installGlobals();
+13
View File
@@ -0,0 +1,13 @@
{
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../../tsconfig.base.json"
}
+48
View File
@@ -0,0 +1,48 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"types": [
"node",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts",
"vite/client"
],
"rootDir": "src",
"jsx": "react-jsx",
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo"
},
"exclude": [
"out-tsc",
"dist",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"vite.config.ts",
"vite.config.mts",
"vitest.config.ts",
"vitest.config.mts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.test.tsx",
"src/**/*.spec.tsx",
"src/**/*.test.js",
"src/**/*.spec.js",
"src/**/*.test.jsx",
"src/**/*.spec.jsx",
"eslint.config.js",
"eslint.config.cjs",
"eslint.config.mjs"
],
"include": [
"src/**/*.js",
"src/**/*.jsx",
"src/**/*.ts",
"src/**/*.tsx"
]
}
+34
View File
@@ -0,0 +1,34 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./out-tsc/vitest",
"types": [
"vitest/globals",
"vitest/importMeta",
"vite/client",
"node",
"vitest"
],
"jsx": "react-jsx"
},
"include": [
"vite.config.ts",
"vite.config.mts",
"vitest.config.ts",
"vitest.config.mts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.test.tsx",
"src/**/*.spec.tsx",
"src/**/*.test.js",
"src/**/*.spec.js",
"src/**/*.test.jsx",
"src/**/*.spec.jsx",
"src/**/*.d.ts"
],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}
+49
View File
@@ -0,0 +1,49 @@
/// <reference types='vitest' />
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import dts from 'vite-plugin-dts';
import * as path from 'path';
export default defineConfig(() => ({
root: __dirname,
cacheDir: '../../node_modules/.vite/libs/login',
plugins: [react(), dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') })],
// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
build: {
outDir: './dist',
emptyOutDir: true,
reportCompressedSize: true,
commonjsOptions: {
transformMixedEsModules: true,
},
lib: {
// Could also be a dictionary or array of multiple entry points.
entry: 'src/index.ts',
name: '@frontend/login',
fileName: 'index',
// Change this to the formats you want to support.
// Don't forget to update your package.json as well.
formats: ['es' as const]
},
rollupOptions: {
// External packages that should not be bundled into your library.
external: ['react','react-dom','react/jsx-runtime']
},
},
test: {setupFiles: ['./src/test-setup.ts'],
watch: false,
globals: true,
environment: 'jsdom',
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
reporters: ['default'],
coverage: {
reportsDirectory: './test-output/vitest/coverage',
provider: 'v8' as const,
}
},
}));
+2 -1
View File
@@ -89,7 +89,8 @@
},
"library": {
"style": "css",
"linter": "none"
"linter": "none",
"unitTestRunner": "vitest"
}
}
},
+156 -56
View File
@@ -16,10 +16,12 @@
"@preact/signals-react": "^3.0.1",
"@remix-run/serve": "^2.15.0",
"pnpm": "^10.8.1",
"react": "18.2.0",
"react-dom": "18.2.0"
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@netlify/remix-edge-adapter": "^3.4.3",
"@nx/eslint": "20.7.2",
"@nx/eslint-plugin": "20.7.2",
@@ -34,6 +36,9 @@
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/jest-dom": "6.4.2",
"@testing-library/react": "16.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/node": "^20.0.0",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
@@ -44,6 +49,10 @@
"@vitest/ui": "^3.0.0",
"eslint": "~8.57.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
"eslint-plugin-react": "7.35.0",
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"jsonc-eslint-parser": "^2.1.0",
@@ -1059,31 +1068,6 @@
}
}
},
"apps/editor2d/node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"apps/editor2d/node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.3.1"
}
},
"apps/editor2d/node_modules/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
@@ -1195,7 +1179,6 @@
"@remix-run/react": "^2.8.1",
"@remix-run/router": "^1.15.3",
"@remix-run/serve": "^2.8.1",
"@storyteller/api": "file:../../libs/api",
"@tweenjs/tween.js": "^18.6.4",
"@types/lodash": "^4.17.6",
"@types/react-virtualized": "^9.22.2",
@@ -1826,6 +1809,19 @@
"eslint": ">=7.0.0"
}
},
"apps/editor3d/node_modules/eslint-plugin-react-hooks": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz",
"integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
}
},
"apps/editor3d/node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
@@ -2019,6 +2015,10 @@
"name": "@storyteller/api",
"version": "0.0.1"
},
"libs/login": {
"name": "@frontend/login",
"version": "0.0.1"
},
"node_modules/@adobe/css-tools": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz",
@@ -4714,6 +4714,10 @@
"react": ">=16.3"
}
},
"node_modules/@frontend/login": {
"resolved": "libs/login",
"link": true
},
"node_modules/@headlessui/react": {
"version": "1.7.19",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz",
@@ -9811,6 +9815,27 @@
"storybook": "^8.6.12"
}
},
"node_modules/@storybook/test/node_modules/@testing-library/jest-dom": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz",
"integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@adobe/css-tools": "^4.4.0",
"aria-query": "^5.0.0",
"chalk": "^3.0.0",
"css.escape": "^1.5.1",
"dom-accessibility-api": "^0.6.3",
"lodash": "^4.17.21",
"redent": "^3.0.0"
},
"engines": {
"node": ">=14",
"npm": ">=6",
"yarn": ">=1"
}
},
"node_modules/@storybook/test/node_modules/@vitest/expect": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz",
@@ -9869,6 +9894,27 @@
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@storybook/test/node_modules/chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@storybook/test/node_modules/dom-accessibility-api": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
"integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
"dev": true,
"license": "MIT"
},
"node_modules/@storybook/test/node_modules/tinyrainbow": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz",
@@ -10782,24 +10828,49 @@
"license": "MIT"
},
"node_modules/@testing-library/jest-dom": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz",
"integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==",
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz",
"integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@adobe/css-tools": "^4.4.0",
"@adobe/css-tools": "^4.3.2",
"@babel/runtime": "^7.9.2",
"aria-query": "^5.0.0",
"chalk": "^3.0.0",
"css.escape": "^1.5.1",
"dom-accessibility-api": "^0.6.3",
"lodash": "^4.17.21",
"lodash": "^4.17.15",
"redent": "^3.0.0"
},
"engines": {
"node": ">=14",
"npm": ">=6",
"yarn": ">=1"
},
"peerDependencies": {
"@jest/globals": ">= 28",
"@types/bun": "latest",
"@types/jest": ">= 28",
"jest": ">= 28",
"vitest": ">= 0.32"
},
"peerDependenciesMeta": {
"@jest/globals": {
"optional": true
},
"@types/bun": {
"optional": true
},
"@types/jest": {
"optional": true
},
"jest": {
"optional": true
},
"vitest": {
"optional": true
}
}
},
"node_modules/@testing-library/jest-dom/node_modules/chalk": {
@@ -10823,6 +10894,34 @@
"dev": true,
"license": "MIT"
},
"node_modules/@testing-library/react": {
"version": "16.1.0",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.1.0.tgz",
"integrity": "sha512-Q2ToPvg0KsVL0ohND9A3zLJWcOXXcO8IDu3fj11KhNt0UlCWyFyvnCIBkd12tidB2lkiVRG8VFqdhcqhqnAQtg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.5"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@testing-library/dom": "^10.0.0",
"@types/react": "^18.0.0 || ^19.0.0",
"@types/react-dom": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@testing-library/user-event": {
"version": "14.5.2",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz",
@@ -16777,9 +16876,9 @@
}
},
"node_modules/eslint-plugin-jsx-a11y": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz",
"integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==",
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.1.tgz",
"integrity": "sha512-zHByM9WTUMnfsDTafGXRiqxp6lFtNoSOWBY6FonVRn3A+BUwN1L/tdBXT40BcBJi0cZjOGTXZ0eD/rTG9fEJ0g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -16791,6 +16890,7 @@
"axobject-query": "^4.1.0",
"damerau-levenshtein": "^1.0.8",
"emoji-regex": "^9.2.2",
"es-iterator-helpers": "^1.1.0",
"hasown": "^2.0.2",
"jsx-ast-utils": "^3.3.5",
"language-tags": "^1.0.9",
@@ -16848,29 +16948,29 @@
}
},
"node_modules/eslint-plugin-react": {
"version": "7.37.5",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
"integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
"version": "7.35.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz",
"integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==",
"dev": true,
"license": "MIT",
"dependencies": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
"array.prototype.flatmap": "^1.3.3",
"array.prototype.flatmap": "^1.3.2",
"array.prototype.tosorted": "^1.1.4",
"doctrine": "^2.1.0",
"es-iterator-helpers": "^1.2.1",
"es-iterator-helpers": "^1.0.19",
"estraverse": "^5.3.0",
"hasown": "^2.0.2",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
"object.entries": "^1.1.9",
"object.entries": "^1.1.8",
"object.fromentries": "^2.0.8",
"object.values": "^1.2.1",
"object.values": "^1.2.0",
"prop-types": "^15.8.1",
"resolve": "^2.0.0-next.5",
"semver": "^6.3.1",
"string.prototype.matchall": "^4.0.12",
"string.prototype.matchall": "^4.0.11",
"string.prototype.repeat": "^1.0.0"
},
"engines": {
@@ -16881,16 +16981,16 @@
}
},
"node_modules/eslint-plugin-react-hooks": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz",
"integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz",
"integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-react-refresh": {
@@ -26976,9 +27076,9 @@
}
},
"node_modules/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
@@ -27059,16 +27159,16 @@
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.0"
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.2.0"
"react": "^18.3.1"
}
},
"node_modules/react-drag-drop-files": {
+11 -2
View File
@@ -8,10 +8,12 @@
"@preact/signals-react": "^3.0.1",
"@remix-run/serve": "^2.15.0",
"pnpm": "^10.8.1",
"react": "18.2.0",
"react-dom": "18.2.0"
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@netlify/remix-edge-adapter": "^3.4.3",
"@nx/eslint": "20.7.2",
"@nx/eslint-plugin": "20.7.2",
@@ -26,6 +28,9 @@
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/jest-dom": "6.4.2",
"@testing-library/react": "16.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/node": "^20.0.0",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
@@ -36,6 +41,10 @@
"@vitest/ui": "^3.0.0",
"eslint": "~8.57.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
"eslint-plugin-react": "7.35.0",
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"jsonc-eslint-parser": "^2.1.0",
@@ -1,167 +0,0 @@
import { ApiManager, ApiResponse } from "../apis/ApiManager";
import { BetaKey } from "../models/BetaKeys";
import { Pagination } from "../models/Pagination";
export class BetaKeysApi extends ApiManager {
public CreateBetaKey({
maybeNote,
maybeReferrerUsername,
numberOfKeys,
uuidIdempotencyToken,
}: {
maybeNote?: string;
maybeReferrerUsername?: string;
numberOfKeys: number;
uuidIdempotencyToken: string;
}): Promise<ApiResponse<string[]>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/beta_keys/create`;
const body = {
maybe_note: maybeNote,
maybe_referrer_username: maybeReferrerUsername,
number_of_keys: numberOfKeys,
uuid_idempotency_token: uuidIdempotencyToken,
};
return this.post<
{
maybe_note?: string;
maybe_referrer_username?: string;
number_of_keys: number;
uuid_idempotency_token: string;
},
{
success?: boolean;
beta_keys?: string[];
BadInput?: string;
}
>({ endpoint, body })
.then((response) => ({
success: response.success ?? false,
data: response.beta_keys,
errorMessage: response.BadInput,
}))
.catch((err) => {
return { success: false, errorMessage: err.message };
});
}
public ListBetaKeys({
sortAscending,
pageSize,
pageIndex,
maybeReferrerUsername,
onlyListRemaining,
}: {
sortAscending?: boolean;
pageSize?: number;
pageIndex?: number;
maybeReferrerUsername?: string;
onlyListRemaining?: boolean;
}): Promise<ApiResponse<BetaKey[], Pagination>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/beta_keys/list`;
const query = {
sort_ascending: sortAscending,
page_size: pageSize,
page_index: pageIndex,
maybe_referrer_username: maybeReferrerUsername,
only_list_remaining: onlyListRemaining,
};
return this.get<{
success?: boolean;
beta_keys?: BetaKey[];
pagination?: Pagination;
BadInput?: string;
}>({ endpoint, query })
.then((response) => ({
success: response.success ?? false,
data: response.beta_keys,
pagination: response.pagination,
errorMessage: response.BadInput,
}))
.catch((err) => {
return { success: false, errorMessage: err.message };
});
}
public RedeemBetaKey({
betaKey,
}: {
betaKey: string;
}): Promise<ApiResponse<undefined>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/beta_keys/redeem`;
return this.post<
{
beta_key: string;
},
{
success?: boolean;
BadInput?: string;
}
>({ endpoint, body: { beta_key: betaKey } })
.then((response) => ({
success: response.success ?? false,
errorMessage: response.BadInput,
}))
.catch((err) => {
return { success: false, errorMessage: err.message };
});
}
public UpdateBetaKeyIsDistributed({
betaKey,
isDistributed,
}: {
betaKey: string;
isDistributed: boolean;
}): Promise<ApiResponse<undefined>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/beta_keys/${betaKey}/distributed`;
return this.post<
{
is_distributed: boolean;
},
{
success?: boolean;
BadInput?: string;
}
>({ endpoint, body: { is_distributed: isDistributed } })
.then((response) => ({
success: response.success ?? false,
errorMessage: response.BadInput,
}))
.catch((err) => {
return { success: false, errorMessage: err.message };
});
}
public UpdateBetaKeyNote({
token,
note,
}: {
token: string;
note?: string;
}): Promise<ApiResponse<undefined>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/beta_keys/${token}/note`;
return this.post<
{
note?: string;
},
{
success?: boolean;
BadInput?: string;
}
>({ endpoint, body: { note } })
.then((response) => ({
success: response.success ?? false,
errorMessage: response.BadInput,
}))
.catch((err) => {
return { success: false, errorMessage: err.message };
});
}
}
@@ -1,143 +0,0 @@
# Recursive Folder Comparison Report: Classes vs Classes
Generated on: 2025-04-16 13:33:19
## File Comparison Table
| File Path | Status | Classes | Classes | Difference |
|------------------------------------|----------|--------------------|--------------------|------------------------------|
| ApiManager/MediaFilesApi.ts | be67aab2:44342e0f | 10.6KB (364 lines) | 10.6KB (369 lines) | +56B (+5 lines) 5% different |
| ApiManager/VoiceDesignerApi.ts | e4d874c3:3635ba42 | 2.0KB (77 lines) | 2.1KB (78 lines) | +94B (+1 lines) 5% different |
| ApiManager/PromptsApi.ts | d73d329a:c4824d2e | 648B (25 lines) | 657B (25 lines) | +9B (0 lines) 4% different |
## Files Present in One Folder But Missing in the Other
### Files Only in Classes (23 files)
- `ApiManager/SegmentationApi.ts` (1.9KB, 84 lines, hash: bb14fbf6)
- `ApiManager/enums/Api.ts` (254B, 7 lines, hash: ea867d98)
- `ApiManager/enums/Billing.ts` (242B, 11 lines, hash: e47c3eaa)
- `ApiManager/enums/Job.ts` (433B, 16 lines, hash: d148fd64)
- `ApiManager/enums/MediaFileClass.ts` (524B, 26 lines, hash: c90ce542)
- `ApiManager/enums/MediaFileType.ts` (1.7KB, 58 lines, hash: a2374fec)
- `ApiManager/enums/QueryFilters.ts` (579B, 29 lines, hash: 6d10a292)
- `ApiManager/enums/Tts.ts` (205B, 7 lines, hash: f6393d2e)
- `ApiManager/enums/UserFeatures.ts` (167B, 6 lines, hash: 05d49e51)
- `ApiManager/enums/Visibility.ts` (92B, 5 lines, hash: 297d031b)
- `ApiManager/enums/WeightCategory.ts` (180B, 8 lines, hash: f9be3d32)
- `ApiManager/enums/WeightType.ts` (208B, 11 lines, hash: 80436726)
- `ApiManager/models/BetaKeys.ts` (502B, 26 lines, hash: 7c718ac6)
- `ApiManager/models/Billing.tsx` (416B, 17 lines, hash: 8db6eb3b)
- `ApiManager/models/Dataset.ts` (588B, 23 lines, hash: 6af860ff)
- `ApiManager/models/Job.ts` (1.8KB, 72 lines, hash: 9d7b385a)
- `ApiManager/models/MediaFile.ts` (1.8KB, 59 lines, hash: 41778349)
- `ApiManager/models/Pagination.ts` (200B, 9 lines, hash: 837b24d3)
- `ApiManager/models/Prompts.ts` (424B, 16 lines, hash: 8ef1f366)
- `ApiManager/models/StatusAlert.ts` (175B, 9 lines, hash: fcee4684)
- `ApiManager/models/UserBookmark.ts` (1.6KB, 75 lines, hash: 8f70d1b1)
- `ApiManager/models/Users.ts` (1.3KB, 50 lines, hash: 5ed82bbd)
- `ApiManager/models/Weight.ts` (767B, 40 lines, hash: 3f9cccdb)
### Files Only in Classes (4 files)
- `ApiHelpers.ts` (637B, 17 lines, hash: 9b638c6c)
- `ApiManager/StudioGen2Api.ts` (1.6KB, 61 lines, hash: b2707195)
- `EnvironmentVariables.ts` (263B, 10 lines, hash: 29c93666)
- `GetFrontendEnvironment.ts` (1.9KB, 65 lines, hash: 7ee8b738)
## Files with Differences (Sorted by Most Different First)
### `ApiManager/MediaUploadApi.ts` (72% different)
- Classes: 10.3KB, 349 lines, hash: 707d2bf2
- Classes: 10.0KB, 339 lines, hash: 06a93d8c
- Difference: -255 bytes, -10 lines
### `ApiManager/EngineApi.ts` (69% different)
- Classes: 1.0KB, 39 lines, hash: c4850e80
- Classes: 5.5KB, 213 lines, hash: 85e20a81
- Difference: +4469 bytes, +174 lines
### `ApiManager/JobsApi.ts` (28% different)
- Classes: 2.0KB, 77 lines, hash: f7eb8e22
- Classes: 1.9KB, 74 lines, hash: 2aa03349
- Difference: -56 bytes, -3 lines
### `ApiManager/ApiManager.ts` (14% different)
- Classes: 5.5KB, 235 lines, hash: 44db0b07
- Classes: 5.3KB, 211 lines, hash: 67a3a046
- Difference: -200 bytes, -24 lines
### `ApiManager/BillingApi.ts` (6% different)
- Classes: 1.0KB, 33 lines, hash: 20051893
- Classes: 1.0KB, 33 lines, hash: f5b7af84
- Difference: -8 bytes, +0 lines
### `ApiManager/VoiceDesignerApi.ts` (5% different)
- Classes: 2.0KB, 77 lines, hash: e4d874c3
- Classes: 2.1KB, 78 lines, hash: 3635ba42
- Difference: +94 bytes, +1 lines
### `ApiManager/MediaFilesApi.ts` (5% different)
- Classes: 10.6KB, 364 lines, hash: be67aab2
- Classes: 10.6KB, 369 lines, hash: 44342e0f
- Difference: +56 bytes, +5 lines
### `ApiManager/PromptsApi.ts` (4% different)
- Classes: 648B, 25 lines, hash: d73d329a
- Classes: 657B, 25 lines, hash: c4824d2e
- Difference: +9 bytes, +0 lines
### `ApiManager/MiscApi.ts` (3% different)
- Classes: 799B, 26 lines, hash: 298f5d93
- Classes: 799B, 26 lines, hash: 187ad676
- Difference: +0 bytes, +0 lines
### `ApiManager/TtsApi.ts` (3% different)
- Classes: 1.7KB, 64 lines, hash: 5feb5cad
- Classes: 1.7KB, 64 lines, hash: 6228b278
- Difference: +2 bytes, +0 lines
### `ApiManager/index.ts` (2% different)
- Classes: 564B, 18 lines, hash: 55a9094b
- Classes: 597B, 19 lines, hash: 1fe59701
- Difference: +33 bytes, +1 lines
### `ApiManager/UserBookmarksApi.ts` (2% different)
- Classes: 5.4KB, 201 lines, hash: e3e4cb19
- Classes: 5.5KB, 202 lines, hash: fd3afc78
- Difference: +56 bytes, +1 lines
### `ApiManager/WeightsApi.ts` (2% different)
- Classes: 7.8KB, 295 lines, hash: c12a98df
- Classes: 7.9KB, 296 lines, hash: 8a7dbb68
- Difference: +39 bytes, +1 lines
### `ApiManager/VideoApi.ts` (1% different)
- Classes: 1.9KB, 70 lines, hash: a9947328
- Classes: 1.9KB, 70 lines, hash: cb947c07
- Difference: -11 bytes, +0 lines
### `ApiManager/BetaKeysApi.ts` (1% different)
- Classes: 4.3KB, 167 lines, hash: 8d4ec6f1
- Classes: 4.3KB, 167 lines, hash: 33f1e4b3
- Difference: -3 bytes, +0 lines
### `ApiManager/UsersApi.ts` (0% different)
- Classes: 3.9KB, 161 lines, hash: 65121217
- Classes: 3.9KB, 161 lines, hash: 72db0eae
- Difference: -6 bytes, +0 lines
## Summary
- **Total Unique Files**: 49
- **Files in Classes**: 45
- **Files in Classes**: 26
- **Identical Files**: 6
- **Different Files**: 16
- **Files Only in Classes**: 23
- **Files Only in Classes**: 4
## Path Information
- Classes: `/Users/michaelchung/storyteller-rust/frontend/apps/editor2d/src/Classes/`
- Classes: `/Users/michaelchung/storyteller-rust/frontend/apps/editor3d/app/Classes/`
+5 -1
View File
@@ -16,6 +16,10 @@
"skipLibCheck": true,
"strict": true,
"target": "es2022",
"customConditions": ["development"]
"customConditions": ["development"],
"baseUrl": ".",
"paths": {
"@frontend/login": ["libs/login/src/index.ts"]
}
}
}
+4 -4
View File
@@ -4,13 +4,13 @@
"files": [],
"references": [
{
"path": "./apps/editor2d"
"path": "./libs/api"
},
{
"path": "./libs/login"
},
{
"path": "./apps/editor3d"
},
{
"path": "./libs/api"
}
]
}