@platoorg/ts-client
v0.5.0
Published
Code generator that turns a plato-manifest.json into a typed, framework-agnostic client
Readme
@platoorg/ts-client
A TypeScript code generator that reads a Plato plato-manifest.json and emits
a fully-typed, framework-agnostic TypeScript client.
Install
npm install @platoorg/ts-clientUsage
npx plato-ts [manifest] [output]| Argument | Default | Description |
|------------|-----------------|------------------------------------|
| manifest | plato-manifest.json | Path to your Plato manifest file |
| output | plato-client.ts | Where to write the generated file |
Examples
# Run from your project root — looks for plato-manifest.json by default
npx plato-ts
# Custom manifest path
npx plato-ts path/to/plato-manifest.json
# Explicit manifest and output
npx plato-ts src/schemas/plato-manifest.json src/lib/plato/client.tsSchema sync
@platoorg/ts-client also ships plato-sync — a tool to push your
plato-manifest.json schema to a live Plato instance (or preview what would
change).
# Apply manifest to your Plato instance
plato-sync
# Preview changes without applying
plato-sync --preview
# Export the current remote schema to a local manifest
plato-sync --export > plato-manifest.json
# Target a specific namespace
plato-sync --namespace=my-blogEnvironment variables:
| Variable | Description |
|-------------------|--------------------------------------------------|
| PLATO_URL | Base URL of your Plato instance (required) |
| PLATO_NAMESPACE | Namespace slug (or pass --namespace=<ns>) |
| PLATO_API_KEY | Full-access API key |
| PLATO_SECRET | Shared secret for zero-config bootstrap |
What gets generated
Interfaces
One TypeScript interface per schema, extending a shared PlatoItem base.
Fields marked required: true in the manifest are non-optional.
export interface PlatoItem {
id: string;
created_at: string;
updated_at: string;
}
/** singleton */
export interface Homepage extends PlatoItem {
hero_title: string; // required
hero_subtitle?: string;
hero_image?: string; // media asset URL
}
/** collection */
export interface Post extends PlatoItem {
title: string; // required
body?: string;
published_at?: string; // ISO 8601 date string
cover?: string; // media asset URL
author?: string; // ID of related item
tags?: string[]; // IDs of related items
}Filter param interfaces (collections only)
export interface PostParams {
title?: string;
published_at?: string;
// ... one key per field
}PlatoClient class
const client = new PlatoClient(
'http://localhost:6100', // Plato base URL
'my-namespace', // namespace slug
'your-api-key', // optional — omit for public namespaces
);
// singletons
const home = await client.getHomepage();
await client.updateHomepage({ hero_title: 'New headline' });
// collections
const posts = await client.listPost({ published: 'true' });
const post = await client.getPost('1234567890');
const newPost = await client.createPost({ title: 'Hello world', published: false });
await client.updatePost('1234567890', { title: 'Updated' });
await client.deletePost('1234567890');Field type mapping
| Plato type | TypeScript type | Notes |
|-----------------|-----------------|--------------------------|
| string | string | |
| number | number | |
| boolean | boolean | |
| date | string | ISO 8601 date string |
| media | string | media asset URL |
| relation_one | string | ID of related item |
| relation_many | string[] | IDs of related items |
Using as a library
import { generateTypeScript } from '@platoorg/ts-client';
import type { Manifest } from '@platoorg/ts-client';
const manifest: Manifest = JSON.parse(fs.readFileSync('plato-manifest.json', 'utf8'));
const code = generateTypeScript(manifest);
fs.writeFileSync('plato-client.ts', code);