@fayz-ai/sdk 0.9.0 → 0.10.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 +2 -2
- package/dist/ai-builder.js +1 -1
- package/dist/{chunk-2YJXKDHO.js → chunk-6UZOXHGJ.js} +11 -6
- package/dist/chunk-6UZOXHGJ.js.map +1 -0
- package/dist/{chunk-V4GWI7WH.js → chunk-7UXTYT6I.js} +65 -4
- package/dist/chunk-7UXTYT6I.js.map +1 -0
- package/dist/{chunk-7XM4LONE.js → chunk-BJFMBVMP.js} +2 -2
- package/dist/chunk-BJFMBVMP.js.map +1 -0
- package/dist/chunk-HA5O3CW7.js +181 -0
- package/dist/chunk-HA5O3CW7.js.map +1 -0
- package/dist/chunk-KVMRRT3O.js +135 -0
- package/dist/chunk-KVMRRT3O.js.map +1 -0
- package/dist/deprecations.d.ts +98 -0
- package/dist/deprecations.d.ts.map +1 -0
- package/dist/deprecations.js +3 -0
- package/dist/deprecations.js.map +1 -0
- package/dist/deprecations.json +119 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/release-channels.js +1 -1
- package/dist/release-channels.json +103 -0
- package/dist/shop.d.ts +32 -0
- package/dist/shop.d.ts.map +1 -1
- package/dist/shop.js +2 -1
- package/dist/supported-surface.d.ts +8 -1
- package/dist/supported-surface.d.ts.map +1 -1
- package/dist/supported-surface.js +1 -1
- package/{src → dist}/supported-surface.json +5 -3
- package/dist/vite.d.ts +30 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +10 -2
- package/dist/vite.js.map +1 -1
- package/package.json +10 -17
- package/dist/chunk-2YJXKDHO.js.map +0 -1
- package/dist/chunk-7XM4LONE.js.map +0 -1
- package/dist/chunk-GQPVDQEB.js +0 -135
- package/dist/chunk-GQPVDQEB.js.map +0 -1
- package/dist/chunk-V4GWI7WH.js.map +0 -1
- package/src/agent.test.ts +0 -114
- package/src/agent.ts +0 -335
- package/src/ai-builder.ts +0 -115
- package/src/app-params.ts +0 -69
- package/src/client.test.ts +0 -176
- package/src/client.ts +0 -229
- package/src/index.ts +0 -94
- package/src/release-channels.json +0 -103
- package/src/release-channels.test.ts +0 -41
- package/src/release-channels.ts +0 -41
- package/src/runtime.test.ts +0 -123
- package/src/runtime.ts +0 -211
- package/src/shop.test.ts +0 -114
- package/src/shop.ts +0 -1118
- package/src/supported-surface.ts +0 -33
- package/src/types.ts +0 -67
- package/src/vite.ts +0 -121
package/src/ai-builder.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
// The AI Builder request taxonomy — the contract the platform's request
|
|
2
|
-
// classifier targets. The classifier itself lives in the `fayz` platform repo;
|
|
3
|
-
// this is the canonical source of truth for the request classes and the
|
|
4
|
-
// architecture layer each is allowed to touch (docs/ARCHITECTURE.md).
|
|
5
|
-
|
|
6
|
-
/** Ownership layer a request may modify. */
|
|
7
|
-
export type FayzLayer = 'app' | 'plugin-config' | 'private-extension' | 'platform' | 'none'
|
|
8
|
-
|
|
9
|
-
export type AiBuilderRequestClass =
|
|
10
|
-
| 'app-edit'
|
|
11
|
-
| 'plugin-config'
|
|
12
|
-
| 'private-extension'
|
|
13
|
-
| 'platform-or-plugin-upgrade'
|
|
14
|
-
| 'unsafe-blocked'
|
|
15
|
-
|
|
16
|
-
export interface AiBuilderRequestClassDef {
|
|
17
|
-
id: AiBuilderRequestClass
|
|
18
|
-
label: string
|
|
19
|
-
/** Which ownership layer this class is allowed to modify. */
|
|
20
|
-
layer: FayzLayer
|
|
21
|
-
/** Who may perform it. */
|
|
22
|
-
editableBy: 'ai' | 'partner' | 'fayz' | 'none'
|
|
23
|
-
needsCode: boolean
|
|
24
|
-
needsDeploy: boolean
|
|
25
|
-
description: string
|
|
26
|
-
examples: string[]
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const AI_BUILDER_REQUEST_CLASSES: Record<AiBuilderRequestClass, AiBuilderRequestClassDef> = {
|
|
30
|
-
'app-edit': {
|
|
31
|
-
id: 'app-edit',
|
|
32
|
-
label: 'App edit',
|
|
33
|
-
layer: 'app',
|
|
34
|
-
editableBy: 'ai',
|
|
35
|
-
needsCode: false,
|
|
36
|
-
needsDeploy: false,
|
|
37
|
-
description:
|
|
38
|
-
'Change the generated app: pages, routes, layout, theme, copy, blocks, slots. Manifest-level edits (ladder 1–4) need no code; custom components/pages (ladder 5–6) are app-owned code.',
|
|
39
|
-
examples: [
|
|
40
|
-
'Change the brand color and headline',
|
|
41
|
-
'Add a new landing page with a hero and product grid',
|
|
42
|
-
'Reorder dashboard cards',
|
|
43
|
-
],
|
|
44
|
-
},
|
|
45
|
-
'plugin-config': {
|
|
46
|
-
id: 'plugin-config',
|
|
47
|
-
label: 'Plugin config',
|
|
48
|
-
layer: 'plugin-config',
|
|
49
|
-
editableBy: 'ai',
|
|
50
|
-
needsCode: false,
|
|
51
|
-
needsDeploy: false,
|
|
52
|
-
description:
|
|
53
|
-
'Configure an installed plugin as manifest data: enabled modules, fields, statuses, rules, feature flags, labels, currency.',
|
|
54
|
-
examples: [
|
|
55
|
-
'Enable the reconciliation module in financial',
|
|
56
|
-
'Add a "VIP" status to clients',
|
|
57
|
-
'Turn on delivery pricing in the menu',
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
'private-extension': {
|
|
61
|
-
id: 'private-extension',
|
|
62
|
-
label: 'Private extension',
|
|
63
|
-
layer: 'private-extension',
|
|
64
|
-
editableBy: 'partner',
|
|
65
|
-
needsCode: true,
|
|
66
|
-
needsDeploy: true,
|
|
67
|
-
description:
|
|
68
|
-
'Add new business behaviour as an app-local plugin (own entities, data, migrations, AI tools, connectors). The sanctioned partner/Silvio path — scaffold with `fayz create plugin`. See CUSTOMIZATION.md.',
|
|
69
|
-
examples: [
|
|
70
|
-
'Build a loyalty-points engine with its own table',
|
|
71
|
-
'Add a custom importer for a legacy ERP',
|
|
72
|
-
'Integrate a provider Fayz does not support yet (adapter)',
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
'platform-or-plugin-upgrade': {
|
|
76
|
-
id: 'platform-or-plugin-upgrade',
|
|
77
|
-
label: 'Platform / plugin upgrade',
|
|
78
|
-
layer: 'platform',
|
|
79
|
-
editableBy: 'fayz',
|
|
80
|
-
needsCode: true,
|
|
81
|
-
needsDeploy: true,
|
|
82
|
-
description:
|
|
83
|
-
'Change owned by Fayz: bump SDK/plugin versions, run manifest/DB migrations, evolve an engine. Not editable from a generated app.',
|
|
84
|
-
examples: [
|
|
85
|
-
'Upgrade @fayz-ai/core across the fleet',
|
|
86
|
-
'Migrate manifests v2 → v3',
|
|
87
|
-
'Add a capability to an official plugin',
|
|
88
|
-
],
|
|
89
|
-
},
|
|
90
|
-
'unsafe-blocked': {
|
|
91
|
-
id: 'unsafe-blocked',
|
|
92
|
-
label: 'Unsafe / blocked',
|
|
93
|
-
layer: 'none',
|
|
94
|
-
editableBy: 'none',
|
|
95
|
-
needsCode: false,
|
|
96
|
-
needsDeploy: false,
|
|
97
|
-
description:
|
|
98
|
-
'Requests that would break the boundary and must be refused or rerouted: mutating SDK/runtime/plugin internals, forking an SDK page, importing a provider SDK directly into app code, or bypassing tenancy/permissions/security.',
|
|
99
|
-
examples: [
|
|
100
|
-
'Edit the code inside @fayz-ai/plugin-crm',
|
|
101
|
-
'Copy an SDK page into the app and modify it',
|
|
102
|
-
'Call the Supabase client directly from a storefront component',
|
|
103
|
-
'Disable row-level security for a tenant',
|
|
104
|
-
],
|
|
105
|
-
},
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export const AI_BUILDER_REQUEST_CLASS_IDS = Object.keys(
|
|
109
|
-
AI_BUILDER_REQUEST_CLASSES,
|
|
110
|
-
) as AiBuilderRequestClass[]
|
|
111
|
-
|
|
112
|
-
/** True when a request class is permitted (anything but unsafe-blocked). */
|
|
113
|
-
export function isAllowedRequestClass(id: AiBuilderRequestClass): boolean {
|
|
114
|
-
return id !== 'unsafe-blocked'
|
|
115
|
-
}
|
package/src/app-params.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { FayzAppParams, FayzRuntimeEnvironment } from './types'
|
|
2
|
-
|
|
3
|
-
function readSearchParams(): URLSearchParams {
|
|
4
|
-
const href = globalThis.location?.href
|
|
5
|
-
return href ? new URL(href).searchParams : new URLSearchParams()
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function readMeta(name: string): string | undefined {
|
|
9
|
-
const documentRef = globalThis.document
|
|
10
|
-
const value = documentRef?.querySelector<HTMLMetaElement>(`meta[name="${name}"]`)?.content?.trim()
|
|
11
|
-
return value || undefined
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function readEnv(name: string): string | undefined {
|
|
15
|
-
const env = (import.meta as unknown as { env?: Record<string, string | undefined> }).env
|
|
16
|
-
return env?.[name]?.trim() || undefined
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function firstValue(...values: Array<string | undefined>): string | undefined {
|
|
20
|
-
return values.find((value) => value && value.trim())?.trim()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function normalizeEnvironment(value?: string): FayzRuntimeEnvironment {
|
|
24
|
-
return value === 'production' ? 'production' : 'preview'
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function resolveAppParams(): FayzAppParams {
|
|
28
|
-
const search = readSearchParams()
|
|
29
|
-
const token = firstValue(
|
|
30
|
-
search.get('token') ?? undefined,
|
|
31
|
-
search.get('fayz_token') ?? undefined,
|
|
32
|
-
readMeta('fayz-token'),
|
|
33
|
-
readEnv('VITE_FAYZ_TOKEN'),
|
|
34
|
-
)
|
|
35
|
-
const appId = firstValue(
|
|
36
|
-
search.get('appId') ?? undefined,
|
|
37
|
-
search.get('app_id') ?? undefined,
|
|
38
|
-
readMeta('fayz-app-id'),
|
|
39
|
-
readEnv('VITE_FAYZ_APP_ID'),
|
|
40
|
-
)
|
|
41
|
-
const projectId = firstValue(
|
|
42
|
-
search.get('projectId') ?? undefined,
|
|
43
|
-
search.get('project_id') ?? undefined,
|
|
44
|
-
readMeta('fayz-project-id'),
|
|
45
|
-
readEnv('VITE_FAYZ_PROJECT_ID'),
|
|
46
|
-
)
|
|
47
|
-
const apiBaseUrl = firstValue(
|
|
48
|
-
search.get('apiBaseUrl') ?? undefined,
|
|
49
|
-
search.get('api_base_url') ?? undefined,
|
|
50
|
-
readMeta('fayz-api-base-url'),
|
|
51
|
-
readEnv('VITE_FAYZ_API_BASE_URL'),
|
|
52
|
-
globalThis.location?.origin,
|
|
53
|
-
) ?? ''
|
|
54
|
-
const environment = normalizeEnvironment(firstValue(
|
|
55
|
-
search.get('environment') ?? undefined,
|
|
56
|
-
readMeta('fayz-environment'),
|
|
57
|
-
readEnv('VITE_FAYZ_ENVIRONMENT'),
|
|
58
|
-
))
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
apiBaseUrl,
|
|
62
|
-
environment,
|
|
63
|
-
...(appId ? { appId } : {}),
|
|
64
|
-
...(projectId ? { projectId } : {}),
|
|
65
|
-
...(token ? { token } : {}),
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export const appParams = resolveAppParams()
|
package/src/client.test.ts
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
-
import { createFayzClient } from './client'
|
|
3
|
-
|
|
4
|
-
function jsonResponse(body: unknown, status = 200): Response {
|
|
5
|
-
return new Response(JSON.stringify(body), {
|
|
6
|
-
status,
|
|
7
|
-
headers: { 'Content-Type': 'application/json' },
|
|
8
|
-
})
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
describe('createFayzClient', () => {
|
|
12
|
-
it('normalizes Fayz API requests with app id and bearer token', async () => {
|
|
13
|
-
const fetcher = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse({ user: { id: 'user-1', email: 'vini@fayz.ai' } }))
|
|
14
|
-
const client = createFayzClient({
|
|
15
|
-
baseUrl: 'https://api.fayz.ai/',
|
|
16
|
-
appId: 'app-1',
|
|
17
|
-
token: 'session-token',
|
|
18
|
-
fetcher,
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
const user = await client.auth.me()
|
|
22
|
-
|
|
23
|
-
expect(user.id).toBe('user-1')
|
|
24
|
-
expect(fetcher).toHaveBeenCalledWith(
|
|
25
|
-
'https://api.fayz.ai/api/auth/me',
|
|
26
|
-
expect.objectContaining({
|
|
27
|
-
headers: expect.objectContaining({
|
|
28
|
-
'X-App-Id': 'app-1',
|
|
29
|
-
Authorization: 'Bearer session-token',
|
|
30
|
-
}),
|
|
31
|
-
}),
|
|
32
|
-
)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('accepts direct user responses for public auth/me compatibility', async () => {
|
|
36
|
-
const fetcher = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse({ id: 'user-2' }))
|
|
37
|
-
const client = createFayzClient({ baseUrl: 'https://api.fayz.ai', fetcher })
|
|
38
|
-
|
|
39
|
-
await expect(client.auth.me()).resolves.toEqual({ id: 'user-2' })
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('lists project table rows through the Fayz data API', async () => {
|
|
43
|
-
const fetcher = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse({
|
|
44
|
-
rows: [{ id: 'booking-1' }],
|
|
45
|
-
total: 12,
|
|
46
|
-
}))
|
|
47
|
-
const client = createFayzClient({
|
|
48
|
-
baseUrl: 'https://api.fayz.ai',
|
|
49
|
-
appId: 'app-1',
|
|
50
|
-
token: async () => 'runtime-token',
|
|
51
|
-
fetcher,
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
const result = await client.data.listRows<{ id: string }>({
|
|
55
|
-
projectId: 'project 1',
|
|
56
|
-
table: 'v_appointments',
|
|
57
|
-
filters: [
|
|
58
|
-
{ column: 'starts_at', operator: 'gte', value: '2026-06-14T00:00:00.000Z' },
|
|
59
|
-
{ column: 'status', operator: 'neq', value: 'cancelled' },
|
|
60
|
-
],
|
|
61
|
-
sortColumn: 'starts_at',
|
|
62
|
-
sortDirection: 'asc',
|
|
63
|
-
limit: 20,
|
|
64
|
-
runtime: true,
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
expect(result.rows[0]?.id).toBe('booking-1')
|
|
68
|
-
expect(result.total).toBe(12)
|
|
69
|
-
|
|
70
|
-
const [url, init] = fetcher.mock.calls[0] ?? []
|
|
71
|
-
expect(url).toContain('https://api.fayz.ai/api/v1/runtime/projects/project%201/database/tables/v_appointments/rows?')
|
|
72
|
-
expect(url).toContain('filters=')
|
|
73
|
-
expect(url).toContain('sortColumn=starts_at')
|
|
74
|
-
expect(url).toContain('sortDirection=asc')
|
|
75
|
-
expect(url).toContain('limit=20')
|
|
76
|
-
expect(init).toEqual(expect.objectContaining({
|
|
77
|
-
headers: expect.objectContaining({
|
|
78
|
-
'X-App-Id': 'app-1',
|
|
79
|
-
Authorization: 'Bearer runtime-token',
|
|
80
|
-
}),
|
|
81
|
-
}))
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
it('counts table rows using the Fayz data API total', async () => {
|
|
85
|
-
const fetcher = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse({
|
|
86
|
-
rows: [],
|
|
87
|
-
total: 7,
|
|
88
|
-
}))
|
|
89
|
-
const client = createFayzClient({ baseUrl: 'https://api.fayz.ai', fetcher })
|
|
90
|
-
|
|
91
|
-
await expect(client.data.countRows({
|
|
92
|
-
projectId: 'project-1',
|
|
93
|
-
table: 'clients',
|
|
94
|
-
filters: [{ column: 'active', operator: 'eq', value: true }],
|
|
95
|
-
})).resolves.toBe(7)
|
|
96
|
-
|
|
97
|
-
const [url] = fetcher.mock.calls[0] ?? []
|
|
98
|
-
expect(url).toContain('/api/projects/project-1/database/tables/clients/rows?')
|
|
99
|
-
expect(url).toContain('page=1')
|
|
100
|
-
expect(url).toContain('limit=1')
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('creates table rows through the Fayz data API', async () => {
|
|
104
|
-
const fetcher = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse({ id: 'menu-1', name: 'Burger' }, 201))
|
|
105
|
-
const client = createFayzClient({
|
|
106
|
-
baseUrl: 'https://api.fayz.ai',
|
|
107
|
-
appId: 'app-1',
|
|
108
|
-
token: 'runtime-token',
|
|
109
|
-
fetcher,
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
const row = await client.data.createRow<{ id: string; name: string }>({
|
|
113
|
-
projectId: 'project-1',
|
|
114
|
-
table: 'menu_items',
|
|
115
|
-
schema: 'public',
|
|
116
|
-
runtime: true,
|
|
117
|
-
row: { name: 'Burger' },
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
expect(row).toEqual({ id: 'menu-1', name: 'Burger' })
|
|
121
|
-
|
|
122
|
-
const [url, init] = fetcher.mock.calls[0] ?? []
|
|
123
|
-
expect(url).toBe('https://api.fayz.ai/api/v1/runtime/projects/project-1/database/tables/menu_items/rows?schema=public')
|
|
124
|
-
expect(init).toEqual(expect.objectContaining({
|
|
125
|
-
method: 'POST',
|
|
126
|
-
body: JSON.stringify({ name: 'Burger' }),
|
|
127
|
-
headers: expect.objectContaining({
|
|
128
|
-
'Content-Type': 'application/json',
|
|
129
|
-
'X-App-Id': 'app-1',
|
|
130
|
-
Authorization: 'Bearer runtime-token',
|
|
131
|
-
}),
|
|
132
|
-
}))
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('updates table rows by primary key through the Fayz data API', async () => {
|
|
136
|
-
const fetcher = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse({ id: 'table-1', status: 'occupied' }))
|
|
137
|
-
const client = createFayzClient({ baseUrl: 'https://api.fayz.ai', fetcher })
|
|
138
|
-
|
|
139
|
-
const row = await client.data.updateRow<{ id: string; status: string }>({
|
|
140
|
-
projectId: 'project-1',
|
|
141
|
-
table: 'restaurant_tables',
|
|
142
|
-
primaryKeys: { id: 'table-1' },
|
|
143
|
-
row: { status: 'occupied' },
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
expect(row.status).toBe('occupied')
|
|
147
|
-
|
|
148
|
-
const [url, init] = fetcher.mock.calls[0] ?? []
|
|
149
|
-
expect(url).toBe('https://api.fayz.ai/api/projects/project-1/database/tables/restaurant_tables/rows')
|
|
150
|
-
expect(init).toEqual(expect.objectContaining({
|
|
151
|
-
method: 'PATCH',
|
|
152
|
-
body: JSON.stringify({
|
|
153
|
-
primaryKeys: { id: 'table-1' },
|
|
154
|
-
data: { status: 'occupied' },
|
|
155
|
-
}),
|
|
156
|
-
}))
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
it('deletes table rows through the Fayz data API', async () => {
|
|
160
|
-
const fetcher = vi.fn<typeof fetch>().mockResolvedValue(jsonResponse({ deletedCount: 1 }))
|
|
161
|
-
const client = createFayzClient({ baseUrl: 'https://api.fayz.ai', fetcher })
|
|
162
|
-
|
|
163
|
-
await expect(client.data.deleteRows({
|
|
164
|
-
projectId: 'project-1',
|
|
165
|
-
table: 'restaurant_tables',
|
|
166
|
-
rows: [{ id: 'table-1' }],
|
|
167
|
-
})).resolves.toEqual({ deletedCount: 1 })
|
|
168
|
-
|
|
169
|
-
const [url, init] = fetcher.mock.calls[0] ?? []
|
|
170
|
-
expect(url).toBe('https://api.fayz.ai/api/projects/project-1/database/tables/restaurant_tables/rows')
|
|
171
|
-
expect(init).toEqual(expect.objectContaining({
|
|
172
|
-
method: 'DELETE',
|
|
173
|
-
body: JSON.stringify({ rows: [{ id: 'table-1' }] }),
|
|
174
|
-
}))
|
|
175
|
-
})
|
|
176
|
-
})
|
package/src/client.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import { appParams } from './app-params'
|
|
2
|
-
import { createFayzRuntimeClient } from './runtime'
|
|
3
|
-
import type { FayzAuthMeResponse, FayzUser } from './types'
|
|
4
|
-
|
|
5
|
-
export interface FayzClientOptions {
|
|
6
|
-
baseUrl?: string
|
|
7
|
-
token?: string | (() => string | undefined | Promise<string | undefined>)
|
|
8
|
-
appId?: string
|
|
9
|
-
fetcher?: typeof fetch
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface FayzRequestOptions extends Omit<RequestInit, 'headers'> {
|
|
13
|
-
headers?: Record<string, string>
|
|
14
|
-
token?: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export type FayzTableFilterOperator =
|
|
18
|
-
| 'eq'
|
|
19
|
-
| 'neq'
|
|
20
|
-
| 'gt'
|
|
21
|
-
| 'lt'
|
|
22
|
-
| 'gte'
|
|
23
|
-
| 'lte'
|
|
24
|
-
| 'like'
|
|
25
|
-
| 'ilike'
|
|
26
|
-
| 'is_null'
|
|
27
|
-
| 'is_not_null'
|
|
28
|
-
|
|
29
|
-
export interface FayzTableFilter {
|
|
30
|
-
column: string
|
|
31
|
-
operator: FayzTableFilterOperator
|
|
32
|
-
value?: unknown
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface FayzTableListOptions {
|
|
36
|
-
projectId?: string
|
|
37
|
-
table: string
|
|
38
|
-
schema?: string
|
|
39
|
-
filters?: FayzTableFilter[]
|
|
40
|
-
sortColumn?: string
|
|
41
|
-
sortDirection?: 'asc' | 'desc'
|
|
42
|
-
page?: number
|
|
43
|
-
limit?: number
|
|
44
|
-
runtime?: boolean
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface FayzTableListResponse<T> {
|
|
48
|
-
rows: T[]
|
|
49
|
-
total: number
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface FayzTableMutationOptions {
|
|
53
|
-
projectId?: string
|
|
54
|
-
table: string
|
|
55
|
-
schema?: string
|
|
56
|
-
runtime?: boolean
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface FayzTableCreateOptions<T = Record<string, unknown>> extends FayzTableMutationOptions {
|
|
60
|
-
row: T
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface FayzTableUpdateOptions<T = Record<string, unknown>> extends FayzTableMutationOptions {
|
|
64
|
-
primaryKeys: Record<string, unknown>
|
|
65
|
-
row: Partial<T>
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface FayzTableDeleteOptions extends FayzTableMutationOptions {
|
|
69
|
-
rows: Record<string, unknown>[]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface FayzTableDeleteResponse {
|
|
73
|
-
deletedCount: number
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export class FayzApiError extends Error {
|
|
77
|
-
constructor(
|
|
78
|
-
message: string,
|
|
79
|
-
readonly status: number,
|
|
80
|
-
readonly responseBody?: unknown,
|
|
81
|
-
) {
|
|
82
|
-
super(message)
|
|
83
|
-
this.name = 'FayzApiError'
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function normalizeBaseUrl(baseUrl: string): string {
|
|
88
|
-
return baseUrl.replace(/\/+$/, '')
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function apiPath(path: string): string {
|
|
92
|
-
if (/^https?:\/\//.test(path)) return path
|
|
93
|
-
const normalized = path.startsWith('/') ? path : `/${path}`
|
|
94
|
-
return normalized.startsWith('/api/') ? normalized : `/api${normalized}`
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function parseResponse<T>(response: Response): Promise<T> {
|
|
98
|
-
if (response.status === 204) return undefined as T
|
|
99
|
-
|
|
100
|
-
const text = await response.text()
|
|
101
|
-
let body: unknown
|
|
102
|
-
try {
|
|
103
|
-
body = text ? JSON.parse(text) : undefined
|
|
104
|
-
} catch {
|
|
105
|
-
body = text
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (!response.ok) {
|
|
109
|
-
const message = typeof body === 'object' && body
|
|
110
|
-
? String((body as { message?: unknown; error?: unknown }).message ?? (body as { error?: unknown }).error ?? `Fayz API request failed with status ${response.status}`)
|
|
111
|
-
: `Fayz API request failed with status ${response.status}`
|
|
112
|
-
throw new FayzApiError(message, response.status, body)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return body as T
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async function resolveToken(token: FayzClientOptions['token']): Promise<string | undefined> {
|
|
119
|
-
return typeof token === 'function' ? token() : token
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function unwrapUser(body: FayzUser | FayzAuthMeResponse): FayzUser {
|
|
123
|
-
return typeof body === 'object' && body && 'user' in body
|
|
124
|
-
? (body as FayzAuthMeResponse).user
|
|
125
|
-
: body as FayzUser
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function tableRowsPath(options: FayzTableListOptions): string {
|
|
129
|
-
const route = tableRowsRoute(options)
|
|
130
|
-
const params = new URLSearchParams()
|
|
131
|
-
|
|
132
|
-
if (options.schema) params.set('schema', options.schema)
|
|
133
|
-
if (options.filters?.length) params.set('filters', JSON.stringify(options.filters))
|
|
134
|
-
if (options.sortColumn) params.set('sortColumn', options.sortColumn)
|
|
135
|
-
if (options.sortDirection) params.set('sortDirection', options.sortDirection)
|
|
136
|
-
if (options.page != null) params.set('page', String(options.page))
|
|
137
|
-
if (options.limit != null) params.set('limit', String(options.limit))
|
|
138
|
-
|
|
139
|
-
const query = params.toString()
|
|
140
|
-
return query ? `${route}?${query}` : route
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function tableRowsRoute(options: FayzTableMutationOptions): string {
|
|
144
|
-
const projectId = encodeURIComponent(options.projectId ?? appParams.projectId ?? 'current')
|
|
145
|
-
const table = encodeURIComponent(options.table)
|
|
146
|
-
return options.runtime
|
|
147
|
-
? `/api/v1/runtime/projects/${projectId}/database/tables/${table}/rows`
|
|
148
|
-
: `/api/projects/${projectId}/database/tables/${table}/rows`
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function mutationRowsPath(options: FayzTableMutationOptions): string {
|
|
152
|
-
const route = tableRowsRoute(options)
|
|
153
|
-
const params = new URLSearchParams()
|
|
154
|
-
|
|
155
|
-
if (options.schema) params.set('schema', options.schema)
|
|
156
|
-
|
|
157
|
-
const query = params.toString()
|
|
158
|
-
return query ? `${route}?${query}` : route
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function createFayzClient(options: FayzClientOptions = {}) {
|
|
162
|
-
const baseUrl = normalizeBaseUrl(options.baseUrl ?? appParams.apiBaseUrl)
|
|
163
|
-
const fetcher = options.fetcher ?? fetch
|
|
164
|
-
const appId = options.appId ?? appParams.appId
|
|
165
|
-
const token = options.token ?? appParams.token
|
|
166
|
-
|
|
167
|
-
async function request<T>(path: string, init: FayzRequestOptions = {}): Promise<T> {
|
|
168
|
-
const requestToken = init.token ?? await resolveToken(token)
|
|
169
|
-
const headers: Record<string, string> = {
|
|
170
|
-
...(init.body ? { 'Content-Type': 'application/json' } : {}),
|
|
171
|
-
...(appId ? { 'X-App-Id': appId } : {}),
|
|
172
|
-
...init.headers,
|
|
173
|
-
...(requestToken ? { Authorization: `Bearer ${requestToken}` } : {}),
|
|
174
|
-
}
|
|
175
|
-
const response = await fetcher(`${baseUrl}${apiPath(path)}`, {
|
|
176
|
-
...init,
|
|
177
|
-
headers,
|
|
178
|
-
})
|
|
179
|
-
return parseResponse<T>(response)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
request,
|
|
184
|
-
auth: {
|
|
185
|
-
async me(): Promise<FayzUser> {
|
|
186
|
-
return unwrapUser(await request<FayzUser | FayzAuthMeResponse>('/auth/me'))
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
data: {
|
|
190
|
-
async listRows<T = Record<string, unknown>>(options: FayzTableListOptions): Promise<FayzTableListResponse<T>> {
|
|
191
|
-
return request<FayzTableListResponse<T>>(tableRowsPath(options))
|
|
192
|
-
},
|
|
193
|
-
async countRows(options: FayzTableListOptions): Promise<number> {
|
|
194
|
-
const response = await request<FayzTableListResponse<unknown>>(tableRowsPath({
|
|
195
|
-
...options,
|
|
196
|
-
page: options.page ?? 1,
|
|
197
|
-
limit: 1,
|
|
198
|
-
}))
|
|
199
|
-
return response.total
|
|
200
|
-
},
|
|
201
|
-
async createRow<T = Record<string, unknown>>(options: FayzTableCreateOptions<Partial<T>>): Promise<T> {
|
|
202
|
-
return request<T>(mutationRowsPath(options), {
|
|
203
|
-
method: 'POST',
|
|
204
|
-
body: JSON.stringify(options.row),
|
|
205
|
-
})
|
|
206
|
-
},
|
|
207
|
-
async updateRow<T = Record<string, unknown>>(options: FayzTableUpdateOptions<T>): Promise<T> {
|
|
208
|
-
return request<T>(mutationRowsPath(options), {
|
|
209
|
-
method: 'PATCH',
|
|
210
|
-
body: JSON.stringify({
|
|
211
|
-
primaryKeys: options.primaryKeys,
|
|
212
|
-
data: options.row,
|
|
213
|
-
}),
|
|
214
|
-
})
|
|
215
|
-
},
|
|
216
|
-
async deleteRows(options: FayzTableDeleteOptions): Promise<FayzTableDeleteResponse> {
|
|
217
|
-
return request<FayzTableDeleteResponse>(mutationRowsPath(options), {
|
|
218
|
-
method: 'DELETE',
|
|
219
|
-
body: JSON.stringify({ rows: options.rows }),
|
|
220
|
-
})
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
runtime: {
|
|
224
|
-
createClient: createFayzRuntimeClient,
|
|
225
|
-
},
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export const fayz = createFayzClient()
|
package/src/index.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
export { appParams, resolveAppParams } from './app-params'
|
|
2
|
-
export { createFayzClient, fayz, FayzApiError } from './client'
|
|
3
|
-
export type {
|
|
4
|
-
FayzClientOptions,
|
|
5
|
-
FayzRequestOptions,
|
|
6
|
-
FayzTableFilter,
|
|
7
|
-
FayzTableFilterOperator,
|
|
8
|
-
FayzTableListOptions,
|
|
9
|
-
FayzTableListResponse,
|
|
10
|
-
FayzTableMutationOptions,
|
|
11
|
-
FayzTableCreateOptions,
|
|
12
|
-
FayzTableUpdateOptions,
|
|
13
|
-
FayzTableDeleteOptions,
|
|
14
|
-
FayzTableDeleteResponse,
|
|
15
|
-
} from './client'
|
|
16
|
-
export {
|
|
17
|
-
fayzPackageVersionSets,
|
|
18
|
-
resolveFayzPackageDependencies,
|
|
19
|
-
resolveFayzPackageVersion,
|
|
20
|
-
resolveFayzPackageVersions,
|
|
21
|
-
} from './release-channels'
|
|
22
|
-
export type { FayzPackageChannel, FayzPackageVersionSet } from './release-channels'
|
|
23
|
-
export {
|
|
24
|
-
getSupportedPackages,
|
|
25
|
-
getInternalPackages,
|
|
26
|
-
isSupportedPackage,
|
|
27
|
-
fayzSupportedSurface,
|
|
28
|
-
} from './supported-surface'
|
|
29
|
-
export type { FayzPackageTier, FayzSupportedSurface } from './supported-surface'
|
|
30
|
-
export {
|
|
31
|
-
AI_BUILDER_REQUEST_CLASSES,
|
|
32
|
-
AI_BUILDER_REQUEST_CLASS_IDS,
|
|
33
|
-
isAllowedRequestClass,
|
|
34
|
-
} from './ai-builder'
|
|
35
|
-
export type {
|
|
36
|
-
FayzLayer,
|
|
37
|
-
AiBuilderRequestClass,
|
|
38
|
-
AiBuilderRequestClassDef,
|
|
39
|
-
} from './ai-builder'
|
|
40
|
-
export {
|
|
41
|
-
createFayzRuntimeClient,
|
|
42
|
-
FayzRuntimeError,
|
|
43
|
-
} from './runtime'
|
|
44
|
-
export { createFayzAgentClient, FayzAgentError } from './agent'
|
|
45
|
-
export type {
|
|
46
|
-
AgentAttachmentColumn,
|
|
47
|
-
AgentAttachmentDigest,
|
|
48
|
-
AgentAttachmentSheet,
|
|
49
|
-
FayzAgentChatInput,
|
|
50
|
-
FayzAgentChatResponse,
|
|
51
|
-
FayzAgentClient,
|
|
52
|
-
FayzAgentClientOptions,
|
|
53
|
-
FayzAgentInfo,
|
|
54
|
-
FayzAgentTool,
|
|
55
|
-
FayzAgentToolCall,
|
|
56
|
-
FayzAgentToolResult,
|
|
57
|
-
} from './agent'
|
|
58
|
-
export {
|
|
59
|
-
createFayzShopProvider,
|
|
60
|
-
FayzShopError,
|
|
61
|
-
} from './shop'
|
|
62
|
-
export type {
|
|
63
|
-
FayzShopProviderOptions,
|
|
64
|
-
FayzShopProductMetadataOverlay,
|
|
65
|
-
FayzShopListProductsOptions,
|
|
66
|
-
FayzShopListOrdersOptions,
|
|
67
|
-
FayzShopListCustomersOptions,
|
|
68
|
-
FayzShopListDiscountsOptions,
|
|
69
|
-
FayzShopProductStatus,
|
|
70
|
-
FayzShopOrderStatus,
|
|
71
|
-
FayzShopFinancialStatus,
|
|
72
|
-
FayzShopFulfillmentStatus,
|
|
73
|
-
} from './shop'
|
|
74
|
-
export type {
|
|
75
|
-
FayzRuntimeClientOptions,
|
|
76
|
-
FayzRuntimeEnvironment,
|
|
77
|
-
GoogleCalendarEvent,
|
|
78
|
-
GoogleCalendarEventInput,
|
|
79
|
-
GoogleCalendarEventTime,
|
|
80
|
-
ListGoogleCalendarEventsInput,
|
|
81
|
-
PluginOAuthExchangeInput,
|
|
82
|
-
PluginOAuthExchangeResponse,
|
|
83
|
-
RuntimePluginOAuthGrant,
|
|
84
|
-
} from './runtime'
|
|
85
|
-
export type {
|
|
86
|
-
AppManifest,
|
|
87
|
-
FayzApiErrorBody,
|
|
88
|
-
FayzAppParams,
|
|
89
|
-
FayzAuthMeResponse,
|
|
90
|
-
FayzUser,
|
|
91
|
-
PageManifest,
|
|
92
|
-
PluginRef,
|
|
93
|
-
SurfaceManifest,
|
|
94
|
-
} from './types'
|