@fayz-ai/sdk 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/dist/automations.d.ts +94 -0
  3. package/dist/automations.d.ts.map +1 -0
  4. package/dist/automations.js +61 -0
  5. package/dist/automations.js.map +1 -0
  6. package/dist/{chunk-7UXTYT6I.js → chunk-4YRHC5N7.js} +490 -31
  7. package/dist/chunk-4YRHC5N7.js.map +1 -0
  8. package/dist/chunk-7TTGX2SM.js +135 -0
  9. package/dist/chunk-7TTGX2SM.js.map +1 -0
  10. package/dist/events.d.ts +48 -0
  11. package/dist/events.d.ts.map +1 -0
  12. package/dist/events.js +101 -0
  13. package/dist/events.js.map +1 -0
  14. package/dist/index.d.ts +8 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +307 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/lib/app-shell-pwa.d.ts +13 -0
  19. package/dist/lib/app-shell-pwa.d.ts.map +1 -0
  20. package/dist/lib/boot-skeleton.d.ts +33 -0
  21. package/dist/lib/boot-skeleton.d.ts.map +1 -0
  22. package/dist/lib/connector-oauth.d.ts +118 -0
  23. package/dist/lib/connector-oauth.d.ts.map +1 -0
  24. package/dist/lib/credentials.d.ts +98 -0
  25. package/dist/lib/credentials.d.ts.map +1 -0
  26. package/dist/lib/dedupe-fetch.d.ts +26 -0
  27. package/dist/lib/dedupe-fetch.d.ts.map +1 -0
  28. package/dist/lib/platform-url.d.ts +15 -0
  29. package/dist/lib/platform-url.d.ts.map +1 -0
  30. package/dist/lib/runtime-token.d.ts +104 -0
  31. package/dist/lib/runtime-token.d.ts.map +1 -0
  32. package/dist/release-channels.js +1 -1
  33. package/dist/release-channels.json +93 -93
  34. package/dist/shop.d.ts +381 -11
  35. package/dist/shop.d.ts.map +1 -1
  36. package/dist/shop.js +1 -1
  37. package/dist/vite.d.ts +19 -0
  38. package/dist/vite.d.ts.map +1 -1
  39. package/dist/vite.js +374 -47
  40. package/dist/vite.js.map +1 -1
  41. package/package.json +9 -1
  42. package/dist/chunk-7UXTYT6I.js.map +0 -1
  43. package/dist/chunk-KVMRRT3O.js +0 -135
  44. package/dist/chunk-KVMRRT3O.js.map +0 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  Fayz builds real, multi-tenant SaaS apps by composing plugins. `@fayz-ai/sdk` is the seam between a generated Fayz project and the platform behind it: a typed API client, the shared manifest/user/params types, a runtime broker for OAuth-backed integrations, and the release-channel resolver that keeps every package on a coherent version set.
11
11
 
12
- This is the lowest-trust, zero-React layer — no UI, no framework, just the contract. Generated apps call Fayz through the SDK instead of importing provider clients directly, so OAuth secrets and tenant authority stay server-side where they belong. If you're reading Fayz tables, exchanging plugin OAuth grants, or pinning a package channel, you start here.
12
+ This is the lowest-trust, zero-React layer — no UI, no framework, just the contract. Generated apps call Fayz through the SDK instead of importing provider clients directly, which is what keeps OAuth secrets and tenant authority server-side. If you're reading Fayz tables, exchanging plugin OAuth grants, or pinning a package channel, you start here.
13
13
 
14
14
  ## What's inside
