@fayz-ai/sdk 0.15.0 → 0.30.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.
@@ -52,27 +52,6 @@ var deprecations_default = {
52
52
  codemod: "commerce.discounts-to-promotions",
53
53
  reference: "docs/storefront/storefront-architecture-spine.md (M6, I8), docs/storefront/storefront-contract.md"
54
54
  },
55
- {
56
- id: "shop.inventory.directCountWrite",
57
- package: "@fayz-ai/shop",
58
- surface: "sql-column-write",
59
- title: "direct writes to plg_shop_product_variants.inventory_count (and plg_shop_products.inventory_count)",
60
- deprecatedIn: "0.9.0",
61
- removeIn: "0.11.0",
62
- replacement: "insert a plg_shop_stock_movements row (receipt / adjustment / loss / count) \u2014 the ledger is the truth and inventory_count is its mirror",
63
- shim: "0036 turns a direct write to a VARIANT count into an `adjustment` movement with reason `legacy_write`, and 0037 forwards a write to the PRODUCT count to that product's default variant the same way. Both RAISE a WARNING. The quantities are exact; the taxonomy is not \u2014 the shim is told a number changed and never why, so a sale arriving this way is recorded as an adjustment with no order_id.",
64
- where: [
65
- "packages/shop/migrations/0036_inventory_count_mirror.sql",
66
- "packages/shop/migrations/0037_default_variant.sql"
67
- ],
68
- signals: [
69
- "DEPRECATED (I10): direct write to plg_shop_product_variants.inventory_count",
70
- "DEPRECATED (I10): direct write to plg_shop_products.inventory_count"
71
- ],
72
- detect: "Not visible in a store's repo: it is a property of the callers writing to a pool. Count the `legacy_write` reason in plg_shop_stock_movements \u2014 that count IS the migration backlog.",
73
- codemod: "shop.inventory-count-write",
74
- reference: "docs/storefront/inventory-model.md \xA76, \xA79 step 3"
75
- },
76
55
  {
77
56
  id: "shop.placeOrder.variantless",
78
57
  package: "@fayz-ai/shop",
@@ -82,7 +61,7 @@ var deprecations_default = {
82
61
  removeIn: "0.11.0",
83
62
  replacement: "every product gets a default variant (migration 0037), and the variant is the universal sellable unit \u2014 the order line resolves a variant and the sale reaches the ledger",
84
63
  shim: "0039 keeps the leg: a line whose product has no variant at all still sells, guarded against the product-level inventory_count exactly as before 0034. It emits one enumerable NOTICE per order naming the products that took it, so the deprecation is countable rather than silent. Such a sale does NOT reach the stock ledger, so it answers none of the questions inventory-model.md \xA70 exists for.",
85
- where: ["packages/shop/migrations/0039_place_order_ledger.sql"],
64
+ where: ["packages/shop/migrations/000_baseline.sql"],
86
65
  signals: ["shop_place_order: DEPRECATED variantless stock path used for"],
87
66
  detect: "Not visible in a store's repo: it is pool state. Its exit condition is in 0039's header \u2014 the count of products with no variant must read 0 on every pool.",
88
67
  codemod: "shop.place-order-variantless",
@@ -177,5 +156,5 @@ function deprecationWindowMinors(row) {
177
156
  }
178
157
 
179
158
  export { deprecationMessage, deprecationWindowMinors, deprecationsForCodemod, fayzDeprecationPolicy, getDeprecation, hasDeprecation, isDeprecationShimmed, listDeprecationCodemods, listDeprecations, resetDeprecationWarnings, table, warnDeprecated };
180
- //# sourceMappingURL=chunk-HA5O3CW7.js.map
181
- //# sourceMappingURL=chunk-HA5O3CW7.js.map
159
+ //# sourceMappingURL=chunk-LCW5ZV5S.js.map
160
+ //# sourceMappingURL=chunk-LCW5ZV5S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/deprecations.json","../src/deprecations.ts"],"names":[],"mappings":"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","file":"chunk-LCW5ZV5S.js","sourcesContent":["{\n \"registryVersion\": 1,\n \"policy\": {\n \"minMinorsBeforeRemoval\": 2,\n \"summary\": \"Nothing is removed without a shim, and the deprecation is enumerable (spine I10). A deprecation is ANNOUNCED in a minor release and REMOVED no earlier than two minor releases later, so a store always has one whole release in which both the old and the new input work. Every shim's warning names its replacement (I2). Every row here carries a codemod id; a codemod that cannot be safe refuses and names the decision a human must make.\"\n },\n \"deprecations\": [\n {\n \"id\": \"admin.package.saas\",\n \"package\": \"@fayz-ai/saas\",\n \"surface\": \"package-name\",\n \"title\": \"the @fayz-ai/saas package name\",\n \"deprecatedIn\": \"0.10.0\",\n \"removeIn\": \"0.12.0\",\n \"replacement\": \"@fayz-ai/admin — same exports, same subpaths (/ui, /db, /org, /billing, /permissions), renamed because the package is the admin surface (shell, CRUD engine, org, billing, permissions), not the business model\",\n \"shim\": \"packages/saas is now a thin package that re-exports @fayz-ai/admin, so an app that has not migrated builds and runs unchanged. What it costs is a second package in the graph and one console warning per entry point per session. It ships no implementation, so there is no behaviour to drift.\",\n \"where\": [\"packages/saas/src/index.ts\", \"packages/saas/package.json\", \"packages/sdk/src/vite.ts\"],\n \"detect\": \"The app's package.json depends on @fayz-ai/saas, or any file under src/ imports from '@fayz-ai/saas'.\",\n \"codemod\": \"admin.saas-package-rename\",\n \"reference\": \"packages/saas/README.md\"\n },\n {\n \"id\": \"shop.provider.productMetadata\",\n \"package\": \"@fayz-ai/sdk\",\n \"surface\": \"provider-option\",\n \"title\": \"createFayzShopProvider({ productMetadata })\",\n \"deprecatedIn\": \"0.9.0\",\n \"removeIn\": \"0.11.0\",\n \"replacement\": \"product variants — plg_shop_product_variants, read through products.bySlug / getProductVariants (admin > product > variants)\",\n \"shim\": \"The overlay is still merged into each product's metadata for DISPLAY, so a store passing it keeps rendering. What it no longer does is define the option axes checkout sells: 0028 variants are the sellable unit and 0029 prices and names an order line from them. An axis that exists only in the overlay renders a picker that resolves to no variant.\",\n \"where\": [\"packages/sdk/src/shop.ts\", \"packages/storefront/src/data/product-options.ts\"],\n \"detect\": \"The app passes `productMetadata` to createFayzShopProvider (usually src/config/shop.ts), or the running provider warns once per session.\",\n \"codemod\": \"shop.product-metadata-overlay\",\n \"reference\": \"docs/storefront/storefront-architecture-spine.md (M5), docs/storefront/storefront-contract.md\"\n },\n {\n \"id\": \"storefront.commerce.discounts\",\n \"package\": \"@fayz-ai/storefront\",\n \"surface\": \"document-field\",\n \"title\": \"config.discounts / commerce.discounts (percent coupon codes)\",\n \"deprecatedIn\": \"0.9.0\",\n \"removeIn\": \"0.11.0\",\n \"replacement\": \"promotions.promotions — a rule-engine Promotion with an eligibility rule on `code` and a percentage application method (spine M6, I8)\",\n \"shim\": \"The provider still honours the legacy path: every `{code, percent}` entry is translated by storefrontDiscountToPromotion and evaluated by the ONE rule engine, so the money is identical. What the legacy shape cannot express is everything the engine exists for — buy-N-get-M, tiers, minimum subtotal, product/category scoping, automatic application.\",\n \"where\": [\n \"packages/shop/src/rules/adapter.ts\",\n \"packages/storefront/src/hooks/use-discount-validator.ts\",\n \"packages/storefront/src/document/sections.ts\"\n ],\n \"detect\": \"commerce.discounts is present in the Store Document (config.discounts in a config-derived document).\",\n \"codemod\": \"commerce.discounts-to-promotions\",\n \"reference\": \"docs/storefront/storefront-architecture-spine.md (M6, I8), docs/storefront/storefront-contract.md\"\n },\n{\n \"id\": \"shop.placeOrder.variantless\",\n \"package\": \"@fayz-ai/shop\",\n \"surface\": \"sql-code-path\",\n \"title\": \"the variantless leg of shop_place_order\",\n \"deprecatedIn\": \"0.9.0\",\n \"removeIn\": \"0.11.0\",\n \"replacement\": \"every product gets a default variant (migration 0037), and the variant is the universal sellable unit — the order line resolves a variant and the sale reaches the ledger\",\n \"shim\": \"0039 keeps the leg: a line whose product has no variant at all still sells, guarded against the product-level inventory_count exactly as before 0034. It emits one enumerable NOTICE per order naming the products that took it, so the deprecation is countable rather than silent. Such a sale does NOT reach the stock ledger, so it answers none of the questions inventory-model.md §0 exists for.\",\n \"where\": [\"packages/shop/migrations/000_baseline.sql\"],\n \"signals\": [\"shop_place_order: DEPRECATED variantless stock path used for\"],\n \"detect\": \"Not visible in a store's repo: it is pool state. Its exit condition is in 0039's header — the count of products with no variant must read 0 on every pool.\",\n \"codemod\": \"shop.place-order-variantless\",\n \"reference\": \"docs/storefront/inventory-model.md §10 q6, packages/shop/migrations/0039_place_order_ledger.sql (header)\"\n },\n {\n \"id\": \"storefront.backend.supabaseUrl\",\n \"package\": \"@fayz-ai/storefront\",\n \"surface\": \"document-field\",\n \"title\": \"config.supabaseUrl / backend.supabaseUrl\",\n \"deprecatedIn\": \"0.9.0\",\n \"removeIn\": \"0.11.0\",\n \"replacement\": \"auth.supabase.url\",\n \"shim\": \"The legacy field still rides in the backend section so an old config round-trips losslessly, and hydrateStoreDocument still sets config.supabaseUrl from it.\",\n \"where\": [\"packages/storefront/src/document/sections.ts\", \"packages/storefront/src/document/round-trip.ts\"],\n \"detect\": \"backend.supabaseUrl is present in the Store Document.\",\n \"codemod\": \"backend.supabase-to-auth\",\n \"reference\": \"docs/storefront/storefront-contract.md\"\n },\n {\n \"id\": \"storefront.backend.supabaseAnonKey\",\n \"package\": \"@fayz-ai/storefront\",\n \"surface\": \"document-field\",\n \"title\": \"config.supabaseAnonKey / backend.supabaseAnonKey\",\n \"deprecatedIn\": \"0.9.0\",\n \"removeIn\": \"0.11.0\",\n \"replacement\": \"auth.supabase.anonKey\",\n \"shim\": \"The legacy field still rides in the backend section so an old config round-trips losslessly, and hydrateStoreDocument still sets config.supabaseAnonKey from it.\",\n \"where\": [\"packages/storefront/src/document/sections.ts\", \"packages/storefront/src/document/round-trip.ts\"],\n \"detect\": \"backend.supabaseAnonKey is present in the Store Document.\",\n \"codemod\": \"backend.supabase-to-auth\",\n \"reference\": \"docs/storefront/storefront-contract.md\"\n }\n ]\n}\n","import registry from './deprecations.json'\n\n// ---------------------------------------------------------------------------\n// The deprecation registry — spine I10, as ROWS.\n//\n// \"Nothing is removed without a shim, and the deprecation is enumerable.\" The\n// enumerable half is this file. WooCommerce keeps 60 deprecated hooks alive\n// through a DECLARED map dispatched at runtime; the reason that works at their\n// scale is that the map is data one tool can read. Ours is\n// `deprecations.json`, and it lives here for the same reason\n// `supported-surface.json` and `release-channels.json` do: @fayz-ai/sdk has no\n// dependencies, so every package, the CLI and a generated app can all read the\n// same table without anyone taking a dependency to do it.\n//\n// Two properties are load-bearing, and both are tested:\n//\n// 1. EVERY warning names its replacement (I2). A shim that can import this\n// module builds its message with `deprecationMessage(id)`, so the warning\n// and the row cannot drift. A shim that CANNOT — PL/pgSQL cannot import\n// JSON — declares its literal marker text in the row's `signals`, and a\n// test asserts that text really occurs in the named migration.\n// 2. EVERY row carries a codemod id. `fayz upgrade` either transforms the\n// document or REFUSES and names the decision a human must make. A\n// deprecation with no answer at all is the thing this registry exists to\n// make impossible.\n//\n// The policy is a number, not a promise: a deprecation announced in 0.9 is\n// removed no earlier than 0.11, so a fleet always has one whole release in\n// which both the old and the new input work.\n// ---------------------------------------------------------------------------\n\n/** Where a deprecated thing lives, which is also what can detect it. */\nexport type FayzDeprecationSurface =\n /** A field of the Store Document (and of the config it is derived from). */\n | 'document-field'\n /** An option passed to a provider factory in the store's own code. */\n | 'provider-option'\n /** A write to a column that is no longer the truth. */\n | 'sql-column-write'\n /** A branch of a SQL function kept alive for data that has not migrated. */\n | 'sql-code-path'\n /** A package name kept alive by a re-export after the package was renamed. */\n | 'package-name'\n\nexport interface FayzDeprecation {\n /** Stable dotted id. The key everything else references. */\n id: string\n /** Package that owns the surface. */\n package: string\n surface: FayzDeprecationSurface\n /** What is deprecated, in the words the author would recognize. */\n title: string\n /** SDK minor in which the deprecation was ANNOUNCED. */\n deprecatedIn: string\n /** SDK minor in which the shim is REMOVED. */\n removeIn: string\n /** What to use instead. Every warning for this id names it (I2). */\n replacement: string\n /** What keeps working during the window, and precisely what it costs. */\n shim: string\n /** Repo paths where the shim lives — the registry has to be auditable. */\n where: string[]\n /**\n * Literal marker text the shim emits at runtime, for shims that cannot build\n * their message from this row (PL/pgSQL). Asserted against the real file by\n * packages/shop/src/deprecations.test.ts.\n */\n signals?: string[]\n /** How `fayz upgrade` finds it in a store — including \"you cannot, here is\n * the query that counts it in the pool instead\". */\n detect: string\n /** Codemod id that retires it. Never empty: a codemod that cannot be safe\n * exists anyway and refuses, naming the human decision. */\n codemod: string\n /** The design record. */\n reference: string\n}\n\nexport interface FayzDeprecationPolicy {\n /** Minimum number of minor releases between announcement and removal. */\n minMinorsBeforeRemoval: number\n summary: string\n}\n\nexport interface FayzDeprecationRegistry {\n registryVersion: number\n policy: FayzDeprecationPolicy\n deprecations: FayzDeprecation[]\n}\n\nconst table = registry as unknown as FayzDeprecationRegistry\n\nexport const fayzDeprecationPolicy: FayzDeprecationPolicy = table.policy\n\n/** Every deprecation, in declaration order. */\nexport function listDeprecations(): FayzDeprecation[] {\n return table.deprecations.map((row) => ({ ...row, where: [...row.where], signals: row.signals ? [...row.signals] : undefined }))\n}\n\n/** One row by id. Unknown ids throw and name the valid set (I2). */\nexport function getDeprecation(id: string): FayzDeprecation {\n const row = table.deprecations.find((entry) => entry.id === id)\n if (!row) {\n throw new Error(\n `Unknown deprecation id \"${id}\". Valid: ${table.deprecations.map((entry) => entry.id).join(', ')}`,\n )\n }\n return row\n}\n\nexport function hasDeprecation(id: string): boolean {\n return table.deprecations.some((entry) => entry.id === id)\n}\n\n/** Deprecation ids a given codemod retires. */\nexport function deprecationsForCodemod(codemod: string): FayzDeprecation[] {\n return table.deprecations.filter((entry) => entry.codemod === codemod)\n}\n\n/** Every codemod id the registry references, deduped, in declaration order. */\nexport function listDeprecationCodemods(): string[] {\n return [...new Set(table.deprecations.map((entry) => entry.codemod))]\n}\n\n/**\n * The warning text for a deprecation — the ONE place its prose is built.\n *\n * `context` is the caller's specifics (\"on variant abc\", \"at commerce.discounts[0]\");\n * it is appended, never substituted, so no caller can drop the replacement.\n */\nexport function deprecationMessage(id: string, context?: string): string {\n const row = getDeprecation(id)\n const where = context ? ` ${context}` : ''\n return (\n `DEPRECATED (${row.id}):${where} ${row.title} is deprecated since ${row.deprecatedIn} ` +\n `and is REMOVED in ${row.removeIn}. Use instead: ${row.replacement}. ` +\n `Migrate with \\`fayz upgrade\\` (codemod ${row.codemod}).`\n )\n}\n\nconst warned = new Set<string>()\n\n/**\n * Warn once per id per session.\n *\n * Once, because the alternative is one line per request, which buries the\n * signal this exists to produce. The dedupe key is the ID ALONE, not\n * (id, context): a shim whose context varies per call would otherwise\n * re-warn forever and reintroduce exactly the flood the once-ness exists to\n * prevent. Returns true when it actually warned, so a shim is testable\n * without reading the console.\n */\nexport function warnDeprecated(id: string, context?: string): boolean {\n if (warned.has(id)) return false\n warned.add(id)\n console.warn(deprecationMessage(id, context))\n return true\n}\n\n/** Test seam — re-arms every once-per-session deprecation warning. */\nexport function resetDeprecationWarnings(): void {\n warned.clear()\n}\n\nfunction minorOf(version: string): { major: number; minor: number } {\n const [major = '0', minor = '0'] = version.split('.')\n return { major: Number(major), minor: Number(minor) }\n}\n\n/**\n * Does `version` still get the shim?\n *\n * The question every consumer actually asks, answered from the table rather\n * than from a comment. Compared on (major, minor) because the policy is stated\n * in minors — a patch never removes anything.\n */\nexport function isDeprecationShimmed(id: string, version: string): boolean {\n const row = getDeprecation(id)\n const at = minorOf(version)\n const gone = minorOf(row.removeIn)\n if (at.major !== gone.major) return at.major < gone.major\n return at.minor < gone.minor\n}\n\n/** Minors between announcement and removal — the policy's unit. */\nexport function deprecationWindowMinors(row: FayzDeprecation): number {\n const from = minorOf(row.deprecatedIn)\n const to = minorOf(row.removeIn)\n // Majors are not commensurable with minors; a major bump is treated as\n // \"far beyond the window\", which is the only safe reading.\n if (to.major > from.major) return Number.POSITIVE_INFINITY\n return to.minor - from.minor\n}\n\nexport { table as fayzDeprecationRegistry }\n"]}
@@ -0,0 +1,135 @@
1
+ // src/release-channels.json
2
+ var release_channels_default = {
3
+ channels: {
4
+ stable: {
5
+ "@fayz-ai/sdk": "^0.30.1",
6
+ "@fayz-ai/admin": "^0.30.1",
7
+ "@fayz-ai/core": "^0.30.1",
8
+ "@fayz-ai/auth": "^0.30.0",
9
+ "@fayz-ai/ui": "^0.30.0",
10
+ "@fayz-ai/shop": "^0.30.0",
11
+ "@fayz-ai/storefront": "^0.30.0",
12
+ "@fayz-ai/portal": "^0.30.0",
13
+ "@fayz-ai/courses": "^0.30.0",
14
+ "@fayz-ai/db": "^0.18.1",
15
+ "@fayz-ai/plugin-agenda": "^0.18.0",
16
+ "@fayz-ai/plugin-auth": "^0.12.10",
17
+ "@fayz-ai/plugin-automations": "^0.13.8",
18
+ "@fayz-ai/plugin-blog": "^0.12.13",
19
+ "@fayz-ai/plugin-conversations": "^0.20.0",
20
+ "@fayz-ai/plugin-courses": "^0.10.18",
21
+ "@fayz-ai/plugin-crm": "^0.28.2",
22
+ "@fayz-ai/plugin-dashboard": "^0.9.17",
23
+ "@fayz-ai/plugin-financial": "^0.15.0",
24
+ "@fayz-ai/plugin-forms": "^0.11.0",
25
+ "@fayz-ai/plugin-inventory": "^0.13.0",
26
+ "@fayz-ai/plugin-marketing": "^0.13.0",
27
+ "@fayz-ai/plugin-menu": "^0.10.16",
28
+ "@fayz-ai/plugin-orders": "^0.12.13",
29
+ "@fayz-ai/plugin-payments": "^0.9.15",
30
+ "@fayz-ai/plugin-reports": "^0.14.0",
31
+ "@fayz-ai/plugin-reputation": "^0.10.12",
32
+ "@fayz-ai/plugin-shop": "^0.16.0",
33
+ "@fayz-ai/plugin-sites": "^0.9.15",
34
+ "@fayz-ai/plugin-tables": "^0.11.0",
35
+ "@fayz-ai/plugin-tasks": "^0.10.15"
36
+ },
37
+ latest: {
38
+ "@fayz-ai/sdk": "^0.30.1",
39
+ "@fayz-ai/admin": "^0.30.1",
40
+ "@fayz-ai/core": "^0.30.1",
41
+ "@fayz-ai/auth": "^0.30.0",
42
+ "@fayz-ai/ui": "^0.30.0",
43
+ "@fayz-ai/shop": "^0.30.0",
44
+ "@fayz-ai/storefront": "^0.30.0",
45
+ "@fayz-ai/portal": "^0.30.0",
46
+ "@fayz-ai/courses": "^0.30.0",
47
+ "@fayz-ai/db": "^0.18.1",
48
+ "@fayz-ai/plugin-agenda": "^0.18.0",
49
+ "@fayz-ai/plugin-auth": "^0.12.10",
50
+ "@fayz-ai/plugin-automations": "^0.13.8",
51
+ "@fayz-ai/plugin-blog": "^0.12.13",
52
+ "@fayz-ai/plugin-conversations": "^0.20.0",
53
+ "@fayz-ai/plugin-courses": "^0.10.18",
54
+ "@fayz-ai/plugin-crm": "^0.28.2",
55
+ "@fayz-ai/plugin-dashboard": "^0.9.17",
56
+ "@fayz-ai/plugin-financial": "^0.15.0",
57
+ "@fayz-ai/plugin-forms": "^0.11.0",
58
+ "@fayz-ai/plugin-inventory": "^0.13.0",
59
+ "@fayz-ai/plugin-marketing": "^0.13.0",
60
+ "@fayz-ai/plugin-menu": "^0.10.16",
61
+ "@fayz-ai/plugin-orders": "^0.12.13",
62
+ "@fayz-ai/plugin-payments": "^0.9.15",
63
+ "@fayz-ai/plugin-reports": "^0.14.0",
64
+ "@fayz-ai/plugin-reputation": "^0.10.12",
65
+ "@fayz-ai/plugin-shop": "^0.16.0",
66
+ "@fayz-ai/plugin-sites": "^0.9.15",
67
+ "@fayz-ai/plugin-tables": "^0.11.0",
68
+ "@fayz-ai/plugin-tasks": "^0.10.15"
69
+ },
70
+ preview: {
71
+ "@fayz-ai/sdk": "^0.30.1",
72
+ "@fayz-ai/admin": "^0.30.1",
73
+ "@fayz-ai/core": "^0.30.1",
74
+ "@fayz-ai/auth": "^0.30.0",
75
+ "@fayz-ai/ui": "^0.30.0",
76
+ "@fayz-ai/shop": "^0.30.0",
77
+ "@fayz-ai/storefront": "^0.30.0",
78
+ "@fayz-ai/portal": "^0.30.0",
79
+ "@fayz-ai/courses": "^0.30.0",
80
+ "@fayz-ai/db": "^0.18.1",
81
+ "@fayz-ai/plugin-agenda": "^0.18.0",
82
+ "@fayz-ai/plugin-auth": "^0.12.10",
83
+ "@fayz-ai/plugin-automations": "^0.13.8",
84
+ "@fayz-ai/plugin-blog": "^0.12.13",
85
+ "@fayz-ai/plugin-conversations": "^0.20.0",
86
+ "@fayz-ai/plugin-courses": "^0.10.18",
87
+ "@fayz-ai/plugin-crm": "^0.28.2",
88
+ "@fayz-ai/plugin-dashboard": "^0.9.17",
89
+ "@fayz-ai/plugin-financial": "^0.15.0",
90
+ "@fayz-ai/plugin-forms": "^0.11.0",
91
+ "@fayz-ai/plugin-inventory": "^0.13.0",
92
+ "@fayz-ai/plugin-marketing": "^0.13.0",
93
+ "@fayz-ai/plugin-menu": "^0.10.16",
94
+ "@fayz-ai/plugin-orders": "^0.12.13",
95
+ "@fayz-ai/plugin-payments": "^0.9.15",
96
+ "@fayz-ai/plugin-reports": "^0.14.0",
97
+ "@fayz-ai/plugin-reputation": "^0.10.12",
98
+ "@fayz-ai/plugin-shop": "^0.16.0",
99
+ "@fayz-ai/plugin-sites": "^0.9.15",
100
+ "@fayz-ai/plugin-tables": "^0.11.0",
101
+ "@fayz-ai/plugin-tasks": "^0.10.15"
102
+ }
103
+ }
104
+ };
105
+
106
+ // src/release-channels.ts
107
+ var releaseChannelPackages = release_channels_default.channels;
108
+ function buildVersionSet(channel) {
109
+ return {
110
+ channel,
111
+ packages: { ...releaseChannelPackages[channel] }
112
+ };
113
+ }
114
+ var fayzPackageVersionSets = {
115
+ stable: buildVersionSet("stable"),
116
+ latest: buildVersionSet("latest"),
117
+ preview: buildVersionSet("preview")
118
+ };
119
+ function resolveFayzPackageVersions(channel = "stable") {
120
+ return fayzPackageVersionSets[channel];
121
+ }
122
+ function resolveFayzPackageDependencies(channel = "stable") {
123
+ return { ...resolveFayzPackageVersions(channel).packages };
124
+ }
125
+ function resolveFayzPackageVersion(packageName, channel = "stable") {
126
+ const version = resolveFayzPackageVersions(channel).packages[packageName];
127
+ if (!version) {
128
+ throw new Error(`No Fayz package version configured for ${packageName} in ${channel} channel`);
129
+ }
130
+ return version;
131
+ }
132
+
133
+ export { fayzPackageVersionSets, resolveFayzPackageDependencies, resolveFayzPackageVersion, resolveFayzPackageVersions };
134
+ //# sourceMappingURL=chunk-QFCM6SHF.js.map
135
+ //# sourceMappingURL=chunk-QFCM6SHF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/release-channels.json","../src/release-channels.ts"],"names":[],"mappings":"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","file":"chunk-QFCM6SHF.js","sourcesContent":["{\n \"channels\": {\n \"stable\": {\n \"@fayz-ai/sdk\": \"^0.30.1\",\n \"@fayz-ai/admin\": \"^0.30.1\",\n \"@fayz-ai/core\": \"^0.30.1\",\n \"@fayz-ai/auth\": \"^0.30.0\",\n \"@fayz-ai/ui\": \"^0.30.0\",\n \"@fayz-ai/shop\": \"^0.30.0\",\n \"@fayz-ai/storefront\": \"^0.30.0\",\n \"@fayz-ai/portal\": \"^0.30.0\",\n \"@fayz-ai/courses\": \"^0.30.0\",\n \"@fayz-ai/db\": \"^0.18.1\",\n \"@fayz-ai/plugin-agenda\": \"^0.18.0\",\n \"@fayz-ai/plugin-auth\": \"^0.12.10\",\n \"@fayz-ai/plugin-automations\": \"^0.13.8\",\n \"@fayz-ai/plugin-blog\": \"^0.12.13\",\n \"@fayz-ai/plugin-conversations\": \"^0.20.0\",\n \"@fayz-ai/plugin-courses\": \"^0.10.18\",\n \"@fayz-ai/plugin-crm\": \"^0.28.2\",\n \"@fayz-ai/plugin-dashboard\": \"^0.9.17\",\n \"@fayz-ai/plugin-financial\": \"^0.15.0\",\n \"@fayz-ai/plugin-forms\": \"^0.11.0\",\n \"@fayz-ai/plugin-inventory\": \"^0.13.0\",\n \"@fayz-ai/plugin-marketing\": \"^0.13.0\",\n \"@fayz-ai/plugin-menu\": \"^0.10.16\",\n \"@fayz-ai/plugin-orders\": \"^0.12.13\",\n \"@fayz-ai/plugin-payments\": \"^0.9.15\",\n \"@fayz-ai/plugin-reports\": \"^0.14.0\",\n \"@fayz-ai/plugin-reputation\": \"^0.10.12\",\n \"@fayz-ai/plugin-shop\": \"^0.16.0\",\n \"@fayz-ai/plugin-sites\": \"^0.9.15\",\n \"@fayz-ai/plugin-tables\": \"^0.11.0\",\n \"@fayz-ai/plugin-tasks\": \"^0.10.15\"\n },\n \"latest\": {\n \"@fayz-ai/sdk\": \"^0.30.1\",\n \"@fayz-ai/admin\": \"^0.30.1\",\n \"@fayz-ai/core\": \"^0.30.1\",\n \"@fayz-ai/auth\": \"^0.30.0\",\n \"@fayz-ai/ui\": \"^0.30.0\",\n \"@fayz-ai/shop\": \"^0.30.0\",\n \"@fayz-ai/storefront\": \"^0.30.0\",\n \"@fayz-ai/portal\": \"^0.30.0\",\n \"@fayz-ai/courses\": \"^0.30.0\",\n \"@fayz-ai/db\": \"^0.18.1\",\n \"@fayz-ai/plugin-agenda\": \"^0.18.0\",\n \"@fayz-ai/plugin-auth\": \"^0.12.10\",\n \"@fayz-ai/plugin-automations\": \"^0.13.8\",\n \"@fayz-ai/plugin-blog\": \"^0.12.13\",\n \"@fayz-ai/plugin-conversations\": \"^0.20.0\",\n \"@fayz-ai/plugin-courses\": \"^0.10.18\",\n \"@fayz-ai/plugin-crm\": \"^0.28.2\",\n \"@fayz-ai/plugin-dashboard\": \"^0.9.17\",\n \"@fayz-ai/plugin-financial\": \"^0.15.0\",\n \"@fayz-ai/plugin-forms\": \"^0.11.0\",\n \"@fayz-ai/plugin-inventory\": \"^0.13.0\",\n \"@fayz-ai/plugin-marketing\": \"^0.13.0\",\n \"@fayz-ai/plugin-menu\": \"^0.10.16\",\n \"@fayz-ai/plugin-orders\": \"^0.12.13\",\n \"@fayz-ai/plugin-payments\": \"^0.9.15\",\n \"@fayz-ai/plugin-reports\": \"^0.14.0\",\n \"@fayz-ai/plugin-reputation\": \"^0.10.12\",\n \"@fayz-ai/plugin-shop\": \"^0.16.0\",\n \"@fayz-ai/plugin-sites\": \"^0.9.15\",\n \"@fayz-ai/plugin-tables\": \"^0.11.0\",\n \"@fayz-ai/plugin-tasks\": \"^0.10.15\"\n },\n \"preview\": {\n \"@fayz-ai/sdk\": \"^0.30.1\",\n \"@fayz-ai/admin\": \"^0.30.1\",\n \"@fayz-ai/core\": \"^0.30.1\",\n \"@fayz-ai/auth\": \"^0.30.0\",\n \"@fayz-ai/ui\": \"^0.30.0\",\n \"@fayz-ai/shop\": \"^0.30.0\",\n \"@fayz-ai/storefront\": \"^0.30.0\",\n \"@fayz-ai/portal\": \"^0.30.0\",\n \"@fayz-ai/courses\": \"^0.30.0\",\n \"@fayz-ai/db\": \"^0.18.1\",\n \"@fayz-ai/plugin-agenda\": \"^0.18.0\",\n \"@fayz-ai/plugin-auth\": \"^0.12.10\",\n \"@fayz-ai/plugin-automations\": \"^0.13.8\",\n \"@fayz-ai/plugin-blog\": \"^0.12.13\",\n \"@fayz-ai/plugin-conversations\": \"^0.20.0\",\n \"@fayz-ai/plugin-courses\": \"^0.10.18\",\n \"@fayz-ai/plugin-crm\": \"^0.28.2\",\n \"@fayz-ai/plugin-dashboard\": \"^0.9.17\",\n \"@fayz-ai/plugin-financial\": \"^0.15.0\",\n \"@fayz-ai/plugin-forms\": \"^0.11.0\",\n \"@fayz-ai/plugin-inventory\": \"^0.13.0\",\n \"@fayz-ai/plugin-marketing\": \"^0.13.0\",\n \"@fayz-ai/plugin-menu\": \"^0.10.16\",\n \"@fayz-ai/plugin-orders\": \"^0.12.13\",\n \"@fayz-ai/plugin-payments\": \"^0.9.15\",\n \"@fayz-ai/plugin-reports\": \"^0.14.0\",\n \"@fayz-ai/plugin-reputation\": \"^0.10.12\",\n \"@fayz-ai/plugin-shop\": \"^0.16.0\",\n \"@fayz-ai/plugin-sites\": \"^0.9.15\",\n \"@fayz-ai/plugin-tables\": \"^0.11.0\",\n \"@fayz-ai/plugin-tasks\": \"^0.10.15\"\n }\n }\n}\n","import releaseChannels from './release-channels.json'\n\nexport type FayzPackageChannel = 'stable' | 'latest' | 'preview'\n\nexport interface FayzPackageVersionSet {\n channel: FayzPackageChannel\n packages: Record<string, string>\n}\n\nconst releaseChannelPackages = releaseChannels.channels as Record<FayzPackageChannel, Record<string, string>>\n\nfunction buildVersionSet(channel: FayzPackageChannel): FayzPackageVersionSet {\n return {\n channel,\n packages: { ...releaseChannelPackages[channel] },\n }\n}\n\nexport const fayzPackageVersionSets: Record<FayzPackageChannel, FayzPackageVersionSet> = {\n stable: buildVersionSet('stable'),\n latest: buildVersionSet('latest'),\n preview: buildVersionSet('preview'),\n}\n\nexport function resolveFayzPackageVersions(channel: FayzPackageChannel = 'stable'): FayzPackageVersionSet {\n return fayzPackageVersionSets[channel]\n}\n\nexport function resolveFayzPackageDependencies(channel: FayzPackageChannel = 'stable'): Record<string, string> {\n return { ...resolveFayzPackageVersions(channel).packages }\n}\n\nexport function resolveFayzPackageVersion(packageName: string, channel: FayzPackageChannel = 'stable'): string {\n const version = resolveFayzPackageVersions(channel).packages[packageName]\n\n if (!version) {\n throw new Error(`No Fayz package version configured for ${packageName} in ${channel} channel`)\n }\n\n return version\n}\n"]}
@@ -1,3 +1,3 @@
1
- export { deprecationMessage, deprecationWindowMinors, deprecationsForCodemod, fayzDeprecationPolicy, table as fayzDeprecationRegistry, getDeprecation, hasDeprecation, isDeprecationShimmed, listDeprecationCodemods, listDeprecations, resetDeprecationWarnings, warnDeprecated } from './chunk-HA5O3CW7.js';
1
+ export { deprecationMessage, deprecationWindowMinors, deprecationsForCodemod, fayzDeprecationPolicy, table as fayzDeprecationRegistry, getDeprecation, hasDeprecation, isDeprecationShimmed, listDeprecationCodemods, listDeprecations, resetDeprecationWarnings, warnDeprecated } from './chunk-LCW5ZV5S.js';
2
2
  //# sourceMappingURL=deprecations.js.map
3
3
  //# sourceMappingURL=deprecations.js.map
@@ -51,28 +51,7 @@
51
51
  "codemod": "commerce.discounts-to-promotions",
52
52
  "reference": "docs/storefront/storefront-architecture-spine.md (M6, I8), docs/storefront/storefront-contract.md"
53
53
  },
54
- {
55
- "id": "shop.inventory.directCountWrite",
56
- "package": "@fayz-ai/shop",
57
- "surface": "sql-column-write",
58
- "title": "direct writes to plg_shop_product_variants.inventory_count (and plg_shop_products.inventory_count)",
59
- "deprecatedIn": "0.9.0",
60
- "removeIn": "0.11.0",
61
- "replacement": "insert a plg_shop_stock_movements row (receipt / adjustment / loss / count) — the ledger is the truth and inventory_count is its mirror",
62
- "shim": "0036 turns a direct write to a VARIANT count into an `adjustment` movement with reason `legacy_write`, and 0037 forwards a write to the PRODUCT count to that product's default variant the same way. Both RAISE a WARNING. The quantities are exact; the taxonomy is not — the shim is told a number changed and never why, so a sale arriving this way is recorded as an adjustment with no order_id.",
63
- "where": [
64
- "packages/shop/migrations/0036_inventory_count_mirror.sql",
65
- "packages/shop/migrations/0037_default_variant.sql"
66
- ],
67
- "signals": [
68
- "DEPRECATED (I10): direct write to plg_shop_product_variants.inventory_count",
69
- "DEPRECATED (I10): direct write to plg_shop_products.inventory_count"
70
- ],
71
- "detect": "Not visible in a store's repo: it is a property of the callers writing to a pool. Count the `legacy_write` reason in plg_shop_stock_movements — that count IS the migration backlog.",
72
- "codemod": "shop.inventory-count-write",
73
- "reference": "docs/storefront/inventory-model.md §6, §9 step 3"
74
- },
75
- {
54
+ {
76
55
  "id": "shop.placeOrder.variantless",
77
56
  "package": "@fayz-ai/shop",
78
57
  "surface": "sql-code-path",
@@ -81,7 +60,7 @@
81
60
  "removeIn": "0.11.0",
82
61
  "replacement": "every product gets a default variant (migration 0037), and the variant is the universal sellable unit — the order line resolves a variant and the sale reaches the ledger",
83
62
  "shim": "0039 keeps the leg: a line whose product has no variant at all still sells, guarded against the product-level inventory_count exactly as before 0034. It emits one enumerable NOTICE per order naming the products that took it, so the deprecation is countable rather than silent. Such a sale does NOT reach the stock ledger, so it answers none of the questions inventory-model.md §0 exists for.",
84
- "where": ["packages/shop/migrations/0039_place_order_ledger.sql"],
63
+ "where": ["packages/shop/migrations/000_baseline.sql"],
85
64
  "signals": ["shop_place_order: DEPRECATED variantless stock path used for"],
86
65
  "detect": "Not visible in a store's repo: it is pool state. Its exit condition is in 0039's header — the count of products with no variant must read 0 on every pool.",
87
66
  "codemod": "shop.place-order-variantless",
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,uBAAuB;IACtC,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;IACtB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,OAAO,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAA;IAC1C,sEAAsE;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,OAAO,IAAI,MAAM,CAAA;IACjB,0DAA0D;IAC1D,OAAO,IAAI,IAAI,CAAA;CAChB;AAeD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAqGzF"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,uBAAuB;IACtC,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;IACtB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,OAAO,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAA;IAC1C,sEAAsE;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,OAAO,IAAI,MAAM,CAAA;IACjB,0DAA0D;IAC1D,OAAO,IAAI,IAAI,CAAA;CAChB;AAgCD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAyGzF"}
package/dist/events.js CHANGED
@@ -1,4 +1,17 @@
1
1
  // src/events.ts
2
+ function debugOn() {
3
+ try {
4
+ const flag = typeof localStorage !== "undefined" ? localStorage.getItem("debug") : null;
5
+ if (flag === "off") return false;
6
+ if (flag) return flag.split(",").some((p) => ["*", "bridge", "bridge.*"].includes(p.trim()));
7
+ return import.meta.env?.DEV === true;
8
+ } catch {
9
+ return false;
10
+ }
11
+ }
12
+ function dlog(message, ...data) {
13
+ if (debugOn()) console.log(`%cbridge%c ${message}`, "color:hsl(210 60% 45%);font-weight:600", "", ...data);
14
+ }
2
15
  var MAX_BATCH = 50;
3
16
  var MAX_QUEUE = 500;
4
17
  var MAX_ATTEMPTS = 5;
@@ -30,7 +43,10 @@ function createFayzEventsClient(options) {
30
43
  },
31
44
  body: JSON.stringify({ events: batch.map((q) => q.event) })
32
45
  });
