@fayz-ai/core 0.9.0 → 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.
Files changed (218) hide show
  1. package/README.md +2 -2
  2. package/dist/access/index.js.map +1 -1
  3. package/dist/chunk-BEGXYHS4.js +566 -0
  4. package/dist/chunk-BEGXYHS4.js.map +1 -0
  5. package/dist/chunk-ED6NBH6U.js +348 -0
  6. package/dist/chunk-ED6NBH6U.js.map +1 -0
  7. package/dist/chunk-EWKX4VUM.js +429 -0
  8. package/dist/chunk-EWKX4VUM.js.map +1 -0
  9. package/dist/chunk-LARZWDHA.js +319 -0
  10. package/dist/chunk-LARZWDHA.js.map +1 -0
  11. package/dist/chunk-OXQGRJZT.js +125 -0
  12. package/dist/chunk-OXQGRJZT.js.map +1 -0
  13. package/dist/chunk-RRYFXUQX.js +1247 -0
  14. package/dist/chunk-RRYFXUQX.js.map +1 -0
  15. package/dist/{chunk-5RJVUC6J.js → chunk-TDI6F6PT.js} +373 -25
  16. package/dist/chunk-TDI6F6PT.js.map +1 -0
  17. package/dist/{chunk-V2MSAUHO.js → chunk-UVKH6RDX.js} +211 -335
  18. package/dist/chunk-UVKH6RDX.js.map +1 -0
  19. package/dist/chunk-V53GR4UT.js +289 -0
  20. package/dist/chunk-V53GR4UT.js.map +1 -0
  21. package/dist/connector-runtime/index.d.ts +15 -0
  22. package/dist/connector-runtime/index.d.ts.map +1 -0
  23. package/dist/connector-runtime/index.js +3 -0
  24. package/dist/connector-runtime/index.js.map +1 -0
  25. package/dist/data/archetype.d.ts.map +1 -1
  26. package/dist/data/backend-env.d.ts +38 -0
  27. package/dist/data/backend-env.d.ts.map +1 -0
  28. package/dist/data/bulk.d.ts +24 -0
  29. package/dist/data/bulk.d.ts.map +1 -1
  30. package/dist/data/cached.d.ts.map +1 -1
  31. package/dist/data/custom-fields.d.ts +5 -0
  32. package/dist/data/custom-fields.d.ts.map +1 -0
  33. package/dist/data/index.d.ts +2 -1
  34. package/dist/data/index.d.ts.map +1 -1
  35. package/dist/data/index.js +3 -1
  36. package/dist/data/mock.d.ts.map +1 -1
  37. package/dist/data/platform-api.d.ts.map +1 -1
  38. package/dist/data/resolve.d.ts.map +1 -1
  39. package/dist/data/supabase.d.ts.map +1 -1
  40. package/dist/data/types.d.ts +8 -0
  41. package/dist/data/types.d.ts.map +1 -1
  42. package/dist/entity/events.d.ts +14 -0
  43. package/dist/entity/events.d.ts.map +1 -0
  44. package/dist/events/envelope.d.ts +31 -0
  45. package/dist/events/envelope.d.ts.map +1 -0
  46. package/dist/events/index.d.ts +4 -0
  47. package/dist/events/index.d.ts.map +1 -1
  48. package/dist/events/log.d.ts +44 -0
  49. package/dist/events/log.d.ts.map +1 -0
  50. package/dist/events/types.d.ts +40 -0
  51. package/dist/events/types.d.ts.map +1 -0
  52. package/dist/fields/store.d.ts +45 -0
  53. package/dist/fields/store.d.ts.map +1 -0
  54. package/dist/i18n/index.d.ts +10 -0
  55. package/dist/i18n/index.d.ts.map +1 -1
  56. package/dist/i18n/index.js +1 -1
  57. package/dist/i18n/shell-translations.en.d.ts.map +1 -1
  58. package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
  59. package/dist/index.d.ts +45 -21
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +543 -56
  62. package/dist/index.js.map +1 -1
  63. package/dist/integrations/events.d.ts +7 -0
  64. package/dist/integrations/events.d.ts.map +1 -0
  65. package/dist/integrations/index.d.ts +533 -29
  66. package/dist/integrations/index.d.ts.map +1 -1
  67. package/dist/integrations/index.js +3 -1
  68. package/dist/integrations/permissions.d.ts +132 -0
  69. package/dist/integrations/permissions.d.ts.map +1 -0
  70. package/dist/integrations/request.d.ts +170 -0
  71. package/dist/integrations/request.d.ts.map +1 -0
  72. package/dist/integrations/runtime-token.d.ts +33 -0
  73. package/dist/integrations/runtime-token.d.ts.map +1 -0
  74. package/dist/integrations/runtime.d.ts +398 -0
  75. package/dist/integrations/runtime.d.ts.map +1 -0
  76. package/dist/integrations/settings.d.ts +102 -0
  77. package/dist/integrations/settings.d.ts.map +1 -0
  78. package/dist/integrations/store.d.ts +145 -0
  79. package/dist/integrations/store.d.ts.map +1 -0
  80. package/dist/{address/index.d.ts → lib/address.d.ts} +1 -1
  81. package/dist/{address/index.d.ts.map → lib/address.d.ts.map} +1 -1
  82. package/dist/{phone/index.d.ts → lib/phone.d.ts} +1 -1
  83. package/dist/lib/phone.d.ts.map +1 -0
  84. package/dist/{seo/index.d.ts → lib/seo.d.ts} +18 -1
  85. package/dist/lib/seo.d.ts.map +1 -0
  86. package/dist/{tenant/index.d.ts → lib/tenant.d.ts} +1 -1
  87. package/dist/lib/tenant.d.ts.map +1 -0
  88. package/dist/manifest/index.d.ts +1 -1
  89. package/dist/manifest/index.d.ts.map +1 -1
  90. package/dist/messaging/index.d.ts +3 -0
  91. package/dist/messaging/index.d.ts.map +1 -0
  92. package/dist/messaging/registry.d.ts +35 -0
  93. package/dist/messaging/registry.d.ts.map +1 -0
  94. package/dist/messaging/types.d.ts +67 -0
  95. package/dist/messaging/types.d.ts.map +1 -0
  96. package/dist/plugin/index.js +3 -1
  97. package/dist/plugin/runtime.d.ts +17 -0
  98. package/dist/plugin/runtime.d.ts.map +1 -1
  99. package/dist/registry/block-catalog.d.ts +78 -0
  100. package/dist/registry/block-catalog.d.ts.map +1 -0
  101. package/dist/registry/block-constraints.d.ts +64 -0
  102. package/dist/registry/block-constraints.d.ts.map +1 -0
  103. package/dist/registry/block-schema.d.ts +69 -0
  104. package/dist/registry/block-schema.d.ts.map +1 -0
  105. package/dist/registry/blocks.d.ts +84 -0
  106. package/dist/registry/blocks.d.ts.map +1 -0
  107. package/dist/registry/entities.d.ts +179 -0
  108. package/dist/registry/entities.d.ts.map +1 -0
  109. package/dist/registry/extension-points.d.ts +117 -0
  110. package/dist/registry/extension-points.d.ts.map +1 -0
  111. package/dist/registry/handles.d.ts +41 -0
  112. package/dist/registry/handles.d.ts.map +1 -0
  113. package/dist/registry/index.d.ts +41 -41
  114. package/dist/registry/index.d.ts.map +1 -1
  115. package/dist/registry/loaders.d.ts +55 -0
  116. package/dist/registry/loaders.d.ts.map +1 -0
  117. package/dist/registry/registry-class.d.ts +157 -0
  118. package/dist/registry/registry-class.d.ts.map +1 -0
  119. package/dist/registry/schema-check.d.ts +14 -0
  120. package/dist/registry/schema-check.d.ts.map +1 -0
  121. package/dist/router/index.d.ts +78 -1
  122. package/dist/router/index.d.ts.map +1 -1
  123. package/dist/router/index.js +1 -1
  124. package/dist/{shell-translations.pt-br-2GWRQRRP.js → shell-translations.pt-br-BM5ZFSKJ.js} +72 -3
  125. package/dist/shell-translations.pt-br-BM5ZFSKJ.js.map +1 -0
  126. package/dist/telemetry/errors.d.ts +87 -0
  127. package/dist/telemetry/errors.d.ts.map +1 -0
  128. package/dist/testing/index.js +4 -1
  129. package/dist/{testing/index.d.ts → testing.d.ts} +5 -3
  130. package/dist/testing.d.ts.map +1 -0
  131. package/dist/types/analytics.d.ts +213 -0
  132. package/dist/types/analytics.d.ts.map +1 -0
  133. package/dist/types/crud.d.ts +37 -3
  134. package/dist/types/crud.d.ts.map +1 -1
  135. package/dist/types/plugins.d.ts +138 -1
  136. package/dist/types/plugins.d.ts.map +1 -1
  137. package/package.json +9 -17
  138. package/dist/blocks/index.d.ts +0 -25
  139. package/dist/blocks/index.d.ts.map +0 -1
  140. package/dist/chunk-5RJVUC6J.js.map +0 -1
  141. package/dist/chunk-L4TLMYGC.js +0 -42
  142. package/dist/chunk-L4TLMYGC.js.map +0 -1
  143. package/dist/chunk-V2MSAUHO.js.map +0 -1
  144. package/dist/chunk-X5THHG6T.js +0 -77
  145. package/dist/chunk-X5THHG6T.js.map +0 -1
  146. package/dist/chunk-Y2C2FBQP.js +0 -35
  147. package/dist/chunk-Y2C2FBQP.js.map +0 -1
  148. package/dist/chunk-YH25Y4FW.js +0 -311
  149. package/dist/chunk-YH25Y4FW.js.map +0 -1
  150. package/dist/phone/index.d.ts.map +0 -1
  151. package/dist/seo/index.d.ts.map +0 -1
  152. package/dist/shell-translations.pt-br-2GWRQRRP.js.map +0 -1
  153. package/dist/tenant/index.d.ts.map +0 -1
  154. package/dist/testing/index.d.ts.map +0 -1
  155. package/src/access/denial.ts +0 -33
  156. package/src/access/engine.test.ts +0 -48
  157. package/src/access/engine.ts +0 -136
  158. package/src/access/index.ts +0 -14
  159. package/src/access/limits.ts +0 -18
  160. package/src/address/index.ts +0 -188
  161. package/src/app/render.tsx +0 -69
  162. package/src/blocks/index.tsx +0 -68
  163. package/src/data/archetype.ts +0 -255
  164. package/src/data/bulk.ts +0 -35
  165. package/src/data/cached.ts +0 -55
  166. package/src/data/count.test.ts +0 -152
  167. package/src/data/count.ts +0 -131
  168. package/src/data/filters.test.ts +0 -70
  169. package/src/data/filters.ts +0 -90
  170. package/src/data/index.ts +0 -11
  171. package/src/data/mock.ts +0 -90
  172. package/src/data/platform-api.ts +0 -209
  173. package/src/data/refresh.ts +0 -115
  174. package/src/data/resolve.ts +0 -126
  175. package/src/data/supabase.ts +0 -230
  176. package/src/data/types.ts +0 -50
  177. package/src/entity/index.ts +0 -2
  178. package/src/entity/registry.ts +0 -49
  179. package/src/events/index.tsx +0 -82
  180. package/src/i18n/index.ts +0 -476
  181. package/src/i18n/shell-translations.en.ts +0 -875
  182. package/src/i18n/shell-translations.pt-br.ts +0 -873
  183. package/src/index.ts +0 -217
  184. package/src/integrations/index.ts +0 -237
  185. package/src/lib/cache.ts +0 -118
  186. package/src/lib/csv.ts +0 -54
  187. package/src/lib/format.ts +0 -58
  188. package/src/manifest/app-manifest.schema.json +0 -676
  189. package/src/manifest/index.ts +0 -518
  190. package/src/manifest/serialize.ts +0 -52
  191. package/src/phone/index.ts +0 -85
  192. package/src/plugin/createSafeDataProvider.ts +0 -30
  193. package/src/plugin/index.ts +0 -1
  194. package/src/plugin/runtime.ts +0 -331
  195. package/src/registry/index.ts +0 -163
  196. package/src/router/history.ts +0 -86
  197. package/src/router/index.ts +0 -29
  198. package/src/runtime/index.ts +0 -15
  199. package/src/runtime/oauth.ts +0 -219
  200. package/src/search/engine.ts +0 -559
  201. package/src/search/index.ts +0 -25
  202. package/src/search/text.ts +0 -206
  203. package/src/search/types.ts +0 -75
  204. package/src/seo/index.ts +0 -128
  205. package/src/tenant/index.ts +0 -38
  206. package/src/testing/index.ts +0 -116
  207. package/src/types/auth.ts +0 -41
  208. package/src/types/billing.ts +0 -39
  209. package/src/types/crud.ts +0 -184
  210. package/src/types/entities.ts +0 -142
  211. package/src/types/entitlements.ts +0 -45
  212. package/src/types/i18n.ts +0 -7
  213. package/src/types/index.ts +0 -11
  214. package/src/types/org.ts +0 -137
  215. package/src/types/payment.ts +0 -44
  216. package/src/types/permissions.ts +0 -32
  217. package/src/types/plugins.ts +0 -480
  218. package/src/types/theme.ts +0 -8
