@fayz-ai/core 0.9.0 → 0.10.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 (170) hide show
  1. package/README.md +2 -2
  2. package/dist/access/index.js.map +1 -1
  3. package/dist/{chunk-L4TLMYGC.js → chunk-6RBW2Y5K.js} +3 -3
  4. package/dist/chunk-6RBW2Y5K.js.map +1 -0
  5. package/dist/chunk-732GZEUI.js +1592 -0
  6. package/dist/chunk-732GZEUI.js.map +1 -0
  7. package/dist/{chunk-X5THHG6T.js → chunk-CPMHCTX3.js} +3 -3
  8. package/dist/chunk-CPMHCTX3.js.map +1 -0
  9. package/dist/{chunk-V2MSAUHO.js → chunk-JO7Z2AOE.js} +2 -2
  10. package/dist/chunk-JO7Z2AOE.js.map +1 -0
  11. package/dist/{chunk-5RJVUC6J.js → chunk-M27JPX3K.js} +12 -3
  12. package/dist/chunk-M27JPX3K.js.map +1 -0
  13. package/dist/chunk-OXQGRJZT.js +125 -0
  14. package/dist/chunk-OXQGRJZT.js.map +1 -0
  15. package/dist/data/backend-env.d.ts +38 -0
  16. package/dist/data/backend-env.d.ts.map +1 -0
  17. package/dist/data/index.js +1 -1
  18. package/dist/entity/events.d.ts +14 -0
  19. package/dist/entity/events.d.ts.map +1 -0
  20. package/dist/events/envelope.d.ts +31 -0
  21. package/dist/events/envelope.d.ts.map +1 -0
  22. package/dist/events/index.d.ts +4 -0
  23. package/dist/events/index.d.ts.map +1 -1
  24. package/dist/events/log.d.ts +44 -0
  25. package/dist/events/log.d.ts.map +1 -0
  26. package/dist/events/types.d.ts +40 -0
  27. package/dist/events/types.d.ts.map +1 -0
  28. package/dist/i18n/index.d.ts +10 -0
  29. package/dist/i18n/index.d.ts.map +1 -1
  30. package/dist/i18n/index.js +1 -1
  31. package/dist/index.d.ts +27 -17
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +388 -52
  34. package/dist/index.js.map +1 -1
  35. package/dist/integrations/index.js +1 -1
  36. package/dist/{integrations/index.d.ts → integrations.d.ts} +2 -2
  37. package/dist/integrations.d.ts.map +1 -0
  38. package/dist/{address/index.d.ts → lib/address.d.ts} +1 -1
  39. package/dist/{address/index.d.ts.map → lib/address.d.ts.map} +1 -1
  40. package/dist/{phone/index.d.ts → lib/phone.d.ts} +1 -1
  41. package/dist/lib/phone.d.ts.map +1 -0
  42. package/dist/{seo/index.d.ts → lib/seo.d.ts} +18 -1
  43. package/dist/lib/seo.d.ts.map +1 -0
  44. package/dist/{tenant/index.d.ts → lib/tenant.d.ts} +1 -1
  45. package/dist/lib/tenant.d.ts.map +1 -0
  46. package/dist/manifest/index.d.ts +1 -1
  47. package/dist/manifest/index.d.ts.map +1 -1
  48. package/dist/messaging/index.d.ts +3 -0
  49. package/dist/messaging/index.d.ts.map +1 -0
  50. package/dist/messaging/registry.d.ts +35 -0
  51. package/dist/messaging/registry.d.ts.map +1 -0
  52. package/dist/messaging/types.d.ts +67 -0
  53. package/dist/messaging/types.d.ts.map +1 -0
  54. package/dist/plugin/index.js +2 -1
  55. package/dist/plugin/runtime.d.ts +17 -0
  56. package/dist/plugin/runtime.d.ts.map +1 -1
  57. package/dist/registry/block-catalog.d.ts +78 -0
  58. package/dist/registry/block-catalog.d.ts.map +1 -0
  59. package/dist/registry/block-constraints.d.ts +64 -0
  60. package/dist/registry/block-constraints.d.ts.map +1 -0
  61. package/dist/registry/block-schema.d.ts +69 -0
  62. package/dist/registry/block-schema.d.ts.map +1 -0
  63. package/dist/registry/blocks.d.ts +84 -0
  64. package/dist/registry/blocks.d.ts.map +1 -0
  65. package/dist/registry/entities.d.ts +153 -0
  66. package/dist/registry/entities.d.ts.map +1 -0
  67. package/dist/registry/extension-points.d.ts +117 -0
  68. package/dist/registry/extension-points.d.ts.map +1 -0
  69. package/dist/registry/handles.d.ts +41 -0
  70. package/dist/registry/handles.d.ts.map +1 -0
  71. package/dist/registry/index.d.ts +41 -41
  72. package/dist/registry/index.d.ts.map +1 -1
  73. package/dist/registry/loaders.d.ts +55 -0
  74. package/dist/registry/loaders.d.ts.map +1 -0
  75. package/dist/registry/registry-class.d.ts +157 -0
  76. package/dist/registry/registry-class.d.ts.map +1 -0
  77. package/dist/registry/schema-check.d.ts +14 -0
  78. package/dist/registry/schema-check.d.ts.map +1 -0
  79. package/dist/router/index.d.ts +78 -1
  80. package/dist/router/index.d.ts.map +1 -1
  81. package/dist/router/index.js +1 -1
  82. package/dist/testing/index.js +1 -1
  83. package/dist/{testing/index.d.ts → testing.d.ts} +3 -3
  84. package/dist/testing.d.ts.map +1 -0
  85. package/dist/types/analytics.d.ts +196 -0
  86. package/dist/types/analytics.d.ts.map +1 -0
  87. package/dist/types/crud.d.ts +22 -2
  88. package/dist/types/crud.d.ts.map +1 -1
  89. package/dist/types/plugins.d.ts +55 -1
  90. package/dist/types/plugins.d.ts.map +1 -1
  91. package/package.json +6 -18
  92. package/dist/blocks/index.d.ts +0 -25
  93. package/dist/blocks/index.d.ts.map +0 -1
  94. package/dist/chunk-5RJVUC6J.js.map +0 -1
  95. package/dist/chunk-L4TLMYGC.js.map +0 -1
  96. package/dist/chunk-V2MSAUHO.js.map +0 -1
  97. package/dist/chunk-X5THHG6T.js.map +0 -1
  98. package/dist/chunk-Y2C2FBQP.js +0 -35
  99. package/dist/chunk-Y2C2FBQP.js.map +0 -1
  100. package/dist/chunk-YH25Y4FW.js +0 -311
  101. package/dist/chunk-YH25Y4FW.js.map +0 -1
  102. package/dist/integrations/index.d.ts.map +0 -1
  103. package/dist/phone/index.d.ts.map +0 -1
  104. package/dist/seo/index.d.ts.map +0 -1
  105. package/dist/tenant/index.d.ts.map +0 -1
  106. package/dist/testing/index.d.ts.map +0 -1
  107. package/src/access/denial.ts +0 -33
  108. package/src/access/engine.test.ts +0 -48
  109. package/src/access/engine.ts +0 -136
  110. package/src/access/index.ts +0 -14
  111. package/src/access/limits.ts +0 -18
  112. package/src/address/index.ts +0 -188
  113. package/src/app/render.tsx +0 -69
  114. package/src/blocks/index.tsx +0 -68
  115. package/src/data/archetype.ts +0 -255
  116. package/src/data/bulk.ts +0 -35
  117. package/src/data/cached.ts +0 -55
  118. package/src/data/count.test.ts +0 -152
  119. package/src/data/count.ts +0 -131
  120. package/src/data/filters.test.ts +0 -70
  121. package/src/data/filters.ts +0 -90
  122. package/src/data/index.ts +0 -11
  123. package/src/data/mock.ts +0 -90
  124. package/src/data/platform-api.ts +0 -209
  125. package/src/data/refresh.ts +0 -115
  126. package/src/data/resolve.ts +0 -126
  127. package/src/data/supabase.ts +0 -230
  128. package/src/data/types.ts +0 -50
  129. package/src/entity/index.ts +0 -2
  130. package/src/entity/registry.ts +0 -49
  131. package/src/events/index.tsx +0 -82
  132. package/src/i18n/index.ts +0 -476
  133. package/src/i18n/shell-translations.en.ts +0 -875
  134. package/src/i18n/shell-translations.pt-br.ts +0 -873
  135. package/src/index.ts +0 -217
  136. package/src/integrations/index.ts +0 -237
  137. package/src/lib/cache.ts +0 -118
  138. package/src/lib/csv.ts +0 -54
  139. package/src/lib/format.ts +0 -58
  140. package/src/manifest/app-manifest.schema.json +0 -676
  141. package/src/manifest/index.ts +0 -518
  142. package/src/manifest/serialize.ts +0 -52
  143. package/src/phone/index.ts +0 -85
  144. package/src/plugin/createSafeDataProvider.ts +0 -30
  145. package/src/plugin/index.ts +0 -1
  146. package/src/plugin/runtime.ts +0 -331
  147. package/src/registry/index.ts +0 -163
  148. package/src/router/history.ts +0 -86
  149. package/src/router/index.ts +0 -29
  150. package/src/runtime/index.ts +0 -15
  151. package/src/runtime/oauth.ts +0 -219
  152. package/src/search/engine.ts +0 -559
  153. package/src/search/index.ts +0 -25
  154. package/src/search/text.ts +0 -206
  155. package/src/search/types.ts +0 -75
  156. package/src/seo/index.ts +0 -128
  157. package/src/tenant/index.ts +0 -38
  158. package/src/testing/index.ts +0 -116
  159. package/src/types/auth.ts +0 -41
  160. package/src/types/billing.ts +0 -39
  161. package/src/types/crud.ts +0 -184
  162. package/src/types/entities.ts +0 -142
  163. package/src/types/entitlements.ts +0 -45
  164. package/src/types/i18n.ts +0 -7
  165. package/src/types/index.ts +0 -11
  166. package/src/types/org.ts +0 -137
  167. package/src/types/payment.ts +0 -44
  168. package/src/types/permissions.ts +0 -32
  169. package/src/types/plugins.ts +0 -480
  170. package/src/types/theme.ts +0 -8
