@almadar/sdk 0.2.5 → 0.3.1
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/README.md +1 -5
- package/dist/{AlmadarApp-DgwtnIRy.d.ts → AlmadarApp-mS7H6kiA.d.ts} +1 -1
- package/dist/client/index.d.ts +20 -4
- package/dist/client/index.js +118 -53
- package/dist/client/index.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +120 -55
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +2 -2
- package/dist/react/index.js.map +1 -1
- package/dist/server/express.js +113 -52
- package/dist/server/express.js.map +1 -1
- package/dist/server/hono.js +113 -52
- package/dist/server/hono.js.map +1 -1
- package/dist/server/index.js +113 -52
- package/dist/server/index.js.map +1 -1
- package/dist/types-CVGXdQRM.d.ts +193 -0
- package/package.json +4 -4
- package/dist/types-C6RJADoY.d.ts +0 -125
package/dist/server/express.js
CHANGED
|
@@ -2,6 +2,48 @@ import { parseOrbitalSchema } from '@almadar/core';
|
|
|
2
2
|
|
|
3
3
|
// src/client/AlmadarClient.ts
|
|
4
4
|
|
|
5
|
+
// src/types.ts
|
|
6
|
+
function isGenerateMetaOrganism(value) {
|
|
7
|
+
if (value === null || typeof value !== "object") return false;
|
|
8
|
+
const v = value;
|
|
9
|
+
if (typeof v.name !== "string") return false;
|
|
10
|
+
return v.source === "factory" || v.source === "free-lolo";
|
|
11
|
+
}
|
|
12
|
+
function isGenerateMetaCacheVerdict(value) {
|
|
13
|
+
if (value === null) return true;
|
|
14
|
+
if (typeof value !== "object") return false;
|
|
15
|
+
const v = value;
|
|
16
|
+
if (v.verdict !== "hit" && v.verdict !== "miss") return false;
|
|
17
|
+
return v.chosen === null || typeof v.chosen === "string";
|
|
18
|
+
}
|
|
19
|
+
function isGenerateMeta(value) {
|
|
20
|
+
if (value === null || typeof value !== "object") return false;
|
|
21
|
+
const v = value;
|
|
22
|
+
if (v.tier !== "confirmed" && v.tier !== "hit" && v.tier !== "miss") return false;
|
|
23
|
+
if (!Array.isArray(v.organisms) || !v.organisms.every(isGenerateMetaOrganism)) return false;
|
|
24
|
+
if (!Array.isArray(v.demoted) || !v.demoted.every((d) => typeof d === "string")) return false;
|
|
25
|
+
if (!isGenerateMetaCacheVerdict(v.cacheVerdict)) return false;
|
|
26
|
+
return typeof v.durationMs === "number";
|
|
27
|
+
}
|
|
28
|
+
var API_ERROR_CODES = {
|
|
29
|
+
API_KEY: 4001,
|
|
30
|
+
RATE_LIMITED: 4029,
|
|
31
|
+
CATALOG_OUT_OF_SCOPE: 4040,
|
|
32
|
+
PIN_UNKNOWN_ORGANISM: 4041,
|
|
33
|
+
PIN_OUT_OF_SCOPE: 4042,
|
|
34
|
+
PIN_CONFLICT: 4043,
|
|
35
|
+
PIN_UNKNOWN_KNOB: 4044,
|
|
36
|
+
PIN_ORBITAL_REQUIRED: 4045,
|
|
37
|
+
ASYNC_UNSUPPORTED: 4060,
|
|
38
|
+
FOCUS_STALE: 4090,
|
|
39
|
+
SERVER: 5e3,
|
|
40
|
+
GENERATION_FAILED: 5001,
|
|
41
|
+
RUNTIME: 5002,
|
|
42
|
+
WORKSPACE_OPEN: 5003,
|
|
43
|
+
AI_UNCONFIGURED: 5030
|
|
44
|
+
};
|
|
45
|
+
var STREAM_ERROR_CODES = ["failed", "runtime", "workspace_open", "ai_unconfigured", "focus_stale"];
|
|
46
|
+
|
|
5
47
|
// src/client/errors.ts
|
|
6
48
|
var AlmadarError = class extends Error {
|
|
7
49
|
code;
|
|
@@ -39,18 +81,68 @@ var ServerError = class extends AlmadarError {
|
|
|
39
81
|
this.name = "ServerError";
|
|
40
82
|
}
|
|
41
83
|
};
|
|
84
|
+
var PinError = class extends AlmadarError {
|
|
85
|
+
constructor(body) {
|
|
86
|
+
super(body);
|
|
87
|
+
this.name = "PinError";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var AsyncUnsupportedError = class extends AlmadarError {
|
|
91
|
+
constructor(body) {
|
|
92
|
+
super(body);
|
|
93
|
+
this.name = "AsyncUnsupportedError";
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var GenerationFailedError = class extends AlmadarError {
|
|
97
|
+
constructor(body) {
|
|
98
|
+
super(body);
|
|
99
|
+
this.name = "GenerationFailedError";
|
|
100
|
+
}
|
|
101
|
+
};
|
|
42
102
|
function errorFromBody(body) {
|
|
43
103
|
switch (body.code) {
|
|
44
|
-
case
|
|
104
|
+
case API_ERROR_CODES.API_KEY:
|
|
45
105
|
return new ApiKeyError(body);
|
|
46
|
-
case
|
|
106
|
+
case API_ERROR_CODES.RATE_LIMITED:
|
|
47
107
|
return new RateLimitedError(body);
|
|
48
|
-
case
|
|
108
|
+
case API_ERROR_CODES.CATALOG_OUT_OF_SCOPE:
|
|
49
109
|
return new CatalogOutOfScopeError(body);
|
|
110
|
+
case API_ERROR_CODES.PIN_UNKNOWN_ORGANISM:
|
|
111
|
+
case API_ERROR_CODES.PIN_OUT_OF_SCOPE:
|
|
112
|
+
case API_ERROR_CODES.PIN_CONFLICT:
|
|
113
|
+
case API_ERROR_CODES.PIN_UNKNOWN_KNOB:
|
|
114
|
+
case API_ERROR_CODES.PIN_ORBITAL_REQUIRED:
|
|
115
|
+
return new PinError(body);
|
|
116
|
+
case API_ERROR_CODES.ASYNC_UNSUPPORTED:
|
|
117
|
+
return new AsyncUnsupportedError(body);
|
|
118
|
+
case API_ERROR_CODES.GENERATION_FAILED:
|
|
119
|
+
return new GenerationFailedError(body);
|
|
50
120
|
default:
|
|
51
121
|
return new ServerError(body);
|
|
52
122
|
}
|
|
53
123
|
}
|
|
124
|
+
function isStreamErrorCode(code) {
|
|
125
|
+
if (code === void 0) return false;
|
|
126
|
+
return STREAM_ERROR_CODES.some((c) => c === code);
|
|
127
|
+
}
|
|
128
|
+
function streamErrorFromEvent(data) {
|
|
129
|
+
const message = data.error;
|
|
130
|
+
if (!isStreamErrorCode(data.code)) {
|
|
131
|
+
return new ServerError({ code: API_ERROR_CODES.SERVER, message });
|
|
132
|
+
}
|
|
133
|
+
switch (data.code) {
|
|
134
|
+
case "failed":
|
|
135
|
+
return new GenerationFailedError({ code: API_ERROR_CODES.GENERATION_FAILED, message });
|
|
136
|
+
case "ai_unconfigured":
|
|
137
|
+
return new ServerError({ code: API_ERROR_CODES.AI_UNCONFIGURED, message });
|
|
138
|
+
case "workspace_open":
|
|
139
|
+
return new ServerError({ code: API_ERROR_CODES.WORKSPACE_OPEN, message });
|
|
140
|
+
case "focus_stale":
|
|
141
|
+
return new ServerError({ code: API_ERROR_CODES.FOCUS_STALE, message });
|
|
142
|
+
case "runtime":
|
|
143
|
+
return new ServerError({ code: API_ERROR_CODES.RUNTIME, message });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
54
146
|
|
|
55
147
|
// src/client/sseParser.ts
|
|
56
148
|
async function* parseSSE(stream) {
|
|
@@ -106,7 +198,6 @@ function indexOfNewline(s) {
|
|
|
106
198
|
|
|
107
199
|
// src/client/AlmadarClient.ts
|
|
108
200
|
var DEFAULT_BASE_URL = "https://studio.almadar.io";
|
|
109
|
-
var POLL_BACKOFF_MS = [1e3, 2e3, 5e3, 1e4, 3e4];
|
|
110
201
|
var AlmadarClient = class {
|
|
111
202
|
apiKey;
|
|
112
203
|
baseUrl;
|
|
@@ -124,19 +215,10 @@ var AlmadarClient = class {
|
|
|
124
215
|
}
|
|
125
216
|
async generate(input) {
|
|
126
217
|
if (input.async === true) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
appId: input.appId,
|
|
131
|
-
async: true,
|
|
132
|
-
provider: input.provider,
|
|
133
|
-
model: input.model,
|
|
134
|
-
catalogMode: input.catalogMode,
|
|
135
|
-
stdAllowList: input.stdAllowList
|
|
218
|
+
throw new AsyncUnsupportedError({
|
|
219
|
+
code: API_ERROR_CODES.ASYNC_UNSUPPORTED,
|
|
220
|
+
message: "AlmadarClient has no async job surface. Omit `async` (or pass false) and consume the streaming response via `onEvent` instead."
|
|
136
221
|
});
|
|
137
|
-
assertString(handle.jobId, "AsyncJobHandle.jobId");
|
|
138
|
-
assertString(handle.statusUrl, "AsyncJobHandle.statusUrl");
|
|
139
|
-
return this.pollUntilComplete(handle, input.onEvent);
|
|
140
222
|
}
|
|
141
223
|
return this.streamGenerate(input);
|
|
142
224
|
}
|
|
@@ -170,56 +252,35 @@ var AlmadarClient = class {
|
|
|
170
252
|
provider: input.provider,
|
|
171
253
|
model: input.model,
|
|
172
254
|
catalogMode: input.catalogMode,
|
|
173
|
-
stdAllowList: input.stdAllowList
|
|
255
|
+
stdAllowList: input.stdAllowList,
|
|
256
|
+
pin: input.pin
|
|
174
257
|
})
|
|
175
258
|
});
|
|
176
259
|
if (!res.ok) throw await this.errorFromResponse(res);
|
|
177
260
|
if (res.body === null) throw new Error("AlmadarClient.generate: server returned no body");
|
|
178
261
|
let final = null;
|
|
262
|
+
let meta;
|
|
179
263
|
for await (const raw of parseSSE(res.body)) {
|
|
180
264
|
const event = parseSseEvent(raw.data);
|
|
181
265
|
if (event === null) continue;
|
|
182
266
|
input.onEvent?.(event);
|
|
183
|
-
if (event.type === "
|
|
267
|
+
if (event.type === "generation_meta") {
|
|
268
|
+
meta = event.data;
|
|
269
|
+
} else if (event.type === "complete") {
|
|
184
270
|
if (event.data.schema === void 0) {
|
|
185
|
-
throw new ServerError({ code:
|
|
271
|
+
throw new ServerError({ code: API_ERROR_CODES.SERVER, message: "`complete` event did not contain a schema" });
|
|
186
272
|
}
|
|
187
273
|
const schema = parseOrbitalSchema(event.data.schema);
|
|
188
|
-
final = { schema, appId: event.data.appId };
|
|
274
|
+
final = { schema, appId: event.data.appId, meta };
|
|
189
275
|
} else if (event.type === "error") {
|
|
190
|
-
throw
|
|
276
|
+
throw streamErrorFromEvent(event.data);
|
|
191
277
|
}
|
|
192
278
|
}
|
|
193
279
|
if (final === null) {
|
|
194
|
-
throw new ServerError({ code:
|
|
280
|
+
throw new ServerError({ code: API_ERROR_CODES.SERVER, message: "SSE stream ended without `complete` event" });
|
|
195
281
|
}
|
|
196
282
|
return final;
|
|
197
283
|
}
|
|
198
|
-
async pollUntilComplete(handle, onEvent) {
|
|
199
|
-
let attempt = 0;
|
|
200
|
-
for (; ; ) {
|
|
201
|
-
const delay = POLL_BACKOFF_MS[Math.min(attempt, POLL_BACKOFF_MS.length - 1)];
|
|
202
|
-
await sleep(delay);
|
|
203
|
-
attempt += 1;
|
|
204
|
-
const status = await this.requestJson("GET", handle.statusUrl);
|
|
205
|
-
assertString(status.state, "JobStatus.state");
|
|
206
|
-
if (status.events !== void 0 && onEvent !== void 0) {
|
|
207
|
-
for (const e of status.events) onEvent(e);
|
|
208
|
-
}
|
|
209
|
-
if (status.state === "complete") {
|
|
210
|
-
if (status.result === void 0) {
|
|
211
|
-
throw new ServerError({ code: 500, message: "Job complete but no result returned" });
|
|
212
|
-
}
|
|
213
|
-
return status.result;
|
|
214
|
-
}
|
|
215
|
-
if (status.state === "error") {
|
|
216
|
-
throw errorFromBody({
|
|
217
|
-
code: status.errorCode ?? 500,
|
|
218
|
-
message: status.errorMessage ?? "Job failed"
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
284
|
async requestJson(method, path, body) {
|
|
224
285
|
const isAbsolute = path.startsWith("http://") || path.startsWith("https://");
|
|
225
286
|
const url = isAbsolute ? path : `${this.baseUrl}${path}`;
|
|
@@ -235,7 +296,7 @@ var AlmadarClient = class {
|
|
|
235
296
|
if (!res.ok) throw await this.errorFromResponse(res);
|
|
236
297
|
const text = await res.text();
|
|
237
298
|
if (text === "") {
|
|
238
|
-
throw new ServerError({ code:
|
|
299
|
+
throw new ServerError({ code: API_ERROR_CODES.SERVER, message: "Empty response body" });
|
|
239
300
|
}
|
|
240
301
|
const parsed = JSON.parse(text);
|
|
241
302
|
return parsed;
|
|
@@ -280,16 +341,16 @@ function parseSseEvent(dataLine) {
|
|
|
280
341
|
}
|
|
281
342
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return null;
|
|
282
343
|
if (typeof payload.type !== "string" || typeof payload.timestamp !== "number") return null;
|
|
344
|
+
if (payload.type === "generation_meta") {
|
|
345
|
+
return isGenerateMeta(payload.data) ? { type: "generation_meta", data: payload.data, timestamp: payload.timestamp } : null;
|
|
346
|
+
}
|
|
283
347
|
return payload;
|
|
284
348
|
}
|
|
285
349
|
function assertString(v, name) {
|
|
286
350
|
if (typeof v !== "string" || v === "") {
|
|
287
|
-
throw new ServerError({ code:
|
|
351
|
+
throw new ServerError({ code: API_ERROR_CODES.SERVER, message: `Malformed server response: ${name} is not a string` });
|
|
288
352
|
}
|
|
289
353
|
}
|
|
290
|
-
function sleep(ms) {
|
|
291
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
292
|
-
}
|
|
293
354
|
|
|
294
355
|
// src/server/index.ts
|
|
295
356
|
function resolveEndUserId(opts, req) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client/errors.ts","../../src/client/sseParser.ts","../../src/client/AlmadarClient.ts","../../src/server/index.ts","../../src/server/express.ts"],"names":["createGenerateHandler","createEditHandler"],"mappings":"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","file":"express.js","sourcesContent":["/**\n * Typed SDK errors. Server emits a structured `ApiErrorBody`; the HTTP layer\n * maps the `code` to one of these subclasses. Customers `catch` by class.\n */\n\nimport type { ApiErrorBody } from '../types';\n\nexport class AlmadarError extends Error {\n readonly code: number;\n readonly details?: ApiErrorBody['details'];\n constructor(body: ApiErrorBody) {\n super(body.message);\n this.name = 'AlmadarError';\n this.code = body.code;\n this.details = body.details;\n }\n}\n\n/** 4001 — invalid, revoked, or missing API key. */\nexport class ApiKeyError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ApiKeyError';\n }\n}\n\n/** 4029 — team cap (feature counter) exceeded. Retry after a billing cycle. */\nexport class RateLimitedError extends AlmadarError {\n readonly retryAfterSeconds?: number;\n constructor(body: ApiErrorBody, retryAfterSeconds?: number) {\n super(body);\n this.name = 'RateLimitedError';\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\n/** 4040 — the team's behavior catalog (subset/replace mode) cannot serve the request. */\nexport class CatalogOutOfScopeError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'CatalogOutOfScopeError';\n }\n}\n\n/** Anything else from the server with a recognized envelope but no specific subclass. */\nexport class ServerError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ServerError';\n }\n}\n\nexport function errorFromBody(body: ApiErrorBody): AlmadarError {\n switch (body.code) {\n case 4001:\n return new ApiKeyError(body);\n case 4029:\n return new RateLimitedError(body);\n case 4040:\n return new CatalogOutOfScopeError(body);\n default:\n return new ServerError(body);\n }\n}\n","/**\n * Minimal Server-Sent Events parser. Reads a `ReadableStream<Uint8Array>`\n * (the body of a `fetch` Response) and yields decoded events. Universal:\n * works in browser, Node 18+, Deno, Bun.\n *\n * Spec subset implemented:\n * - `event:` and `data:` fields\n * - dispatch on blank line\n * - newline-tolerant (CRLF + LF)\n * - skips comments (`:`-prefixed lines)\n *\n * Not implemented (we don't need them):\n * - `id:` / `retry:` fields\n * - reconnection / last-event-id\n */\n\nexport interface RawSseEvent {\n /** `event:` field value. Empty string when absent — matches the spec default. */\n event: string;\n /** Concatenated `data:` lines, joined by newlines. */\n data: string;\n}\n\nexport async function* parseSSE(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<RawSseEvent, void, void> {\n const reader = stream.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let currentEvent = '';\n let currentData = '';\n\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let newlineIdx: number;\n while ((newlineIdx = indexOfNewline(buffer)) !== -1) {\n const rawLine = buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + (buffer[newlineIdx] === '\\r' && buffer[newlineIdx + 1] === '\\n' ? 2 : 1));\n\n if (rawLine === '') {\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n currentEvent = '';\n currentData = '';\n }\n continue;\n }\n if (rawLine.startsWith(':')) continue;\n\n const colon = rawLine.indexOf(':');\n const field = colon === -1 ? rawLine : rawLine.slice(0, colon);\n const rawValue = colon === -1 ? '' : rawLine.slice(colon + 1);\n const value2 = rawValue.startsWith(' ') ? rawValue.slice(1) : rawValue;\n\n if (field === 'event') {\n currentEvent = value2;\n } else if (field === 'data') {\n currentData = currentData === '' ? value2 : `${currentData}\\n${value2}`;\n }\n }\n }\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction indexOfNewline(s: string): number {\n for (let i = 0; i < s.length; i += 1) {\n const c = s[i];\n if (c === '\\n' || c === '\\r') return i;\n }\n return -1;\n}\n","/**\n * `AlmadarClient` — server / Node-side HTTP client targeting `/api/v1/agent/*`.\n * Authenticates with a team-bound API key (`sk_*`) issued from\n * Studio's `/settings/sdk` panel. See `docs/Almadar_Studio_SDK.md` §5.\n *\n * Never instantiate this in a browser bundle — `apiKey` must never leave\n * the customer's server.\n */\n\nimport { parseOrbitalSchema, type OrbitalSchema, type SSEEvent } from '@almadar/core';\nimport type {\n AlmadarClientOptions,\n ApiErrorBody,\n AsyncJobHandle,\n CompileOptions,\n CompileResult,\n EditSchemaPatch,\n GenerateOptions,\n GenerateResult,\n} from '../types';\nimport { errorFromBody, ServerError } from './errors';\nimport { parseSSE } from './sseParser';\n\nconst DEFAULT_BASE_URL = 'https://studio.almadar.io';\nconst POLL_BACKOFF_MS: readonly number[] = [1000, 2000, 5000, 10_000, 30_000];\n\ninterface JobStatus {\n state: 'pending' | 'complete' | 'error';\n events?: readonly SSEEvent[];\n result?: GenerateResult;\n errorCode?: number;\n errorMessage?: string;\n}\n\nexport class AlmadarClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(opts: AlmadarClientOptions) {\n if (!opts.apiKey || typeof opts.apiKey !== 'string') {\n throw new Error('AlmadarClient: opts.apiKey is required');\n }\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (typeof this.fetchImpl !== 'function') {\n throw new Error('AlmadarClient: no fetch available — pass opts.fetch for Node <18');\n }\n }\n\n async generate(input: GenerateOptions): Promise<GenerateResult> {\n if (input.async === true) {\n const handle = await this.requestJson<AsyncJobHandle>('POST', '/api/v1/agent/generate', {\n prompt: input.prompt,\n endUserId: input.endUserId,\n appId: input.appId,\n async: true,\n provider: input.provider,\n model: input.model,\n catalogMode: input.catalogMode,\n stdAllowList: input.stdAllowList,\n });\n assertString(handle.jobId, 'AsyncJobHandle.jobId');\n assertString(handle.statusUrl, 'AsyncJobHandle.statusUrl');\n return this.pollUntilComplete(handle, input.onEvent);\n }\n return this.streamGenerate(input);\n }\n\n async editSchema(appId: string, patch: EditSchemaPatch): Promise<OrbitalSchema> {\n if (!appId) throw new Error('AlmadarClient.editSchema: appId is required');\n const schema = await this.requestJson<OrbitalSchema>('PUT', '/api/v1/agent/edit-schema', {\n appId,\n patch,\n });\n assertString(schema.name, 'OrbitalSchema.name');\n return schema;\n }\n\n async compileToApp(schema: OrbitalSchema, opts?: CompileOptions): Promise<CompileResult> {\n const result = await this.requestJson<CompileResult>('POST', '/api/v1/agent/compile', {\n schema,\n target: opts?.target,\n shell: opts?.shell,\n });\n assertString(result.downloadUrl, 'CompileResult.downloadUrl');\n assertString(result.expiresAt, 'CompileResult.expiresAt');\n return result;\n }\n\n private async streamGenerate(input: GenerateOptions): Promise<GenerateResult> {\n const res = await this.fetchImpl(`${this.baseUrl}/api/v1/agent/generate`, {\n method: 'POST',\n headers: this.headers({ accept: 'text/event-stream', contentType: 'application/json' }, input.endUserId),\n body: JSON.stringify({\n prompt: input.prompt,\n endUserId: input.endUserId,\n appId: input.appId,\n provider: input.provider,\n model: input.model,\n catalogMode: input.catalogMode,\n stdAllowList: input.stdAllowList,\n }),\n });\n if (!res.ok) throw await this.errorFromResponse(res);\n if (res.body === null) throw new Error('AlmadarClient.generate: server returned no body');\n\n let final: GenerateResult | null = null;\n for await (const raw of parseSSE(res.body)) {\n const event = parseSseEvent(raw.data);\n if (event === null) continue;\n input.onEvent?.(event);\n if (event.type === 'complete') {\n if (event.data.schema === undefined) {\n throw new ServerError({ code: 500, message: '`complete` event did not contain a schema' });\n }\n const schema = parseOrbitalSchema(event.data.schema);\n final = { schema, appId: event.data.appId };\n } else if (event.type === 'error') {\n throw errorFromBody({ code: 500, message: event.data.error });\n }\n }\n if (final === null) {\n throw new ServerError({ code: 500, message: 'SSE stream ended without `complete` event' });\n }\n return final;\n }\n\n private async pollUntilComplete(\n handle: AsyncJobHandle,\n onEvent: GenerateOptions['onEvent'],\n ): Promise<GenerateResult> {\n let attempt = 0;\n for (;;) {\n const delay = POLL_BACKOFF_MS[Math.min(attempt, POLL_BACKOFF_MS.length - 1)];\n await sleep(delay);\n attempt += 1;\n const status = await this.requestJson<JobStatus>('GET', handle.statusUrl);\n assertString(status.state, 'JobStatus.state');\n if (status.events !== undefined && onEvent !== undefined) {\n for (const e of status.events) onEvent(e);\n }\n if (status.state === 'complete') {\n if (status.result === undefined) {\n throw new ServerError({ code: 500, message: 'Job complete but no result returned' });\n }\n return status.result;\n }\n if (status.state === 'error') {\n throw errorFromBody({\n code: status.errorCode ?? 500,\n message: status.errorMessage ?? 'Job failed',\n });\n }\n }\n }\n\n private async requestJson<T>(method: string, path: string, body?: object): Promise<T> {\n const isAbsolute = path.startsWith('http://') || path.startsWith('https://');\n const url = isAbsolute ? path : `${this.baseUrl}${path}`;\n const init: RequestInit = {\n method,\n headers: this.headers({\n accept: 'application/json',\n contentType: body !== undefined ? 'application/json' : undefined,\n }),\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await this.fetchImpl(url, init);\n if (!res.ok) throw await this.errorFromResponse(res);\n const text = await res.text();\n if (text === '') {\n throw new ServerError({ code: 500, message: 'Empty response body' });\n }\n const parsed: T = JSON.parse(text);\n return parsed;\n }\n\n private headers(\n opts: { accept?: string; contentType?: string },\n endUserId?: string,\n ): Record<string, string> {\n const h: Record<string, string> = { authorization: `Bearer ${this.apiKey}` };\n if (opts.accept !== undefined) h['accept'] = opts.accept;\n if (opts.contentType !== undefined) h['content-type'] = opts.contentType;\n if (endUserId !== undefined && endUserId !== '') h['x-end-user-id'] = endUserId;\n return h;\n }\n\n private async errorFromResponse(res: Response): Promise<Error> {\n const text = await res.text();\n let body: ApiErrorBody;\n try {\n const parsed: ApiErrorBody | null = text === '' ? null : JSON.parse(text);\n body = parsed !== null && typeof parsed.code === 'number' && typeof parsed.message === 'string'\n ? parsed\n : {\n code: res.status,\n message: res.statusText !== '' ? res.statusText : 'HTTP error',\n };\n } catch {\n body = { code: res.status, message: text !== '' ? text : res.statusText };\n }\n const retryAfter = res.headers.get('retry-after');\n const err = errorFromBody(body);\n if (err.name === 'RateLimitedError' && retryAfter !== null) {\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n Object.defineProperty(err, 'retryAfterSeconds', { value: seconds, enumerable: true });\n }\n }\n return err;\n }\n}\n\n/**\n * Parse one SSE `data:` line into the canonical `SSEEvent` union.\n * The server is the trusted emitter, so we validate only the envelope\n * (object with string `type` and numeric `timestamp`) and cast to the\n * discriminated union. Malformed lines are ignored.\n */\nfunction parseSseEvent(dataLine: string): SSEEvent | null {\n if (dataLine === '') return null;\n let payload;\n try {\n payload = JSON.parse(dataLine);\n } catch {\n return null;\n }\n if (payload === null || typeof payload !== 'object' || Array.isArray(payload)) return null;\n if (typeof payload.type !== 'string' || typeof payload.timestamp !== 'number') return null;\n return payload as SSEEvent;\n}\n\nfunction assertString(v: string | undefined, name: string): asserts v is string {\n if (typeof v !== 'string' || v === '') {\n throw new ServerError({ code: 500, message: `Malformed server response: ${name} is not a string` });\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * `@almadar/sdk/server` — Framework-agnostic Web-standard Fetch handlers for\n * the Almadar agent proxy. Node-only; never import from browser or React code.\n *\n * Usage:\n * import { createGenerateHandler, createEditHandler } from '@almadar/sdk/server';\n * const handler = createGenerateHandler({ apiKey: process.env.ALMADAR_API_KEY! });\n * // handler: (request: Request) => Promise<Response>\n *\n * For framework adapters see `@almadar/sdk/server/express` and `@almadar/sdk/server/hono`.\n */\n\nimport type { OrbitalSchema } from '@almadar/core';\nimport { AlmadarClient } from '../client/AlmadarClient';\nimport type { EditSchemaRequest, EditSchemaPatch, GenerateRequest, SSEEvent } from '../types';\n\n// ============================================================================\n// Public option surface\n// ============================================================================\n\nexport interface GenerateHandlerOptions {\n /** API key issued from Studio's /settings/sdk panel. */\n apiKey: string;\n /** Defaults to https://studio.almadar.io. */\n baseUrl?: string;\n /**\n * Derive a stable end-user id from the incoming Web Request.\n * Falls back to the `x-user-id` request header when omitted.\n */\n endUserId?: (req: Request) => string;\n}\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\nfunction resolveEndUserId(opts: GenerateHandlerOptions, req: Request): string | undefined {\n if (opts.endUserId) return opts.endUserId(req);\n const header = req.headers.get('x-user-id');\n return typeof header === 'string' && header.length > 0 ? header : undefined;\n}\n\nfunction encodeSseEvent(event: SSEEvent): string {\n return `data: ${JSON.stringify(event)}\\n\\n`;\n}\n\n// ============================================================================\n// createGenerateHandler\n// ============================================================================\n\n/**\n * Returns a Web-standard Fetch handler that streams a generate call as SSE.\n *\n * Body shape accepted: `{ prompt: string; endUserId?: string; appId?: string }`\n */\nexport function createGenerateHandler(\n opts: GenerateHandlerOptions,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let body: GenerateRequest;\n try {\n body = (await request.json()) as GenerateRequest;\n } catch {\n return new Response(JSON.stringify({ error: 'invalid JSON body' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const rawPrompt = body.prompt ?? body.message;\n const prompt = typeof rawPrompt === 'string' ? rawPrompt : '';\n\n if (!prompt) {\n return new Response(JSON.stringify({ error: 'prompt or message is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const bodyEndUserId = typeof body.endUserId === 'string' ? body.endUserId : undefined;\n const endUserId = bodyEndUserId ?? resolveEndUserId(opts, request);\n const appId = typeof body.appId === 'string' ? body.appId : undefined;\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n const encoder = new TextEncoder();\n try {\n await client.generate({\n prompt,\n endUserId,\n appId,\n onEvent: (event: SSEEvent) => {\n controller.enqueue(encoder.encode(encodeSseEvent(event)));\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const errorEvent: SSEEvent = {\n type: 'error',\n timestamp: Date.now(),\n data: { error: message },\n };\n controller.enqueue(encoder.encode(encodeSseEvent(errorEvent)));\n } finally {\n controller.close();\n }\n },\n });\n\n return new Response(stream, {\n status: 200,\n headers: {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n },\n });\n };\n}\n\n// ============================================================================\n// createEditHandler\n// ============================================================================\n\n/**\n * Returns a Web-standard Fetch handler that calls `editSchema` and returns JSON.\n *\n * Body shape accepted: `{ appId: string; patch: EditSchemaPatch }`\n */\nexport function createEditHandler(\n opts: GenerateHandlerOptions,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let body: EditSchemaRequest;\n try {\n body = (await request.json()) as EditSchemaRequest;\n } catch {\n return new Response(JSON.stringify({ error: 'invalid JSON body' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const appId = typeof body.appId === 'string' ? body.appId : '';\n if (!appId) {\n return new Response(JSON.stringify({ error: 'appId is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const patch: EditSchemaPatch | undefined = body.patch;\n if (patch === undefined || patch === null || typeof patch !== 'object') {\n return new Response(JSON.stringify({ error: 'patch is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n try {\n const schema: OrbitalSchema = await client.editSchema(appId, patch);\n return new Response(JSON.stringify(schema), {\n status: 200,\n headers: { 'content-type': 'application/json' },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return new Response(JSON.stringify({ error: message }), {\n status: 500,\n headers: { 'content-type': 'application/json' },\n });\n }\n };\n}\n","/**\n * `@almadar/sdk/server/express` — Express adapter for the Almadar server handlers.\n *\n * Node-only. The consumer must provide their own `express` installation.\n * This module imports express TYPES only; it is never bundled with express itself.\n *\n * Usage:\n * import { createGenerateHandler, createEditHandler } from '@almadar/sdk/server/express';\n * app.post('/api/agent/generate', createGenerateHandler({ apiKey }));\n * app.put('/api/agent/edit', createEditHandler({ apiKey }));\n */\n\nimport type { Request as ExpressRequest, Response as ExpressResponse, RequestHandler } from 'express';\nimport {\n createGenerateHandler as coreGenerateHandler,\n createEditHandler as coreEditHandler,\n} from './index';\n\n// ============================================================================\n// Express-specific option surface\n// ============================================================================\n\nexport interface GenerateHandlerOptions {\n /** API key issued from Studio's /settings/sdk panel. */\n apiKey: string;\n /** Defaults to https://studio.almadar.io. */\n baseUrl?: string;\n /**\n * Derive a stable end-user id from the Express request.\n * Falls back to the `x-user-id` request header when omitted.\n */\n endUserId?: (req: ExpressRequest) => string;\n}\n\n// ============================================================================\n// Express↔Fetch bridge helpers\n// ============================================================================\n\n/**\n * Convert an Express `Request` to a Web-standard `Request`.\n * Re-serialises the already-parsed body so the core handler's `request.json()` succeeds.\n */\nfunction expressReqToWebRequest(req: ExpressRequest): Request {\n const protocol = req.protocol;\n const host = req.get('host') ?? 'localhost';\n const url = `${protocol}://${host}${req.originalUrl}`;\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (typeof value === 'string') {\n headers.set(key, value);\n } else if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n }\n }\n const bodyJson = JSON.stringify(req.body);\n return new Request(url, { method: req.method, headers, body: bodyJson });\n}\n\n/**\n * Write a Web-standard `Response` back to an express `Response`.\n * Streams the body chunk-by-chunk so SSE works without buffering.\n */\nasync function pipeWebResponseToExpress(\n webRes: Response,\n res: ExpressResponse,\n): Promise<void> {\n res.status(webRes.status);\n webRes.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n if (webRes.body === null) {\n res.end();\n return;\n }\n const reader = webRes.body.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } finally {\n reader.releaseLock();\n res.end();\n }\n}\n\n// ============================================================================\n// Exported factories\n// ============================================================================\n\n/**\n * Returns an Express `RequestHandler` that streams a generate call as SSE.\n *\n * Body shape accepted: `{ prompt: string; endUserId?: string; appId?: string }`\n */\nexport function createGenerateHandler(opts: GenerateHandlerOptions): RequestHandler {\n const coreHandler = coreGenerateHandler({\n apiKey: opts.apiKey,\n baseUrl: opts.baseUrl,\n endUserId: opts.endUserId\n ? (webReq: Request) => {\n // The x-user-id header is available on the Web Request; express opts.endUserId\n // receives the original express req via closure — pass the header value as a\n // synthetic express request shaped enough for the callback.\n const userId = webReq.headers.get('x-user-id');\n return userId ?? '';\n }\n : undefined,\n });\n return async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n if (opts.endUserId) {\n const userId = opts.endUserId(req);\n if (userId) req.headers['x-user-id'] = userId;\n }\n const webReq = expressReqToWebRequest(req);\n const webRes = await coreHandler(webReq);\n await pipeWebResponseToExpress(webRes, res);\n };\n}\n\n/**\n * Returns an Express `RequestHandler` that calls `editSchema` and returns JSON.\n *\n * Body shape accepted: `{ appId: string; patch: EditSchemaPatch }`\n */\nexport function createEditHandler(opts: GenerateHandlerOptions): RequestHandler {\n const coreHandler = coreEditHandler({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n return async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n const webReq = expressReqToWebRequest(req);\n const webRes = await coreHandler(webReq);\n await pipeWebResponseToExpress(webRes, res);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/types.ts","../../src/client/errors.ts","../../src/client/sseParser.ts","../../src/client/AlmadarClient.ts","../../src/server/index.ts","../../src/server/express.ts"],"names":["createGenerateHandler","createEditHandler"],"mappings":"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","file":"express.js","sourcesContent":["/**\n * Public SDK types. Canonical schema / payload types come from `@almadar/core`;\n * the SDK adds the HTTP-layer option shapes and re-exports the canonical SSE\n * event union.\n */\n\nimport type { EntityData, EventPayload, OrbitalSchema, SSEEvent } from '@almadar/core';\n\nexport type { EntityData, EventPayload, OrbitalSchema, SSEEvent };\n\n/**\n * Typed request envelope for `createGenerateHandler`.\n * Body shape: `{ prompt: string; endUserId?: string; appId?: string }`\n */\nexport interface GenerateRequest {\n prompt?: string;\n /** Alias accepted alongside `prompt`. */\n message?: string;\n endUserId?: string;\n appId?: string;\n}\n\n/**\n * Typed request envelope for `createEditHandler`.\n * Body shape: `{ appId: string; patch: EditSchemaPatch }`\n */\nexport interface EditSchemaRequest {\n appId?: string;\n patch?: EditSchemaPatch;\n}\n\n/**\n * Server-emitted error envelope. `code` maps to the SDK error subclasses:\n * 4001 → ApiKeyError, 4029 → RateLimitedError, 4040 → CatalogOutOfScopeError,\n * 4041-4045 → PinError, 4060 → AsyncUnsupportedError, 5001 → GenerationFailedError.\n * See `API_ERROR_CODES` for the full code table.\n */\nexport interface ApiErrorBody {\n code: number;\n message: string;\n details?: EventPayload;\n}\n\nexport const CATALOG_MODES = ['extend', 'subset', 'replace'] as const;\nexport type CatalogMode = (typeof CATALOG_MODES)[number];\n\n/**\n * Pin generation to a specific organism (and, when the organism has more than\n * one factory orbital, the orbital to use). `knobs` fills factory config.\n */\nexport interface GeneratePin {\n organism: string;\n /** Required iff the organism has more than one orbital. */\n orbital?: string;\n appName?: string;\n knobs?: Record<string, string | number | boolean>;\n}\n\n/** Which cache tier served the generation — L1 confirmed factory HIT, HIT-fail demote, or free-compose MISS. */\nexport type GenerationTier = 'confirmed' | 'hit' | 'miss';\n\nexport interface GenerateMetaOrganism {\n name: string;\n source: 'factory' | 'free-lolo';\n}\n\nexport interface GenerateMeta {\n tier: GenerationTier;\n organisms: GenerateMetaOrganism[];\n /** Organism names that HIT-failed and were demoted to free-compose. */\n demoted: string[];\n cacheVerdict: { verdict: 'hit' | 'miss'; chosen: string | null } | null;\n durationMs: number;\n}\n\nexport interface GenerationMetaEvent {\n type: 'generation_meta';\n data: GenerateMeta;\n timestamp: number;\n}\n\n/** Canonical SSE events plus the SDK-only `generation_meta` summary event. */\nexport type GenerateStreamEvent = SSEEvent | GenerationMetaEvent;\n\nfunction isGenerateMetaOrganism(value: unknown): value is GenerateMetaOrganism {\n if (value === null || typeof value !== 'object') return false;\n const v = value as { name?: unknown; source?: unknown };\n if (typeof v.name !== 'string') return false;\n return v.source === 'factory' || v.source === 'free-lolo';\n}\n\nfunction isGenerateMetaCacheVerdict(value: unknown): value is GenerateMeta['cacheVerdict'] {\n if (value === null) return true;\n if (typeof value !== 'object') return false;\n const v = value as { verdict?: unknown; chosen?: unknown };\n if (v.verdict !== 'hit' && v.verdict !== 'miss') return false;\n return v.chosen === null || typeof v.chosen === 'string';\n}\n\n/** Runtime guard for the `generation_meta` SSE payload — the zero-cast bridge from JSON. */\nexport function isGenerateMeta(value: unknown): value is GenerateMeta {\n if (value === null || typeof value !== 'object') return false;\n const v = value as {\n tier?: unknown;\n organisms?: unknown;\n demoted?: unknown;\n cacheVerdict?: unknown;\n durationMs?: unknown;\n };\n if (v.tier !== 'confirmed' && v.tier !== 'hit' && v.tier !== 'miss') return false;\n if (!Array.isArray(v.organisms) || !v.organisms.every(isGenerateMetaOrganism)) return false;\n if (!Array.isArray(v.demoted) || !v.demoted.every((d) => typeof d === 'string')) return false;\n if (!isGenerateMetaCacheVerdict(v.cacheVerdict)) return false;\n return typeof v.durationMs === 'number';\n}\n\nexport const API_ERROR_CODES = {\n INVALID_REQUEST: 4000,\n API_KEY: 4001,\n ORIGIN_FORBIDDEN: 4003,\n EDIT_CONFIRM_REQUIRED: 4009,\n RATE_LIMITED: 4029,\n CATALOG_OUT_OF_SCOPE: 4040,\n PIN_UNKNOWN_ORGANISM: 4041,\n PIN_OUT_OF_SCOPE: 4042,\n PIN_CONFLICT: 4043,\n PIN_UNKNOWN_KNOB: 4044,\n PIN_ORBITAL_REQUIRED: 4045,\n ASYNC_UNSUPPORTED: 4060,\n FOCUS_STALE: 4090,\n SERVER: 5000,\n GENERATION_FAILED: 5001,\n RUNTIME: 5002,\n WORKSPACE_OPEN: 5003,\n AI_UNCONFIGURED: 5030,\n} as const;\nexport type ApiErrorCode = (typeof API_ERROR_CODES)[keyof typeof API_ERROR_CODES];\n\n/** `error` event `code` values on the generate SSE stream. */\nexport const STREAM_ERROR_CODES = ['failed', 'runtime', 'workspace_open', 'ai_unconfigured', 'focus_stale'] as const;\nexport type StreamErrorCode = (typeof STREAM_ERROR_CODES)[number];\n\nexport interface GenerateOptions {\n prompt: string;\n endUserId?: string;\n appId?: string;\n /** Streaming callback for canonical SSE events plus the SDK's `generation_meta` summary. */\n onEvent?: (event: GenerateStreamEvent) => void;\n /**\n * The client has no async job surface: passing `true` throws\n * `AsyncUnsupportedError` (code 4060) before any network call is made.\n * For long-running generations use the default streaming mode with `onEvent`.\n */\n async?: boolean;\n /**\n * Agent provider override (e.g. 'deepseek', 'openai').\n * Omit to use the server's default.\n */\n provider?: string;\n /**\n * Agent model override (e.g. 'deepseek-chat').\n * Omit to use the server's default.\n */\n model?: string;\n /**\n * Behavior catalog mode — 'subset' narrows generation to stdAllowList.\n * Server-specific; omit if the agent does not support it.\n */\n catalogMode?: CatalogMode;\n /**\n * Allow-list of std behavior names. Requires a server that supports catalog\n * narrowing (e.g. the builder Rabit/Studio agent).\n */\n stdAllowList?: string[];\n /** Pin generation to a specific organism/orbital instead of free-composing. */\n pin?: GeneratePin;\n}\n\nexport interface GenerateResult {\n schema: OrbitalSchema;\n appId?: string;\n /** Absent for third-party servers built with `createGenerateHandler` that don't emit `generation_meta`. */\n meta?: GenerateMeta;\n}\n\n/**\n * Body of a `PUT /api/v1/agent/edit-schema`. Strictly structural; the SDK\n * does not deep-type the patch — that's the server's job. Field types are\n * `EventPayload`-compatible so callers can't sneak in arbitrary objects.\n */\nexport interface EditSchemaPatch {\n orbital?: string;\n traitOverrides?: EventPayload;\n config?: EventPayload;\n}\n\nexport interface CompileOptions {\n target?: 'express' | 'hono';\n shell?: 'typescript' | 'python' | 'mobile';\n}\n\nexport interface CompileResult {\n downloadUrl: string;\n expiresAt: string;\n}\n\nexport interface AlmadarClientOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof fetch;\n}\n\n/**\n * Props for `<AlmadarApp />` — renders an orbital schema. The runtime mode\n * decides whether effects (persist/fetch/call-service) hit a backend or stay\n * mocked in-browser.\n */\nexport interface AlmadarAppProps {\n schema: OrbitalSchema;\n /**\n * - `static`: pure client-side, no server effects. Use with `data`.\n * - `mock` (default): in-browser fake server, faker-seeded if `data` is undefined.\n * - `server`: real backend at `serverUrl`.\n */\n mode?: 'static' | 'mock' | 'server';\n /** Seed data keyed by entity name (canonical `EntityData` shape). */\n data?: EntityData;\n /** Required when `mode === 'server'`. */\n serverUrl?: string;\n initialPagePath?: string;\n height?: string;\n className?: string;\n /**\n * Tiers of config knobs to surface as auto-derived controls. When provided,\n * a control rail is rendered next to the app. Omit to hide controls.\n * Common values: `['presentation']`, `['presentation', 'domain']`.\n */\n exposedTiers?: string[];\n /** Where to render the auto-derived controls rail. Default: 'right'. */\n controlsPosition?: 'right' | 'bottom';\n /**\n * Explicit override for whether the config-controls rail renders. When\n * omitted, falls back to legacy behavior: `exposedTiers` non-empty and\n * `mode !== 'server'`.\n */\n showControls?: boolean;\n}\n\n/**\n * Props for `<OrbitalConfigPanel />` — low-level control rail used by\n * `<AlmadarApp />` when `exposedTiers` is set.\n */\nexport interface OrbitalConfigPanelProps {\n schema: string | OrbitalSchema;\n exposedTiers?: string[];\n position?: 'right' | 'bottom';\n onSchemaChange?: (schema: OrbitalSchema) => void;\n}\n","/**\n * Typed SDK errors. Server emits a structured `ApiErrorBody`; the HTTP layer\n * maps the `code` to one of these subclasses. Customers `catch` by class.\n */\n\nimport { API_ERROR_CODES, STREAM_ERROR_CODES } from '../types';\nimport type { ApiErrorBody, StreamErrorCode } from '../types';\n\nexport class AlmadarError extends Error {\n readonly code: number;\n readonly details?: ApiErrorBody['details'];\n constructor(body: ApiErrorBody) {\n super(body.message);\n this.name = 'AlmadarError';\n this.code = body.code;\n this.details = body.details;\n }\n}\n\n/** 4001 — invalid, revoked, or missing API key. */\nexport class ApiKeyError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ApiKeyError';\n }\n}\n\n/** 4029 — team cap (feature counter) exceeded. Retry after a billing cycle. */\nexport class RateLimitedError extends AlmadarError {\n readonly retryAfterSeconds?: number;\n constructor(body: ApiErrorBody, retryAfterSeconds?: number) {\n super(body);\n this.name = 'RateLimitedError';\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\n/** 4040 — the team's behavior catalog (subset/replace mode) cannot serve the request. */\nexport class CatalogOutOfScopeError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'CatalogOutOfScopeError';\n }\n}\n\n/** Anything else from the server with a recognized envelope but no specific subclass. */\nexport class ServerError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ServerError';\n }\n}\n\n/** 4041-4045 — pin resolution failed: unknown organism, out-of-scope, conflicting pins, unknown knob, or a missing required orbital. */\nexport class PinError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'PinError';\n }\n}\n\n/** 4060 — `generate({ async: true })` has no server-side job surface; use the default streaming mode instead. */\nexport class AsyncUnsupportedError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'AsyncUnsupportedError';\n }\n}\n\n/** 5001 — generation failed server-side. */\nexport class GenerationFailedError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'GenerationFailedError';\n }\n}\n\nexport function errorFromBody(body: ApiErrorBody): AlmadarError {\n switch (body.code) {\n case API_ERROR_CODES.API_KEY:\n return new ApiKeyError(body);\n case API_ERROR_CODES.RATE_LIMITED:\n return new RateLimitedError(body);\n case API_ERROR_CODES.CATALOG_OUT_OF_SCOPE:\n return new CatalogOutOfScopeError(body);\n case API_ERROR_CODES.PIN_UNKNOWN_ORGANISM:\n case API_ERROR_CODES.PIN_OUT_OF_SCOPE:\n case API_ERROR_CODES.PIN_CONFLICT:\n case API_ERROR_CODES.PIN_UNKNOWN_KNOB:\n case API_ERROR_CODES.PIN_ORBITAL_REQUIRED:\n return new PinError(body);\n case API_ERROR_CODES.ASYNC_UNSUPPORTED:\n return new AsyncUnsupportedError(body);\n case API_ERROR_CODES.GENERATION_FAILED:\n return new GenerationFailedError(body);\n default:\n return new ServerError(body);\n }\n}\n\nfunction isStreamErrorCode(code: string | undefined): code is StreamErrorCode {\n if (code === undefined) return false;\n return STREAM_ERROR_CODES.some((c) => c === code);\n}\n\n/** Maps a `generate` SSE `error` event's `{ error, code }` payload to a typed SDK error. */\nexport function streamErrorFromEvent(data: { error: string; code?: string }): AlmadarError {\n const message = data.error;\n if (!isStreamErrorCode(data.code)) {\n return new ServerError({ code: API_ERROR_CODES.SERVER, message });\n }\n switch (data.code) {\n case 'failed':\n return new GenerationFailedError({ code: API_ERROR_CODES.GENERATION_FAILED, message });\n case 'ai_unconfigured':\n return new ServerError({ code: API_ERROR_CODES.AI_UNCONFIGURED, message });\n case 'workspace_open':\n return new ServerError({ code: API_ERROR_CODES.WORKSPACE_OPEN, message });\n case 'focus_stale':\n return new ServerError({ code: API_ERROR_CODES.FOCUS_STALE, message });\n case 'runtime':\n return new ServerError({ code: API_ERROR_CODES.RUNTIME, message });\n }\n}\n","/**\n * Minimal Server-Sent Events parser. Reads a `ReadableStream<Uint8Array>`\n * (the body of a `fetch` Response) and yields decoded events. Universal:\n * works in browser, Node 18+, Deno, Bun.\n *\n * Spec subset implemented:\n * - `event:` and `data:` fields\n * - dispatch on blank line\n * - newline-tolerant (CRLF + LF)\n * - skips comments (`:`-prefixed lines)\n *\n * Not implemented (we don't need them):\n * - `id:` / `retry:` fields\n * - reconnection / last-event-id\n */\n\nexport interface RawSseEvent {\n /** `event:` field value. Empty string when absent — matches the spec default. */\n event: string;\n /** Concatenated `data:` lines, joined by newlines. */\n data: string;\n}\n\nexport async function* parseSSE(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<RawSseEvent, void, void> {\n const reader = stream.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let currentEvent = '';\n let currentData = '';\n\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let newlineIdx: number;\n while ((newlineIdx = indexOfNewline(buffer)) !== -1) {\n const rawLine = buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + (buffer[newlineIdx] === '\\r' && buffer[newlineIdx + 1] === '\\n' ? 2 : 1));\n\n if (rawLine === '') {\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n currentEvent = '';\n currentData = '';\n }\n continue;\n }\n if (rawLine.startsWith(':')) continue;\n\n const colon = rawLine.indexOf(':');\n const field = colon === -1 ? rawLine : rawLine.slice(0, colon);\n const rawValue = colon === -1 ? '' : rawLine.slice(colon + 1);\n const value2 = rawValue.startsWith(' ') ? rawValue.slice(1) : rawValue;\n\n if (field === 'event') {\n currentEvent = value2;\n } else if (field === 'data') {\n currentData = currentData === '' ? value2 : `${currentData}\\n${value2}`;\n }\n }\n }\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction indexOfNewline(s: string): number {\n for (let i = 0; i < s.length; i += 1) {\n const c = s[i];\n if (c === '\\n' || c === '\\r') return i;\n }\n return -1;\n}\n","/**\n * `AlmadarClient` — server / Node-side HTTP client targeting `/api/v1/agent/*`.\n * Authenticates with a team-bound API key (`sk_*`) issued from\n * Studio's `/settings/sdk` panel. See `docs/Almadar_Studio_SDK.md` §5.\n *\n * Never instantiate this in a browser bundle — `apiKey` must never leave\n * the customer's server.\n */\n\nimport { parseOrbitalSchema, type OrbitalSchema, type SSEEvent } from '@almadar/core';\nimport { API_ERROR_CODES, isGenerateMeta } from '../types';\nimport type {\n AlmadarClientOptions,\n ApiErrorBody,\n CompileOptions,\n CompileResult,\n EditSchemaPatch,\n GenerateMeta,\n GenerateOptions,\n GenerateResult,\n GenerateStreamEvent,\n} from '../types';\nimport { AsyncUnsupportedError, errorFromBody, ServerError, streamErrorFromEvent } from './errors';\nimport { parseSSE } from './sseParser';\n\nconst DEFAULT_BASE_URL = 'https://studio.almadar.io';\n\nexport class AlmadarClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(opts: AlmadarClientOptions) {\n if (!opts.apiKey || typeof opts.apiKey !== 'string') {\n throw new Error('AlmadarClient: opts.apiKey is required');\n }\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (typeof this.fetchImpl !== 'function') {\n throw new Error('AlmadarClient: no fetch available — pass opts.fetch for Node <18');\n }\n }\n\n async generate(input: GenerateOptions): Promise<GenerateResult> {\n if (input.async === true) {\n throw new AsyncUnsupportedError({\n code: API_ERROR_CODES.ASYNC_UNSUPPORTED,\n message: 'AlmadarClient has no async job surface. Omit `async` (or pass false) and consume the streaming response via `onEvent` instead.',\n });\n }\n return this.streamGenerate(input);\n }\n\n async editSchema(appId: string, patch: EditSchemaPatch): Promise<OrbitalSchema> {\n if (!appId) throw new Error('AlmadarClient.editSchema: appId is required');\n const schema = await this.requestJson<OrbitalSchema>('PUT', '/api/v1/agent/edit-schema', {\n appId,\n patch,\n });\n assertString(schema.name, 'OrbitalSchema.name');\n return schema;\n }\n\n async compileToApp(schema: OrbitalSchema, opts?: CompileOptions): Promise<CompileResult> {\n const result = await this.requestJson<CompileResult>('POST', '/api/v1/agent/compile', {\n schema,\n target: opts?.target,\n shell: opts?.shell,\n });\n assertString(result.downloadUrl, 'CompileResult.downloadUrl');\n assertString(result.expiresAt, 'CompileResult.expiresAt');\n return result;\n }\n\n private async streamGenerate(input: GenerateOptions): Promise<GenerateResult> {\n const res = await this.fetchImpl(`${this.baseUrl}/api/v1/agent/generate`, {\n method: 'POST',\n headers: this.headers({ accept: 'text/event-stream', contentType: 'application/json' }, input.endUserId),\n body: JSON.stringify({\n prompt: input.prompt,\n endUserId: input.endUserId,\n appId: input.appId,\n provider: input.provider,\n model: input.model,\n catalogMode: input.catalogMode,\n stdAllowList: input.stdAllowList,\n pin: input.pin,\n }),\n });\n if (!res.ok) throw await this.errorFromResponse(res);\n if (res.body === null) throw new Error('AlmadarClient.generate: server returned no body');\n\n let final: GenerateResult | null = null;\n let meta: GenerateMeta | undefined;\n for await (const raw of parseSSE(res.body)) {\n const event = parseSseEvent(raw.data);\n if (event === null) continue;\n input.onEvent?.(event);\n if (event.type === 'generation_meta') {\n meta = event.data;\n } else if (event.type === 'complete') {\n if (event.data.schema === undefined) {\n throw new ServerError({ code: API_ERROR_CODES.SERVER, message: '`complete` event did not contain a schema' });\n }\n const schema = parseOrbitalSchema(event.data.schema);\n final = { schema, appId: event.data.appId, meta };\n } else if (event.type === 'error') {\n throw streamErrorFromEvent(event.data);\n }\n }\n if (final === null) {\n throw new ServerError({ code: API_ERROR_CODES.SERVER, message: 'SSE stream ended without `complete` event' });\n }\n return final;\n }\n\n private async requestJson<T>(method: string, path: string, body?: object): Promise<T> {\n const isAbsolute = path.startsWith('http://') || path.startsWith('https://');\n const url = isAbsolute ? path : `${this.baseUrl}${path}`;\n const init: RequestInit = {\n method,\n headers: this.headers({\n accept: 'application/json',\n contentType: body !== undefined ? 'application/json' : undefined,\n }),\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await this.fetchImpl(url, init);\n if (!res.ok) throw await this.errorFromResponse(res);\n const text = await res.text();\n if (text === '') {\n throw new ServerError({ code: API_ERROR_CODES.SERVER, message: 'Empty response body' });\n }\n const parsed: T = JSON.parse(text);\n return parsed;\n }\n\n private headers(\n opts: { accept?: string; contentType?: string },\n endUserId?: string,\n ): Record<string, string> {\n const h: Record<string, string> = { authorization: `Bearer ${this.apiKey}` };\n if (opts.accept !== undefined) h['accept'] = opts.accept;\n if (opts.contentType !== undefined) h['content-type'] = opts.contentType;\n if (endUserId !== undefined && endUserId !== '') h['x-end-user-id'] = endUserId;\n return h;\n }\n\n private async errorFromResponse(res: Response): Promise<Error> {\n const text = await res.text();\n let body: ApiErrorBody;\n try {\n const parsed: ApiErrorBody | null = text === '' ? null : JSON.parse(text);\n body = parsed !== null && typeof parsed.code === 'number' && typeof parsed.message === 'string'\n ? parsed\n : {\n code: res.status,\n message: res.statusText !== '' ? res.statusText : 'HTTP error',\n };\n } catch {\n body = { code: res.status, message: text !== '' ? text : res.statusText };\n }\n const retryAfter = res.headers.get('retry-after');\n const err = errorFromBody(body);\n if (err.name === 'RateLimitedError' && retryAfter !== null) {\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n Object.defineProperty(err, 'retryAfterSeconds', { value: seconds, enumerable: true });\n }\n }\n return err;\n }\n}\n\n/**\n * Parse one SSE `data:` line into the `GenerateStreamEvent` union. The server\n * is the trusted emitter, so we validate only the envelope (object with\n * string `type` and numeric `timestamp`) and cast to the canonical `SSEEvent`\n * union — except `generation_meta`, which is SDK-only and goes through the\n * `isGenerateMeta` runtime guard instead of a cast. Malformed lines are ignored.\n */\nfunction parseSseEvent(dataLine: string): GenerateStreamEvent | null {\n if (dataLine === '') return null;\n let payload;\n try {\n payload = JSON.parse(dataLine);\n } catch {\n return null;\n }\n if (payload === null || typeof payload !== 'object' || Array.isArray(payload)) return null;\n if (typeof payload.type !== 'string' || typeof payload.timestamp !== 'number') return null;\n if (payload.type === 'generation_meta') {\n return isGenerateMeta(payload.data)\n ? { type: 'generation_meta', data: payload.data, timestamp: payload.timestamp }\n : null;\n }\n return payload as SSEEvent;\n}\n\nfunction assertString(v: string | undefined, name: string): asserts v is string {\n if (typeof v !== 'string' || v === '') {\n throw new ServerError({ code: API_ERROR_CODES.SERVER, message: `Malformed server response: ${name} is not a string` });\n }\n}\n","/**\n * `@almadar/sdk/server` — Framework-agnostic Web-standard Fetch handlers for\n * the Almadar agent proxy. Node-only; never import from browser or React code.\n *\n * Usage:\n * import { createGenerateHandler, createEditHandler } from '@almadar/sdk/server';\n * const handler = createGenerateHandler({ apiKey: process.env.ALMADAR_API_KEY! });\n * // handler: (request: Request) => Promise<Response>\n *\n * For framework adapters see `@almadar/sdk/server/express` and `@almadar/sdk/server/hono`.\n */\n\nimport type { OrbitalSchema } from '@almadar/core';\nimport { AlmadarClient } from '../client/AlmadarClient';\nimport type { EditSchemaRequest, EditSchemaPatch, GenerateRequest, GenerateStreamEvent, SSEEvent } from '../types';\n\n// ============================================================================\n// Public option surface\n// ============================================================================\n\nexport interface GenerateHandlerOptions {\n /** API key issued from Studio's /settings/sdk panel. */\n apiKey: string;\n /** Defaults to https://studio.almadar.io. */\n baseUrl?: string;\n /**\n * Derive a stable end-user id from the incoming Web Request.\n * Falls back to the `x-user-id` request header when omitted.\n */\n endUserId?: (req: Request) => string;\n}\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\nfunction resolveEndUserId(opts: GenerateHandlerOptions, req: Request): string | undefined {\n if (opts.endUserId) return opts.endUserId(req);\n const header = req.headers.get('x-user-id');\n return typeof header === 'string' && header.length > 0 ? header : undefined;\n}\n\nfunction encodeSseEvent(event: GenerateStreamEvent): string {\n return `data: ${JSON.stringify(event)}\\n\\n`;\n}\n\n// ============================================================================\n// createGenerateHandler\n// ============================================================================\n\n/**\n * Returns a Web-standard Fetch handler that streams a generate call as SSE.\n *\n * Body shape accepted: `{ prompt: string; endUserId?: string; appId?: string }`\n */\nexport function createGenerateHandler(\n opts: GenerateHandlerOptions,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let body: GenerateRequest;\n try {\n body = (await request.json()) as GenerateRequest;\n } catch {\n return new Response(JSON.stringify({ error: 'invalid JSON body' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const rawPrompt = body.prompt ?? body.message;\n const prompt = typeof rawPrompt === 'string' ? rawPrompt : '';\n\n if (!prompt) {\n return new Response(JSON.stringify({ error: 'prompt or message is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const bodyEndUserId = typeof body.endUserId === 'string' ? body.endUserId : undefined;\n const endUserId = bodyEndUserId ?? resolveEndUserId(opts, request);\n const appId = typeof body.appId === 'string' ? body.appId : undefined;\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n const encoder = new TextEncoder();\n try {\n await client.generate({\n prompt,\n endUserId,\n appId,\n onEvent: (event: GenerateStreamEvent) => {\n controller.enqueue(encoder.encode(encodeSseEvent(event)));\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const errorEvent: SSEEvent = {\n type: 'error',\n timestamp: Date.now(),\n data: { error: message },\n };\n controller.enqueue(encoder.encode(encodeSseEvent(errorEvent)));\n } finally {\n controller.close();\n }\n },\n });\n\n return new Response(stream, {\n status: 200,\n headers: {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n },\n });\n };\n}\n\n// ============================================================================\n// createEditHandler\n// ============================================================================\n\n/**\n * Returns a Web-standard Fetch handler that calls `editSchema` and returns JSON.\n *\n * Body shape accepted: `{ appId: string; patch: EditSchemaPatch }`\n */\nexport function createEditHandler(\n opts: GenerateHandlerOptions,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let body: EditSchemaRequest;\n try {\n body = (await request.json()) as EditSchemaRequest;\n } catch {\n return new Response(JSON.stringify({ error: 'invalid JSON body' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const appId = typeof body.appId === 'string' ? body.appId : '';\n if (!appId) {\n return new Response(JSON.stringify({ error: 'appId is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const patch: EditSchemaPatch | undefined = body.patch;\n if (patch === undefined || patch === null || typeof patch !== 'object') {\n return new Response(JSON.stringify({ error: 'patch is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n try {\n const schema: OrbitalSchema = await client.editSchema(appId, patch);\n return new Response(JSON.stringify(schema), {\n status: 200,\n headers: { 'content-type': 'application/json' },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return new Response(JSON.stringify({ error: message }), {\n status: 500,\n headers: { 'content-type': 'application/json' },\n });\n }\n };\n}\n","/**\n * `@almadar/sdk/server/express` — Express adapter for the Almadar server handlers.\n *\n * Node-only. The consumer must provide their own `express` installation.\n * This module imports express TYPES only; it is never bundled with express itself.\n *\n * Usage:\n * import { createGenerateHandler, createEditHandler } from '@almadar/sdk/server/express';\n * app.post('/api/agent/generate', createGenerateHandler({ apiKey }));\n * app.put('/api/agent/edit', createEditHandler({ apiKey }));\n */\n\nimport type { Request as ExpressRequest, Response as ExpressResponse, RequestHandler } from 'express';\nimport {\n createGenerateHandler as coreGenerateHandler,\n createEditHandler as coreEditHandler,\n} from './index';\n\n// ============================================================================\n// Express-specific option surface\n// ============================================================================\n\nexport interface GenerateHandlerOptions {\n /** API key issued from Studio's /settings/sdk panel. */\n apiKey: string;\n /** Defaults to https://studio.almadar.io. */\n baseUrl?: string;\n /**\n * Derive a stable end-user id from the Express request.\n * Falls back to the `x-user-id` request header when omitted.\n */\n endUserId?: (req: ExpressRequest) => string;\n}\n\n// ============================================================================\n// Express↔Fetch bridge helpers\n// ============================================================================\n\n/**\n * Convert an Express `Request` to a Web-standard `Request`.\n * Re-serialises the already-parsed body so the core handler's `request.json()` succeeds.\n */\nfunction expressReqToWebRequest(req: ExpressRequest): Request {\n const protocol = req.protocol;\n const host = req.get('host') ?? 'localhost';\n const url = `${protocol}://${host}${req.originalUrl}`;\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (typeof value === 'string') {\n headers.set(key, value);\n } else if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n }\n }\n const bodyJson = JSON.stringify(req.body);\n return new Request(url, { method: req.method, headers, body: bodyJson });\n}\n\n/**\n * Write a Web-standard `Response` back to an express `Response`.\n * Streams the body chunk-by-chunk so SSE works without buffering.\n */\nasync function pipeWebResponseToExpress(\n webRes: Response,\n res: ExpressResponse,\n): Promise<void> {\n res.status(webRes.status);\n webRes.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n if (webRes.body === null) {\n res.end();\n return;\n }\n const reader = webRes.body.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } finally {\n reader.releaseLock();\n res.end();\n }\n}\n\n// ============================================================================\n// Exported factories\n// ============================================================================\n\n/**\n * Returns an Express `RequestHandler` that streams a generate call as SSE.\n *\n * Body shape accepted: `{ prompt: string; endUserId?: string; appId?: string }`\n */\nexport function createGenerateHandler(opts: GenerateHandlerOptions): RequestHandler {\n const coreHandler = coreGenerateHandler({\n apiKey: opts.apiKey,\n baseUrl: opts.baseUrl,\n endUserId: opts.endUserId\n ? (webReq: Request) => {\n // The x-user-id header is available on the Web Request; express opts.endUserId\n // receives the original express req via closure — pass the header value as a\n // synthetic express request shaped enough for the callback.\n const userId = webReq.headers.get('x-user-id');\n return userId ?? '';\n }\n : undefined,\n });\n return async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n if (opts.endUserId) {\n const userId = opts.endUserId(req);\n if (userId) req.headers['x-user-id'] = userId;\n }\n const webReq = expressReqToWebRequest(req);\n const webRes = await coreHandler(webReq);\n await pipeWebResponseToExpress(webRes, res);\n };\n}\n\n/**\n * Returns an Express `RequestHandler` that calls `editSchema` and returns JSON.\n *\n * Body shape accepted: `{ appId: string; patch: EditSchemaPatch }`\n */\nexport function createEditHandler(opts: GenerateHandlerOptions): RequestHandler {\n const coreHandler = coreEditHandler({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n return async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {\n const webReq = expressReqToWebRequest(req);\n const webRes = await coreHandler(webReq);\n await pipeWebResponseToExpress(webRes, res);\n };\n}\n"]}
|