15
15
  - `createFayzClient` / `fayz` — typed client with `auth.me()` and `data` row access (`listRows`, `countRows`, `createRow`, `updateRow`, `deleteRows`) plus `FayzApiError`
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Client for the Fayz public automations surface.
3
+ *
4
+ * `/api/public/projects/:id/automations` is how a published app reads and
5
+ * manages the automations the PLATFORM executes for it — the same rows the
6
+ * owner sees in Fayz > Automations. Reads authenticate with the publishable
7
+ * key alone; writes additionally carry the signed-in end user's app session
8
+ * token (Supabase access token), verified server-side against the app's own
9
+ * JWKS — a bundle-shipped key must never be enough to flip a tenant's switch.
10
+ */
11
+ export interface FayzAutomationAction {
12
+ id: string;
13
+ type: string;
14
+ enabled: boolean;
15
+ config: {
16
+ subject?: string;
17
+ body?: string;
18
+ recipient?: string;
19
+ };
20
+ }
21
+ export interface FayzAutomation {
22
+ id: string;
23
+ name: string;
24
+ trigger: string;
25
+ triggerConfig: {
26
+ eventKey?: string;
27
+ sourceChannel?: string;
28
+ conditions?: unknown[];
29
+ conditionMatch?: string;
30
+ };
31
+ enabled: boolean;
32
+ tenantId: string | null;
33
+ actions: FayzAutomationAction[];
34
+ createdAt: string;
35
+ updatedAt: string;
36
+ }
37
+ export interface FayzAutomationExecution {
38
+ id: string;
39
+ automationId: string;
40
+ automationName: string;
41
+ trigger: string;
42
+ status: string;
43
+ error: string | null;
44
+ executedAt: string;
45
+ tenantId: string | null;
46
+ }
47
+ export interface FayzAutomationsClientOptions {
48
+ /** e.g. `https://fayz.ai/api` — the same base the agent client takes. */
49
+ baseUrl: string;
50
+ projectId: string;
51
+ publishableKey: string;
52
+ fetcher?: typeof fetch;
53
+ }
54
+ export declare class FayzAutomationsError extends Error {
55
+ readonly status: number;
56
+ constructor(message: string, status: number);
57
+ }
58
+ export interface FayzAutomationsClient {
59
+ list(input: {
60
+ tenantId: string;
61
+ }): Promise<FayzAutomation[]>;
62
+ create(input: {
63
+ tenantId: string;
64
+ appSessionToken: string;
65
+ eventKey: string;
66
+ sourceChannel: string;
67
+ name?: string;
68
+ enabled?: boolean;
69
+ action?: {
70
+ subject?: string;
71
+ body?: string;
72
+ recipient?: string;
73
+ };
74
+ }): Promise<FayzAutomation>;
75
+ update(input: {
76
+ id: string;
77
+ tenantId: string;
78
+ appSessionToken: string;
79
+ enabled?: boolean;
80
+ /** `null` clears a field — the app re-materializes its catalog default. */
81
+ action?: {
82
+ subject?: string | null;
83
+ body?: string | null;
84
+ recipient?: string | null;
85
+ };
86
+ }): Promise<FayzAutomation>;
87
+ listExecutions(input: {
88
+ tenantId: string;
89
+ eventKey?: string;
90
+ limit?: number;
91
+ }): Promise<FayzAutomationExecution[]>;
92
+ }
93
+ export declare function createFayzAutomationsClient(options: FayzAutomationsClientOptions): FayzAutomationsClient;
94
+ //# sourceMappingURL=automations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automations.d.ts","sourceRoot":"","sources":["../src/automations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ // src/automations.ts
2
+ var FayzAutomationsError = class extends Error {
3
+ constructor(message, status) {
4
+ super(message);
5
+ this.status = status;
6
+ }
7
+ };
8
+ function createFayzAutomationsClient(options) {
9
+ const fetcher = options.fetcher ?? ((...args) => fetch(...args));
10
+ const base = `${options.baseUrl.replace(/\/$/, "")}/public/projects/${options.projectId}/automations`;
11
+ async function call(path, init = {}) {
12
+ const { appSessionToken, ...rest } = init;
13
+ const response = await fetcher(`${base}${path}`, {
14
+ ...rest,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "x-fayz-agent-key": options.publishableKey,
18
+ ...appSessionToken ? { Authorization: `Bearer ${appSessionToken}` } : {},
19
+ ...rest.headers ?? {}
20
+ }
21
+ });
22
+ const body = await response.json().catch(() => ({}));
23
+ if (!response.ok) {
24
+ throw new FayzAutomationsError(body.message ?? body.error ?? `HTTP ${response.status}`, response.status);
25
+ }
26
+ return body;
27
+ }
28
+ return {
29
+ async list({ tenantId }) {
30
+ const body = await call(
31
+ `?tenantId=${encodeURIComponent(tenantId)}`
32
+ );
33
+ return body.automations ?? [];
34
+ },
35
+ async create({ tenantId, appSessionToken, ...rest }) {
36
+ const body = await call(
37
+ `?tenantId=${encodeURIComponent(tenantId)}`,
38
+ { method: "POST", body: JSON.stringify(rest), appSessionToken }
39
+ );
40
+ return body.automation;
41
+ },
42
+ async update({ id, tenantId, appSessionToken, ...rest }) {
43
+ const body = await call(
44
+ `/${encodeURIComponent(id)}?tenantId=${encodeURIComponent(tenantId)}`,
45
+ { method: "PATCH", body: JSON.stringify(rest), appSessionToken }
46
+ );
47
+ return body.automation;
48
+ },
49
+ async listExecutions({ tenantId, eventKey, limit }) {
50
+ const params = new URLSearchParams({ tenantId });
51
+ if (eventKey) params.set("eventKey", eventKey);
52
+ if (limit) params.set("limit", String(limit));
53
+ const body = await call(`/executions?${params}`);
54
+ return body.executions ?? [];
55
+ }
56
+ };
57
+ }
58
+
59
+ export { FayzAutomationsError, createFayzAutomationsClient };
60
+ //# sourceMappingURL=automations.js.map
61
+ //# sourceMappingURL=automations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/automations.ts"],"names":[],"mappings":";AAsDO,IAAM,oBAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,EAC9C,WAAA,CAAY,SAA0B,MAAA,EAAgB;AACpD,IAAA,KAAA,CAAM,OAAO,CAAA;AADuB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAEtC;AACF;AA4BO,SAAS,4BAA4B,OAAA,EAA8D;AACxG,EAAA,MAAM,UAAU,OAAA,CAAQ,OAAA,KAAY,IAAI,IAAA,KAAmC,KAAA,CAAM,GAAG,IAAI,CAAA,CAAA;AACxF,EAAA,MAAM,IAAA,GAAO,CAAA,EAAG,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAC,CAAA,iBAAA,EAAoB,OAAA,CAAQ,SAAS,CAAA,YAAA,CAAA;AAEvF,EAAA,eAAe,IAAA,CACb,IAAA,EACA,IAAA,GAAmD,EAAC,EACxC;AACZ,IAAA,MAAM,EAAE,eAAA,EAAiB,GAAG,IAAA,EAAK,GAAI,IAAA;AACrC,IAAA,MAAM,WAAW,MAAM,OAAA,CAAQ,GAAG,IAAI,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,MAC/C,GAAG,IAAA;AAAA,MACH,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,oBAAoB,OAAA,CAAQ,cAAA;AAAA,QAC5B,GAAI,kBAAkB,EAAE,aAAA,EAAe,UAAU,eAAe,CAAA,CAAA,KAAO,EAAC;AAAA,QACxE,GAAI,IAAA,CAAK,OAAA,IAAW;AAAC;AACvB,KACD,CAAA;AACD,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACpD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,oBAAA,CAAqB,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,KAAA,IAAS,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,MAAM,CAAA;AAAA,IACzG;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,IAAA,CAAK,EAAE,QAAA,EAAS,EAAG;AACvB,MAAA,MAAM,OAAO,MAAM,IAAA;AAAA,QACjB,CAAA,UAAA,EAAa,kBAAA,CAAmB,QAAQ,CAAC,CAAA;AAAA,OAC3C;AACA,MAAA,OAAO,IAAA,CAAK,eAAe,EAAC;AAAA,IAC9B,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,EAAE,UAAU,eAAA,EAAiB,GAAG,MAAK,EAAG;AACnD,MAAA,MAAM,OAAO,MAAM,IAAA;AAAA,QACjB,CAAA,UAAA,EAAa,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,QACzC,EAAE,QAAQ,MAAA,EAAQ,IAAA,EAAM,KAAK,SAAA,CAAU,IAAI,GAAG,eAAA;AAAgB,OAChE;AACA,MAAA,OAAO,IAAA,CAAK,UAAA;AAAA,IACd,CAAA;AAAA,IAEA,MAAM,OAAO,EAAE,EAAA,EAAI,UAAU,eAAA,EAAiB,GAAG,MAAK,EAAG;AACvD,MAAA,MAAM,OAAO,MAAM,IAAA;AAAA,QACjB,IAAI,kBAAA,CAAmB,EAAE,CAAC,CAAA,UAAA,EAAa,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,QACnE,EAAE,QAAQ,OAAA,EAAS,IAAA,EAAM,KAAK,SAAA,CAAU,IAAI,GAAG,eAAA;AAAgB,OACjE;AACA,MAAA,OAAO,IAAA,CAAK,UAAA;AAAA,IACd,CAAA;AAAA,IAEA,MAAM,cAAA,CAAe,EAAE,QAAA,EAAU,QAAA,EAAU,OAAM,EAAG;AAClD,MAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,EAAE,UAAU,CAAA;AAC/C,MAAA,IAAI,QAAA,EAAU,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,QAAQ,CAAA;AAC7C,MAAA,IAAI,OAAO,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAC5C,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAgD,CAAA,YAAA,EAAe,MAAM,CAAA,CAAE,CAAA;AAC1F,MAAA,OAAO,IAAA,CAAK,cAAc,EAAC;AAAA,IAC7B;AAAA,GACF;AACF","file":"automations.js","sourcesContent":["/**\n * Client for the Fayz public automations surface.\n *\n * `/api/public/projects/:id/automations` is how a published app reads and\n * manages the automations the PLATFORM executes for it — the same rows the\n * owner sees in Fayz > Automations. Reads authenticate with the publishable\n * key alone; writes additionally carry the signed-in end user's app session\n * token (Supabase access token), verified server-side against the app's own\n * JWKS — a bundle-shipped key must never be enough to flip a tenant's switch.\n */\n\nexport interface FayzAutomationAction {\n id: string\n type: string\n enabled: boolean\n config: { subject?: string; body?: string; recipient?: string }\n}\n\nexport interface FayzAutomation {\n id: string\n name: string\n trigger: string\n triggerConfig: {\n eventKey?: string\n sourceChannel?: string\n conditions?: unknown[]\n conditionMatch?: string\n }\n enabled: boolean\n tenantId: string | null\n actions: FayzAutomationAction[]\n createdAt: string\n updatedAt: string\n}\n\nexport interface FayzAutomationExecution {\n id: string\n automationId: string\n automationName: string\n trigger: string\n status: string\n error: string | null\n executedAt: string\n tenantId: string | null\n}\n\nexport interface FayzAutomationsClientOptions {\n /** e.g. `https://fayz.ai/api` — the same base the agent client takes. */\n baseUrl: string\n projectId: string\n publishableKey: string\n fetcher?: typeof fetch\n}\n\nexport class FayzAutomationsError extends Error {\n constructor(message: string, readonly status: number) {\n super(message)\n }\n}\n\nexport interface FayzAutomationsClient {\n list(input: { tenantId: string }): Promise<FayzAutomation[]>\n create(input: {\n tenantId: string\n appSessionToken: string\n eventKey: string\n sourceChannel: string\n name?: string\n enabled?: boolean\n action?: { subject?: string; body?: string; recipient?: string }\n }): Promise<FayzAutomation>\n update(input: {\n id: string\n tenantId: string\n appSessionToken: string\n enabled?: boolean\n /** `null` clears a field — the app re-materializes its catalog default. */\n action?: { subject?: string | null; body?: string | null; recipient?: string | null }\n }): Promise<FayzAutomation>\n listExecutions(input: {\n tenantId: string\n eventKey?: string\n limit?: number\n }): Promise<FayzAutomationExecution[]>\n}\n\nexport function createFayzAutomationsClient(options: FayzAutomationsClientOptions): FayzAutomationsClient {\n const fetcher = options.fetcher ?? ((...args: Parameters<typeof fetch>) => fetch(...args))\n const base = `${options.baseUrl.replace(/\\/$/, '')}/public/projects/${options.projectId}/automations`\n\n async function call<T>(\n path: string,\n init: RequestInit & { appSessionToken?: string } = {},\n ): Promise<T> {\n const { appSessionToken, ...rest } = init\n const response = await fetcher(`${base}${path}`, {\n ...rest,\n headers: {\n 'Content-Type': 'application/json',\n 'x-fayz-agent-key': options.publishableKey,\n ...(appSessionToken ? { Authorization: `Bearer ${appSessionToken}` } : {}),\n ...(rest.headers ?? {}),\n },\n })\n const body = (await response.json().catch(() => ({}))) as T & { message?: string; error?: string }\n if (!response.ok) {\n throw new FayzAutomationsError(body.message ?? body.error ?? `HTTP ${response.status}`, response.status)\n }\n return body\n }\n\n return {\n async list({ tenantId }) {\n const body = await call<{ automations: FayzAutomation[] }>(\n `?tenantId=${encodeURIComponent(tenantId)}`,\n )\n return body.automations ?? []\n },\n\n async create({ tenantId, appSessionToken, ...rest }) {\n const body = await call<{ automation: FayzAutomation }>(\n `?tenantId=${encodeURIComponent(tenantId)}`,\n { method: 'POST', body: JSON.stringify(rest), appSessionToken },\n )\n return body.automation\n },\n\n async update({ id, tenantId, appSessionToken, ...rest }) {\n const body = await call<{ automation: FayzAutomation }>(\n `/${encodeURIComponent(id)}?tenantId=${encodeURIComponent(tenantId)}`,\n { method: 'PATCH', body: JSON.stringify(rest), appSessionToken },\n )\n return body.automation\n },\n\n async listExecutions({ tenantId, eventKey, limit }) {\n const params = new URLSearchParams({ tenantId })\n if (eventKey) params.set('eventKey', eventKey)\n if (limit) params.set('limit', String(limit))\n const body = await call<{ executions: FayzAutomationExecution[] }>(`/executions?${params}`)\n return body.executions ?? []\n },\n }\n}\n"]}