stashapp-api
v0.3.22
Published
Easy to use adapter for interaction with a Stash server through GraphQL.
Maintainers
Readme
stashapp-api
A TypeScript npm package for interacting with the Stash GraphQL server.
Features
- Singleton connection class (URL + API key)
- Type-safe methods for all available queries (auto-generated via GraphQL introspection/codegen)
- Strict TypeScript types for all queries and arguments
- Ready for npm publishing
Usage
import { StashApp } from "stashapp-api";
const stash = StashApp.init({
url: "http://your-stash-url/graphql",
apiKey: "your-api-key",
});
// Find performers with performer_filter
const performers = await stash.findPerformers({
filter: { per_page: 10 },
performer_filter: {
gender: { modifier: "EQUALS", value: "FEMALE" },
favorite: true,
},
});
// Find scenes with scene_filter (now returns detailed studio, performer, and tag information)
const scenes = await stash.findScenes({
filter: { per_page: 5 },
scene_filter: {
rating100: { modifier: "GREATER_THAN", value: 80 },
performer_favorite: true,
},
});
// Access detailed information
scenes.scenes.forEach((scene) => {
console.log(`Scene: ${scene.title}`);
console.log(`Studio: ${scene.studio?.name} (${scene.studio?.url})`);
scene.performers.forEach((performer) => {
console.log(`Performer: ${performer.name} (${performer.gender})`);
console.log(` Details: ${performer.details}`);
console.log(` Rating: ${performer.rating100}`);
});
scene.tags.forEach((tag) => {
console.log(`Tag: ${tag.name} - ${tag.description}`);
});
});
// Find tags with tag_filter
const tags = await stash.findTags({
filter: { per_page: 10 },
tag_filter: {
favorite: true,
name: { modifier: "MATCHES_REGEX", value: "^A" },
},
});
// Start a metadata scan
const scanJobId = await stash.metadataScan({
input: {
paths: ["/path/to/your/content"],
rescan: false,
scanGenerateCovers: true,
scanGeneratePreviews: false,
scanGenerateImagePreviews: false,
scanGenerateSprites: false,
scanGeneratePhashes: true,
scanGenerateThumbnails: true,
},
});
console.log(`Scan started with job ID: ${scanJobId}`);
// Update a scene
const updatedScene = await stash.sceneUpdate({
input: {
id: "scene-id",
title: "New Title",
},
});
// Update multiple scenes
const updatedScenes = await stash.scenesUpdate({
input: {
ids: ["scene-id-1", "scene-id-2"],
title: "Bulk Updated Title",
},
});
// Update a performer
const updatedPerformer = await stash.performerUpdate({
input: {
id: "performer-id",
name: "Updated Name",
favorite: true,
},
});
// Update a studio
const updatedStudio = await stash.studioUpdate({
input: {
id: "studio-id",
name: "Updated Studio Name",
},
});Development
Environment Setup
Copy
.env.exampleto.envand fill in your Stash server details:cp .env.example .envEdit
.envwith your Stash server configuration:STASH_ENDPOINT=http://your-stash-server:port STASH_API_KEY=your_api_key_here
🔄 Schema Refresh Process
When you need to refresh the schema (after updating GraphQL operations or when Stash server schema changes):
npm run refreshThis single command does everything:
npm run update-schema- Fetches latest GraphQL schema from your Stash servernpm run codegen- Regenerates TypeScript types and SDK methods from schema + operationsnpm run build- Compiles TypeScript to JavaScript
Individual commands (if you need granular control):
npm run update-schema- Only fetch the latest GraphQL schema from your Stash servernpm run codegen- Only generate types and queries from the schemanpm run build- Only compile TypeScript to JavaScript
Initial Setup
Before using the package, you need to generate the GraphQL types:
- Set up your
.envfile with your Stash server details - Run
npm run refreshto fetch the schema and generate types - The generated files will be in
src/generated/
📝 Important Notes
- Always run
npm run refreshafter modifying.graphqlfiles insrc/operations/ - The schema refresh requires your Stash server to be running and accessible
- Generated types are based on both your GraphQL operations AND the server's schema
- If you get type errors after adding fields, you forgot to run
npm run refresh
License
MIT
