@fayz-ai/admin 0.49.0 → 0.51.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 (29) hide show
  1. package/dist/ScheduleEditor-6YFOBHAE.js +6 -0
  2. package/dist/{ScheduleEditor-BXWJ7CMI.js.map → ScheduleEditor-6YFOBHAE.js.map} +1 -1
  3. package/dist/SubscriptionPage-DI6UV5LF.js +8 -0
  4. package/dist/{SubscriptionPage-VBDDRSVW.js.map → SubscriptionPage-DI6UV5LF.js.map} +1 -1
  5. package/dist/app/admin-app.d.ts.map +1 -1
  6. package/dist/app/config.d.ts +6 -0
  7. package/dist/app/config.d.ts.map +1 -1
  8. package/dist/billing/index.js +3 -3
  9. package/dist/{chunk-2Q6QHTZV.js → chunk-3S7UULIC.js} +4 -4
  10. package/dist/{chunk-2Q6QHTZV.js.map → chunk-3S7UULIC.js.map} +1 -1
  11. package/dist/{chunk-KVIINVY6.js → chunk-4RKG7YH5.js} +3 -3
  12. package/dist/{chunk-KVIINVY6.js.map → chunk-4RKG7YH5.js.map} +1 -1
  13. package/dist/{chunk-OEY3V6J3.js → chunk-DASJ4UF3.js} +3 -3
  14. package/dist/{chunk-OEY3V6J3.js.map → chunk-DASJ4UF3.js.map} +1 -1
  15. package/dist/{chunk-ZMP52ZHM.js → chunk-EOYE3ZAC.js} +3 -3
  16. package/dist/{chunk-ZMP52ZHM.js.map → chunk-EOYE3ZAC.js.map} +1 -1
  17. package/dist/{chunk-F346TYKO.js → chunk-TAN7UGC2.js} +5 -5
  18. package/dist/{chunk-F346TYKO.js.map → chunk-TAN7UGC2.js.map} +1 -1
  19. package/dist/{chunk-GZWX4ZIK.js → chunk-XQM74EP4.js} +37 -3
  20. package/dist/chunk-XQM74EP4.js.map +1 -0
  21. package/dist/data/client.d.ts +19 -0
  22. package/dist/data/client.d.ts.map +1 -1
  23. package/dist/index.js +14 -13
  24. package/dist/index.js.map +1 -1
  25. package/dist/org/index.js +2 -2
  26. package/package.json +7 -7
  27. package/dist/ScheduleEditor-BXWJ7CMI.js +0 -6
  28. package/dist/SubscriptionPage-VBDDRSVW.js +0 -8
  29. package/dist/chunk-GZWX4ZIK.js.map +0 -1
package/dist/org/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { ORG_CACHE_TTL_MS, OrgMark, OrgProvider, WorkspaceChooser, WorkspaceChooserGate, WorkspaceSwitching, WorkspaceSwitchingHost, clearOrgSnapshot, createMockOrgAdapter, createSupabaseOrgAdapter, decideWorkspaceChoice, getAutoPick, markWorkspaceSwitch, orgInitials, readOrgSnapshot, setAutoPick, takeWorkspaceSwitch, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional, useWorkspaceSwitchingStore } from '../chunk-ZMP52ZHM.js';
1
+ export { ORG_CACHE_TTL_MS, OrgMark, OrgProvider, WorkspaceChooser, WorkspaceChooserGate, WorkspaceSwitching, WorkspaceSwitchingHost, clearOrgSnapshot, createMockOrgAdapter, createSupabaseOrgAdapter, decideWorkspaceChoice, getAutoPick, markWorkspaceSwitch, orgInitials, readOrgSnapshot, setAutoPick, takeWorkspaceSwitch, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional, useWorkspaceSwitchingStore } from '../chunk-EOYE3ZAC.js';
2
2
  import '../chunk-UQ2NTFQC.js';
3
- export { getPersistedOrgId, persistOrgId, useOrganizationStore } from '../chunk-GZWX4ZIK.js';
3
+ export { getPersistedOrgId, persistOrgId, useOrganizationStore } from '../chunk-XQM74EP4.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "fayz": {
4
4
  "status": "beta"
5
5
  },