33
- if (response.ok) return;
46
+ if (response.ok) {
47
+ dlog(`flushed ${batch.length} event(s) \u2192 ${response.status}`, batch.map((q) => q.event.key));
48
+ return;
49
+ }
34
50
  if (response.status >= 400 && response.status < 500 && response.status !== 429) {
35
51
  console.warn(`[fayz-events] batch dropped: ingress answered ${response.status}`);
36
52
  return;
@@ -47,7 +63,8 @@ function createFayzEventsClient(options) {
47
63
  queue = queue.slice(batch.length);
48
64
  retryBackoffMs = BASE_RETRY_MS;
49
65
  if (queue.length > 0) schedule(0);
50
- } catch {
66
+ } catch (err) {
67
+ dlog(`flush failed, will retry in ${retryBackoffMs}ms`, err instanceof Error ? err.message : err);
51
68
  for (const q of batch) q.attempts++;
52
69
  const dead = batch.filter((q) => q.attempts >= MAX_ATTEMPTS);
53
70
  if (dead.length > 0) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/events.ts"],"names":[],"mappings":"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","file":"events.js","sourcesContent":["/**\n * Client for the Fayz domain-event ingress.\n *\n * `POST /api/public/projects/:id/events` is the door the platform opens for a\n * published app to report facts (`agenda.booking_created`, …) so automations can\n * react to them. This client owns what the transport needs and the emitter must\n * not think about: batching, retry with backoff, and flushing on page exit. The\n * emitter keeps calling `emitDomainEvent` — the bridge in `@fayz-ai/admin`\n * forwards every event here.\n *\n * Events carry an emitter-generated `id`: the server dedupes on it, which is\n * what makes retrying safe. A batch the server already saw counts as duplicates\n * instead of re-running automations.\n */\n\nexport interface FayzDomainEventInput {\n /** Emitter-owned id — the dedupe key across retries. */\n id: string\n key: string\n payload: Record<string, unknown>\n tenantId?: string | null\n actorId?: string | null\n /** ISO. The emitter decides — a reprocessed event keeps the original. */\n occurredAt: string\n subject?: { type: string; id: string } | null\n}\n\nexport interface FayzEventsClientOptions {\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 /** How long the queue coalesces before sending. Default 2s. */\n flushDelayMs?: number\n}\n\nexport interface FayzEventsClient {\n /** Queues an event; the batch goes out after `flushDelayMs` or on `flush()`. */\n enqueue(event: FayzDomainEventInput): void\n /** Sends everything queued now. Resolves when the attempt settles. */\n flush(): Promise<void>\n pending(): number\n /** Unhooks the page-exit listener and drops the queue. */\n dispose(): void\n}\n\n// The server caps a batch at 50; the queue caps total backlog so a dead network\n// cannot grow memory forever. Dropping is announced — never silent.\nconst MAX_BATCH = 50\nconst MAX_QUEUE = 500\nconst MAX_ATTEMPTS = 5\nconst BASE_RETRY_MS = 5_000\nconst MAX_RETRY_MS = 60_000\n\ninterface QueuedEvent {\n event: FayzDomainEventInput\n attempts: number\n}\n\nexport function createFayzEventsClient(options: FayzEventsClientOptions): FayzEventsClient {\n const fetcher = options.fetcher ?? ((...args: Parameters<typeof fetch>) => fetch(...args))\n const flushDelayMs = options.flushDelayMs ?? 2_000\n const url = `${options.baseUrl.replace(/\\/$/, '')}/public/projects/${options.projectId}/events`\n\n let queue: QueuedEvent[] = []\n let timer: ReturnType<typeof setTimeout> | null = null\n let retryBackoffMs = BASE_RETRY_MS\n let inFlight: Promise<void> | null = null\n let disposed = false\n\n function schedule(delay: number): void {\n if (timer || disposed) return\n timer = setTimeout(() => {\n timer = null\n void flush()\n }, delay)\n }\n\n async function send(batch: QueuedEvent[], keepalive: boolean): Promise<void> {\n const response = await fetcher(url, {\n method: 'POST',\n keepalive,\n headers: {\n 'Content-Type': 'application/json',\n 'x-fayz-agent-key': options.publishableKey,\n },\n body: JSON.stringify({ events: batch.map((q) => q.event) }),\n })\n if (response.ok) return\n // 4xx other than 429 will not heal on retry — a malformed envelope or a\n // revoked key retried forever is just noise on the owner's rate budget.\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n console.warn(`[fayz-events] batch dropped: ingress answered ${response.status}`)\n return\n }\n throw new Error(`ingress answered ${response.status}`)\n }\n\n async function flush(): Promise<void> {\n if (inFlight) return inFlight\n if (queue.length === 0 || disposed) return\n const batch = queue.slice(0, MAX_BATCH)\n inFlight = (async () => {\n try {\n await send(batch, false)\n queue = queue.slice(batch.length)\n retryBackoffMs = BASE_RETRY_MS\n if (queue.length > 0) schedule(0)\n } catch {\n // Transient — the batch stays at the front, with a strike each.\n for (const q of batch) q.attempts++\n const dead = batch.filter((q) => q.attempts >= MAX_ATTEMPTS)\n if (dead.length > 0) {\n console.warn(`[fayz-events] dropped ${dead.length} event(s) after ${MAX_ATTEMPTS} attempts`)\n queue = queue.filter((q) => q.attempts < MAX_ATTEMPTS)\n }\n if (queue.length > 0) schedule(retryBackoffMs)\n retryBackoffMs = Math.min(retryBackoffMs * 2, MAX_RETRY_MS)\n } finally {\n inFlight = null\n }\n })()\n return inFlight\n }\n\n // On page exit there is no time for the retry dance: one keepalive shot with\n // whatever is queued. `fetch` keepalive (not sendBeacon) because the key\n // travels in a header, which a beacon cannot carry.\n const onPageHide = (): void => {\n if (queue.length === 0) return\n const batch = queue.slice(0, MAX_BATCH)\n queue = queue.slice(batch.length)\n void send(batch, true).catch(() => {})\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('pagehide', onPageHide)\n }\n\n return {\n enqueue(event) {\n if (disposed) return\n if (queue.length >= MAX_QUEUE) {\n console.warn('[fayz-events] queue full — dropping oldest event')\n queue.shift()\n }\n queue.push({ event, attempts: 0 })\n schedule(flushDelayMs)\n },\n flush,\n pending: () => queue.length,\n dispose() {\n disposed = true\n if (timer) clearTimeout(timer)\n timer = null\n queue = []\n if (typeof window !== 'undefined') {\n window.removeEventListener('pagehide', onPageHide)\n }\n },\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/events.ts"],"names":[],"mappings":";AAmDA,SAAS,OAAA,GAAmB;AAC1B,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,OAAO,YAAA,KAAiB,cAAc,YAAA,CAAa,OAAA,CAAQ,OAAO,CAAA,GAAI,IAAA;AACnF,IAAA,IAAI,IAAA,KAAS,OAAO,OAAO,KAAA;AAC3B,IAAA,IAAI,MAAM,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA,CAAE,KAAK,CAAC,CAAA,KAAM,CAAC,GAAA,EAAK,UAAU,UAAU,CAAA,CAAE,SAAS,CAAA,CAAE,IAAA,EAAM,CAAC,CAAA;AAC3F,IAAA,OAAQ,MAAA,CAAA,IAAA,CAAuD,KAAK,GAAA,KAAQ,IAAA;AAAA,EAC9E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AACA,SAAS,IAAA,CAAK,YAAoB,IAAA,EAAuB;AAEvD,EAAA,IAAI,OAAA,EAAQ,EAAG,OAAA,CAAQ,GAAA,CAAI,CAAA,WAAA,EAAc,OAAO,CAAA,CAAA,EAAI,wCAAA,EAA0C,EAAA,EAAI,GAAG,IAAI,CAAA;AAC3G;AAEA,IAAM,SAAA,GAAY,EAAA;AAClB,IAAM,SAAA,GAAY,GAAA;AAClB,IAAM,YAAA,GAAe,CAAA;AACrB,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,YAAA,GAAe,GAAA;AAOd,SAAS,uBAAuB,OAAA,EAAoD;AACzF,EAAA,MAAM,UAAU,OAAA,CAAQ,OAAA,KAAY,IAAI,IAAA,KAAmC,KAAA,CAAM,GAAG,IAAI,CAAA,CAAA;AACxF,EAAA,MAAM,YAAA,GAAe,QAAQ,YAAA,IAAgB,GAAA;AAC7C,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAC,CAAA,iBAAA,EAAoB,OAAA,CAAQ,SAAS,CAAA,OAAA,CAAA;AAEtF,EAAA,IAAI,QAAuB,EAAC;AAC5B,EAAA,IAAI,KAAA,GAA8C,IAAA;AAClD,EAAA,IAAI,cAAA,GAAiB,aAAA;AACrB,EAAA,IAAI,QAAA,GAAiC,IAAA;AACrC,EAAA,IAAI,QAAA,GAAW,KAAA;AAEf,EAAA,SAAS,SAAS,KAAA,EAAqB;AACrC,IAAA,IAAI,SAAS,QAAA,EAAU;AACvB,IAAA,KAAA,GAAQ,WAAW,MAAM;AACvB,MAAA,KAAA,GAAQ,IAAA;AACR,MAAA,KAAK,KAAA,EAAM;AAAA,IACb,GAAG,KAAK,CAAA;AAAA,EACV;AAEA,EAAA,eAAe,IAAA,CAAK,OAAsB,SAAA,EAAmC;AAC3E,IAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,GAAA,EAAK;AAAA,MAClC,MAAA,EAAQ,MAAA;AAAA,MACR,SAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,oBAAoB,OAAA,CAAQ;AAAA,OAC9B;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAA,EAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAA,EAAG;AAAA,KAC3D,CAAA;AACD,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,IAAA,CAAK,CAAA,QAAA,EAAW,KAAA,CAAM,MAAM,CAAA,iBAAA,EAAe,SAAS,MAAM,CAAA,CAAA,EAAI,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AAC3F,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,CAAS,UAAU,GAAA,IAAO,QAAA,CAAS,SAAS,GAAA,IAAO,QAAA,CAAS,WAAW,GAAA,EAAK;AAC9E,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,8CAAA,EAAiD,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAC/E,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,EACvD;AAEA,EAAA,eAAe,KAAA,GAAuB;AACpC,IAAA,IAAI,UAAU,OAAO,QAAA;AACrB,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,QAAA,EAAU;AACpC,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,SAAS,CAAA;AACtC,IAAA,QAAA,GAAA,CAAY,YAAY;AACtB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,OAAO,KAAK,CAAA;AACvB,QAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,KAAA,CAAM,MAAM,CAAA;AAChC,QAAA,cAAA,GAAiB,aAAA;AACjB,QAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,QAAA,CAAS,CAAC,CAAA;AAAA,MAClC,SAAS,GAAA,EAAK;AACZ,QAAA,IAAA,CAAK,+BAA+B,cAAc,CAAA,EAAA,CAAA,EAAM,eAAe,KAAA,GAAQ,GAAA,CAAI,UAAU,GAAG,CAAA;AAEhG,QAAA,KAAA,MAAW,CAAA,IAAK,OAAO,CAAA,CAAE,QAAA,EAAA;AACzB,QAAA,MAAM,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,YAAY,CAAA;AAC3D,QAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,UAAA,OAAA,CAAQ,KAAK,CAAA,sBAAA,EAAyB,IAAA,CAAK,MAAM,CAAA,gBAAA,EAAmB,YAAY,CAAA,SAAA,CAAW,CAAA;AAC3F,UAAA,KAAA,GAAQ,MAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,YAAY,CAAA;AAAA,QACvD;AACA,QAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,QAAA,CAAS,cAAc,CAAA;AAC7C,QAAA,cAAA,GAAiB,IAAA,CAAK,GAAA,CAAI,cAAA,GAAiB,CAAA,EAAG,YAAY,CAAA;AAAA,MAC5D,CAAA,SAAE;AACA,QAAA,QAAA,GAAW,IAAA;AAAA,MACb;AAAA,IACF,CAAA,GAAG;AACH,IAAA,OAAO,QAAA;AAAA,EACT;AAKA,EAAA,MAAM,aAAa,MAAY;AAC7B,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,SAAS,CAAA;AACtC,IAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,KAAA,CAAM,MAAM,CAAA;AAChC,IAAA,KAAK,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA,CAAE,MAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAAA,EACvC,CAAA;AACA,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAA,CAAO,gBAAA,CAAiB,YAAY,UAAU,CAAA;AAAA,EAChD;AAEA,EAAA,OAAO;AAAA,IACL,QAAQ,KAAA,EAAO;AACb,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,IAAI,KAAA,CAAM,UAAU,SAAA,EAAW;AAC7B,QAAA,OAAA,CAAQ,KAAK,uDAAkD,CAAA;AAC/D,QAAA,KAAA,CAAM,KAAA,EAAM;AAAA,MACd;AACA,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,KAAA,EAAO,QAAA,EAAU,GAAG,CAAA;AACjC,MAAA,QAAA,CAAS,YAAY,CAAA;AAAA,IACvB,CAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,EAAS,MAAM,KAAA,CAAM,MAAA;AAAA,IACrB,OAAA,GAAU;AACR,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,IAAI,KAAA,eAAoB,KAAK,CAAA;AAC7B,MAAA,KAAA,GAAQ,IAAA;AACR,MAAA,KAAA,GAAQ,EAAC;AACT,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,QAAA,MAAA,CAAO,mBAAA,CAAoB,YAAY,UAAU,CAAA;AAAA,MACnD;AAAA,IACF;AAAA,GACF;AACF","file":"events.js","sourcesContent":["/**\n * Client for the Fayz domain-event ingress.\n *\n * `POST /api/public/projects/:id/events` is the door the platform opens for a\n * published app to report facts (`agenda.booking_created`, …) so automations can\n * react to them. This client owns what the transport needs and the emitter must\n * not think about: batching, retry with backoff, and flushing on page exit. The\n * emitter keeps calling `emitDomainEvent` — the bridge in `@fayz-ai/admin`\n * forwards every event here.\n *\n * Events carry an emitter-generated `id`: the server dedupes on it, which is\n * what makes retrying safe. A batch the server already saw counts as duplicates\n * instead of re-running automations.\n */\n\nexport interface FayzDomainEventInput {\n /** Emitter-owned id — the dedupe key across retries. */\n id: string\n key: string\n payload: Record<string, unknown>\n tenantId?: string | null\n actorId?: string | null\n /** ISO. The emitter decides — a reprocessed event keeps the original. */\n occurredAt: string\n subject?: { type: string; id: string } | null\n}\n\nexport interface FayzEventsClientOptions {\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 /** How long the queue coalesces before sending. Default 2s. */\n flushDelayMs?: number\n}\n\nexport interface FayzEventsClient {\n /** Queues an event; the batch goes out after `flushDelayMs` or on `flush()`. */\n enqueue(event: FayzDomainEventInput): void\n /** Sends everything queued now. Resolves when the attempt settles. */\n flush(): Promise<void>\n pending(): number\n /** Unhooks the page-exit listener and drops the queue. */\n dispose(): void\n}\n\n// The server caps a batch at 50; the queue caps total backlog so a dead network\n// cannot grow memory forever. Dropping is announced — never silent.\n// Local copy of the core `createDebug` gate ('bridge' scope) — this package\n// deliberately has no dependency on @fayz-ai/core, and five lines beat one.\nfunction debugOn(): boolean {\n try {\n const flag = typeof localStorage !== 'undefined' ? localStorage.getItem('debug') : null\n if (flag === 'off') return false\n if (flag) return flag.split(',').some((p) => ['*', 'bridge', 'bridge.*'].includes(p.trim()))\n return (import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV === true\n } catch {\n return false\n }\n}\nfunction dlog(message: string, ...data: unknown[]): void {\n // eslint-disable-next-line no-console\n if (debugOn()) console.log(`%cbridge%c ${message}`, 'color:hsl(210 60% 45%);font-weight:600', '', ...data)\n}\n\nconst MAX_BATCH = 50\nconst MAX_QUEUE = 500\nconst MAX_ATTEMPTS = 5\nconst BASE_RETRY_MS = 5_000\nconst MAX_RETRY_MS = 60_000\n\ninterface QueuedEvent {\n event: FayzDomainEventInput\n attempts: number\n}\n\nexport function createFayzEventsClient(options: FayzEventsClientOptions): FayzEventsClient {\n const fetcher = options.fetcher ?? ((...args: Parameters<typeof fetch>) => fetch(...args))\n const flushDelayMs = options.flushDelayMs ?? 2_000\n const url = `${options.baseUrl.replace(/\\/$/, '')}/public/projects/${options.projectId}/events`\n\n let queue: QueuedEvent[] = []\n let timer: ReturnType<typeof setTimeout> | null = null\n let retryBackoffMs = BASE_RETRY_MS\n let inFlight: Promise<void> | null = null\n let disposed = false\n\n function schedule(delay: number): void {\n if (timer || disposed) return\n timer = setTimeout(() => {\n timer = null\n void flush()\n }, delay)\n }\n\n async function send(batch: QueuedEvent[], keepalive: boolean): Promise<void> {\n const response = await fetcher(url, {\n method: 'POST',\n keepalive,\n headers: {\n 'Content-Type': 'application/json',\n 'x-fayz-agent-key': options.publishableKey,\n },\n body: JSON.stringify({ events: batch.map((q) => q.event) }),\n })\n if (response.ok) {\n dlog(`flushed ${batch.length} event(s) → ${response.status}`, batch.map((q) => q.event.key))\n return\n }\n // 4xx other than 429 will not heal on retry — a malformed envelope or a\n // revoked key retried forever is just noise on the owner's rate budget.\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n console.warn(`[fayz-events] batch dropped: ingress answered ${response.status}`)\n return\n }\n throw new Error(`ingress answered ${response.status}`)\n }\n\n async function flush(): Promise<void> {\n if (inFlight) return inFlight\n if (queue.length === 0 || disposed) return\n const batch = queue.slice(0, MAX_BATCH)\n inFlight = (async () => {\n try {\n await send(batch, false)\n queue = queue.slice(batch.length)\n retryBackoffMs = BASE_RETRY_MS\n if (queue.length > 0) schedule(0)\n } catch (err) {\n dlog(`flush failed, will retry in ${retryBackoffMs}ms`, err instanceof Error ? err.message : err)\n // Transient — the batch stays at the front, with a strike each.\n for (const q of batch) q.attempts++\n const dead = batch.filter((q) => q.attempts >= MAX_ATTEMPTS)\n if (dead.length > 0) {\n console.warn(`[fayz-events] dropped ${dead.length} event(s) after ${MAX_ATTEMPTS} attempts`)\n queue = queue.filter((q) => q.attempts < MAX_ATTEMPTS)\n }\n if (queue.length > 0) schedule(retryBackoffMs)\n retryBackoffMs = Math.min(retryBackoffMs * 2, MAX_RETRY_MS)\n } finally {\n inFlight = null\n }\n })()\n return inFlight\n }\n\n // On page exit there is no time for the retry dance: one keepalive shot with\n // whatever is queued. `fetch` keepalive (not sendBeacon) because the key\n // travels in a header, which a beacon cannot carry.\n const onPageHide = (): void => {\n if (queue.length === 0) return\n const batch = queue.slice(0, MAX_BATCH)\n queue = queue.slice(batch.length)\n void send(batch, true).catch(() => {})\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('pagehide', onPageHide)\n }\n\n return {\n enqueue(event) {\n if (disposed) return\n if (queue.length >= MAX_QUEUE) {\n console.warn('[fayz-events] queue full — dropping oldest event')\n queue.shift()\n }\n queue.push({ event, attempts: 0 })\n schedule(flushDelayMs)\n },\n flush,\n pending: () => queue.length,\n dispose() {\n disposed = true\n if (timer) clearTimeout(timer)\n timer = null\n queue = []\n if (typeof window !== 'undefined') {\n window.removeEventListener('pagehide', onPageHide)\n }\n },\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -22,6 +22,8 @@ export { ConnectorCredentialSinkError, createFayzConnectorCredentialSink, getCon
22
22
  export type { ConnectorCredentialAuthKind, ConnectorCredentialRef, ConnectorCredentialSink, FayzConnectorCredentialSinkOptions, FayzRuntimeTokenRequest, FayzRuntimeTokenSource, StoreConnectorCredentialInput, } from './lib/credentials';
23
23
  export { ConnectorOAuthError, ConnectorOAuthStarterMissingError, createFayzConnectorOAuthStarter, fayzConnectorOAuth, getConnectorOAuthStarter, setConnectorOAuthStarter, startConnectorOAuth, } from './lib/connector-oauth';
24
24
  export type { ConnectorOAuthStarter, FayzConnectorOAuthStarterOptions, StartConnectorOAuthInput, } from './lib/connector-oauth';
25
+ export { createFayzConnectorAccountSource, describeConnectorAccount, getConnectorAccountSource, setConnectorAccountSource, } from './lib/connector-account';
26
+ export type { ConnectorAccountInfo, ConnectorAccountSource, DescribeConnectorAccountInput, FayzConnectorAccountSourceOptions, } from './lib/connector-account';
25
27
  export { createFayzRuntimeTokenSource, FayzRuntimeTokenError } from './lib/runtime-token';
26
28
  export type { FayzRuntimeTokenSourceHandle, FayzRuntimeTokenSourceOptions, SupabaseSessionClientLike, } from './lib/runtime-token';
27
29
  export type { AppManifest, FayzApiErrorBody, FayzAppParams, FayzAuthMeResponse, FayzUser, PageManifest, PluginRef, SurfaceManifest, } from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- export { fayzPackageVersionSets, resolveFayzPackageDependencies, resolveFayzPackageVersion, resolveFayzPackageVersions } from './chunk-M5CVCRIL.js';
1
+ export { fayzPackageVersionSets, resolveFayzPackageDependencies, resolveFayzPackageVersion, resolveFayzPackageVersions } from './chunk-QFCM6SHF.js';
2
2
  export { surface as fayzSupportedSurface, getInternalPackages, getSupportedPackages, isSupportedPackage } from './chunk-6UZOXHGJ.js';
3
3
  export { AI_BUILDER_REQUEST_CLASSES, AI_BUILDER_REQUEST_CLASS_IDS, isAllowedRequestClass } from './chunk-BJFMBVMP.js';
4
4
  export { FayzApiError, createFayzClient, fayz } from './chunk-UWOQAD5A.js';
5
5
  export { FayzRuntimeError, createFayzRuntimeClient } from './chunk-FRIOW6KW.js';
6
6
  export { appParams, resolveAppParams } from './chunk-YGX37DT3.js';
7
- export { FayzAgentError, createFayzAgentClient } from './chunk-LSBVNW75.js';
8
- export { FayzShopError, createDedupedFetch, createFayzShopProvider, getDedupeStats, resetDedupeStats } from './chunk-QLTIO3QK.js';
9
- export { deprecationMessage, deprecationWindowMinors, deprecationsForCodemod, fayzDeprecationPolicy, table as fayzDeprecationRegistry, getDeprecation, hasDeprecation, isDeprecationShimmed, listDeprecationCodemods, listDeprecations, resetDeprecationWarnings, warnDeprecated } from './chunk-HA5O3CW7.js';
7
+ export { FayzAgentError, createFayzAgentClient } from './chunk-KTRZI44K.js';
8
+ export { FayzShopError, createDedupedFetch, createFayzShopProvider, getDedupeStats, resetDedupeStats } from './chunk-BTXIUI4E.js';
9
+ export { deprecationMessage, deprecationWindowMinors, deprecationsForCodemod, fayzDeprecationPolicy, table as fayzDeprecationRegistry, getDeprecation, hasDeprecation, isDeprecationShimmed, listDeprecationCodemods, listDeprecations, resetDeprecationWarnings, warnDeprecated } from './chunk-LCW5ZV5S.js';
10
10
 
11
11
  // src/lib/platform-url.ts
12
12
  function fayzPlatformOrigin(baseUrl) {
@@ -201,6 +201,65 @@ function fayzConnectorOAuth(connectorId, options = {}) {
201
201
  });
202
202
  }
203
203
 
204
+ // src/lib/connector-account.ts
205
+ var _source = null;
206
+ function setConnectorAccountSource(source) {
207
+ _source = source;
208
+ }
209
+ function getConnectorAccountSource() {
210
+ return _source;
211
+ }
212
+ function requireValue3(value, field) {
213
+ const normalized = typeof value === "string" ? value.trim() : "";
214
+ if (!normalized) throw new Error(`${field} is required to describe a connector account`);
215
+ return normalized;
216
+ }
217
+ function createFayzConnectorAccountSource(options) {
218
+ const projectId = requireValue3(options.projectId, "projectId");
219
+ const origin = fayzPlatformOrigin(options.baseUrl);
220
+ const fetcher = options.fetcher ?? fetch;
221
+ return {
222
+ async describe(input) {
223
+ const connectorId = requireValue3(input.connectorId, "connectorId");
224
+ const source = options.runtimeToken;
225
+ const request = { tenantId: input.tenantId };
226
+ const value = typeof source === "function" ? await source(request) : source;
227
+ const token = typeof value === "string" ? value.trim() : "";
228
+ if (!token) return null;
229
+ const url = `${origin}/api/public/projects/${encodeURIComponent(projectId)}/connectors/connections?connectorSlug=${encodeURIComponent(connectorId)}`;
230
+ let response;
231
+ try {
232
+ response = await fetcher(url, { headers: { Authorization: `Bearer ${token}` } });
233
+ } catch {
234
+ return null;
235
+ }
236
+ if (!response.ok) return null;
237
+ const payload = await response.json().catch(() => null);
238
+ const rows = Array.isArray(payload?.connections) ? payload.connections : [];
239
+ const live = rows.find((row) => !row.revokedAt) ?? rows[0];
240
+ if (!live) return null;
241
+ const text = (key) => {
242
+ const value2 = live[key];
243
+ return typeof value2 === "string" && value2.trim() ? value2.trim() : null;
244
+ };
245
+ return {
246
+ displayName: text("displayName"),
247
+ providerAccountKey: text("providerAccountKey"),
248
+ status: text("status")
249
+ };
250
+ }
251
+ };
252
+ }
253
+ async function describeConnectorAccount(input) {
254
+ const source = input.source === void 0 ? getConnectorAccountSource() : input.source;
255
+ if (!source) return null;
256
+ try {
257
+ return await source.describe(input);
258
+ } catch {
259
+ return null;
260
+ }
261
+ }
262
+
204
263
  // src/lib/runtime-token.ts
205
264
  var FayzRuntimeTokenError = class extends Error {
206
265
  constructor(message, status) {
@@ -209,7 +268,7 @@ var FayzRuntimeTokenError = class extends Error {
209
268
  this.name = "FayzRuntimeTokenError";
210
269
  }
211
270
  };
212
- function requireValue3(value, field) {
271
+ function requireValue4(value, field) {
213
272
  const normalized = typeof value === "string" ? value.trim() : "";
214
273
  if (!normalized) throw new FayzRuntimeTokenError(`${field} is required to mint a Fayz runtime token`);
215
274
  return normalized;
@@ -222,7 +281,7 @@ function withoutToken(text, token) {
222
281
  return token ? text.split(token).join("[redacted]") : text;
223
282
  }
224
283
  function createFayzRuntimeTokenSource(options) {
225
- const projectId = requireValue3(options.projectId, "projectId");
284
+ const projectId = requireValue4(options.projectId, "projectId");
226
285
  if (options.supabase === void 0 && options.accessToken === void 0) {
227
286
  throw new FayzRuntimeTokenError(
228
287
  "A Fayz runtime token source needs a session: pass either `supabase` or `accessToken`"
@@ -310,6 +369,6 @@ function createFayzRuntimeTokenSource(options) {
310
369
  return source;
311
370
  }
312
371
 
313
- export { ConnectorCredentialSinkError, ConnectorOAuthError, ConnectorOAuthStarterMissingError, FayzRuntimeTokenError, createFayzConnectorCredentialSink, createFayzConnectorOAuthStarter, createFayzRuntimeTokenSource, fayzConnectorOAuth, fayzPlatformOrigin, getConnectorCredentialSink, getConnectorOAuthStarter, setConnectorCredentialSink, setConnectorOAuthStarter, startConnectorOAuth };
372
+ export { ConnectorCredentialSinkError, ConnectorOAuthError, ConnectorOAuthStarterMissingError, FayzRuntimeTokenError, createFayzConnectorAccountSource, createFayzConnectorCredentialSink, createFayzConnectorOAuthStarter, createFayzRuntimeTokenSource, describeConnectorAccount, fayzConnectorOAuth, fayzPlatformOrigin, getConnectorAccountSource, getConnectorCredentialSink, getConnectorOAuthStarter, setConnectorAccountSource, setConnectorCredentialSink, setConnectorOAuthStarter, startConnectorOAuth };
314
373
  //# sourceMappingURL=index.js.map
315
374
  //# sourceMappingURL=index.js.map