feat: scaffold workspace with search, fetch, and extract packages
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "@tts/shared",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||
"lint": "echo \"no lint configured\""
|
||||
},
|
||||
"dependencies": {
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './types.js';
|
||||
export * from './schemas.js';
|
||||
@@ -0,0 +1,54 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
/** Validate a Workshop item ID (a non-empty run of digits). */
|
||||
export const itemIdSchema = z
|
||||
.string()
|
||||
.regex(/^\d+$/, 'Item ID must be a number')
|
||||
.min(1);
|
||||
|
||||
/** Query params for `GET /search`. */
|
||||
export const searchQuerySchema = z.object({
|
||||
q: z.string().trim().min(1, 'Search query is required'),
|
||||
page: z.coerce.number().int().min(1).default(1),
|
||||
});
|
||||
|
||||
export const assetKindSchema = z.enum([
|
||||
'pdf',
|
||||
'deckFace',
|
||||
'deckBack',
|
||||
'image',
|
||||
'imageSecondary',
|
||||
]);
|
||||
|
||||
export const assetRefSchema = z.object({
|
||||
kind: assetKindSchema,
|
||||
url: z.string().url(),
|
||||
ownerGuid: z.string(),
|
||||
});
|
||||
|
||||
export const extractedObjectSchema = z.object({
|
||||
guid: z.string(),
|
||||
name: z.string(),
|
||||
type: z.string(),
|
||||
parentGuid: z.string().optional(),
|
||||
childrenGuids: z.array(z.string()),
|
||||
refs: z.array(assetRefSchema),
|
||||
});
|
||||
|
||||
export const workshopItemSchema = z.object({
|
||||
id: z.string(),
|
||||
title: z.string(),
|
||||
author: z.string(),
|
||||
previewImageUrl: z.string(),
|
||||
fileUrl: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
tags: z.array(z.string()).optional(),
|
||||
timeCreated: z.number().optional(),
|
||||
timeUpdated: z.number().optional(),
|
||||
});
|
||||
|
||||
export const searchResultSchema = z.object({
|
||||
items: z.array(workshopItemSchema),
|
||||
page: z.number(),
|
||||
hasMore: z.boolean(),
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* A single object inside a Tabletop Simulator save file.
|
||||
* Mirrors the structure produced by BSON-deserializing a TTS save.
|
||||
*/
|
||||
export interface TTSObject {
|
||||
Name: string;
|
||||
GUID: string;
|
||||
Description: string;
|
||||
/** Set by `markParent` during traversal; not present in the raw save. */
|
||||
Parent?: TTSObject;
|
||||
|
||||
CustomPDF?: {
|
||||
PDFUrl: string;
|
||||
};
|
||||
|
||||
ContainedObjects?: TTSObject[];
|
||||
|
||||
CardID?: number;
|
||||
CustomDeck?: {
|
||||
[key: number]: {
|
||||
BackURL: string;
|
||||
FaceURL: string;
|
||||
UniqueBack: boolean;
|
||||
NumHeight: number;
|
||||
NumWidth: number;
|
||||
};
|
||||
};
|
||||
CustomImage?: {
|
||||
ImageURL: string;
|
||||
ImageSecondaryURL: string;
|
||||
};
|
||||
}
|
||||
|
||||
/** A full Tabletop Simulator save file. */
|
||||
export interface TTSMod {
|
||||
GameMode: string;
|
||||
Date: string;
|
||||
ObjectStates: TTSObject[];
|
||||
}
|
||||
|
||||
/** Metadata for a Workshop item, from the Steam Web API. */
|
||||
export interface WorkshopItem {
|
||||
id: string;
|
||||
title: string;
|
||||
author: string;
|
||||
previewImageUrl: string;
|
||||
fileUrl?: string;
|
||||
description?: string;
|
||||
tags?: string[];
|
||||
timeCreated?: number;
|
||||
timeUpdated?: number;
|
||||
}
|
||||
|
||||
/** A page of Workshop search results. */
|
||||
export interface SearchResult {
|
||||
items: WorkshopItem[];
|
||||
page: number;
|
||||
hasMore: boolean;
|
||||
}
|
||||
|
||||
/** A reference to an external asset embedded in a TTS object. */
|
||||
export type AssetKind =
|
||||
| 'pdf'
|
||||
| 'deckFace'
|
||||
| 'deckBack'
|
||||
| 'image'
|
||||
| 'imageSecondary';
|
||||
|
||||
export interface AssetRef {
|
||||
kind: AssetKind;
|
||||
url: string;
|
||||
/** GUID of the object that owns this reference. */
|
||||
ownerGuid: string;
|
||||
}
|
||||
|
||||
/** A flattened, lightweight view of an object for inspection/rendering. */
|
||||
export interface ExtractedObject {
|
||||
guid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
parentGuid?: string;
|
||||
childrenGuids: string[];
|
||||
refs: AssetRef[];
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user