@agimon-ai/po-core 0.0.0-alpha.114 → 0.0.0-alpha.115

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.
@@ -11,6 +11,10 @@ function createProviderRoutes(options) {
11
11
  runtime: options.runtime
12
12
  });
13
13
  let closed = false;
14
+ const loginResponse = (flow, status = 200) => Response.json({ flow: flow && options.pollIntervalMs !== void 0 ? {
15
+ ...flow,
16
+ pollIntervalMs: options.pollIntervalMs
17
+ } : flow }, { status });
14
18
  return {
15
19
  async fetch(request) {
16
20
  if (closed) return Response.json({ error: "Provider mount is closed." }, { status: 503 });
@@ -27,7 +31,7 @@ function createProviderRoutes(options) {
27
31
  const body = await request.json();
28
32
  if (!record(body) || typeof body.providerId !== "string" || body.type !== "oauth" && body.type !== "api_key") return Response.json({ error: "A provider and supported login method are required." }, { status: 400 });
29
33
  const result = await auth.startLogin(body.providerId, body.type, options.remote);
30
- return result.ok ? Response.json({ flow: result.flow }, { status: 201 }) : Response.json({ error: result.error }, { status: result.code === "unknown_provider" ? 404 : result.code === "busy" ? 409 : 400 });
34
+ return result.ok ? loginResponse(result.flow, 201) : Response.json({ error: result.error }, { status: result.code === "unknown_provider" ? 404 : result.code === "busy" ? 409 : 400 });
31
35
  }
32
36
  const flow = /^\/logins\/([^/]+)(\/answer)?$/u.exec(url.pathname);
33
37
  if (flow) {
@@ -36,10 +40,10 @@ function createProviderRoutes(options) {
36
40
  if (flow[2] && request.method === "POST") {
37
41
  const body = await request.json();
38
42
  if (!record(body) || typeof body.promptId !== "string" || typeof body.value !== "string") return Response.json({ error: "A prompt ID and answer are required." }, { status: 400 });
39
- return auth.answerLogin(id, body.promptId, body.value) === "answered" ? Response.json({ flow: auth.getLogin(id) }) : Response.json({ error: "Login is no longer waiting for this answer." }, { status: 409 });
43
+ return auth.answerLogin(id, body.promptId, body.value) === "answered" ? loginResponse(auth.getLogin(id)) : Response.json({ error: "Login is no longer waiting for this answer." }, { status: 409 });
40
44
  }
41
- if (!flow[2] && request.method === "GET") return Response.json({ flow: auth.getLogin(id) });
42
- if (!flow[2] && request.method === "DELETE") return Response.json({ flow: auth.cancelLogin(id) });
45
+ if (!flow[2] && request.method === "GET") return loginResponse(auth.getLogin(id));
46
+ if (!flow[2] && request.method === "DELETE") return loginResponse(auth.cancelLogin(id));
43
47
  }
44
48
  return Response.json({ error: "Provider route not found." }, { status: 404 });
45
49
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"providerRoutes.cjs","names":["createProviderAuth"],"sources":["../../../src/server/providerRoutes.ts"],"sourcesContent":["import type { PoApiHandler } from '../exports/packageApi';\nimport { createProviderAuth } from '../services/providerAuth';\nimport type { AuthRuntime } from '../types/server/auth';\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport interface ProviderRoutesOptions {\n /** The runtime holding this target's credentials: Pi's auth.json on Node, the org owner when hosted. */\n readonly runtime: () => Promise<AuthRuntime>;\n readonly onChange?: () => void;\n readonly onNotice: (message: string) => void;\n /** Every browser driving a login is on another machine (hosted Po), so redirect-free methods win. */\n readonly remote?: boolean;\n}\n\n/** The providers settings routes, `/providers`, `/models` and `/logins`, over any credential runtime. */\nexport function createProviderRoutes(options: ProviderRoutesOptions): PoApiHandler {\n const auth = createProviderAuth({\n ...(options.onChange ? { onChange: options.onChange } : {}),\n onNotice: options.onNotice,\n runtime: options.runtime,\n });\n let closed = false;\n return {\n async fetch(request) {\n if (closed) return Response.json({ error: 'Provider mount is closed.' }, { status: 503 });\n const url = new URL(request.url);\n try {\n if (url.pathname === '/providers' && request.method === 'GET')\n return Response.json({ providers: await auth.listProviders() });\n if (url.pathname === '/models' && request.method === 'GET')\n return Response.json({ models: await auth.listModels() });\n const provider = /^\\/providers\\/([^/]+)$/u.exec(url.pathname);\n if (provider && request.method === 'DELETE') {\n const result = await auth.logout(decodeURIComponent(provider[1]));\n return result.ok\n ? Response.json({ ok: true })\n : Response.json({ error: result.error }, { status: result.code === 'unknown_provider' ? 404 : 502 });\n }\n if (url.pathname === '/logins' && request.method === 'POST') {\n const body: unknown = await request.json();\n if (\n !record(body) ||\n typeof body.providerId !== 'string' ||\n (body.type !== 'oauth' && body.type !== 'api_key')\n )\n return Response.json({ error: 'A provider and supported login method are required.' }, { status: 400 });\n const result = await auth.startLogin(body.providerId, body.type, options.remote);\n return result.ok\n ? Response.json({ flow: result.flow }, { status: 201 })\n : Response.json(\n { error: result.error },\n { status: result.code === 'unknown_provider' ? 404 : result.code === 'busy' ? 409 : 400 },\n );\n }\n const flow = /^\\/logins\\/([^/]+)(\\/answer)?$/u.exec(url.pathname);\n if (flow) {\n const id = decodeURIComponent(flow[1]);\n if (!auth.getLogin(id)) return Response.json({ error: 'Login flow not found.' }, { status: 404 });\n if (flow[2] && request.method === 'POST') {\n const body: unknown = await request.json();\n if (!record(body) || typeof body.promptId !== 'string' || typeof body.value !== 'string')\n return Response.json({ error: 'A prompt ID and answer are required.' }, { status: 400 });\n const answer = auth.answerLogin(id, body.promptId, body.value);\n return answer === 'answered'\n ? Response.json({ flow: auth.getLogin(id) })\n : Response.json({ error: 'Login is no longer waiting for this answer.' }, { status: 409 });\n }\n if (!flow[2] && request.method === 'GET') return Response.json({ flow: auth.getLogin(id) });\n if (!flow[2] && request.method === 'DELETE') return Response.json({ flow: auth.cancelLogin(id) });\n }\n return Response.json({ error: 'Provider route not found.' }, { status: 404 });\n } catch (error) {\n return Response.json(\n { error: error instanceof Error ? error.message : String(error) },\n { status: error instanceof SyntaxError ? 400 : 502 },\n );\n }\n },\n close() {\n closed = true;\n auth.close();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"providerRoutes.cjs","names":["createProviderAuth"],"sources":["../../../src/server/providerRoutes.ts"],"sourcesContent":["import type { PoApiHandler } from '../exports/packageApi';\nimport { createProviderAuth } from '../services/providerAuth';\nimport type { AuthRuntime, LoginFlowSnapshot } from '../types/server/auth';\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport interface ProviderRoutesOptions {\n /** The runtime holding this target's credentials: Pi's auth.json on Node, the org owner when hosted. */\n readonly runtime: () => Promise<AuthRuntime>;\n readonly onChange?: () => void;\n readonly onNotice: (message: string) => void;\n /** Every browser driving a login is on another machine (hosted Po), so redirect-free methods win. */\n readonly remote?: boolean;\n /** Admitted by an HTTP-only host that cannot push provider revisions to its browser. */\n readonly pollIntervalMs?: number;\n}\n\n/** The providers settings routes, `/providers`, `/models` and `/logins`, over any credential runtime. */\nexport function createProviderRoutes(options: ProviderRoutesOptions): PoApiHandler {\n const auth = createProviderAuth({\n ...(options.onChange ? { onChange: options.onChange } : {}),\n onNotice: options.onNotice,\n runtime: options.runtime,\n });\n let closed = false;\n const loginResponse = (flow: LoginFlowSnapshot | undefined, status = 200): Response =>\n Response.json(\n {\n flow: flow && options.pollIntervalMs !== undefined ? { ...flow, pollIntervalMs: options.pollIntervalMs } : flow,\n },\n { status },\n );\n return {\n async fetch(request) {\n if (closed) return Response.json({ error: 'Provider mount is closed.' }, { status: 503 });\n const url = new URL(request.url);\n try {\n if (url.pathname === '/providers' && request.method === 'GET')\n return Response.json({ providers: await auth.listProviders() });\n if (url.pathname === '/models' && request.method === 'GET')\n return Response.json({ models: await auth.listModels() });\n const provider = /^\\/providers\\/([^/]+)$/u.exec(url.pathname);\n if (provider && request.method === 'DELETE') {\n const result = await auth.logout(decodeURIComponent(provider[1]));\n return result.ok\n ? Response.json({ ok: true })\n : Response.json({ error: result.error }, { status: result.code === 'unknown_provider' ? 404 : 502 });\n }\n if (url.pathname === '/logins' && request.method === 'POST') {\n const body: unknown = await request.json();\n if (\n !record(body) ||\n typeof body.providerId !== 'string' ||\n (body.type !== 'oauth' && body.type !== 'api_key')\n )\n return Response.json({ error: 'A provider and supported login method are required.' }, { status: 400 });\n const result = await auth.startLogin(body.providerId, body.type, options.remote);\n return result.ok\n ? loginResponse(result.flow, 201)\n : Response.json(\n { error: result.error },\n { status: result.code === 'unknown_provider' ? 404 : result.code === 'busy' ? 409 : 400 },\n );\n }\n const flow = /^\\/logins\\/([^/]+)(\\/answer)?$/u.exec(url.pathname);\n if (flow) {\n const id = decodeURIComponent(flow[1]);\n if (!auth.getLogin(id)) return Response.json({ error: 'Login flow not found.' }, { status: 404 });\n if (flow[2] && request.method === 'POST') {\n const body: unknown = await request.json();\n if (!record(body) || typeof body.promptId !== 'string' || typeof body.value !== 'string')\n return Response.json({ error: 'A prompt ID and answer are required.' }, { status: 400 });\n const answer = auth.answerLogin(id, body.promptId, body.value);\n return answer === 'answered'\n ? loginResponse(auth.getLogin(id))\n : Response.json({ error: 'Login is no longer waiting for this answer.' }, { status: 409 });\n }\n if (!flow[2] && request.method === 'GET') return loginResponse(auth.getLogin(id));\n if (!flow[2] && request.method === 'DELETE') return loginResponse(auth.cancelLogin(id));\n }\n return Response.json({ error: 'Provider route not found.' }, { status: 404 });\n } catch (error) {\n return Response.json(\n { error: error instanceof Error ? error.message : String(error) },\n { status: error instanceof SyntaxError ? 400 : 502 },\n );\n }\n },\n close() {\n closed = true;\n auth.close();\n },\n };\n}\n"],"mappings":"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"}
@@ -9,6 +9,8 @@ export interface ProviderRoutesOptions {
9
9
  readonly onNotice: (message: string) => void;
10
10
  /** Every browser driving a login is on another machine (hosted Po), so redirect-free methods win. */
11
11
  readonly remote?: boolean;
12
+ /** Admitted by an HTTP-only host that cannot push provider revisions to its browser. */
13
+ readonly pollIntervalMs?: number;
12
14
  }
13
15
  /** The providers settings routes, `/providers`, `/models` and `/logins`, over any credential runtime. */
14
16
  export declare function createProviderRoutes(options: ProviderRoutesOptions): PoApiHandler;
@@ -1 +1 @@
1
- {"version":3,"file":"providerRoutes.d.mts","names":[],"sources":["../../../src/server/providerRoutes.ts"],"mappings":";;;;iBAQiB;;WAEN,eAAe,QAAQ;WACvB;WACA,WAAW;;WAEX;;;wBAIK,qBAAqB,SAAS,wBAAwB"}
1
+ {"version":3,"file":"providerRoutes.d.mts","names":[],"sources":["../../../src/server/providerRoutes.ts"],"mappings":";;;;iBAQiB;;WAEN,eAAe,QAAQ;WACvB;WACA,WAAW;;WAEX;;WAEA;;;wBAIK,qBAAqB,SAAS,wBAAwB"}
@@ -11,6 +11,10 @@ function createProviderRoutes(options) {
11
11
  runtime: options.runtime
12
12
  });
13
13
  let closed = false;
14
+ const loginResponse = (flow, status = 200) => Response.json({ flow: flow && options.pollIntervalMs !== void 0 ? {
15
+ ...flow,
16
+ pollIntervalMs: options.pollIntervalMs
17
+ } : flow }, { status });
14
18
  return {
15
19
  async fetch(request) {
16
20
  if (closed) return Response.json({ error: "Provider mount is closed." }, { status: 503 });
@@ -27,7 +31,7 @@ function createProviderRoutes(options) {
27
31
  const body = await request.json();
28
32
  if (!record(body) || typeof body.providerId !== "string" || body.type !== "oauth" && body.type !== "api_key") return Response.json({ error: "A provider and supported login method are required." }, { status: 400 });
29
33
  const result = await auth.startLogin(body.providerId, body.type, options.remote);
30
- return result.ok ? Response.json({ flow: result.flow }, { status: 201 }) : Response.json({ error: result.error }, { status: result.code === "unknown_provider" ? 404 : result.code === "busy" ? 409 : 400 });
34
+ return result.ok ? loginResponse(result.flow, 201) : Response.json({ error: result.error }, { status: result.code === "unknown_provider" ? 404 : result.code === "busy" ? 409 : 400 });
31
35
  }
32
36
  const flow = /^\/logins\/([^/]+)(\/answer)?$/u.exec(url.pathname);
33
37
  if (flow) {
@@ -36,10 +40,10 @@ function createProviderRoutes(options) {
36
40
  if (flow[2] && request.method === "POST") {
37
41
  const body = await request.json();
38
42
  if (!record(body) || typeof body.promptId !== "string" || typeof body.value !== "string") return Response.json({ error: "A prompt ID and answer are required." }, { status: 400 });
39
- return auth.answerLogin(id, body.promptId, body.value) === "answered" ? Response.json({ flow: auth.getLogin(id) }) : Response.json({ error: "Login is no longer waiting for this answer." }, { status: 409 });
43
+ return auth.answerLogin(id, body.promptId, body.value) === "answered" ? loginResponse(auth.getLogin(id)) : Response.json({ error: "Login is no longer waiting for this answer." }, { status: 409 });
40
44
  }
41
- if (!flow[2] && request.method === "GET") return Response.json({ flow: auth.getLogin(id) });
42
- if (!flow[2] && request.method === "DELETE") return Response.json({ flow: auth.cancelLogin(id) });
45
+ if (!flow[2] && request.method === "GET") return loginResponse(auth.getLogin(id));
46
+ if (!flow[2] && request.method === "DELETE") return loginResponse(auth.cancelLogin(id));
43
47
  }
44
48
  return Response.json({ error: "Provider route not found." }, { status: 404 });
45
49
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"providerRoutes.mjs","names":[],"sources":["../../../src/server/providerRoutes.ts"],"sourcesContent":["import type { PoApiHandler } from '../exports/packageApi';\nimport { createProviderAuth } from '../services/providerAuth';\nimport type { AuthRuntime } from '../types/server/auth';\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport interface ProviderRoutesOptions {\n /** The runtime holding this target's credentials: Pi's auth.json on Node, the org owner when hosted. */\n readonly runtime: () => Promise<AuthRuntime>;\n readonly onChange?: () => void;\n readonly onNotice: (message: string) => void;\n /** Every browser driving a login is on another machine (hosted Po), so redirect-free methods win. */\n readonly remote?: boolean;\n}\n\n/** The providers settings routes, `/providers`, `/models` and `/logins`, over any credential runtime. */\nexport function createProviderRoutes(options: ProviderRoutesOptions): PoApiHandler {\n const auth = createProviderAuth({\n ...(options.onChange ? { onChange: options.onChange } : {}),\n onNotice: options.onNotice,\n runtime: options.runtime,\n });\n let closed = false;\n return {\n async fetch(request) {\n if (closed) return Response.json({ error: 'Provider mount is closed.' }, { status: 503 });\n const url = new URL(request.url);\n try {\n if (url.pathname === '/providers' && request.method === 'GET')\n return Response.json({ providers: await auth.listProviders() });\n if (url.pathname === '/models' && request.method === 'GET')\n return Response.json({ models: await auth.listModels() });\n const provider = /^\\/providers\\/([^/]+)$/u.exec(url.pathname);\n if (provider && request.method === 'DELETE') {\n const result = await auth.logout(decodeURIComponent(provider[1]));\n return result.ok\n ? Response.json({ ok: true })\n : Response.json({ error: result.error }, { status: result.code === 'unknown_provider' ? 404 : 502 });\n }\n if (url.pathname === '/logins' && request.method === 'POST') {\n const body: unknown = await request.json();\n if (\n !record(body) ||\n typeof body.providerId !== 'string' ||\n (body.type !== 'oauth' && body.type !== 'api_key')\n )\n return Response.json({ error: 'A provider and supported login method are required.' }, { status: 400 });\n const result = await auth.startLogin(body.providerId, body.type, options.remote);\n return result.ok\n ? Response.json({ flow: result.flow }, { status: 201 })\n : Response.json(\n { error: result.error },\n { status: result.code === 'unknown_provider' ? 404 : result.code === 'busy' ? 409 : 400 },\n );\n }\n const flow = /^\\/logins\\/([^/]+)(\\/answer)?$/u.exec(url.pathname);\n if (flow) {\n const id = decodeURIComponent(flow[1]);\n if (!auth.getLogin(id)) return Response.json({ error: 'Login flow not found.' }, { status: 404 });\n if (flow[2] && request.method === 'POST') {\n const body: unknown = await request.json();\n if (!record(body) || typeof body.promptId !== 'string' || typeof body.value !== 'string')\n return Response.json({ error: 'A prompt ID and answer are required.' }, { status: 400 });\n const answer = auth.answerLogin(id, body.promptId, body.value);\n return answer === 'answered'\n ? Response.json({ flow: auth.getLogin(id) })\n : Response.json({ error: 'Login is no longer waiting for this answer.' }, { status: 409 });\n }\n if (!flow[2] && request.method === 'GET') return Response.json({ flow: auth.getLogin(id) });\n if (!flow[2] && request.method === 'DELETE') return Response.json({ flow: auth.cancelLogin(id) });\n }\n return Response.json({ error: 'Provider route not found.' }, { status: 404 });\n } catch (error) {\n return Response.json(\n { error: error instanceof Error ? error.message : String(error) },\n { status: error instanceof SyntaxError ? 400 : 502 },\n );\n }\n },\n close() {\n closed = true;\n auth.close();\n },\n };\n}\n"],"mappings":";;AAIA,SAAS,OAAO,OAAkD;CAChE,OAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;;AAYA,SAAgB,qBAAqB,SAA8C;CACjF,MAAM,OAAO,mBAAmB;EAC9B,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;EACzD,UAAU,QAAQ;EAClB,SAAS,QAAQ;CACnB,CAAC;CACD,IAAI,SAAS;CACb,OAAO;EACL,MAAM,MAAM,SAAS;GACnB,IAAI,QAAQ,OAAO,SAAS,KAAK,EAAE,OAAO,4BAA4B,GAAG,EAAE,QAAQ,IAAI,CAAC;GACxF,MAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;GAC/B,IAAI;IACF,IAAI,IAAI,aAAa,gBAAgB,QAAQ,WAAW,OACtD,OAAO,SAAS,KAAK,EAAE,WAAW,MAAM,KAAK,cAAc,EAAE,CAAC;IAChE,IAAI,IAAI,aAAa,aAAa,QAAQ,WAAW,OACnD,OAAO,SAAS,KAAK,EAAE,QAAQ,MAAM,KAAK,WAAW,EAAE,CAAC;IAC1D,MAAM,WAAW,0BAA0B,KAAK,IAAI,QAAQ;IAC5D,IAAI,YAAY,QAAQ,WAAW,UAAU;KAC3C,MAAM,SAAS,MAAM,KAAK,OAAO,mBAAmB,SAAS,EAAE,CAAC;KAChE,OAAO,OAAO,KACV,SAAS,KAAK,EAAE,IAAI,KAAK,CAAC,IAC1B,SAAS,KAAK,EAAE,OAAO,OAAO,MAAM,GAAG,EAAE,QAAQ,OAAO,SAAS,qBAAqB,MAAM,IAAI,CAAC;IACvG;IACA,IAAI,IAAI,aAAa,aAAa,QAAQ,WAAW,QAAQ;KAC3D,MAAM,OAAgB,MAAM,QAAQ,KAAK;KACzC,IACE,CAAC,OAAO,IAAI,KACZ,OAAO,KAAK,eAAe,YAC1B,KAAK,SAAS,WAAW,KAAK,SAAS,WAExC,OAAO,SAAS,KAAK,EAAE,OAAO,sDAAsD,GAAG,EAAE,QAAQ,IAAI,CAAC;KACxG,MAAM,SAAS,MAAM,KAAK,WAAW,KAAK,YAAY,KAAK,MAAM,QAAQ,MAAM;KAC/E,OAAO,OAAO,KACV,SAAS,KAAK,EAAE,MAAM,OAAO,KAAK,GAAG,EAAE,QAAQ,IAAI,CAAC,IACpD,SAAS,KACP,EAAE,OAAO,OAAO,MAAM,GACtB,EAAE,QAAQ,OAAO,SAAS,qBAAqB,MAAM,OAAO,SAAS,SAAS,MAAM,IAAI,CAC1F;IACN;IACA,MAAM,OAAO,kCAAkC,KAAK,IAAI,QAAQ;IAChE,IAAI,MAAM;KACR,MAAM,KAAK,mBAAmB,KAAK,EAAE;KACrC,IAAI,CAAC,KAAK,SAAS,EAAE,GAAG,OAAO,SAAS,KAAK,EAAE,OAAO,wBAAwB,GAAG,EAAE,QAAQ,IAAI,CAAC;KAChG,IAAI,KAAK,MAAM,QAAQ,WAAW,QAAQ;MACxC,MAAM,OAAgB,MAAM,QAAQ,KAAK;MACzC,IAAI,CAAC,OAAO,IAAI,KAAK,OAAO,KAAK,aAAa,YAAY,OAAO,KAAK,UAAU,UAC9E,OAAO,SAAS,KAAK,EAAE,OAAO,uCAAuC,GAAG,EAAE,QAAQ,IAAI,CAAC;MAEzF,OADe,KAAK,YAAY,IAAI,KAAK,UAAU,KAAK,KAC5C,MAAM,aACd,SAAS,KAAK,EAAE,MAAM,KAAK,SAAS,EAAE,EAAE,CAAC,IACzC,SAAS,KAAK,EAAE,OAAO,8CAA8C,GAAG,EAAE,QAAQ,IAAI,CAAC;KAC7F;KACA,IAAI,CAAC,KAAK,MAAM,QAAQ,WAAW,OAAO,OAAO,SAAS,KAAK,EAAE,MAAM,KAAK,SAAS,EAAE,EAAE,CAAC;KAC1F,IAAI,CAAC,KAAK,MAAM,QAAQ,WAAW,UAAU,OAAO,SAAS,KAAK,EAAE,MAAM,KAAK,YAAY,EAAE,EAAE,CAAC;IAClG;IACA,OAAO,SAAS,KAAK,EAAE,OAAO,4BAA4B,GAAG,EAAE,QAAQ,IAAI,CAAC;GAC9E,SAAS,OAAO;IACd,OAAO,SAAS,KACd,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GAChE,EAAE,QAAQ,iBAAiB,cAAc,MAAM,IAAI,CACrD;GACF;EACF;EACA,QAAQ;GACN,SAAS;GACT,KAAK,MAAM;EACb;CACF;AACF"}
1
+ {"version":3,"file":"providerRoutes.mjs","names":[],"sources":["../../../src/server/providerRoutes.ts"],"sourcesContent":["import type { PoApiHandler } from '../exports/packageApi';\nimport { createProviderAuth } from '../services/providerAuth';\nimport type { AuthRuntime, LoginFlowSnapshot } from '../types/server/auth';\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport interface ProviderRoutesOptions {\n /** The runtime holding this target's credentials: Pi's auth.json on Node, the org owner when hosted. */\n readonly runtime: () => Promise<AuthRuntime>;\n readonly onChange?: () => void;\n readonly onNotice: (message: string) => void;\n /** Every browser driving a login is on another machine (hosted Po), so redirect-free methods win. */\n readonly remote?: boolean;\n /** Admitted by an HTTP-only host that cannot push provider revisions to its browser. */\n readonly pollIntervalMs?: number;\n}\n\n/** The providers settings routes, `/providers`, `/models` and `/logins`, over any credential runtime. */\nexport function createProviderRoutes(options: ProviderRoutesOptions): PoApiHandler {\n const auth = createProviderAuth({\n ...(options.onChange ? { onChange: options.onChange } : {}),\n onNotice: options.onNotice,\n runtime: options.runtime,\n });\n let closed = false;\n const loginResponse = (flow: LoginFlowSnapshot | undefined, status = 200): Response =>\n Response.json(\n {\n flow: flow && options.pollIntervalMs !== undefined ? { ...flow, pollIntervalMs: options.pollIntervalMs } : flow,\n },\n { status },\n );\n return {\n async fetch(request) {\n if (closed) return Response.json({ error: 'Provider mount is closed.' }, { status: 503 });\n const url = new URL(request.url);\n try {\n if (url.pathname === '/providers' && request.method === 'GET')\n return Response.json({ providers: await auth.listProviders() });\n if (url.pathname === '/models' && request.method === 'GET')\n return Response.json({ models: await auth.listModels() });\n const provider = /^\\/providers\\/([^/]+)$/u.exec(url.pathname);\n if (provider && request.method === 'DELETE') {\n const result = await auth.logout(decodeURIComponent(provider[1]));\n return result.ok\n ? Response.json({ ok: true })\n : Response.json({ error: result.error }, { status: result.code === 'unknown_provider' ? 404 : 502 });\n }\n if (url.pathname === '/logins' && request.method === 'POST') {\n const body: unknown = await request.json();\n if (\n !record(body) ||\n typeof body.providerId !== 'string' ||\n (body.type !== 'oauth' && body.type !== 'api_key')\n )\n return Response.json({ error: 'A provider and supported login method are required.' }, { status: 400 });\n const result = await auth.startLogin(body.providerId, body.type, options.remote);\n return result.ok\n ? loginResponse(result.flow, 201)\n : Response.json(\n { error: result.error },\n { status: result.code === 'unknown_provider' ? 404 : result.code === 'busy' ? 409 : 400 },\n );\n }\n const flow = /^\\/logins\\/([^/]+)(\\/answer)?$/u.exec(url.pathname);\n if (flow) {\n const id = decodeURIComponent(flow[1]);\n if (!auth.getLogin(id)) return Response.json({ error: 'Login flow not found.' }, { status: 404 });\n if (flow[2] && request.method === 'POST') {\n const body: unknown = await request.json();\n if (!record(body) || typeof body.promptId !== 'string' || typeof body.value !== 'string')\n return Response.json({ error: 'A prompt ID and answer are required.' }, { status: 400 });\n const answer = auth.answerLogin(id, body.promptId, body.value);\n return answer === 'answered'\n ? loginResponse(auth.getLogin(id))\n : Response.json({ error: 'Login is no longer waiting for this answer.' }, { status: 409 });\n }\n if (!flow[2] && request.method === 'GET') return loginResponse(auth.getLogin(id));\n if (!flow[2] && request.method === 'DELETE') return loginResponse(auth.cancelLogin(id));\n }\n return Response.json({ error: 'Provider route not found.' }, { status: 404 });\n } catch (error) {\n return Response.json(\n { error: error instanceof Error ? error.message : String(error) },\n { status: error instanceof SyntaxError ? 400 : 502 },\n );\n }\n },\n close() {\n closed = true;\n auth.close();\n },\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.mts","names":[],"sources":["../../../../src/types/server/auth.ts"],"mappings":";YAAY;iBAsBK;EACf;EACA;EACA;;;YAIU;EAAgB,SAAS;;EAC/B;EAAc;EAAiB;;EAC/B;EAAgB;EAAiB;;EACjC;EAAgB;EAAiB,kBAAkB;;EACnD;EAAqB;EAAiB;;;YAchC;EACN;EAAc;EAAiB;IAAmB;IAAa;;;EAC/D;EAAkB;EAAa;;EAE/B;EACA;EACA;EACA;EACA;;EAEA;EAAkB;;;iBAwBP;EACf,QAAQ;EACR,OAAO,QAAQ,cAAc;EAC7B,OAAO,OAAO;;iBAGC;WACN;WACA;WACA;;IAEP;MAAW;MAAc;;IACzB;MAAU;MAAc;;;;;;;;iBAQX;EACf,yBAAyB;EACzB,sBAAsB;IAAuB;IAAqB;IAAiB;;;EAEnF;IAAmC;IAAkB;;EACrD,kBAAkB;EAClB,aAAa;;EAEb,QAAQ;IAAW;MAA0B;EAC7C,MAAM,oBAAoB,MAAM,gBAAgB,aAAa,mBAAmB;EAChF,OAAO,oBAAoB;IAAY,SAAS;MAAgB"}
1
+ {"version":3,"file":"auth.d.mts","names":[],"sources":["../../../../src/types/server/auth.ts"],"mappings":";YAAY;iBAsBK;EACf;EACA;EACA;;;YAIU;EAAgB,SAAS;;EAC/B;EAAc;EAAiB;;EAC/B;EAAgB;EAAiB;;EACjC;EAAgB;EAAiB,kBAAkB;;EACnD;EAAqB;EAAiB;;;YAchC;EACN;EAAc;EAAiB;IAAmB;IAAa;;;EAC/D;EAAkB;EAAa;;EAE/B;EACA;EACA;EACA;EACA;;EAEA;EAAkB;;;iBA0BP;EACf,QAAQ;EACR,OAAO,QAAQ,cAAc;EAC7B,OAAO,OAAO;;iBAGC;WACN;WACA;WACA;;IAEP;MAAW;MAAc;;IACzB;MAAU;MAAc;;;;;;;;iBAQX;EACf,yBAAyB;EACzB,sBAAsB;IAAuB;IAAqB;IAAiB;;;EAEnF;IAAmC;IAAkB;;EACrD,kBAAkB;EAClB,aAAa;;EAEb,QAAQ;IAAW;MAA0B;EAC7C,MAAM,oBAAoB,MAAM,gBAAgB,aAAa,mBAAmB;EAChF,OAAO,oBAAoB;IAAY,SAAS;MAAgB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-core",
3
- "version": "0.0.0-alpha.114",
3
+ "version": "0.0.0-alpha.115",
4
4
  "description": "Po runtime systems and reusable core services.",
5
5
  "keywords": [
6
6
  "ai",
@@ -609,8 +609,8 @@
609
609
  "registry": "https://registry.npmjs.org/"
610
610
  },
611
611
  "dependencies": {
612
- "@agimon-ai/po-logsink": "0.0.1-alpha.96",
613
- "@agimon-ai/po-web-security": "0.0.0-alpha.114",
612
+ "@agimon-ai/po-logsink": "0.0.1-alpha.97",
613
+ "@agimon-ai/po-web-security": "0.0.0-alpha.115",
614
614
  "@deepseek-ai/cordis": "4.0.5",
615
615
  "@earendil-works/chord": "1.5.0",
616
616
  "@earendil-works/pi-agent-core": "1.5.0",
@@ -636,7 +636,7 @@
636
636
  "yaml": "2.9.1"
637
637
  },
638
638
  "devDependencies": {
639
- "@agimon-ai/vibe-lint-plugin-po-core": "0.0.0-alpha.114",
639
+ "@agimon-ai/vibe-lint-plugin-po-core": "0.0.0-alpha.115",
640
640
  "@apidevtools/swagger-parser": "^13.1.0",
641
641
  "@asyncapi/parser": "^3.6.4",
642
642
  "@earendil-works/pi-ai": "1.5.0",