@fayz-ai/sdk 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/automations.d.ts +94 -0
- package/dist/automations.d.ts.map +1 -0
- package/dist/automations.js +61 -0
- package/dist/automations.js.map +1 -0
- package/dist/{chunk-7UXTYT6I.js → chunk-5D2B7R3U.js} +473 -31
- package/dist/chunk-5D2B7R3U.js.map +1 -0
- package/dist/chunk-U7SC2YFQ.js +135 -0
- package/dist/chunk-U7SC2YFQ.js.map +1 -0
- package/dist/events.d.ts +48 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +101 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +307 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/boot-skeleton.d.ts +20 -0
- package/dist/lib/boot-skeleton.d.ts.map +1 -0
- package/dist/lib/connector-oauth.d.ts +118 -0
- package/dist/lib/connector-oauth.d.ts.map +1 -0
- package/dist/lib/credentials.d.ts +98 -0
- package/dist/lib/credentials.d.ts.map +1 -0
- package/dist/lib/dedupe-fetch.d.ts +26 -0
- package/dist/lib/dedupe-fetch.d.ts.map +1 -0
- package/dist/lib/platform-url.d.ts +15 -0
- package/dist/lib/platform-url.d.ts.map +1 -0
- package/dist/lib/runtime-token.d.ts +104 -0
- package/dist/lib/runtime-token.d.ts.map +1 -0
- package/dist/release-channels.js +1 -1
- package/dist/release-channels.json +93 -93
- package/dist/shop.d.ts +377 -11
- package/dist/shop.d.ts.map +1 -1
- package/dist/shop.js +1 -1
- package/dist/vite.d.ts +9 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +104 -47
- package/dist/vite.js.map +1 -1
- package/package.json +9 -1
- package/dist/chunk-7UXTYT6I.js.map +0 -1
- package/dist/chunk-KVMRRT3O.js +0 -135
- package/dist/chunk-KVMRRT3O.js.map +0 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sending a merchant to a partner's consent screen — written once.
|
|
3
|
+
*
|
|
4
|
+
* Every OAuth connector needs the same four moves: mint a runtime token, POST
|
|
5
|
+
* the app's own start endpoint, read a URL back, hand it to the hub to navigate
|
|
6
|
+
* to. Copied into each connector that is four chances to disagree about the
|
|
7
|
+
* path, the token, the tenant and the failure — and the failure is the one that
|
|
8
|
+
* matters, because a `startOAuth` this repo forgot to write is a Connect button
|
|
9
|
+
* that renders DISABLED with nothing on screen saying why. That is exactly how
|
|
10
|
+
* Bling shipped.
|
|
11
|
+
*
|
|
12
|
+
* So a connector declares one line:
|
|
13
|
+
*
|
|
14
|
+
* startOAuth: fayzConnectorOAuth('bling')
|
|
15
|
+
*
|
|
16
|
+
* and everything below is shared. The platform side of the contract:
|
|
17
|
+
*
|
|
18
|
+
* POST /api/public/projects/:projectId/oauth/:provider/start
|
|
19
|
+
* Authorization: Bearer <runtime-data token>
|
|
20
|
+
* { tenantId?, redirectTo } → 201 { url }
|
|
21
|
+
*
|
|
22
|
+
* GET /api/oauth/redirect/:provider → 302 to redirectTo
|
|
23
|
+
* ?fayzConnector=<slug>&fayzConnectorStatus=connected|error
|
|
24
|
+
* &fayzConnectorMessage=<slug from a closed set>
|
|
25
|
+
*
|
|
26
|
+
* The redirect half is read by `oauth-return.ts` in `@fayz-ai/admin`; nothing
|
|
27
|
+
* here has to know about it. The provider never gets a per-request
|
|
28
|
+
* `redirect_uri` — Bling ignores one outright and always uses what is registered
|
|
29
|
+
* on the app — so `redirectTo` travels inside the platform's signed state and
|
|
30
|
+
* comes back out at the end.
|
|
31
|
+
*
|
|
32
|
+
* A port and not a bare `fetch`, for the same reason the credential sink is one:
|
|
33
|
+
* WHICH Fayz project this app belongs to is a deployment fact. The app installs
|
|
34
|
+
* one starter at boot; installing none is a valid answer, and then the connect
|
|
35
|
+
* step refuses instead of quietly opening a consent screen for a project that
|
|
36
|
+
* cannot finish the flow.
|
|
37
|
+
*/
|
|
38
|
+
import type { FayzRuntimeTokenSource } from './credentials';
|
|
39
|
+
/** The consent flow did not start. Carries a status when the platform answered. */
|
|
40
|
+
export declare class ConnectorOAuthError extends Error {
|
|
41
|
+
readonly status?: number | undefined;
|
|
42
|
+
constructor(message: string, status?: number | undefined);
|
|
43
|
+
}
|
|
44
|
+
/** This app has nowhere to start a consent flow, so it refuses rather than guessing. */
|
|
45
|
+
export declare class ConnectorOAuthStarterMissingError extends ConnectorOAuthError {
|
|
46
|
+
constructor();
|
|
47
|
+
}
|
|
48
|
+
export interface StartConnectorOAuthInput {
|
|
49
|
+
/**
|
|
50
|
+
* The `:provider` path segment — the platform catalogue's slug, which is what
|
|
51
|
+
* knows the client id, the consent host and the registered redirect.
|
|
52
|
+
*/
|
|
53
|
+
provider: string;
|
|
54
|
+
/**
|
|
55
|
+
* Which connector definition this authorizes. Usually the same word as
|
|
56
|
+
* `provider`; they part when the implementation is named after us rather than
|
|
57
|
+
* after them (`plugbank` is the catalogue's `tecnospeed`).
|
|
58
|
+
*/
|
|
59
|
+
connectorId: string;
|
|
60
|
+
/** Where the merchant lands when it is over — the page they left from, hash and all. */
|
|
61
|
+
redirectTo: string;
|
|
62
|
+
/** The organization being connected. A selector the platform re-checks; see the port doc. */
|
|
63
|
+
tenantId?: string;
|
|
64
|
+
}
|
|
65
|
+
/** Where a consent flow is started from. Supplied once at boot. */
|
|
66
|
+
export interface ConnectorOAuthStarter {
|
|
67
|
+
start(input: StartConnectorOAuthInput): Promise<string>;
|
|
68
|
+
}
|
|
69
|
+
export declare function setConnectorOAuthStarter(starter: ConnectorOAuthStarter | null): void;
|
|
70
|
+
/** Null when the app configured none — callers must refuse, never fall back. */
|
|
71
|
+
export declare function getConnectorOAuthStarter(): ConnectorOAuthStarter | null;
|
|
72
|
+
export interface FayzConnectorOAuthStarterOptions {
|
|
73
|
+
/** The Fayz project this app was published from. */
|
|
74
|
+
projectId: string;
|
|
75
|
+
/**
|
|
76
|
+
* A Fayz **runtime-data** token. Same requirement, and same reason, as the
|
|
77
|
+
* credential sink's: it is the only scheme on the public plane that carries
|
|
78
|
+
* tenant identity, and a publishable key names an app rather than a tenant.
|
|
79
|
+
* Resolved per call so a short-lived token can be refreshed.
|
|
80
|
+
*/
|
|
81
|
+
runtimeToken: FayzRuntimeTokenSource;
|
|
82
|
+
/** Fayz platform origin. Defaults to same-origin, which is what an app proxying `/api` wants. */
|
|
83
|
+
baseUrl?: string;
|
|
84
|
+
fetcher?: typeof fetch;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The starter backed by the Fayz platform. Installed once at boot, next to the
|
|
88
|
+
* credential sink:
|
|
89
|
+
*
|
|
90
|
+
* const runtimeToken = createFayzRuntimeTokenSource({ projectId, supabase: getFayzSupabaseClientOptional })
|
|
91
|
+
* setConnectorCredentialSink(createFayzConnectorCredentialSink({ projectId, runtimeToken }))
|
|
92
|
+
* setConnectorOAuthStarter(createFayzConnectorOAuthStarter({ projectId, runtimeToken }))
|
|
93
|
+
*/
|
|
94
|
+
export declare function createFayzConnectorOAuthStarter(options: FayzConnectorOAuthStarterOptions): ConnectorOAuthStarter;
|
|
95
|
+
/**
|
|
96
|
+
* Start a consent flow through the installed starter.
|
|
97
|
+
*
|
|
98
|
+
* `starter` is a test seam; pass `null` to assert there is none.
|
|
99
|
+
*/
|
|
100
|
+
export declare function startConnectorOAuth(input: StartConnectorOAuthInput & {
|
|
101
|
+
starter?: ConnectorOAuthStarter | null;
|
|
102
|
+
}): Promise<string>;
|
|
103
|
+
/**
|
|
104
|
+
* A connector's whole `startOAuth`, in one line.
|
|
105
|
+
*
|
|
106
|
+
* startOAuth: fayzConnectorOAuth('bling')
|
|
107
|
+
* startOAuth: fayzConnectorOAuth('plugbank', { provider: 'tecnospeed' })
|
|
108
|
+
*
|
|
109
|
+
* `provider` defaults to the connector id because for almost every connector
|
|
110
|
+
* the two are the same word, and a default that is right by construction is one
|
|
111
|
+
* fewer thing for the next connector to get wrong.
|
|
112
|
+
*/
|
|
113
|
+
export declare function fayzConnectorOAuth(connectorId: string, options?: {
|
|
114
|
+
provider?: string;
|
|
115
|
+
}): (redirectTo?: string, context?: {
|
|
116
|
+
tenantId?: string;
|
|
117
|
+
}) => Promise<string>;
|
|
118
|
+
//# sourceMappingURL=connector-oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-oauth.d.ts","sourceRoot":"","sources":["../../src/lib/connector-oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAA2B,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAGpF,mFAAmF;AACnF,qBAAa,mBAAoB,SAAQ,KAAK;IAG1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;gBADxB,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA;CAK3B;AAED,wFAAwF;AACxF,qBAAa,iCAAkC,SAAQ,mBAAmB;;CAKzE;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAA;IAClB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,mEAAmE;AACnE,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACxD;AAID,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAEpF;AAED,gFAAgF;AAChF,wBAAgB,wBAAwB,IAAI,qBAAqB,GAAG,IAAI,CAEvE;AAED,MAAM,WAAW,gCAAgC;IAC/C,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,YAAY,EAAE,sBAAsB,CAAA;IACpC,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB;AAQD;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,gCAAgC,GACxC,qBAAqB,CA2DvB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAAG;IAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAA;CAAE,GAC3E,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAW3E"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The credential sink — where a tenant's secret goes INSTEAD of into the app.
|
|
3
|
+
*
|
|
4
|
+
* A connector declares an "API Key" field, the hub renders it, and the obvious
|
|
5
|
+
* next move is to hand the typed value to the connector's own `saveConnection`.
|
|
6
|
+
* That move is the hole: connector-author code runs in the browser with a
|
|
7
|
+
* working Supabase client in scope, so "the connector promises not to persist
|
|
8
|
+
* it" is a convention, not a guarantee — and this repo broke it three times
|
|
9
|
+
* before anyone noticed. Dropping the columns did not close it either; the
|
|
10
|
+
* secret still reached the code that chose where to put it.
|
|
11
|
+
*
|
|
12
|
+
* So the secret never reaches that code. The hub splits the form and pushes the
|
|
13
|
+
* secret half here, to a holder outside the app: Fayz keeps it, and the data
|
|
14
|
+
* plane (an edge function, the agent runtime) will read it server-side per call
|
|
15
|
+
* — the redeem consumer is FAY-1389; nothing redeems yet.
|
|
16
|
+
*
|
|
17
|
+
* A port rather than a `fetch`, for the same reason `setPostalLookupProvider` is
|
|
18
|
+
* one: who holds the credential is a deployment fact, not a hub fact. An app
|
|
19
|
+
* supplies its sink once at boot. Supplying none is a valid answer — the hub
|
|
20
|
+
* then refuses to save, which is the only safe way to be unconfigured.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* How the tenant authorized. Mirrors `IntegrationAuthKind` in `@fayz-ai/core`,
|
|
24
|
+
* declared again here because `@fayz-ai/sdk` has no dependencies.
|
|
25
|
+
*/
|
|
26
|
+
export type ConnectorCredentialAuthKind = 'oauth' | 'api-key' | 'mtls';
|
|
27
|
+
export interface StoreConnectorCredentialInput {
|
|
28
|
+
/** Connector the secret belongs to, e.g. 'plugbank'. */
|
|
29
|
+
connectorId: string;
|
|
30
|
+
/** Organization it is scoped to, when the app knows it; the holder may also derive it from the session. */
|
|
31
|
+
tenantId?: string;
|
|
32
|
+
/**
|
|
33
|
+
* How the connector authenticates, from its own `ConnectorDefinition`.
|
|
34
|
+
*
|
|
35
|
+
* The holder needs it and the browser must not invent it, so it is threaded
|
|
36
|
+
* from the declaration rather than guessed from the shape of `secrets`.
|
|
37
|
+
* Optional because a holder may not care; the Fayz sink below defaults it.
|
|
38
|
+
*/
|
|
39
|
+
authKind?: ConnectorCredentialAuthKind;
|
|
40
|
+
/** Declared field key → value. The only object the secret lives in, and it is not kept after the call. */
|
|
41
|
+
secrets: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
/** What an app may keep in its own database once the secret is placed: a handle. */
|
|
44
|
+
export interface ConnectorCredentialRef {
|
|
45
|
+
/** Opaque id the holder gave the credential. Never the credential. */
|
|
46
|
+
id: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ConnectorCredentialSink {
|
|
49
|
+
store(input: StoreConnectorCredentialInput): Promise<ConnectorCredentialRef>;
|
|
50
|
+
}
|
|
51
|
+
export declare function setConnectorCredentialSink(sink: ConnectorCredentialSink | null): void;
|
|
52
|
+
/** Null when the app configured none — callers must refuse, never fall back. */
|
|
53
|
+
export declare function getConnectorCredentialSink(): ConnectorCredentialSink | null;
|
|
54
|
+
/** The credential was not placed. Carries a status when the platform answered. */
|
|
55
|
+
export declare class ConnectorCredentialSinkError extends Error {
|
|
56
|
+
readonly status?: number | undefined;
|
|
57
|
+
constructor(message: string, status?: number | undefined);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* What the sink can tell a token source about the call it is authenticating.
|
|
61
|
+
*
|
|
62
|
+
* Only the tenant, and only as a SELECTOR: the runtime-token endpoint proves
|
|
63
|
+
* membership from the session and refuses anything outside it, so naming an org
|
|
64
|
+
* here narrows which of the caller's own organizations the token is for and can
|
|
65
|
+
* never widen it. Without this the source would have to re-derive the active
|
|
66
|
+
* org from a store it does not know about, in an app that may have several.
|
|
67
|
+
*/
|
|
68
|
+
export interface FayzRuntimeTokenRequest {
|
|
69
|
+
tenantId?: string;
|
|
70
|
+
}
|
|
71
|
+
export type FayzRuntimeTokenSource = string | ((request?: FayzRuntimeTokenRequest) => string | undefined | null | Promise<string | undefined | null>);
|
|
72
|
+
export interface FayzConnectorCredentialSinkOptions {
|
|
73
|
+
/** The Fayz project this app was published from. */
|
|
74
|
+
projectId: string;
|
|
75
|
+
/**
|
|
76
|
+
* A Fayz **runtime-data** token — the only scheme this endpoint accepts,
|
|
77
|
+
* because it is the only one on the public plane that carries tenant identity.
|
|
78
|
+
* A publishable key names an APP, so it cannot say which tenant is connecting.
|
|
79
|
+
*
|
|
80
|
+
* Required, and resolved per call so a short-lived token can be refreshed.
|
|
81
|
+
* There is deliberately no fallback: a sink that cannot authenticate looks
|
|
82
|
+
* configured and is worse than none, so an empty token is a refusal, not a
|
|
83
|
+
* best-effort request.
|
|
84
|
+
*/
|
|
85
|
+
runtimeToken: FayzRuntimeTokenSource;
|
|
86
|
+
/** Fayz platform origin. Defaults to same-origin, which is what an app proxying `/api` wants. */
|
|
87
|
+
baseUrl?: string;
|
|
88
|
+
fetcher?: typeof fetch;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A sink backed by the Fayz platform's connector-connection store.
|
|
92
|
+
*
|
|
93
|
+
* Write-only by construction: the response is a handle, and no method here can
|
|
94
|
+
* read a credential back — redemption is a separate endpoint that requires a
|
|
95
|
+
* second key a browser has no way to hold.
|
|
96
|
+
*/
|
|
97
|
+
export declare function createFayzConnectorCredentialSink(options: FayzConnectorCredentialSinkOptions): ConnectorCredentialSink;
|
|
98
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAEtE,MAAM,WAAW,6BAA6B;IAC5C,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAA;IACnB,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,2BAA2B,CAAA;IACtC,0GAA0G;IAC1G,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;CAC7E;AAID,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,GAAG,IAAI,CAErF;AAED,gFAAgF;AAChF,wBAAgB,0BAA0B,IAAI,uBAAuB,GAAG,IAAI,CAE3E;AAgCD,kFAAkF;AAClF,qBAAa,4BAA6B,SAAQ,KAAK;IAGnD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;gBADxB,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA;CAK3B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,sBAAsB,GAC9B,MAAM,GACN,CAAC,CACC,OAAO,CAAC,EAAE,uBAAuB,KAC9B,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,CAAA;AAExE,MAAM,WAAW,kCAAkC;IACjD,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;;;;OASG;IACH,YAAY,EAAE,sBAAsB,CAAA;IACpC,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB;AAuDD;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,kCAAkC,GAC1C,uBAAuB,CA6EzB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request de-duplication at the transport boundary: while a GET is in flight,
|
|
3
|
+
* an identical GET joins it instead of opening a second connection.
|
|
4
|
+
*
|
|
5
|
+
* Above the transport it is already too late — by the time two components have
|
|
6
|
+
* called `list()`, there are two requests. Nothing is cached (the entry dies
|
|
7
|
+
* when the response settles), so this cannot serve stale data: the TTL cache in
|
|
8
|
+
* @fayz-ai/core decides whether to ask, this decides what one question costs.
|
|
9
|
+
*/
|
|
10
|
+
export interface DedupeFetchOptions {
|
|
11
|
+
/** Extra request headers that make two same-URL reads different. */
|
|
12
|
+
varyHeaders?: string[];
|
|
13
|
+
/** Called when a request joined one already in flight. For diagnostics. */
|
|
14
|
+
onCollapse?: (key: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface DedupeStats {
|
|
17
|
+
/** Requests that never reached the network because they joined another. */
|
|
18
|
+
collapsed: number;
|
|
19
|
+
/** Requests currently in flight and joinable. */
|
|
20
|
+
inFlight: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function getDedupeStats(): DedupeStats;
|
|
23
|
+
/** Test seam — drops in-flight bookkeeping and the counter. */
|
|
24
|
+
export declare function resetDedupeStats(): void;
|
|
25
|
+
export declare function createDedupedFetch(baseFetch?: typeof fetch, options?: DedupeFetchOptions): typeof fetch;
|
|
26
|
+
//# sourceMappingURL=dedupe-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedupe-fetch.d.ts","sourceRoot":"","sources":["../../src/lib/dedupe-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgBH,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAYD,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAkBD,wBAAgB,kBAAkB,CAGhC,SAAS,GAAE,OAAO,KAAmC,EACrD,OAAO,GAAE,kBAAuB,GAC/B,OAAO,KAAK,CAsDd"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the Fayz platform lives, from whatever the app happened to configure.
|
|
3
|
+
*
|
|
4
|
+
* Two spellings are already in the wild and they disagree by one segment:
|
|
5
|
+
* `VITE_FAYZ_API_BASE_URL` in a published app's env is written as
|
|
6
|
+
* `https://host/api` (that is what the agent broker client consumes), while the
|
|
7
|
+
* sink and the token source below build paths that start with `/api`. Taking
|
|
8
|
+
* either at face value produces `/api/api/public/...` in half the fleet, and a
|
|
9
|
+
* 404 at connect time reads as "the platform refused my credential".
|
|
10
|
+
*
|
|
11
|
+
* So the origin is normalised once, here, rather than in each caller: trailing
|
|
12
|
+
* slashes go, and a trailing `/api` is dropped because the paths add it back.
|
|
13
|
+
*/
|
|
14
|
+
export declare function fayzPlatformOrigin(baseUrl: string | undefined): string;
|
|
15
|
+
//# sourceMappingURL=platform-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-url.d.ts","sourceRoot":"","sources":["../../src/lib/platform-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGtE"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The key the credential sink needs — minted once, in one place.
|
|
3
|
+
*
|
|
4
|
+
* `ConnectorCredentialSink` requires a Fayz runtime-data token and deliberately
|
|
5
|
+
* has no fallback, so until something hands it one the connect button refuses.
|
|
6
|
+
* The token exists: `POST /api/public/projects/:projectId/runtime-token` trades
|
|
7
|
+
* the app's OWN Supabase session for it. What did not exist is the client, and
|
|
8
|
+
* writing that `fetch` per app is how five apps end up with five cache policies
|
|
9
|
+
* and four of them without one.
|
|
10
|
+
*
|
|
11
|
+
* The exchange, as the platform actually implements it:
|
|
12
|
+
*
|
|
13
|
+
* Authorization: Bearer <the app's Supabase access token>
|
|
14
|
+
* body: { tenantId? } → 201
|
|
15
|
+
* { token, tokenType: 'Bearer', expiresIn, projectId, tenantId }
|
|
16
|
+
*
|
|
17
|
+
* `tenantId` in the body is a SELECTOR, never an assertion. The platform
|
|
18
|
+
* verifies the session against the project's published JWKS, asks the app's own
|
|
19
|
+
* database which organizations that user belongs to, and refuses a `tenantId`
|
|
20
|
+
* outside that set; omitting it is resolved only when the answer is
|
|
21
|
+
* unambiguous. Naming a tenant here therefore cannot widen anything — which is
|
|
22
|
+
* why it is safe for the hub to pass the org the merchant is looking at.
|
|
23
|
+
*
|
|
24
|
+
* Fail-closed throughout: no session means no token means the sink refuses. A
|
|
25
|
+
* source that quietly resolved to an empty string would leave an app looking
|
|
26
|
+
* configured while every save fails, which is the failure that is hard to read.
|
|
27
|
+
*/
|
|
28
|
+
import type { FayzRuntimeTokenRequest } from './credentials';
|
|
29
|
+
/** No token was minted. Carries a status when the platform answered. */
|
|
30
|
+
export declare class FayzRuntimeTokenError extends Error {
|
|
31
|
+
readonly status?: number | undefined;
|
|
32
|
+
constructor(message: string, status?: number | undefined);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The slice of a Supabase client this module touches.
|
|
36
|
+
*
|
|
37
|
+
* Duck-typed because `@fayz-ai/sdk` has no dependencies and must not grow one:
|
|
38
|
+
* an app passes the client it already built (`getFayzSupabaseClientOptional()`
|
|
39
|
+
* in `@fayz-ai/admin`), and nothing here needs the other four hundred methods.
|
|
40
|
+
*/
|
|
41
|
+
export interface SupabaseSessionClientLike {
|
|
42
|
+
auth: {
|
|
43
|
+
getSession(): Promise<{
|
|
44
|
+
data: {
|
|
45
|
+
session: {
|
|
46
|
+
access_token?: string | null;
|
|
47
|
+
} | null;
|
|
48
|
+
};
|
|
49
|
+
}>;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
type Resolvable<T> = T | (() => T | Promise<T>);
|
|
53
|
+
export interface FayzRuntimeTokenSourceOptions {
|
|
54
|
+
/** The Fayz project this app was published from. */
|
|
55
|
+
projectId: string;
|
|
56
|
+
/**
|
|
57
|
+
* The app's Supabase client, or a getter for one.
|
|
58
|
+
*
|
|
59
|
+
* A getter is the usual answer: the client is built when the app boots its
|
|
60
|
+
* backend, which is after the module that installs the sink has run. Reading
|
|
61
|
+
* it once at construction would pin `null` forever.
|
|
62
|
+
*/
|
|
63
|
+
supabase?: Resolvable<SupabaseSessionClientLike | null | undefined>;
|
|
64
|
+
/**
|
|
65
|
+
* Or, for an app whose session does not come from supabase-js, the access
|
|
66
|
+
* token itself. Exactly one of `supabase` / `accessToken` is required.
|
|
67
|
+
*/
|
|
68
|
+
accessToken?: Resolvable<string | null | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Which organization to ask for when the caller names none. Still only a
|
|
71
|
+
* selector — see the header. Apps with one org per user can leave it unset.
|
|
72
|
+
*/
|
|
73
|
+
tenantId?: Resolvable<string | null | undefined>;
|
|
74
|
+
/** Fayz platform origin. Defaults to same-origin, which is what an app proxying `/api` wants. */
|
|
75
|
+
baseUrl?: string;
|
|
76
|
+
fetcher?: typeof fetch;
|
|
77
|
+
/**
|
|
78
|
+
* How long before expiry a cached token stops being handed out. The token is
|
|
79
|
+
* short-lived (15 minutes today) and the request it authenticates is a POST
|
|
80
|
+
* that must not fail at the boundary, so the last stretch is not spent.
|
|
81
|
+
*/
|
|
82
|
+
refreshLeadSeconds?: number;
|
|
83
|
+
/** Test seam. */
|
|
84
|
+
now?: () => number;
|
|
85
|
+
}
|
|
86
|
+
export interface FayzRuntimeTokenSourceHandle {
|
|
87
|
+
(request?: FayzRuntimeTokenRequest): Promise<string>;
|
|
88
|
+
/** Forget every cached token — after a sign-out, or an org switch that changed who is asking. */
|
|
89
|
+
invalidate(): void;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Trade the app's Supabase session for a Fayz runtime-data token, and keep it
|
|
93
|
+
* until shortly before it expires.
|
|
94
|
+
*
|
|
95
|
+
* The result is a function, so it drops straight into the sink:
|
|
96
|
+
*
|
|
97
|
+
* setConnectorCredentialSink(createFayzConnectorCredentialSink({
|
|
98
|
+
* projectId,
|
|
99
|
+
* runtimeToken: createFayzRuntimeTokenSource({ projectId, supabase: getClient }),
|
|
100
|
+
* }))
|
|
101
|
+
*/
|
|
102
|
+
export declare function createFayzRuntimeTokenSource(options: FayzRuntimeTokenSourceOptions): FayzRuntimeTokenSourceHandle;
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=runtime-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-token.d.ts","sourceRoot":"","sources":["../../src/lib/runtime-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAG5D,wEAAwE;AACxE,qBAAa,qBAAsB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;gBADxB,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA;CAK3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE;QACJ,UAAU,IAAI,OAAO,CAAC;YAAE,IAAI,EAAE;gBAAE,OAAO,EAAE;oBAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;iBAAE,GAAG,IAAI,CAAA;aAAE,CAAA;SAAE,CAAC,CAAA;KACtF,CAAA;CACF;AAED,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/C,MAAM,WAAW,6BAA6B;IAC5C,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC,yBAAyB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACnE;;;OAGG;IACH,WAAW,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACnD;;;OAGG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAChD,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;IACtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACpD,iGAAiG;IACjG,UAAU,IAAI,IAAI,CAAA;CACnB;AA8BD;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,4BAA4B,CAqH9B"}
|
package/dist/release-channels.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { fayzPackageVersionSets, resolveFayzPackageDependencies, resolveFayzPackageVersion, resolveFayzPackageVersions } from './chunk-
|
|
1
|
+
export { fayzPackageVersionSets, resolveFayzPackageDependencies, resolveFayzPackageVersion, resolveFayzPackageVersions } from './chunk-U7SC2YFQ.js';
|
|
2
2
|
//# sourceMappingURL=release-channels.js.map
|
|
3
3
|
//# sourceMappingURL=release-channels.js.map
|
|
@@ -1,103 +1,103 @@
|
|
|
1
1
|
{
|
|
2
2
|
"channels": {
|
|
3
3
|
"stable": {
|
|
4
|
-
"@fayz-ai/sdk": "^0.
|
|
5
|
-
"@fayz-ai/admin": "^0.
|
|
6
|
-
"@fayz-ai/core": "^0.
|
|
7
|
-
"@fayz-ai/auth": "^0.
|
|
8
|
-
"@fayz-ai/ui": "^0.
|
|
9
|
-
"@fayz-ai/shop": "^0.
|
|
10
|
-
"@fayz-ai/storefront": "^0.
|
|
11
|
-
"@fayz-ai/portal": "^0.
|
|
12
|
-
"@fayz-ai/courses": "^0.
|
|
13
|
-
"@fayz-ai/db": "^0.
|
|
14
|
-
"@fayz-ai/plugin-agenda": "^0.
|
|
15
|
-
"@fayz-ai/plugin-auth": "^0.
|
|
16
|
-
"@fayz-ai/plugin-automations": "^0.
|
|
17
|
-
"@fayz-ai/plugin-blog": "^0.
|
|
18
|
-
"@fayz-ai/plugin-conversations": "^0.9.
|
|
19
|
-
"@fayz-ai/plugin-courses": "^0.
|
|
20
|
-
"@fayz-ai/plugin-crm": "^0.9.
|
|
21
|
-
"@fayz-ai/plugin-dashboard": "^0.9.
|
|
22
|
-
"@fayz-ai/plugin-financial": "^0.9.
|
|
23
|
-
"@fayz-ai/plugin-forms": "^0.9.
|
|
24
|
-
"@fayz-ai/plugin-inventory": "^0.9.
|
|
25
|
-
"@fayz-ai/plugin-marketing": "^0.
|
|
26
|
-
"@fayz-ai/plugin-menu": "^0.9.
|
|
27
|
-
"@fayz-ai/plugin-orders": "^0.9.
|
|
28
|
-
"@fayz-ai/plugin-payments": "^0.9.
|
|
29
|
-
"@fayz-ai/plugin-reports": "^0.
|
|
30
|
-
"@fayz-ai/plugin-reputation": "^0.9.
|
|
31
|
-
"@fayz-ai/plugin-shop": "^0.
|
|
32
|
-
"@fayz-ai/plugin-sites": "^0.9.
|
|
33
|
-
"@fayz-ai/plugin-tables": "^0.9.
|
|
34
|
-
"@fayz-ai/plugin-tasks": "^0.9.
|
|
4
|
+
"@fayz-ai/sdk": "^0.11.0",
|
|
5
|
+
"@fayz-ai/admin": "^0.11.0",
|
|
6
|
+
"@fayz-ai/core": "^0.11.0",
|
|
7
|
+
"@fayz-ai/auth": "^0.11.0",
|
|
8
|
+
"@fayz-ai/ui": "^0.11.0",
|
|
9
|
+
"@fayz-ai/shop": "^0.11.0",
|
|
10
|
+
"@fayz-ai/storefront": "^0.11.0",
|
|
11
|
+
"@fayz-ai/portal": "^0.11.0",
|
|
12
|
+
"@fayz-ai/courses": "^0.11.0",
|
|
13
|
+
"@fayz-ai/db": "^0.11.0",
|
|
14
|
+
"@fayz-ai/plugin-agenda": "^0.10.0",
|
|
15
|
+
"@fayz-ai/plugin-auth": "^0.10.0",
|
|
16
|
+
"@fayz-ai/plugin-automations": "^0.10.0",
|
|
17
|
+
"@fayz-ai/plugin-blog": "^0.11.0",
|
|
18
|
+
"@fayz-ai/plugin-conversations": "^0.9.2",
|
|
19
|
+
"@fayz-ai/plugin-courses": "^0.10.0",
|
|
20
|
+
"@fayz-ai/plugin-crm": "^0.9.2",
|
|
21
|
+
"@fayz-ai/plugin-dashboard": "^0.9.2",
|
|
22
|
+
"@fayz-ai/plugin-financial": "^0.9.2",
|
|
23
|
+
"@fayz-ai/plugin-forms": "^0.9.2",
|
|
24
|
+
"@fayz-ai/plugin-inventory": "^0.9.2",
|
|
25
|
+
"@fayz-ai/plugin-marketing": "^0.10.0",
|
|
26
|
+
"@fayz-ai/plugin-menu": "^0.9.2",
|
|
27
|
+
"@fayz-ai/plugin-orders": "^0.9.2",
|
|
28
|
+
"@fayz-ai/plugin-payments": "^0.9.2",
|
|
29
|
+
"@fayz-ai/plugin-reports": "^0.10.0",
|
|
30
|
+
"@fayz-ai/plugin-reputation": "^0.9.2",
|
|
31
|
+
"@fayz-ai/plugin-shop": "^0.10.0",
|
|
32
|
+
"@fayz-ai/plugin-sites": "^0.9.2",
|
|
33
|
+
"@fayz-ai/plugin-tables": "^0.9.2",
|
|
34
|
+
"@fayz-ai/plugin-tasks": "^0.9.2"
|
|
35
35
|
},
|
|
36
36
|
"latest": {
|
|
37
|
-
"@fayz-ai/sdk": "^0.
|
|
38
|
-
"@fayz-ai/admin": "^0.
|
|
39
|
-
"@fayz-ai/core": "^0.
|
|
40
|
-
"@fayz-ai/auth": "^0.
|
|
41
|
-
"@fayz-ai/ui": "^0.
|
|
42
|
-
"@fayz-ai/shop": "^0.
|
|
43
|
-
"@fayz-ai/storefront": "^0.
|
|
44
|
-
"@fayz-ai/portal": "^0.
|
|
45
|
-
"@fayz-ai/courses": "^0.
|
|
46
|
-
"@fayz-ai/db": "^0.
|
|
47
|
-
"@fayz-ai/plugin-agenda": "^0.
|
|
48
|
-
"@fayz-ai/plugin-auth": "^0.
|
|
49
|
-
"@fayz-ai/plugin-automations": "^0.
|
|
50
|
-
"@fayz-ai/plugin-blog": "^0.
|
|
51
|
-
"@fayz-ai/plugin-conversations": "^0.9.
|
|
52
|
-
"@fayz-ai/plugin-courses": "^0.
|
|
53
|
-
"@fayz-ai/plugin-crm": "^0.9.
|
|
54
|
-
"@fayz-ai/plugin-dashboard": "^0.9.
|
|
55
|
-
"@fayz-ai/plugin-financial": "^0.9.
|
|
56
|
-
"@fayz-ai/plugin-forms": "^0.9.
|
|
57
|
-
"@fayz-ai/plugin-inventory": "^0.9.
|
|
58
|
-
"@fayz-ai/plugin-marketing": "^0.
|
|
59
|
-
"@fayz-ai/plugin-menu": "^0.9.
|
|
60
|
-
"@fayz-ai/plugin-orders": "^0.9.
|
|
61
|
-
"@fayz-ai/plugin-payments": "^0.9.
|
|
62
|
-
"@fayz-ai/plugin-reports": "^0.
|
|
63
|
-
"@fayz-ai/plugin-reputation": "^0.9.
|
|
64
|
-
"@fayz-ai/plugin-shop": "^0.
|
|
65
|
-
"@fayz-ai/plugin-sites": "^0.9.
|
|
66
|
-
"@fayz-ai/plugin-tables": "^0.9.
|
|
67
|
-
"@fayz-ai/plugin-tasks": "^0.9.
|
|
37
|
+
"@fayz-ai/sdk": "^0.11.0",
|
|
38
|
+
"@fayz-ai/admin": "^0.11.0",
|
|
39
|
+
"@fayz-ai/core": "^0.11.0",
|
|
40
|
+
"@fayz-ai/auth": "^0.11.0",
|
|
41
|
+
"@fayz-ai/ui": "^0.11.0",
|
|
42
|
+
"@fayz-ai/shop": "^0.11.0",
|
|
43
|
+
"@fayz-ai/storefront": "^0.11.0",
|
|
44
|
+
"@fayz-ai/portal": "^0.11.0",
|
|
45
|
+
"@fayz-ai/courses": "^0.11.0",
|
|
46
|
+
"@fayz-ai/db": "^0.11.0",
|
|
47
|
+
"@fayz-ai/plugin-agenda": "^0.10.0",
|
|
48
|
+
"@fayz-ai/plugin-auth": "^0.10.0",
|
|
49
|
+
"@fayz-ai/plugin-automations": "^0.10.0",
|
|
50
|
+
"@fayz-ai/plugin-blog": "^0.11.0",
|
|
51
|
+
"@fayz-ai/plugin-conversations": "^0.9.2",
|
|
52
|
+
"@fayz-ai/plugin-courses": "^0.10.0",
|
|
53
|
+
"@fayz-ai/plugin-crm": "^0.9.2",
|
|
54
|
+
"@fayz-ai/plugin-dashboard": "^0.9.2",
|
|
55
|
+
"@fayz-ai/plugin-financial": "^0.9.2",
|
|
56
|
+
"@fayz-ai/plugin-forms": "^0.9.2",
|
|
57
|
+
"@fayz-ai/plugin-inventory": "^0.9.2",
|
|
58
|
+
"@fayz-ai/plugin-marketing": "^0.10.0",
|
|
59
|
+
"@fayz-ai/plugin-menu": "^0.9.2",
|
|
60
|
+
"@fayz-ai/plugin-orders": "^0.9.2",
|
|
61
|
+
"@fayz-ai/plugin-payments": "^0.9.2",
|
|
62
|
+
"@fayz-ai/plugin-reports": "^0.10.0",
|
|
63
|
+
"@fayz-ai/plugin-reputation": "^0.9.2",
|
|
64
|
+
"@fayz-ai/plugin-shop": "^0.10.0",
|
|
65
|
+
"@fayz-ai/plugin-sites": "^0.9.2",
|
|
66
|
+
"@fayz-ai/plugin-tables": "^0.9.2",
|
|
67
|
+
"@fayz-ai/plugin-tasks": "^0.9.2"
|
|
68
68
|
},
|
|
69
69
|
"preview": {
|
|
70
|
-
"@fayz-ai/sdk": "^0.
|
|
71
|
-
"@fayz-ai/admin": "^0.
|
|
72
|
-
"@fayz-ai/core": "^0.
|
|
73
|
-
"@fayz-ai/auth": "^0.
|
|
74
|
-
"@fayz-ai/ui": "^0.
|
|
75
|
-
"@fayz-ai/shop": "^0.
|
|
76
|
-
"@fayz-ai/storefront": "^0.
|
|
77
|
-
"@fayz-ai/portal": "^0.
|
|
78
|
-
"@fayz-ai/courses": "^0.
|
|
79
|
-
"@fayz-ai/db": "^0.
|
|
80
|
-
"@fayz-ai/plugin-agenda": "^0.
|
|
81
|
-
"@fayz-ai/plugin-auth": "^0.
|
|
82
|
-
"@fayz-ai/plugin-automations": "^0.
|
|
83
|
-
"@fayz-ai/plugin-blog": "^0.
|
|
84
|
-
"@fayz-ai/plugin-conversations": "^0.9.
|
|
85
|
-
"@fayz-ai/plugin-courses": "^0.
|
|
86
|
-
"@fayz-ai/plugin-crm": "^0.9.
|
|
87
|
-
"@fayz-ai/plugin-dashboard": "^0.9.
|
|
88
|
-
"@fayz-ai/plugin-financial": "^0.9.
|
|
89
|
-
"@fayz-ai/plugin-forms": "^0.9.
|
|
90
|
-
"@fayz-ai/plugin-inventory": "^0.9.
|
|
91
|
-
"@fayz-ai/plugin-marketing": "^0.
|
|
92
|
-
"@fayz-ai/plugin-menu": "^0.9.
|
|
93
|
-
"@fayz-ai/plugin-orders": "^0.9.
|
|
94
|
-
"@fayz-ai/plugin-payments": "^0.9.
|
|
95
|
-
"@fayz-ai/plugin-reports": "^0.
|
|
96
|
-
"@fayz-ai/plugin-reputation": "^0.9.
|
|
97
|
-
"@fayz-ai/plugin-shop": "^0.
|
|
98
|
-
"@fayz-ai/plugin-sites": "^0.9.
|
|
99
|
-
"@fayz-ai/plugin-tables": "^0.9.
|
|
100
|
-
"@fayz-ai/plugin-tasks": "^0.9.
|
|
70
|
+
"@fayz-ai/sdk": "^0.11.0",
|
|
71
|
+
"@fayz-ai/admin": "^0.11.0",
|
|
72
|
+
"@fayz-ai/core": "^0.11.0",
|
|
73
|
+
"@fayz-ai/auth": "^0.11.0",
|
|
74
|
+
"@fayz-ai/ui": "^0.11.0",
|
|
75
|
+
"@fayz-ai/shop": "^0.11.0",
|
|
76
|
+
"@fayz-ai/storefront": "^0.11.0",
|
|
77
|
+
"@fayz-ai/portal": "^0.11.0",
|
|
78
|
+
"@fayz-ai/courses": "^0.11.0",
|
|
79
|
+
"@fayz-ai/db": "^0.11.0",
|
|
80
|
+
"@fayz-ai/plugin-agenda": "^0.10.0",
|
|
81
|
+
"@fayz-ai/plugin-auth": "^0.10.0",
|
|
82
|
+
"@fayz-ai/plugin-automations": "^0.10.0",
|
|
83
|
+
"@fayz-ai/plugin-blog": "^0.11.0",
|
|
84
|
+
"@fayz-ai/plugin-conversations": "^0.9.2",
|
|
85
|
+
"@fayz-ai/plugin-courses": "^0.10.0",
|
|
86
|
+
"@fayz-ai/plugin-crm": "^0.9.2",
|
|
87
|
+
"@fayz-ai/plugin-dashboard": "^0.9.2",
|
|
88
|
+
"@fayz-ai/plugin-financial": "^0.9.2",
|
|
89
|
+
"@fayz-ai/plugin-forms": "^0.9.2",
|
|
90
|
+
"@fayz-ai/plugin-inventory": "^0.9.2",
|
|
91
|
+
"@fayz-ai/plugin-marketing": "^0.10.0",
|
|
92
|
+
"@fayz-ai/plugin-menu": "^0.9.2",
|
|
93
|
+
"@fayz-ai/plugin-orders": "^0.9.2",
|
|
94
|
+
"@fayz-ai/plugin-payments": "^0.9.2",
|
|
95
|
+
"@fayz-ai/plugin-reports": "^0.10.0",
|
|
96
|
+
"@fayz-ai/plugin-reputation": "^0.9.2",
|
|
97
|
+
"@fayz-ai/plugin-shop": "^0.10.0",
|
|
98
|
+
"@fayz-ai/plugin-sites": "^0.9.2",
|
|
99
|
+
"@fayz-ai/plugin-tables": "^0.9.2",
|
|
100
|
+
"@fayz-ai/plugin-tasks": "^0.9.2"
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
}
|