package/src/i18n/index.ts DELETED
@@ -1,476 +0,0 @@
1
- import * as React from 'react'
2
- import { shellTranslationsEn } from './shell-translations.en'
3
-
4
- export interface I18nConfig {
5
- defaultLocale: string
6
- supported: string[]
7
- translations: Record<string, Record<string, string>>
8
- }
9
-
10
- const I18nContext = React.createContext<I18nConfig>({
11
- defaultLocale: 'en',
12
- supported: ['en'],
13
- translations: {},
14
- })
15
-
16
- export const I18nProvider = I18nContext.Provider
17
-
18
- export function useI18nConfig(): I18nConfig {
19
- return React.useContext(I18nContext)
20
- }
21
-
22
- export function useTranslation(): (key: string, params?: Record<string, string | number>) => string {
23
- const config = React.useContext(I18nContext)
24
- const localeStore = useLocaleStore()
25
- const locale = localeStore.locale
26
-
27
- return React.useCallback(
28
- (key: string, params?: Record<string, string | number>): string => {
29
- const localizedTranslations = config.translations[locale] ?? {}
30
- const fallback = config.translations[config.defaultLocale] ?? {}
31
- // Global fallback lets plugins register their locales independently of any
32
- // I18nProvider — needed when a de-bridged plugin runs under a host shell
33
- // that doesn't mount @fayz-ai/core's I18nProvider (incremental de-bridge), and
34
- // for manifest apps where plugins self-register translations.
35
- const gLocale = _globalTranslations[locale] ?? {}
36
- const gFallback = _globalTranslations[config.defaultLocale] ?? {}
37
- let raw = localizedTranslations[key] ?? gLocale[key] ?? fallback[key] ?? gFallback[key] ?? key
38
-
39
- if (params) {
40
- for (const [k, v] of Object.entries(params)) {
41
- raw = raw.replace(new RegExp(`\\{\\{${k}\\}\\}`, 'g'), String(v))
42
- }
43
- }
44
- return raw
45
- },
46
- [config, locale],
47
- )
48
- }
49
-
50
- // Minimal locale store (avoids circular dep with stores package)
51
- interface LocaleStore {
52
- locale: string
53
- setLocale: (locale: string) => void
54
- }
55
-
56
- let _localeStore: LocaleStore = {
57
- locale: 'en',
58
- setLocale: (l) => { _localeStore.locale = l },
59
- }
60
- const _localeListeners = new Set<() => void>()
61
-
62
- export function setLocaleStore(store: LocaleStore): void {
63
- _localeStore = store
64
- }
65
-
66
- // Bumped when lazily-loaded translations register so subscribed components
67
- // re-render even though the locale string itself did not change.
68
- let _i18nVersion = 0
69
- function getI18nSnapshot(): string {
70
- return `${_localeStore.locale} ${_i18nVersion}`
71
- }
72
-
73
- function useLocaleStore(): LocaleStore {
74
- const snapshot = React.useSyncExternalStore(
75
- (listener) => {
76
- _localeListeners.add(listener)
77
- return () => _localeListeners.delete(listener)
78
- },
79
- getI18nSnapshot,
80
- getI18nSnapshot,
81
- )
82
- return React.useMemo(() => {
83
- const locale = snapshot.slice(0, snapshot.indexOf(' '))
84
- return { locale, setLocale: setCurrentLocale }
85
- }, [snapshot])
86
- }
87
-
88
- export function getCurrentLocale(): string {
89
- return _localeStore.locale
90
- }
91
-
92
- export function setCurrentLocale(locale: string): void {
93
- if (_localeStore.locale === locale) return
94
- _localeStore.setLocale(locale)
95
- // Fire-and-forget: if the locale's shell translations are lazily split, load
96
- // and register them; keys fall back to 'en' until the chunk arrives.
97
- void preloadLocale(locale)
98
- _localeListeners.forEach((listener) => listener())
99
- }
100
-
101
- // Core built-in translations
102
- export const coreTranslations: Record<string, Record<string, string>> = {
103
- en: {
104
- 'common.save': 'Save',
105
- 'common.saveChanges': 'Save Changes',
106
- 'common.saving': 'Saving...',
107
- 'common.cancel': 'Cancel',
108
- 'common.delete': 'Delete',
109
- 'common.edit': 'Edit',
110
- 'common.close': 'Close',
111
- 'common.confirm': 'Confirm',
112
- 'common.discard': 'Discard',
113
- 'common.back': 'Back',
114
- 'common.formIncomplete': 'Fill in the required fields before saving.',
115
- 'connectors.title': 'Integrations',
116
- 'connectors.subtitle': 'Connect external providers to this module.',
117
- 'connectors.connected': 'Connected',
118
- 'connectors.notConnected': 'Not connected',
119
- 'connectors.connect': 'Connect',
120
- 'connectors.disconnect': 'Disconnect',
121
- 'connectors.test': 'Test',
122
- 'connectors.save': 'Save connection',
123
- 'connectors.testing': 'Testing…',
124
- 'connectors.saving': 'Saving…',
125
- 'connectors.empty': 'No integrations available for this module yet.',
126
- 'connectors.configure': 'Configure',
127
- 'connectors.hubSubtitle': 'Apps, assistants and providers connected to this organization.',
128
- 'connectors.add': 'Add connector',
129
- 'connectors.addSubtitle': 'Integrations available on Fayz for this organization.',
130
- 'connectors.search': 'Search integration…',
131
- 'connectors.noneFound': 'No integration found for “{{query}}”.',
132
- 'connectors.viewAll': 'See every connector',
133
- 'connectors.groupMine': 'In this organization',
134
- 'connectors.groupOffered': 'Offered by Fayz',
135
- 'connectors.docs': 'Provider documentation',
136
- 'connectors.builtIn': 'native',
137
- 'connectors.partOfApp': 'part of the app',
138
- 'connectors.plane.agentic': 'Assistant',
139
- 'connectors.plane.agentic.desc': 'The assistant uses the provider’s own tools on demand. Nothing is copied.',
140
- 'connectors.plane.sync': 'Sync',
141
- 'connectors.plane.sync.desc': 'A pipeline keeps a copy of the data inside the app.',
142
- 'connectors.plane.recommended': 'recommended',
143
- 'connectors.plane.undecided': 'How this one is resolved is decided by Fayz when the integration ships.',
144
- 'connectors.plane.switched': 'Mode changed',
145
- 'connectors.plane.lockedHint': 'This connection cannot change mode after the fact — disconnect and connect again.',
146
- 'connectors.direction.inbound': 'inbound',
147
- 'connectors.direction.outbound': 'outbound',
148
- 'connectors.state.connected': 'connected',
149
- 'connectors.state.ready': 'ready to connect',
150
- 'connectors.state.catalog': 'available on Fayz',
151
- 'connectors.state.soon': 'coming soon',
152
- 'connectors.journey.what': 'What it does',
153
- 'connectors.journey.how': 'How it gets resolved',
154
- 'connectors.journey.authorize': 'Authorize',
155
- 'connectors.journey.access': 'Access',
156
- 'connectors.journey.after': 'Once connected',
157
- 'connectors.after.agentic': 'These tools are available to the assistant right now.',
158
- 'connectors.after.willAgentic': 'The assistant gains this provider’s tools; no copy of the data is made.',
159
- 'connectors.after.willSync': 'A pipeline starts keeping this data in agreement, with mapping and history.',
160
- 'connectors.tools': 'Assistant tools',
161
- 'connectors.entitiesCount': 'reaches {{count}} record types',
162
- 'connectors.entitiesList': 'Records: {{list}}',
163
- 'connectors.capabilitiesUnknown': 'This connector has not published what it reaches yet.',
164
- 'connectors.readOnly': 'read only',
165
- 'connectors.readWrite': 'read and write',
166
- 'connectors.needsPlugin': 'Fayz has this integration built, but this app does not have the plugin that hosts it.',
167
- 'connectors.soonBody': 'Fayz lists this provider, but the integration is not wired yet.',
168
- 'connectors.connectedOn': 'Connected on {{date}}',
169
- 'connectors.lastUsed': 'used {{when}}',
170
- 'connectors.neverUsed': 'not used yet',
171
- 'connectors.grantedByOther': 'authorized by someone else on the team',
172
- 'connectors.revokeConfirm': 'Disconnect {{name}}? It loses access immediately.',
173
- 'connectors.filter.all': 'All',
174
- 'connectors.filter.connected': 'Connected',
175
- 'connectors.filter.agentic': 'Assistant',
176
- 'connectors.filter.sync': 'Sync',
177
- 'connectors.emptyTitle': 'No connectors',
178
- 'connectors.emptyBody': 'Connect a provider, or authorize an external assistant, and it shows up here.',
179
- 'connectors.noProject': 'Connectors unavailable',
180
- 'connectors.noProjectBody': 'This app is not linked to a Fayz project.',
181
- 'connectors.noOrg': 'No organization',
182
- 'connectors.noOrgBody': 'Pick an organization to see its connections.',
183
- 'saveBar.unsaved': 'Unsaved changes',
184
- 'common.add': 'Add',
185
- 'common.loading': 'Loading...',
186
- 'common.error': 'Something went wrong',
187
- 'common.noResults': 'No results found.',
188
- 'common.search': 'Search',
189
- 'common.actions': 'Actions',
190
- 'common.continue': 'Continue',
191
- 'common.done': 'Done',
192
- 'common.yes': 'Yes',
193
- 'common.no': 'No',
194
- 'common.active': 'Active',
195
- 'common.inactive': 'Inactive',
196
- 'common.overview': 'Overview',
197
- 'common.settings': 'Settings',
198
- 'common.plugins': 'Plugins',
199
- 'common.new': 'New',
200
- 'common.filter': 'Filter',
201
- 'common.export': 'Export',
202
- 'common.import': 'Import',
203
- 'common.preview': 'Preview',
204
- 'common.total': 'Total',
205
- 'crud.newItem': 'New {{name}}',
206
- 'crud.editItem': 'Edit {{name}}',
207
- 'crud.deleteConfirm': 'Delete {{name}}?',
208
- 'crud.deleteMessage': 'This action cannot be undone.',
209
- 'crud.created': '{{name}} created',
210
- 'crud.updated': '{{name}} updated',
211
- 'crud.deleted': '{{name}} deleted',
212
- 'crud.noItems': 'No {{namePlural}} yet.',
213
- 'auth.login.title': 'Sign in',
214
- 'auth.login.subtitle': 'Enter your credentials to access your account',
215
- 'auth.login.emailLabel': 'Email',
216
- 'auth.login.passwordLabel': 'Password',
217
- 'auth.login.submit': 'Sign in',
218
- 'auth.login.forgotPassword': 'Forgot password?',
219
- 'auth.login.noAccount': "Don't have an account?",
220
- 'auth.login.signUpLink': 'Sign up',
221
- 'auth.signup.title': 'Create account',
222
- 'auth.signup.submit': 'Create account',
223
- 'auth.signup.hasAccount': 'Already have an account?',
224
- 'auth.signup.signInLink': 'Sign in',
225
- 'auth.setPassword.recoveryTitle': 'Choose a new password',
226
- 'auth.setPassword.recoverySubtitle': 'Set a new password to get back into your account.',
227
- 'auth.setPassword.welcomeTitle': 'Welcome to {{appName}}',
228
- 'auth.setPassword.welcomeSubtitle': 'Choose a password to finish setting up your access.',
229
- 'auth.setPassword.newPassword': 'New password',
230
- 'auth.setPassword.confirmPassword': 'Confirm password',
231
- 'auth.setPassword.submit': 'Save password',
232
- 'auth.setPassword.saving': 'Saving...',
233
- 'auth.setPassword.tooShort': 'Password must be at least 8 characters.',
234
- 'auth.setPassword.mismatch': 'Passwords do not match.',
235
- 'auth.setPassword.checking': 'Checking your link...',
236
- 'auth.setPassword.expiredTitle': 'This link has expired',
237
- 'auth.setPassword.expiredSubtitle': 'Reset links can only be used once. Enter your e-mail and we will send a new one.',
238
- 'auth.setPassword.email': 'E-mail',
239
- 'auth.setPassword.sendNewLink': 'Send new link',
240
- 'auth.setPassword.sending': 'Sending...',
241
- 'auth.setPassword.sent': 'Check your inbox — a new link is on the way.',
242
- 'auth.setPassword.backToLogin': 'Back to sign in',
243
- 'settings.title': 'Settings',
244
- 'settings.company': 'Company',
245
- 'settings.branding': 'Branding',
246
- 'settings.security': 'Security',
247
- 'settings.sites': 'Sites',
248
- 'settings.team': 'Team',
249
- 'settings.billing': 'Billing',
250
- 'settings.locations': 'Locations',
251
- 'billing.title': 'Plans & Billing',
252
- 'billing.currentPlan': 'Current Plan',
253
- 'billing.upgrade': 'Upgrade',
254
- 'billing.manage': 'Manage Subscription',
255
- },
256
- 'pt-BR': {
257
- 'common.save': 'Salvar',
258
- 'common.saveChanges': 'Salvar Alterações',
259
- 'common.saving': 'Salvando...',
260
- 'common.cancel': 'Cancelar',
261
- 'common.delete': 'Excluir',
262
- 'common.edit': 'Editar',
263
- 'common.close': 'Fechar',
264
- 'common.confirm': 'Confirmar',
265
- 'common.discard': 'Descartar',
266
- 'common.back': 'Voltar',
267
- 'common.formIncomplete': 'Preencha os campos obrigatórios antes de salvar.',
268
- 'connectors.title': 'Integrações',
269
- 'connectors.subtitle': 'Conecte provedores externos a este módulo.',
270
- 'connectors.connected': 'Conectado',
271
- 'connectors.notConnected': 'Não conectado',
272
- 'connectors.connect': 'Conectar',
273
- 'connectors.disconnect': 'Desconectar',
274
- 'connectors.test': 'Testar',
275
- 'connectors.save': 'Salvar conexão',
276
- 'connectors.testing': 'Testando…',
277
- 'connectors.saving': 'Salvando…',
278
- 'connectors.empty': 'Nenhuma integração disponível para este módulo ainda.',
279
- 'connectors.configure': 'Configurar',
280
- 'connectors.hubSubtitle': 'Aplicativos, assistentes e provedores ligados a esta organização.',
281
- 'connectors.add': 'Adicionar conector',
282
- 'connectors.addSubtitle': 'Integrações disponíveis no Fayz para esta organização.',
283
- 'connectors.search': 'Buscar integração…',
284
- 'connectors.noneFound': 'Nenhuma integração encontrada para “{{query}}”.',
285
- 'connectors.viewAll': 'Ver todos os conectores',
286
- 'connectors.groupMine': 'Nesta organização',
287
- 'connectors.groupOffered': 'Oferecidos pelo Fayz',
288
- 'connectors.docs': 'Documentação do provedor',
289
- 'connectors.builtIn': 'nativo',
290
- 'connectors.partOfApp': 'faz parte do app',
291
- 'connectors.plane.agentic': 'Assistente',
292
- 'connectors.plane.agentic.desc': 'O assistente usa as ferramentas do provedor na hora. Nada é copiado.',
293
- 'connectors.plane.sync': 'Sincronização',
294
- 'connectors.plane.sync.desc': 'Uma esteira mantém uma cópia dos dados dentro do app.',
295
- 'connectors.plane.recommended': 'recomendado',
296
- 'connectors.plane.undecided': 'O modo desta integração é definido pelo Fayz quando ela for ligada.',
297
- 'connectors.plane.switched': 'Modo alterado',
298
- 'connectors.plane.lockedHint': 'Esta conexão não troca de modo depois de feita — desconecte e conecte de novo.',
299
- 'connectors.direction.inbound': 'entrada',
300
- 'connectors.direction.outbound': 'saída',
301
- 'connectors.state.connected': 'conectado',
302
- 'connectors.state.ready': 'pronto para conectar',
303
- 'connectors.state.catalog': 'disponível no Fayz',
304
- 'connectors.state.soon': 'em breve',
305
- 'connectors.journey.what': 'O que ele faz',
306
- 'connectors.journey.how': 'Como ele resolve',
307
- 'connectors.journey.authorize': 'Autorizar',
308
- 'connectors.journey.access': 'Acesso',
309
- 'connectors.journey.after': 'Depois de conectado',
310
- 'connectors.after.agentic': 'Essas ferramentas já estão à mão do assistente.',
311
- 'connectors.after.willAgentic': 'O assistente ganha as ferramentas do provedor; nenhuma cópia dos dados é feita.',
312
- 'connectors.after.willSync': 'Uma esteira passa a manter esses dados em acordo, com de-para e histórico.',
313
- 'connectors.tools': 'Ferramentas do assistente',
314
- 'connectors.entitiesCount': 'alcança {{count}} tipos de registro',
315
- 'connectors.entitiesList': 'Registros: {{list}}',
316
- 'connectors.capabilitiesUnknown': 'Este conector ainda não publicou o que ele alcança.',
317
- 'connectors.readOnly': 'somente leitura',
318
- 'connectors.readWrite': 'leitura e escrita',
319
- 'connectors.needsPlugin': 'O Fayz tem essa integração pronta, mas este app não tem o plugin que hospeda ela.',
320
- 'connectors.soonBody': 'O Fayz lista este provedor, mas a integração ainda não foi ligada.',
321
- 'connectors.connectedOn': 'Conectado em {{date}}',
322
- 'connectors.lastUsed': 'usado {{when}}',
323
- 'connectors.neverUsed': 'ainda não usado',
324
- 'connectors.grantedByOther': 'autorizado por outra pessoa da equipe',
325
- 'connectors.revokeConfirm': 'Desconectar {{name}}? Ele perde o acesso imediatamente.',
326
- 'connectors.filter.all': 'Tudo',
327
- 'connectors.filter.connected': 'Conectados',
328
- 'connectors.filter.agentic': 'Assistente',
329
- 'connectors.filter.sync': 'Sincronização',
330
- 'connectors.emptyTitle': 'Nenhum conector',
331
- 'connectors.emptyBody': 'Conecte um provedor, ou autorize um assistente externo, e ele aparece aqui.',
332
- 'connectors.noProject': 'Conectores indisponíveis',
333
- 'connectors.noProjectBody': 'Este app não está ligado a um projeto Fayz.',
334
- 'connectors.noOrg': 'Sem organização',
335
- 'connectors.noOrgBody': 'Escolha uma organização para ver as conexões dela.',
336
- 'saveBar.unsaved': 'Alterações não salvas',
337
- 'common.add': 'Adicionar',
338
- 'common.loading': 'Carregando...',
339
- 'common.error': 'Algo deu errado',
340
- 'common.noResults': 'Nenhum resultado encontrado.',
341
- 'common.search': 'Buscar',
342
- 'common.actions': 'Ações',
343
- 'common.continue': 'Continuar',
344
- 'common.done': 'Concluído',
345
- 'common.yes': 'Sim',
346
- 'common.no': 'Não',
347
- 'common.active': 'Ativo',
348
- 'common.inactive': 'Inativo',
349
- 'common.overview': 'Visão Geral',
350
- 'common.settings': 'Configurações',
351
- 'common.plugins': 'Plugins',
352
- 'common.new': 'Novo',
353
- 'common.filter': 'Filtrar',
354
- 'common.export': 'Exportar',
355
- 'common.import': 'Importar',
356
- 'common.preview': 'Pré-visualizar',
357
- 'common.total': 'Total',
358
- 'crud.newItem': 'Novo {{name}}',
359
- 'crud.editItem': 'Editar {{name}}',
360
- 'crud.deleteConfirm': 'Excluir {{name}}?',
361
- 'crud.deleteMessage': 'Esta ação não pode ser desfeita.',
362
- 'crud.created': '{{name}} criado',
363
- 'crud.updated': '{{name}} atualizado',
364
- 'crud.deleted': '{{name}} excluído',
365
- 'crud.noItems': 'Nenhum {{namePlural}} ainda.',
366
- 'auth.login.title': 'Entrar',
367
- 'auth.login.subtitle': 'Digite suas credenciais para acessar sua conta',
368
- 'auth.login.emailLabel': 'E-mail',
369
- 'auth.login.passwordLabel': 'Senha',
370
- 'auth.login.submit': 'Entrar',
371
- 'auth.login.forgotPassword': 'Esqueceu a senha?',
372
- 'auth.login.noAccount': 'Não tem uma conta?',
373
- 'auth.login.signUpLink': 'Cadastrar',
374
- 'auth.signup.title': 'Criar conta',
375
- 'auth.signup.submit': 'Criar conta',
376
- 'auth.signup.hasAccount': 'Já tem uma conta?',
377
- 'auth.signup.signInLink': 'Entrar',
378
- 'auth.setPassword.recoveryTitle': 'Escolha uma nova senha',
379
- 'auth.setPassword.recoverySubtitle': 'Defina uma nova senha para voltar a acessar sua conta.',
380
- 'auth.setPassword.welcomeTitle': 'Bem-vindo ao {{appName}}',
381
- 'auth.setPassword.welcomeSubtitle': 'Escolha uma senha para terminar de configurar seu acesso.',
382
- 'auth.setPassword.newPassword': 'Nova senha',
383
- 'auth.setPassword.confirmPassword': 'Confirmar senha',
384
- 'auth.setPassword.submit': 'Salvar senha',
385
- 'auth.setPassword.saving': 'Salvando...',
386
- 'auth.setPassword.tooShort': 'A senha precisa ter no mínimo 8 caracteres.',
387
- 'auth.setPassword.mismatch': 'As senhas não conferem.',
388
- 'auth.setPassword.checking': 'Verificando seu link...',
389
- 'auth.setPassword.expiredTitle': 'Este link expirou',
390
- 'auth.setPassword.expiredSubtitle': 'Links de acesso só funcionam uma vez. Informe seu e-mail e enviamos um novo.',
391
- 'auth.setPassword.email': 'E-mail',
392
- 'auth.setPassword.sendNewLink': 'Enviar novo link',
393
- 'auth.setPassword.sending': 'Enviando...',
394
- 'auth.setPassword.sent': 'Confira sua caixa de entrada — o novo link está a caminho.',
395
- 'auth.setPassword.backToLogin': 'Voltar para o login',
396
- 'settings.title': 'Configurações',
397
- 'settings.company': 'Empresa',
398
- 'settings.branding': 'Identidade Visual',
399
- 'settings.security': 'Segurança',
400
- 'settings.sites': 'Sites',
401
- 'settings.team': 'Equipe',
402
- 'settings.billing': 'Faturamento',
403
- 'settings.locations': 'Localizações',
404
- 'billing.title': 'Planos e Faturamento',
405
- 'billing.currentPlan': 'Plano Atual',
406
- 'billing.upgrade': 'Fazer Upgrade',
407
- 'billing.manage': 'Gerenciar Assinatura',
408
- },
409
- }
410
-
411
- // Global translation registry — plugins merge their locales here so keys resolve
412
- // regardless of which shell mounts the I18nProvider.
413
- let _globalTranslations: Record<string, Record<string, string>> = {}
414
-
415
- export function registerTranslations(translations?: Record<string, Record<string, string>>): void {
416
- if (!translations) return
417
- _globalTranslations = mergeTranslations(_globalTranslations, translations)
418
- }
419
-
420
- export function mergeTranslations(
421
- base: Record<string, Record<string, string>>,
422
- ...overrides: Array<Record<string, Record<string, string>> | undefined>
423
- ): Record<string, Record<string, string>> {
424
- const result = { ...base }
425
- for (const override of overrides) {
426
- if (!override) continue
427
- for (const [locale, translations] of Object.entries(override)) {
428
- result[locale] = { ...(result[locale] ?? {}), ...translations }
429
- }
430
- }
431
- return result
432
- }
433
-
434
- // Seed the global fallback with core's own translations + the shared shell /
435
- // CRUD / framework translations (extracted from saas-core's central i18n), so
436
- // the native CRUD engine, framework UI and de-bridged plugins resolve their
437
- // keys even under a host shell that does not mount @fayz-ai/core's I18nProvider.
438
- registerTranslations(coreTranslations)
439
- registerTranslations({ en: shellTranslationsEn })
440
-
441
- // ---------------------------------------------------------------------------
442
- // Lazy shell locales. Only 'en' (the fallback) ships eagerly; other locales
443
- // load on demand when the app switches to them (setCurrentLocale) or when the
444
- // app awaits preloadLocale before rendering. Keys resolve through the 'en'
445
- // fallback until the locale chunk arrives, then listeners re-render.
446
- // ---------------------------------------------------------------------------
447
-
448
- const _lazyShellLocales: Record<string, () => Promise<Record<string, string>>> = {
449
- 'pt-BR': () => import('./shell-translations.pt-br').then((m) => m.shellTranslationsPtBr),
450
- }
451
- const _loadedShellLocales = new Set<string>(['en'])
452
- const _pendingShellLocales = new Map<string, Promise<void>>()
453
-
454
- /**
455
- * Ensure a lazily-split shell locale is loaded and registered. Resolves
456
- * immediately for unknown/already-loaded locales. setCurrentLocale calls this
457
- * fire-and-forget; apps that must avoid an English flash on first paint can
458
- * `await preloadLocale('pt-BR')` before rendering.
459
- */
460
- export function preloadLocale(locale: string): Promise<void> {
461
- if (_loadedShellLocales.has(locale)) return Promise.resolve()
462
- const loader = _lazyShellLocales[locale]
463
- if (!loader) return Promise.resolve()
464
- let pending = _pendingShellLocales.get(locale)
465
- if (!pending) {
466
- pending = loader().then((translations) => {
467
- _loadedShellLocales.add(locale)
468
- _pendingShellLocales.delete(locale)
469
- registerTranslations({ [locale]: translations })
470
- _i18nVersion++
471
- _localeListeners.forEach((listener) => listener())
472
- })
473
- _pendingShellLocales.set(locale, pending)
474
- }
475
- return pending
476
- }