6
- "version": "0.49.0",
6
+ "version": "0.51.0",
7
7
  "description": "Fayz SDK admin layer — the admin shell, CRUD engine, multi-tenancy, billing, permissions and org management",
8
8
  "type": "module",
9
9
  "sideEffects": [
@@ -59,12 +59,12 @@
59
59
  "@radix-ui/react-dialog": "^1.1.0",
60
60
  "@tanstack/react-table": "^8.20.0",
61
61
  "cmdk": "^1.0.0",
62
- "@fayz-ai/auth": "^0.49.0",
63
- "@fayz-ai/core": "^0.49.0",
64
- "@fayz-ai/db": "^0.24.1",
65
- "@fayz-ai/sdk": "^0.49.0",
66
- "@fayz-ai/tasks": "^0.49.0",
67
- "@fayz-ai/ui": "^0.49.0"
62
+ "@fayz-ai/auth": "^0.50.0",
63
+ "@fayz-ai/core": "^0.50.0",
64
+ "@fayz-ai/db": "^0.24.3",
65
+ "@fayz-ai/sdk": "^0.50.0",
66
+ "@fayz-ai/tasks": "^0.50.0",
67
+ "@fayz-ai/ui": "^0.50.0"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@supabase/supabase-js": "^2.45.0",
@@ -1,6 +0,0 @@
1
- export { ScheduleEditor } from './chunk-KVIINVY6.js';
2
- import './chunk-ZMP52ZHM.js';
3
- import './chunk-UQ2NTFQC.js';
4
- import './chunk-GZWX4ZIK.js';
5
- //# sourceMappingURL=ScheduleEditor-BXWJ7CMI.js.map
6
- //# sourceMappingURL=ScheduleEditor-BXWJ7CMI.js.map
@@ -1,8 +0,0 @@
1
- export { SubscriptionPage } from './chunk-F346TYKO.js';
2
- import './chunk-YUHCC7JY.js';
3
- import './chunk-OEY3V6J3.js';
4
- import './chunk-ZMP52ZHM.js';
5
- import './chunk-UQ2NTFQC.js';
6
- import './chunk-GZWX4ZIK.js';
7
- //# sourceMappingURL=SubscriptionPage-VBDDRSVW.js.map
8
- //# sourceMappingURL=SubscriptionPage-VBDDRSVW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/data/client.ts","../src/org/store.ts","../src/lib/supabase.ts"],"names":["_getOpt"],"mappings":"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","file":"chunk-GZWX4ZIK.js","sourcesContent":["import { createClient, type SupabaseClient } from '@supabase/supabase-js'\nimport { setGlobalSupabaseClient, getActiveUnitId, getActiveTenantId } from '@fayz-ai/core'\nimport { createDedupedFetch } from '@fayz-ai/sdk'\n\nlet _client: SupabaseClient | null = null\n\n/**\n * Para onde a requisição vai, nos três formatos que `fetch` aceita.\n *\n * `input` pode ser uma string, uma URL ou um Request — e ler `.url` de uma\n * string devolve `undefined` em silêncio, que é como um filtro destes deixa\n * passar exatamente o que devia barrar.\n */\nexport function requestUrl(input: RequestInfo | URL): string {\n if (typeof input === 'string') return input\n if (input instanceof URL) return input.toString()\n return input?.url ?? ''\n}\n\n/** O caminho que o Supabase dá a toda função de borda. Exportada para o teste. */\nexport function isEdgeFunctionCall(input: RequestInfo | URL): boolean {\n return requestUrl(input).includes('/functions/v1/')\n}\n\n/**\n * Create (and cache) the Supabase client for the Fayz app.\n * Also registers it as the global client in @fayz-ai/core so data providers\n * can resolve it without prop-drilling.\n *\n * Idempotent — subsequent calls with the same URL return the cached client.\n */\nexport function createFayzSupabaseClient(url: string, anonKey: string): SupabaseClient {\n if (_client) return _client\n\n if (!url || !anonKey) {\n throw new Error(\n '[@fayz-ai/admin] Supabase URL and anon key are required. ' +\n 'Pass supabaseUrl and supabaseAnonKey to createFayzApp.',\n )\n }\n\n // Every read goes through this client — the one place that can see two\n // components asking the same thing at the same instant.\n const deduped = createDedupedFetch()\n\n _client = createClient(url, anonKey, {\n auth: { autoRefreshToken: true, persistSession: true },\n global: {\n // The active unit rides on every request so the DATABASE can stamp a\n // write with it (041's trigger reads this header). Reads are narrowed by\n // an explicit filter, not by this — a header cannot be trusted to narrow,\n // and it must never be able to widen: the policies resolve unit access\n // through `public.user_unit_ids()`, never through what was sent here.\n //\n // `x-fayz-unit` is in the dedupe vary list. Without that, two identical\n // URLs under different units collapse into one response.\n fetch: (input: RequestInfo | URL, init: RequestInit = {}) => {\n // Estes cabeçalhos são para o BANCO, e só para ele. Uma função de borda\n // recebe o tenant no corpo (`tenantId`) e nunca leu nenhum dos dois — o\n // que ela faz com um cabeçalho desconhecido é RECUSAR O PREFLIGHT, e o\n // navegador então bloqueia o POST antes de ele sair. Nenhuma requisição\n // chega ao log, e quem está usando vê a palavra \"CORS\".\n //\n // As vinte funções deste repositório declaram listas fixas de\n // `Access-Control-Allow-Headers` e nenhuma delas cita `x-fayz-tenant`.\n // Mandar o cabeçalho para lá não compra nada e derruba todas de uma vez.\n if (isEdgeFunctionCall(input)) return deduped(input, init)\n\n const unit = getActiveUnitId()\n // `x-fayz-tenant` rides the same way, for the reason 145 spells out:\n // the archetype policies resolve tenant through app.current_tenant_id(),\n // which knew only the signed JWT claim (nobody mints one) or \"your only\n // account\". A user with two accounts therefore read NOTHING from\n // public.people / orders / products — silently, and long before any\n // screen moved. This is the app finally saying which account it is in.\n //\n // Same rule as the unit header, and 145 enforces it: the value only\n // CHOOSES among the accounts the user already belongs to, validated\n // against app.memberships. It narrows; it can never widen.\n const tenant = getActiveTenantId()\n if (!unit && !tenant) return deduped(input, init)\n const headers = new Headers(init.headers)\n if (unit) headers.set('x-fayz-unit', unit)\n if (tenant) headers.set('x-fayz-tenant', tenant)\n return deduped(input, { ...init, headers })\n },\n },\n })\n\n // Register globally so @fayz-ai/core data providers can use it\n setGlobalSupabaseClient(_client)\n\n return _client\n}\n\n/** Get the cached client — throws if not initialised */\nexport function getFayzSupabaseClient(): SupabaseClient {\n if (!_client) {\n throw new Error(\n '[@fayz-ai/admin] Supabase client not initialised. Call createFayzApp with supabaseUrl and supabaseAnonKey first.',\n )\n }\n return _client\n}\n\n/** Safe getter — returns null if not initialised (mock/offline mode) */\nexport function getFayzSupabaseClientOptional(): SupabaseClient | null {\n return _client\n}\n","import { create } from 'zustand'\nimport { setActiveTenantId, type Organization, type OrgMember, type OrgMembership } from '@fayz-ai/core'\n\nconst STORAGE_KEY = 'fayz:current-org'\n\n// ---------------------------------------------------------------------------\n// Persistence helpers\n// ---------------------------------------------------------------------------\n\nfunction getPersistedOrgId(): string | null {\n try {\n if (typeof localStorage === 'undefined') return null\n return localStorage.getItem(STORAGE_KEY)\n } catch {\n return null\n }\n}\n\nfunction persistOrgId(orgId: string | null): void {\n try {\n if (typeof localStorage === 'undefined') return\n if (orgId) {\n localStorage.setItem(STORAGE_KEY, orgId)\n } else {\n localStorage.removeItem(STORAGE_KEY)\n }\n } catch {\n // ignore\n }\n}\n\n// ---------------------------------------------------------------------------\n// Store interface\n// ---------------------------------------------------------------------------\n\nexport interface OrgStore {\n currentOrg: Organization | null\n userOrgs: OrgMembership[]\n members: OrgMember[]\n /** Person `kind`s that make up the team (from config.team.personKinds). Drives\n * the Person-first Team screen; empty = legacy membership-only mode. */\n teamPersonKinds: string[]\n loading: boolean\n\n /**\n * A conta ativa, e a ESCOLHA que ela representa: persiste o pino.\n *\n * Use quando alguém decidiu — a troca de conta, a resolução do boot. Para\n * apenas PINTAR o que já se sabia, use `paintCurrentOrg`.\n */\n setCurrentOrg: (org: Organization | null) => void\n /**\n * Pinta a conta sem gravar o pino.\n *\n * O snapshot repinta a última conta conhecida antes de o primeiro filho\n * renderizar, para ninguém ver um quadro sem org. Isso é CACHE, não\n * decisão — e enquanto ele gravava o pino, vencia o\n * `decideWorkspaceChoice`: quem usa duas contas ficava preso na última que\n * o snapshot viu, e nada escolhido sobrevivia ao boot.\n */\n paintCurrentOrg: (org: Organization | null) => void\n setUserOrgs: (orgs: OrgMembership[]) => void\n setMembers: (members: OrgMember[]) => void\n setTeamPersonKinds: (kinds: string[]) => void\n setLoading: (loading: boolean) => void\n reset: () => void\n}\n\nexport const useOrganizationStore = create<OrgStore>((set) => ({\n currentOrg: null,\n userOrgs: [],\n members: [],\n teamPersonKinds: [],\n loading: false,\n\n setCurrentOrg: (org) => {\n setActiveTenantId(org?.id)\n persistOrgId(org?.id ?? null)\n set({ currentOrg: org })\n },\n\n // Sem `persistOrgId`: é a única diferença, e é toda a diferença.\n paintCurrentOrg: (org) => {\n setActiveTenantId(org?.id)\n set({ currentOrg: org })\n },\n setUserOrgs: (orgs) => set({ userOrgs: orgs }),\n setMembers: (members) => set({ members }),\n setTeamPersonKinds: (kinds) => set({ teamPersonKinds: kinds }),\n setLoading: (loading) => set({ loading }),\n reset: () => {\n setActiveTenantId(undefined)\n // NOTE: do NOT clear the persisted org id here. The org providers call\n // reset() whenever the auth store transiently reports `user === null` —\n // which happens on every fresh load while the Supabase session hydrates\n // asynchronously. Wiping 'fayz:current-org' at that moment drops a\n // multi-org user's workspace selection BEFORE loadOrgs can read it back,\n // so the app always falls to memberships[0] on reload (single-org users\n // never noticed). The pin is a last-selected hint that's re-validated\n // against the fresh membership list on load, so it's safe to keep across\n // sign-out too (a mismatching pin just falls back to memberships[0]).\n set({ currentOrg: null, userOrgs: [], members: [], loading: false })\n },\n}))\n\nexport { getPersistedOrgId, persistOrgId }\n","// Shim → native Supabase client (unified singleton across shell + plugins).\nimport type { SupabaseClient } from '@supabase/supabase-js'\nimport { getSupabaseClientOptional as _getOpt } from '@fayz-ai/core'\nexport { createSupabaseProvider, setGlobalSupabaseClient } from '@fayz-ai/core'\n// @fayz-ai/core returns a loosely-typed client (no hard supabase coupling); the\n// shell does `.from(...)` against the single public client, so surface it as\n// the real client type.\nexport const getSupabaseClientOptional = (): SupabaseClient | null =>\n _getOpt() as unknown as SupabaseClient | null\nexport {\n getFayzSupabaseClient as getSupabaseClient,\n getFayzSupabaseClientOptional as getSupabaseClientSafe,\n createFayzSupabaseClient as createSupabaseClient,\n} from '../data/client'\nimport { getFayzSupabaseClient } from '../data/client'\n// Core tables now live in the public schema — the \"core\" client is just the\n// plain public client. Kept as a backward-compatible alias for call sites.\nexport const getCoreClient = getFayzSupabaseClient\nexport const getCoreSupabaseClient = getFayzSupabaseClient\nexport const getProjectSupabaseClient = getFayzSupabaseClient\nexport type { SupabaseClient }\n"]}