@zweer/mage-space-client 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/index.cjs +1284 -0
- package/dist/index.d.cts +800 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +800 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1267 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +86 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Niccolò Olivieri Achille
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# @zweer/mage-space-client
|
|
2
|
+
|
|
3
|
+
A TypeScript client for mage.space's internal API. Generate AI images and videos programmatically.
|
|
4
|
+
|
|
5
|
+
**No official mage.space API exists.** This library reverse-engineers the Next.js Server Actions used by the web app to provide a clean, type-safe interface for automation.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @zweer/mage-space-client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { MageSpaceClient } from '@zweer/mage-space-client';
|
|
17
|
+
|
|
18
|
+
const client = new MageSpaceClient({
|
|
19
|
+
refreshToken: process.env.MAGE_REFRESH_TOKEN!,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Submit a generation and poll until it finishes
|
|
23
|
+
const { historyId } = await client.generate({
|
|
24
|
+
prompt: 'A cyberpunk city at sunset, neon lights reflecting on wet streets',
|
|
25
|
+
model: 'mango-v3-pro',
|
|
26
|
+
aspectRatio: 'portrait',
|
|
27
|
+
resolution: '1K',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const result = await client.waitForResult(historyId);
|
|
31
|
+
console.log(result.result?.data.image); // CDN URL of the generated image
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- **Image generation** — submit, poll, fetch, cancel (`generate`, `waitForResult`, `getResult`, `cancelJob`)
|
|
37
|
+
- **Video generation** — Berry-2 family (`generateVideo`)
|
|
38
|
+
- **Characters** — search, full CRUD, pagination, publish/unpublish, image upload, voice, follow/unfollow (`client.characters.*`)
|
|
39
|
+
- **References** — reusable image assets: upload, create, update, list, delete (`client.references.*`)
|
|
40
|
+
- **History & creations** — list history, save/list/delete permanent creations
|
|
41
|
+
- **Auto-auth** — Firebase token refresh (ID token ~1h, session ~24h) handled automatically
|
|
42
|
+
- **Action discovery** — Vercel deploy hash changes handled transparently (multi-page discovery + warm seed)
|
|
43
|
+
|
|
44
|
+
## Authentication
|
|
45
|
+
|
|
46
|
+
Mage.space uses Firebase Authentication. You need a refresh token:
|
|
47
|
+
|
|
48
|
+
1. Log into mage.space in your browser
|
|
49
|
+
2. Open DevTools → Application → IndexedDB → `firebaseLocalStorage`
|
|
50
|
+
3. Find the entry with your user data, copy the `refreshToken` value
|
|
51
|
+
4. Store it as an environment variable
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
export MAGE_REFRESH_TOKEN="AMf-vBw..."
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The library refreshes tokens automatically.
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
### Image generation
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
const { historyId } = await client.generate({
|
|
65
|
+
prompt: 'portrait of @mycharacter in a neon-lit alley',
|
|
66
|
+
model: 'mango-v3-pro',
|
|
67
|
+
aspectRatio: 'portrait',
|
|
68
|
+
resolution: '1K',
|
|
69
|
+
// optional: attach trained characters and reference assets
|
|
70
|
+
characters: [{ id, name, username, image_url }],
|
|
71
|
+
references: [{ id, name, username, image_url }],
|
|
72
|
+
// optional: reference images (first + additional, up to the architecture's limit)
|
|
73
|
+
image: 'https://cdn3.mage.space/.../first.jpg',
|
|
74
|
+
additionalImages: ['https://cdn3.mage.space/.../second.jpg'],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const result = await client.waitForResult(historyId, { intervalMs: 4000, timeoutMs: 300_000 });
|
|
78
|
+
console.log(result.result?.data.image);
|
|
79
|
+
|
|
80
|
+
await client.cancelJob(historyId); // cancel a still-running job
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Video generation (Berry-2)
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const { historyId } = await client.generateVideo({
|
|
87
|
+
prompt: 'a cat walking on a sunny sidewalk',
|
|
88
|
+
aspectRatio: '9:16', // berry_aspect_ratio
|
|
89
|
+
resolution: '480p',
|
|
90
|
+
duration: '5', // seconds, as a string
|
|
91
|
+
});
|
|
92
|
+
const video = await client.waitForResult(historyId);
|
|
93
|
+
console.log(video.result?.data.video);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Characters
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// upload an image, then create a character from it
|
|
100
|
+
const imageUrl = await client.characters.uploadImage(dataUrl); // data:image/jpeg;base64,...
|
|
101
|
+
const character = await client.characters.create({
|
|
102
|
+
name: 'my-character',
|
|
103
|
+
username: 'mychar-abcd',
|
|
104
|
+
image_url: imageUrl,
|
|
105
|
+
tags: ['realistic'],
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await client.characters.update(character.id, { description: 'updated' });
|
|
109
|
+
await client.characters.publish(character.id);
|
|
110
|
+
await client.characters.unpublish(character.id);
|
|
111
|
+
|
|
112
|
+
const { characters } = await client.characters.search({ query: 'mychar' });
|
|
113
|
+
const page = await client.characters.listPaginated({ uid: character.uid, limit: 50 });
|
|
114
|
+
await client.characters.delete(character.id);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### References
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const refUrl = await client.references.uploadImage(dataUrl);
|
|
121
|
+
const reference = await client.references.create({
|
|
122
|
+
name: 'sunflower-dress',
|
|
123
|
+
username: 'sunflowerdress-abcd',
|
|
124
|
+
image_url: refUrl,
|
|
125
|
+
variant: 'outfit', // 'reference' | 'object' | 'outfit' | 'pose'
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const mine = await client.references.list('image');
|
|
129
|
+
const feed = await client.references.listPaginated({ featuredOnly: true, orderBy: 'top' });
|
|
130
|
+
await client.references.delete(reference.id, { confirm: true });
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### History & creations
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
const history = await client.listHistory({ limit: 10, status: 'success' });
|
|
137
|
+
const creations = await client.listCreations({ limit: 10 });
|
|
138
|
+
|
|
139
|
+
// persist a finished result as a permanent creation (returns void — retrieve via listCreations)
|
|
140
|
+
await client.saveCreation(result.result!);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Destructive operations
|
|
144
|
+
|
|
145
|
+
Irreversible deletes require an explicit confirmation flag:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
await client.deleteHistory(historyId, { confirm: true });
|
|
149
|
+
await client.deleteManyHistories([id1, id2], { confirm: true });
|
|
150
|
+
await client.deleteCreation(creationId, { confirm: true });
|
|
151
|
+
await client.deleteManyCreations([id1, id2], { confirm: true });
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## How It Works
|
|
155
|
+
|
|
156
|
+
Unlike traditional REST APIs, mage.space uses Next.js Server Actions:
|
|
157
|
+
- Requests are `POST`ed to a page path with a `next-action` header identifying the server function
|
|
158
|
+
- Responses use the React Server Component (RSC) "Flight" wire format
|
|
159
|
+
- Action hashes change on every Vercel deploy — discovered from the page bundles (across routes) and cached, with a bundled seed for a warm start
|
|
160
|
+
|
|
161
|
+
## Project Structure
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
lib/
|
|
165
|
+
├── index.ts # Public barrel (re-exports)
|
|
166
|
+
├── client.ts # MageSpaceClient facade
|
|
167
|
+
├── http.ts # Server Action HTTP client
|
|
168
|
+
├── auth.ts # Firebase auth (refresh → ID token → session)
|
|
169
|
+
├── generation.ts # Image + video submit / poll / cancel
|
|
170
|
+
├── characters.ts # Character search / CRUD / upload / voice / follow
|
|
171
|
+
├── references.ts # Reference assets: upload / CRUD / list
|
|
172
|
+
├── history.ts # History + creations (list / save / delete)
|
|
173
|
+
├── actions.ts # Multi-page action-hash discovery
|
|
174
|
+
├── rsc.ts # RSC (Flight) response parser
|
|
175
|
+
├── seed.ts # Bundled action-hash seed snapshot
|
|
176
|
+
├── errors.ts # Typed error classes
|
|
177
|
+
└── types.ts # All type definitions
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT
|