package/src/index.ts DELETED
@@ -1,217 +0,0 @@
1
- // Types
2
- export type { EntityArchetype, BaseEntity, PersonEntity, ProductEntity, ServiceEntity, OrderEntity, TransactionEntity, LocationEntity, ScheduleEntity, CategoryEntity } from './types/entities'
3
- export type { EntityDef, EntityImageConfig, FieldDef, FieldType, FieldRelation, FieldGroup, DetailTab, FormLayout, ComputedFieldValue } from './types/crud'
4
- export type { PluginManifest, PluginScope, PluginStatus, ResolvedPluginManifest, PluginRuntime, PluginRuntimeContext, PluginWidgetZone, PluginWidgetDefinition, PluginNavigationEntry, PluginSettingsTab, PluginRouteDefinition, PluginAITool, AIToolMode, AIToolExecution, AgentRpcDeclaration, AIToolParameterProperty, AIToolParameters, AIToolSuggestion, PluginRegistryDef, PluginMigration, PluginDiagnostic, VerticalId, ScaffoldType, TenantPluginBinding, DashboardWidgetDef, DashboardWidgetKind, DashboardSurface, DashboardLayoutConfig, ResolvedDashboardWidget } from './types/plugins'
5
- export { WidgetZone } from './types/plugins'
6
- export type { AuthAdapter, AuthUser, AuthSession, AuthProvider } from './types/auth'
7
- export type { OrgAdapter, Organization, OrgMember, OrgMembership, TeamPerson, Location, Invite, CreateOrgOptions } from './types/org'
8
- export type { PermissionsConfig, FeatureDeclaration, PermissionAction, PermissionProfile, SystemPermission } from './types/permissions'
9
- export type { Plan, BillingConfig, BillingCheckoutFn } from './types/billing'
10
- export type { PlanEntitlements, LimitDeclaration } from './types/entitlements'
11
- export type { ThemeBrand, ThemeRadius, ThemeMode } from './types/theme'
12
- export type { LocaleConfig } from './types/i18n'
13
-
14
- // Data providers
15
- export { createSupabaseProvider, setGlobalSupabaseClient, getSupabaseClientOptional } from './data/supabase'
16
- export { countByTenant, invalidateCount } from './data/count'
17
- export type { CountByTenantOptions } from './data/count'
18
- export { createFayzApiProvider } from './data/platform-api'
19
- export { createMockProvider } from './data/mock'
20
- export { createArchetypeProvider } from './data/archetype'
21
- export { withCache } from './data/cached'
22
- export { resolveDataProvider } from './data/resolve'
23
- export { bulkCreate } from './data/bulk'
24
- export type { BulkWriteOptions, BulkWriteResult } from './data/types'
25
- export {
26
- parseRangeFilter,
27
- isFilterObject,
28
- matchesRange,
29
- applyRangeToQuery,
30
- } from './data/filters'
31
- export type { RangeFilter } from './data/filters'
32
- export {
33
- DATA_CHANGED_EVENT,
34
- emitDataChanged,
35
- matchesDataChange,
36
- useDataChanged,
37
- } from './data/refresh'
38
- export type { DataChangedPayload, DataChangedMatch } from './data/refresh'
39
- export { createSafeDataProvider } from './plugin/createSafeDataProvider'
40
- export {
41
- COUNTRIES, DEFAULT_COUNTRY, getCountry, unmaskPhone, maskPhone, maskDigitCount,
42
- } from './phone'
43
- export type { CountryDef } from './phone'
44
- export {
45
- normalizePostalCode, formatPostalCode, isValidPostalCode,
46
- createViaCepProvider, setPostalLookupProvider, getPostalLookupProvider,
47
- lookupPostalCode, clearPostalCache,
48
- } from './address'
49
- export type { PostalAddress, PostalLookupProvider } from './address'
50
- export type {
51
- PaymentProvider, PaymentMethod, ChargeStatus, CreateChargeInput, PixCharge,
52
- } from './types/payment'
53
- export {
54
- useSeo, applySeo, absoluteUrl, seoOrigin, breadcrumbJsonLd, organizationJsonLd,
55
- } from './seo'
56
- export type { SeoConfig, BreadcrumbItem } from './seo'
57
- export type { DataProvider, CrudQuery, CrudResult, SupabaseProviderConfig, FayzApiProviderConfig } from './data/index'
58
-
59
- // Tenant context (runtime DI for the data layer)
60
- export { setActiveTenantId, getActiveTenantId, subscribeActiveTenant, useActiveTenantId } from './tenant'
61
-
62
- // Runtime broker helpers
63
- export { createFayzRuntimeClient, FayzRuntimeError } from './runtime'
64
- export type {
65
- FayzRuntimeClientOptions,
66
- FayzRuntimeEnvironment,
67
- GoogleCalendarEvent,
68
- GoogleCalendarEventInput,
69
- GoogleCalendarEventTime,
70
- ListGoogleCalendarEventsInput,
71
- PluginOAuthExchangeInput,
72
- PluginOAuthExchangeResponse,
73
- RuntimePluginOAuthGrant,
74
- } from './runtime'
75
-
76
- // Plugin contract assertions (integrity half of the deploy gate)
77
- export { assertPluginManifestContract, assertConnectorContract, PluginContractError } from './testing'
78
-
79
- // Integration connector spine (shared contract for external-provider sync)
80
- export { withAfterHooks, connectorPlanes, preferredPlane, connectorDirection } from './integrations'
81
- export type {
82
- Connector,
83
- ConnectorCapability,
84
- ConnectionConfig,
85
- SyncRun,
86
- SyncDirection,
87
- SyncTrigger,
88
- IntegrationAuthKind,
89
- TestConnectionResult,
90
- ConnectorDefinition,
91
- ConnectorField,
92
- ConnectorStatus,
93
- ConnectorPlane,
94
- ConnectorDirection,
95
- ConnectorAgentTool,
96
- } from './integrations'
97
-
98
- // Shared utilities
99
- export { formatCurrency, formatDate, formatDateTime, getActiveLocale, getDefaultCurrency, setDefaultCurrency } from './lib/format'
100
- export { exportCSV, buildCSV, downloadCSV } from './lib/csv'
101
- export type { CSVColumn } from './lib/csv'
102
- export { globalCache, createCacheStore, stableKey, clearGlobalCache } from './lib/cache'
103
- export type { CacheStore } from './lib/cache'
104
-
105
- // Plugin system
106
- export { definePlugin, resolvePluginRuntime, getWidgetsForZone, getDashboardWidgets, PluginRuntimeProvider, usePluginRuntime, usePluginRuntimeOptional, useConnectorsForPlugin, PLUGIN_API_VERSION, resolvePluginComponent } from './plugin/runtime'
107
- export type { PluginEventDefinition, PluginQuickAction } from './types/plugins'
108
-
109
- // Event bus
110
- export { createEventBus, eventBus, useOnEvent } from './events'
111
- export type { EventBus, EventHandler } from './events'
112
-
113
- // Entity registry
114
- export { registerEntity, getEntityByKey, getAllEntities, clearEntityRegistry, deriveEntityKey } from './entity/registry'
115
- export type { RegisteredEntity } from './entity/registry'
116
-
117
- // Global search (command palette + agent lookups share one engine)
118
- export {
119
- searchEverything, clearSearchCache, setSearchIndexAvailable, isSearchIndexAvailable,
120
- MIN_QUERY_LENGTH, foldText, foldWithMap, digitsOf, normalizeQuery, similarity,
121
- scoreCandidate, highlightRanges,
122
- } from './search'
123
- export type {
124
- SearchTarget, SearchHit, SearchGroup, SearchPath, SearchOptions, GlobalSearchResult,
125
- NormalizedQuery, RankCandidate,
126
- } from './search'
127
-
128
- // Uniform registry (component / block / page / metric / scaffold / plugin)
129
- export {
130
- Registry,
131
- isCustomId,
132
- componentRegistry,
133
- blockRegistry,
134
- pageRegistry,
135
- scaffoldRegistry,
136
- metricRegistry,
137
- pluginRegistry,
138
- registerComponent,
139
- getComponent,
140
- registerBlock,
141
- getBlock,
142
- listBlocks,
143
- registerPage,
144
- getPage,
145
- registerScaffold,
146
- getScaffold,
147
- registerMetric,
148
- getMetric,
149
- listMetrics,
150
- registerPlugin,
151
- getPlugin,
152
- listPlugins,
153
- pluginFactoryRegistry,
154
- registerPluginFactory,
155
- getPluginFactory,
156
- listPluginFactories,
157
- } from './registry'
158
- export type { PluginFactory } from './registry'
159
- export type {
160
- JsonSchema,
161
- RegistrySource,
162
- RegistryMeta,
163
- RegistryEntry,
164
- MetricFormat,
165
- MetricContext,
166
- MetricValue,
167
- MetricDefinition,
168
- } from './registry'
169
-
170
- // Block system (universal page primitive)
171
- export { BlockRenderer, renderBlocks, BlockChildren } from './blocks'
172
- export type { BlockNode, BlockComponentProps } from './blocks'
173
-
174
- // App manifest (the app, as data) + migration runner
175
- export {
176
- CURRENT_MANIFEST_VERSION,
177
- registerManifestMigration,
178
- migrateManifest,
179
- validateManifest,
180
- } from './manifest'
181
- export type {
182
- AppManifest,
183
- BackendProvider,
184
- BackendRef,
185
- SurfaceManifest,
186
- PageManifest,
187
- PluginRef,
188
- ManifestMigration,
189
- AgentContract,
190
- AgentDomainKnowledge,
191
- EntityContract,
192
- AIToolContract,
193
- RpcContract,
194
- } from './manifest'
195
- export { serializeManifest, computeContractHash, serializeManifestWithHash } from './manifest/serialize'
196
- export { default as appManifestSchema } from './manifest/app-manifest.schema.json'
197
-
198
- // App entry points (manifest → running app)
199
- export { defineApp, renderApp, useManifest } from './app/render'
200
- export type { RenderAppOptions } from './app/render'
201
-
202
- // i18n
203
- export { I18nProvider, useI18nConfig, useTranslation, coreTranslations, mergeTranslations, registerTranslations, getCurrentLocale, setCurrentLocale, preloadLocale, setLocaleStore } from './i18n/index'
204
-
205
- // Router
206
- export { hashRouterAdapter, windowRouterAdapter } from './router/index'
207
- export type { RouterAdapter } from './router/index'
208
-
209
- // Global cross-module navigation history (context-aware back buttons)
210
- export {
211
- useNavHistoryStore,
212
- recordNavigation,
213
- useNavReferrer,
214
- navHistoryBack,
215
- routeModule,
216
- } from './router/history'
217
- export type { NavHistoryEntry } from './router/history'
@@ -1,237 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Integration Connector spine
3
- // ---------------------------------------------------------------------------
4
- // An integration is a connector that keeps canonical Fayz data in agreement
5
- // with an external provider (Google Calendar, open banking, Shopify, …). This
6
- // module is the thin shared contract both native (SDK) and client-built
7
- // connectors implement. The heavy lifting (auth, fetch/push, idempotent
8
- // upserts) runs in the data plane — typically a Supabase Edge Function — while
9
- // the control plane (a settings tab + this contract) lives in the app/plugin.
10
- //
11
- // Design notes live in docs/design/bling-integration-brief.md. Proven precedents:
12
- // the Fayz runtime OAuth broker (packages/core/src/runtime/oauth.ts) and the
13
- // bank-statement edge functions in the predecessor app.
14
- import type * as React from 'react'
15
-
16
- /** How a connector authenticates to its provider. */
17
- export type IntegrationAuthKind = 'oauth' | 'api-key' | 'mtls'
18
-
19
- // ---------------------------------------------------------------------------
20
- // Planes — the two ways a connector gets honoured
21
- // ---------------------------------------------------------------------------
22
- // "Integração" and "conector" are the same noun. What differs is the plane it
23
- // runs on:
24
- //
25
- // - 'agentic' — the provider's tools are handed to the assistant. Nothing is
26
- // copied: the agent calls the provider at the moment it needs the answer,
27
- // so there is no mirror to drift and no de-para to maintain. Preferred
28
- // whenever the provider offers it.
29
- // - 'sync' — the old-school pipeline: authorize, map, run, keep an audit
30
- // trail. Required when the data must exist *inside* Fayz — to be listed,
31
- // filtered, reported on, or read while the provider is unreachable.
32
- //
33
- // A connector may support both; `preferredPlane` encodes the house rule.
34
- export type ConnectorPlane = 'agentic' | 'sync'
35
-
36
- /** Which side reaches for the other, from this app's point of view. */
37
- export type ConnectorDirection = 'inbound' | 'outbound'
38
-
39
- /** A tool the assistant gains once a connector is resolved on the agentic plane. */
40
- export interface ConnectorAgentTool {
41
- name: string
42
- description?: string
43
- }
44
-
45
- /** Which way data flows for a given capability. */
46
- export type SyncDirection = 'inbound' | 'outbound' | 'bidirectional'
47
-
48
- /** What causes a sync to run. */
49
- export type SyncTrigger = 'on-write' | 'scheduled' | 'manual' | 'webhook'
50
-
51
- /** One thing a connector can sync (an entity + its direction + triggers). */
52
- export interface ConnectorCapability {
53
- /** Canonical entity synced, e.g. 'booking', 'movement'. */
54
- entity: string
55
- direction: SyncDirection
56
- triggers: SyncTrigger[]
57
- }
58
-
59
- /** The state of a tenant's connection to a provider (one row in a *_integrations table). */
60
- export interface ConnectionConfig {
61
- /** Provider key, e.g. 'google', 'plugbank'. */
62
- provider: string
63
- /** Whether the connection is active and should sync. */
64
- active: boolean
65
- /** Opaque, provider-specific config (calendar id, account id, cursor, …). Never secrets. */
66
- settings?: Record<string, unknown>
67
- /** Last successful sync, ISO timestamp. */
68
- lastSyncAt?: string
69
- }
70
-
71
- /** Audit record of one sync execution (generalizes *_sync_log / *_sync_runs). */
72
- export interface SyncRun {
73
- id?: string
74
- provider: string
75
- direction: SyncDirection
76
- trigger: SyncTrigger
77
- status: 'success' | 'partial' | 'error'
78
- /** Items pulled/pushed and how many were written. */
79
- fetched?: number
80
- written?: number
81
- /** Pagination/incremental cursor advanced by this run. */
82
- cursor?: string
83
- error?: string
84
- startedAt?: string
85
- finishedAt?: string
86
- }
87
-
88
- export interface TestConnectionResult {
89
- ok: boolean
90
- message?: string
91
- }
92
-
93
- /**
94
- * A connector's control-plane descriptor. The data-plane verbs (testConnection,
95
- * sync) are usually thin clients that invoke a Supabase Edge Function — the
96
- * function holds credentials and does the real work.
97
- */
98
- export interface Connector {
99
- /** Stable connector id, e.g. 'google-calendar', 'plugbank'. */
100
- id: string
101
- /** Provider key matching ConnectionConfig.provider. */
102
- provider: string
103
- /** Plugin this connector extends, e.g. 'agenda', 'financial'. */
104
- pluginId: string
105
- authKind: IntegrationAuthKind
106
- capabilities: ConnectorCapability[]
107
- /** Validate the stored credentials/config without syncing. */
108
- testConnection?(config: ConnectionConfig): Promise<TestConnectionResult>
109
- /** Run a sync for the given direction; returns the audit record. */
110
- sync?(input: { config: ConnectionConfig; direction: SyncDirection; trigger: SyncTrigger }): Promise<SyncRun>
111
- }
112
-
113
- // ---------------------------------------------------------------------------
114
- // Connector UI contract — how an addon plugin EXTENDS a host plugin's settings
115
- // ---------------------------------------------------------------------------
116
- // An addon plugin declares one or more ConnectorDefinitions on its manifest
117
- // (`connectors: [...]`). The runtime groups them by `hostPluginId`, and the host
118
- // plugin's settings panel renders them in a unified "Integrations" tab — the
119
- // same connect/credentials experience for every connector. The connector-
120
- // specific bits (import a statement, sync now, history) live in `ExtraPanel`.
121
-
122
- /** A credential input the unified setup form renders for an api-key/mtls connector. */
123
- export interface ConnectorField {
124
- key: string
125
- label: string
126
- type: 'text' | 'password'
127
- placeholder?: string
128
- }
129
-
130
- export interface ConnectorStatus {
131
- connected: boolean
132
- detail?: string
133
- /** Which plane the live connection is running on (when connected). */
134
- plane?: ConnectorPlane
135
- }
136
-
137
- /**
138
- * UI-facing connector descriptor. Built on the data-plane `Connector` concept
139
- * (`pluginId` → `hostPluginId`), plus the control-plane hooks the unified
140
- * Integrations hub calls. Lives in core so `PluginManifest.connectors` can type
141
- * it; the rendering hub lives in `@fayz-ai/saas`.
142
- */
143
- export interface ConnectorDefinition {
144
- /** Stable connector id, e.g. 'google-calendar', 'plugbank'. */
145
- id: string
146
- /** The plugin this connector extends, e.g. 'financial', 'agenda'. */
147
- hostPluginId: string
148
- name: string
149
- description?: string
150
- /** Lucide icon name. */
151
- icon?: string
152
- /**
153
- * The connector's own brand mark — a URL or an inline data URI. Preferred
154
- * over the catalogue's icon and over `icon`, so a connector the Fayz
155
- * directory doesn't carry still shows up as itself.
156
- */
157
- logoUrl?: string
158
- authKind: IntegrationAuthKind
159
- /** Planes this connector can be honoured on. Default: `['sync']`. */
160
- planes?: ConnectorPlane[]
161
- /** Default `'outbound'` — this app reaching a provider. */
162
- direction?: ConnectorDirection
163
- /** What the assistant gains on the agentic plane — shown before connecting. */
164
- agentTools?: ConnectorAgentTool[]
165
- /** Canonical entities this connector touches ('booking', 'movement'). */
166
- entities?: string[]
167
- /** Catalog category ('scheduling', 'payments', …) — matches the Fayz catalog. */
168
- category?: string
169
- /** Provider documentation, linked from the connector's detail. */
170
- docsUrl?: string
171
- /** Declarative credentials — the unified form renders these (api-key / mtls). */
172
- fields?: ConnectorField[]
173
- /** Current connection state for the status badge. */
174
- getStatus(): Promise<ConnectorStatus>
175
- /** Validate credentials without persisting (api-key / mtls). */
176
- testConnection?(values: Record<string, string>): Promise<TestConnectionResult>
177
- /** Persist the connection (api-key / mtls). */
178
- saveConnection?(values: Record<string, string>): Promise<void>
179
- /** Begin an OAuth connect flow — returns the consent URL to redirect to. */
180
- startOAuth?(redirectTo?: string): Promise<string>
181
- /** Tear down the connection. */
182
- disconnect?(): Promise<void>
183
- /** Move an existing connection between planes (only when `planes` has both). */
184
- setPlane?(plane: ConnectorPlane): Promise<void>
185
- /** Optional connector-specific UI below the connect panel (import / sync / history). */
186
- ExtraPanel?: React.ComponentType
187
- }
188
-
189
- /** Planes a connector supports — the contract's default is the sync pipeline. */
190
- export function connectorPlanes(def: Pick<ConnectorDefinition, 'planes'>): ConnectorPlane[] {
191
- return def.planes?.length ? def.planes : ['sync']
192
- }
193
-
194
- /**
195
- * The plane to offer first. Agentic wins whenever the connector supports it:
196
- * handing the assistant a tool costs nothing to keep in agreement, while a sync
197
- * pipeline is a copy that has to be maintained for as long as it exists.
198
- */
199
- export function preferredPlane(def: Pick<ConnectorDefinition, 'planes'>): ConnectorPlane {
200
- return connectorPlanes(def).includes('agentic') ? 'agentic' : 'sync'
201
- }
202
-
203
- /** Direction a connector moves data in — outbound unless it says otherwise. */
204
- export function connectorDirection(def: Pick<ConnectorDefinition, 'direction'>): ConnectorDirection {
205
- return def.direction ?? 'outbound'
206
- }
207
-
208
- /**
209
- * Wrap an object's async methods so a handler fires AFTER selected methods
210
- * resolve — the non-invasive hook for outbound, event-driven sync when there's
211
- * no app-level event bus. Example: wrap an AgendaDataProvider so that after
212
- * createBooking/updateBooking/deleteBooking succeed, an external calendar is
213
- * updated. The handler runs fire-and-forget; its failures never break the call.
214
- */
215
- export function withAfterHooks<T extends object>(
216
- target: T,
217
- methods: Partial<Record<keyof T, (args: unknown[], result: unknown) => void | Promise<void>>>,
218
- ): T {
219
- return new Proxy(target, {
220
- get(obj, prop, receiver) {
221
- const orig = Reflect.get(obj, prop, receiver)
222
- const hook = (methods as Record<string | symbol, ((args: unknown[], result: unknown) => void | Promise<void>) | undefined>)[prop]
223
- if (typeof orig !== 'function' || !hook) return orig
224
- return (...args: unknown[]) => {
225
- const result = (orig as (...a: unknown[]) => unknown).apply(obj, args)
226
- if (result instanceof Promise) {
227
- return result.then((value) => {
228
- try { void Promise.resolve(hook(args, value)).catch(() => {}) } catch { /* never break the call */ }
229
- return value
230
- })
231
- }
232
- try { void Promise.resolve(hook(args, result)).catch(() => {}) } catch { /* noop */ }
233
- return result
234
- }
235
- },
236
- })
237
- }
package/src/lib/cache.ts DELETED
@@ -1,118 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Types
3
- // ---------------------------------------------------------------------------
4
-
5
- interface CacheEntry<T = unknown> {
6
- data: T
7
- expiresAt: number
8
- lastAccess: number
9
- }
10
-
11
- export interface CacheStore {
12
- get<T>(key: string): T | undefined
13
- set<T>(key: string, data: T, ttl?: number): void
14
- /** Clear all entries whose key starts with `prefix` */
15
- invalidate(prefix: string): void
16
- clear(): void
17
- size(): number
18
- }
19
-
20
- export interface CacheConfig {
21
- /** Default time-to-live in ms (default: 60 000 — 1 minute) */
22
- defaultTTL?: number
23
- /** Maximum cached entries before LRU eviction (default: 500) */
24
- maxEntries?: number
25
- }
26
-
27
- // ---------------------------------------------------------------------------
28
- // Stable key helper — deterministic JSON for cache keys
29
- // ---------------------------------------------------------------------------
30
-
31
- function sortDeep(value: unknown): unknown {
32
- if (value === null || value === undefined || typeof value !== 'object') return value
33
- if (Array.isArray(value)) return value.map(sortDeep)
34
- const sorted: Record<string, unknown> = {}
35
- for (const k of Object.keys(value as Record<string, unknown>).sort()) {
36
- sorted[k] = sortDeep((value as Record<string, unknown>)[k])
37
- }
38
- return sorted
39
- }
40
-
41
- export function stableKey(...parts: unknown[]): string {
42
- return parts.map((p) => (typeof p === 'string' ? p : JSON.stringify(sortDeep(p)))).join(':')
43
- }
44
-
45
- // ---------------------------------------------------------------------------
46
- // CacheStore implementation
47
- // ---------------------------------------------------------------------------
48
-
49
- export function createCacheStore(config?: CacheConfig): CacheStore {
50
- const defaultTTL = config?.defaultTTL ?? 60_000
51
- const maxEntries = config?.maxEntries ?? 500
52
- const entries = new Map<string, CacheEntry>()
53
-
54
- function evictLRU() {
55
- if (entries.size <= maxEntries) return
56
- // Find the entry with the oldest lastAccess
57
- let oldestKey: string | null = null
58
- let oldestAccess = Infinity
59
- for (const [key, entry] of entries) {
60
- if (entry.lastAccess < oldestAccess) {
61
- oldestAccess = entry.lastAccess
62
- oldestKey = key
63
- }
64
- }
65
- if (oldestKey) entries.delete(oldestKey)
66
- }
67
-
68
- return {
69
- get<T>(key: string): T | undefined {
70
- const entry = entries.get(key)
71
- if (!entry) return undefined
72
- if (Date.now() > entry.expiresAt) {
73
- entries.delete(key)
74
- return undefined
75
- }
76
- entry.lastAccess = Date.now()
77
- return entry.data as T
78
- },
79
-
80
- set<T>(key: string, data: T, ttl?: number): void {
81
- const now = Date.now()
82
- entries.set(key, {
83
- data,
84
- expiresAt: now + (ttl ?? defaultTTL),
85
- lastAccess: now,
86
- })
87
- evictLRU()
88
- },
89
-
90
- invalidate(prefix: string): void {
91
- for (const key of entries.keys()) {
92
- if (key.startsWith(prefix)) {
93
- entries.delete(key)
94
- }
95
- }
96
- },
97
-
98
- clear(): void {
99
- entries.clear()
100
- },
101
-
102
- size(): number {
103
- return entries.size
104
- },
105
- }
106
- }
107
-
108
- // ---------------------------------------------------------------------------
109
- // Global singleton — auto-flushes on tenant/org switch
110
- // ---------------------------------------------------------------------------
111
-
112
- export const globalCache = createCacheStore()
113
-
114
- /** Flush the global cache — called by the tenant accessor when the active
115
- * tenant changes (replaces the old org-store subscription). */
116
- export function clearGlobalCache(): void {
117
- globalCache.clear()
118
- }
package/src/lib/csv.ts DELETED
@@ -1,54 +0,0 @@
1
- /** Column descriptor for generic CSV export */
2
- export interface CSVColumn {
3
- key: string
4
- label: string
5
- format?: (value: any, row: Record<string, any>) => string
6
- }
7
-
8
- export function escapeCSVField(value: unknown): string {
9
- if (value == null) return ''
10
- const str = String(value)
11
- if (str.includes(',') || str.includes('"') || str.includes('\n')) {
12
- return `"${str.replace(/"/g, '""')}"`
13
- }
14
- return str
15
- }
16
-
17
- /** Build a CSV string from columns + rows. Each cell runs through `column.format` if provided, then escaping. */
18
- export function buildCSV(
19
- columns: CSVColumn[],
20
- rows: Record<string, any>[],
21
- ): string {
22
- const header = columns.map((c) => escapeCSVField(c.label)).join(',')
23
- const body = rows.map((row) =>
24
- columns
25
- .map((col) => {
26
- const raw = row[col.key]
27
- const formatted = col.format ? col.format(raw, row) : raw
28
- return escapeCSVField(formatted)
29
- })
30
- .join(','),
31
- )
32
- return [header, ...body].join('\n')
33
- }
34
-
35
- /** Trigger a CSV file download in the browser. */
36
- export function downloadCSV(csv: string, filename: string): void {
37
- const bom = '\uFEFF'
38
- const blob = new Blob([bom + csv], { type: 'text/csv;charset=utf-8;' })
39
- const url = URL.createObjectURL(blob)
40
- const a = document.createElement('a')
41
- a.href = url
42
- a.download = filename.endsWith('.csv') ? filename : `${filename}.csv`
43
- a.click()
44
- URL.revokeObjectURL(url)
45
- }
46
-
47
- /** Convenience: build + download in one call. */
48
- export function exportCSV(
49
- columns: CSVColumn[],
50
- rows: Record<string, any>[],
51
- filename: string,
52
- ): void {
53
- downloadCSV(buildCSV(columns, rows), filename)
54
- }
package/src/lib/format.ts DELETED
@@ -1,58 +0,0 @@
1
- import { getCurrentLocale } from '../i18n'
2
-
3
- // Currency inferred from the active locale unless the app sets one explicitly
4
- // via createSaasApp({ locale: { currency: 'BRL' } }).
5
- const CURRENCY_BY_LOCALE: Record<string, string> = {
6
- 'pt-BR': 'BRL',
7
- 'pt-PT': 'EUR',
8
- en: 'USD',
9
- 'en-US': 'USD',
10
- 'en-GB': 'GBP',
11
- es: 'EUR',
12
- }
13
-
14
- let _defaultCurrency: string | null = null
15
-
16
- export function setDefaultCurrency(code: string | undefined): void {
17
- _defaultCurrency = code ?? null
18
- }
19
-
20
- export function getActiveLocale(): string {
21
- try {
22
- return getCurrentLocale() || 'en'
23
- } catch {
24
- return 'en'
25
- }
26
- }
27
-
28
- export function getDefaultCurrency(): string {
29
- if (_defaultCurrency) return _defaultCurrency
30
- return CURRENCY_BY_LOCALE[getActiveLocale()] ?? 'USD'
31
- }
32
-
33
- export function formatCurrency(value: unknown, currency?: string): string {
34
- const num = typeof value === 'number' ? value : parseFloat(String(value))
35
- if (isNaN(num)) return String(value ?? '')
36
- return new Intl.NumberFormat(getActiveLocale(), {
37
- style: 'currency',
38
- currency: currency ?? getDefaultCurrency(),
39
- }).format(num)
40
- }
41
-
42
- export function formatDate(value: unknown): string {
43
- if (!value) return ''
44
- try {
45
- return new Intl.DateTimeFormat(getActiveLocale(), { dateStyle: 'medium' }).format(new Date(value as string))
46
- } catch {
47
- return String(value)
48
- }
49
- }
50
-
51
- export function formatDateTime(value: unknown): string {
52
- if (!value) return ''
53
- try {
54
- return new Intl.DateTimeFormat(getActiveLocale(), { dateStyle: 'medium', timeStyle: 'short' }).format(new Date(value as string))
55
- } catch {
56
- return String(value)
57
- }
58
- }