@hanzo/ui 8.0.23 → 8.0.25

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 (60) hide show
  1. package/README.md +59 -0
  2. package/dist/chunk-3NG33DV2.cjs +607 -0
  3. package/dist/chunk-3NG33DV2.cjs.map +1 -0
  4. package/dist/chunk-5CZOYONP.js +343 -0
  5. package/dist/chunk-5CZOYONP.js.map +1 -0
  6. package/dist/{chunk-P2P6ST6J.js → chunk-7ZNK6JSS.js} +9 -394
  7. package/dist/chunk-7ZNK6JSS.js.map +1 -0
  8. package/dist/chunk-GVCOAJLO.js +397 -0
  9. package/dist/chunk-GVCOAJLO.js.map +1 -0
  10. package/dist/chunk-GWNNLYX4.cjs +353 -0
  11. package/dist/chunk-GWNNLYX4.cjs.map +1 -0
  12. package/dist/{chunk-NBZDIMP3.cjs → chunk-ONVERVFG.cjs} +33 -438
  13. package/dist/chunk-ONVERVFG.cjs.map +1 -0
  14. package/dist/chunk-P2QU5MN5.js +555 -0
  15. package/dist/chunk-P2QU5MN5.js.map +1 -0
  16. package/dist/chunk-WHJR5S4L.cjs +418 -0
  17. package/dist/chunk-WHJR5S4L.cjs.map +1 -0
  18. package/dist/framework/CollectionBuilder.d.ts +12 -0
  19. package/dist/framework/CollectionsBrowser.d.ts +26 -19
  20. package/dist/framework/DocTypeRecords.d.ts +31 -11
  21. package/dist/framework/MediaGrid.d.ts +42 -0
  22. package/dist/framework/RecordCards.d.ts +35 -0
  23. package/dist/framework/builder-logic.d.ts +76 -0
  24. package/dist/framework/client.d.ts +31 -44
  25. package/dist/framework/core.cjs +213 -0
  26. package/dist/framework/core.cjs.map +1 -0
  27. package/dist/framework/core.d.ts +6 -0
  28. package/dist/framework/core.js +4 -0
  29. package/dist/framework/core.js.map +1 -0
  30. package/dist/framework/data.d.ts +2 -2
  31. package/dist/framework/fields.d.ts +47 -4
  32. package/dist/framework/index.cjs +1340 -0
  33. package/dist/framework/index.cjs.map +1 -0
  34. package/dist/framework/index.d.ts +9 -23
  35. package/dist/framework/index.js +1119 -0
  36. package/dist/framework/index.js.map +1 -0
  37. package/dist/framework/media.d.ts +53 -0
  38. package/dist/framework/parts.d.ts +74 -0
  39. package/dist/framework/responsive.d.ts +41 -0
  40. package/dist/framework/types.d.ts +13 -7
  41. package/dist/product/SelectMenu.d.ts +13 -1
  42. package/dist/product/index.cjs +2061 -336
  43. package/dist/product/index.cjs.map +1 -1
  44. package/dist/product/index.js +1909 -3
  45. package/dist/product/index.js.map +1 -1
  46. package/dist/product/social/index.cjs +17 -16
  47. package/dist/product/social/index.js +3 -2
  48. package/package.json +11 -5
  49. package/dist/chunk-2BM42AZR.cjs +0 -2301
  50. package/dist/chunk-2BM42AZR.cjs.map +0 -1
  51. package/dist/chunk-7P7R7FC5.js +0 -2231
  52. package/dist/chunk-7P7R7FC5.js.map +0 -1
  53. package/dist/chunk-NBZDIMP3.cjs.map +0 -1
  54. package/dist/chunk-P2P6ST6J.js.map +0 -1
  55. package/dist/framework/Loader.d.ts +0 -4
  56. package/dist/framework.cjs +0 -757
  57. package/dist/framework.cjs.map +0 -1
  58. package/dist/framework.d.ts +0 -1
  59. package/dist/framework.js +0 -727
  60. package/dist/framework.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/framework/types.ts","../src/framework/client.ts","../src/framework/fields.ts","../src/framework/builder-logic.ts","../src/framework/media.ts","../src/framework/data.ts"],"names":[],"mappings":"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","file":"chunk-P2QU5MN5.js","sourcesContent":["/**\n * The Hanzo Framework wire contract — the DocType / DocField / document shapes the\n * cloud `clients/framework` engine serves at `/v1/framework/*` (Frappe's DocType\n * metadata core, rebuilt native in Go; also published standalone as\n * github.com/hanzoai/doctype). These mirror the Go JSON tags exactly.\n *\n * This is the ONE metadata vocabulary the generic renderer builds from, so\n * CMS / ERP / CRM / Helpdesk — all \"just DocTypes\" on one engine — render through\n * the SAME components. Types only; no runtime, no imports, so a host's data layer\n * or a node test can depend on this file alone.\n */\n\n/** The engine's closed fieldtype set (mirrors doctype.Fieldtype). */\nexport type Fieldtype =\n | 'Data'\n | 'Int'\n | 'Float'\n | 'Currency'\n | 'Check'\n | 'Date'\n | 'Datetime'\n | 'Text'\n | 'SmallText'\n | 'LongText'\n | 'RichText'\n | 'Select'\n | 'Link'\n | 'Table'\n | 'Attach'\n | 'JSON'\n | 'Password'\n\n/** One field of a DocType (Frappe's DocField). */\nexport interface DocField {\n fieldname: string\n fieldtype: Fieldtype\n label?: string\n reqd?: boolean\n /** Select → newline-separated choices; Link → target DocType; Table → child DocType. */\n options?: string\n default?: string\n unique?: boolean\n readOnly?: boolean\n hidden?: boolean\n inListView?: boolean\n fetchFrom?: string\n}\n\n/** A role's rights on a DocType (Frappe's DocPerm). */\nexport interface DocPerm {\n role: string\n read?: boolean\n write?: boolean\n create?: boolean\n delete?: boolean\n submit?: boolean\n cancel?: boolean\n}\n\n/** A DocType definition — per-org metadata. */\nexport interface DocType {\n name: string\n module?: string\n isSingle?: boolean\n isSubmittable?: boolean\n autoname?: string\n titleField?: string\n fields: DocField[]\n permissions?: DocPerm[]\n createdAt?: number\n updatedAt?: number\n}\n\n/** The managed document envelope keys the engine always returns. */\nexport interface DocEnvelope {\n name: string\n doctype: string\n /** 0 = draft, 1 = submitted, 2 = cancelled. */\n docstatus: number\n createdAt: number\n updatedAt: number\n}\n\n/** A document: the field data overlaid with the managed envelope keys. */\nexport type FrameworkDoc = Record<string, unknown> & DocEnvelope\n\n/** The three docstatus values, named — so no view compares bare integers. */\nexport const DRAFT = 0\nexport const SUBMITTED = 1\nexport const CANCELLED = 2\n\n/** A registered app lane and (optionally, per-org) which fixtures are installed. */\nexport interface ModuleInfo {\n module: string\n doctypes: string[]\n installed?: string[]\n}\n\n/** The result of installing a module into the caller's org. */\nexport interface InstallResult {\n module: string\n created: string[]\n existing: string[]\n}\n\n/** List query for the generic document surface. */\nexport interface ListQuery {\n filters?: Record<string, string | number | boolean>\n fields?: string[]\n orderBy?: string\n limit?: number\n}\n\n/** The redacted-Password marker the engine returns for a set secret. */\nexport const REDACTED_MARKER = '__set__'\n","/**\n * The generic client for the Hanzo Framework DocType engine (`/v1/framework/*`).\n * It is metadata-driven and doctype-agnostic: the SAME `records` CRUD serves a CMS\n * Page, an ERP Invoice, or a Helpdesk Ticket — an app lane is just a `module`\n * filter over `doctypes`.\n *\n * THE HOST OWNS TRANSPORT. This module never picks an origin, a credential, or a\n * proxy: it takes a `FrameworkTransport` and builds paths RELATIVE to the framework\n * root (`doctypes`, `Article/hello`, `modules/cms/install`). The console maps those\n * onto its own user-bearer `/v1/framework/...` proxy; a native app or a test maps\n * them somewhere else. One client, any host.\n *\n * Names (DocType + document) go verbatim into the path, so they are\n * `encodeURIComponent`-escaped here and kept slug-style on create (`slugify`).\n * Payloads are read defensively from `{ data }` (or a bare array), so a shape drift\n * degrades a list rather than throwing.\n */\nimport type {\n DocType,\n FrameworkDoc,\n InstallResult,\n ListQuery,\n ModuleInfo,\n} from './types'\n\n/**\n * The ONE seam a host injects. Paths are relative to the framework root and never\n * start with a slash; the host prefixes its own base (and adds credentials).\n */\nexport interface FrameworkTransport {\n get: (path: string) => Promise<unknown>\n post: (path: string, body?: unknown) => Promise<unknown>\n put: (path: string, body?: unknown) => Promise<unknown>\n del: (path: string) => Promise<void>\n}\n\n/** The name 8.0.24 shipped for the same seam. One concept, one shape, two spellings. */\nexport type Transport = FrameworkTransport\n\nconst enc = encodeURIComponent\n\nconst asRecord = (v: unknown): Record<string, unknown> =>\n v && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : {}\n\n/** Pull the first array under a common envelope key (the engine uses `data`). */\nexport function rows(payload: unknown): Record<string, unknown>[] {\n if (Array.isArray(payload)) {\n return payload.filter((x) => x && typeof x === 'object') as Record<string, unknown>[]\n }\n const o = asRecord(payload)\n for (const k of ['data', 'items', 'rows']) {\n if (Array.isArray(o[k])) {\n return (o[k] as unknown[]).filter((x) => x && typeof x === 'object') as Record<string, unknown>[]\n }\n }\n return []\n}\n\n/** A framework document is already a flat map + envelope; keep it as-is (typed). */\nconst asDoc = (v: unknown): FrameworkDoc => asRecord(v) as FrameworkDoc\n\nconst asDocType = (v: unknown): DocType => {\n const r = asRecord(v)\n return {\n ...(r as object),\n name: String(r.name ?? ''),\n fields: Array.isArray(r.fields) ? (r.fields as DocType['fields']) : [],\n } as DocType\n}\n\n/** Build the generic document list querystring from a typed ListQuery. Pure. */\nexport function listQuery(q?: ListQuery): string {\n if (!q) return ''\n const p = new URLSearchParams()\n if (q.filters && Object.keys(q.filters).length) p.set('filters', JSON.stringify(q.filters))\n if (q.fields && q.fields.length) p.set('fields', q.fields.join(','))\n if (q.orderBy) p.set('order_by', q.orderBy)\n if (q.limit) p.set('limit', String(q.limit))\n const s = p.toString()\n return s ? `?${s}` : ''\n}\n\n/** The engine surface, as consumed by every DocType view. */\nexport interface FrameworkClient {\n /** The DocType registry (schemas) — the collection definitions of every app lane. */\n doctypes: {\n list: () => Promise<DocType[]>\n get: (name: string) => Promise<DocType>\n create: (dt: DocType) => Promise<DocType>\n update: (name: string, dt: DocType) => Promise<DocType>\n remove: (name: string) => Promise<void>\n }\n /** Generic, metadata-driven document CRUD — the SAME calls for ANY doctype. */\n records: {\n list: (doctype: string, q?: ListQuery) => Promise<FrameworkDoc[]>\n get: (doctype: string, name: string) => Promise<FrameworkDoc>\n create: (doctype: string, data: Record<string, unknown>) => Promise<FrameworkDoc>\n update: (doctype: string, name: string, data: Record<string, unknown>) => Promise<FrameworkDoc>\n remove: (doctype: string, name: string) => Promise<void>\n submit: (doctype: string, name: string) => Promise<FrameworkDoc>\n cancel: (doctype: string, name: string) => Promise<FrameworkDoc>\n }\n /** App-lane fixtures: list the registered lanes, inspect one, install into the org. */\n modules: {\n list: () => Promise<ModuleInfo[]>\n get: (module: string) => Promise<ModuleInfo>\n install: (module: string) => Promise<InstallResult>\n }\n /** Per-org role assignments (grant editors; the owner is seeded System Manager). */\n roles: {\n list: () => Promise<{ user: string; role: string }[]>\n assign: (user: string, role: string) => Promise<void>\n revoke: (user: string, role: string) => Promise<void>\n }\n /** Engine health/reach probe — `GET /summary`. */\n summary: () => Promise<Record<string, unknown>>\n}\n\n/** Bind the framework surface to a host's transport. */\nexport function createFrameworkClient(t: FrameworkTransport): FrameworkClient {\n return {\n doctypes: {\n list: () => t.get('doctypes').then((r) => rows(r).map(asDocType)),\n get: (name) => t.get(`doctypes/${enc(name)}`).then(asDocType),\n create: (dt) => t.post('doctypes', dt).then(asDocType),\n update: (name, dt) => t.put(`doctypes/${enc(name)}`, dt).then(asDocType),\n remove: (name) => t.del(`doctypes/${enc(name)}`),\n },\n\n records: {\n list: (doctype, q) => t.get(`${enc(doctype)}${listQuery(q)}`).then((r) => rows(r).map(asDoc)),\n get: (doctype, name) => t.get(`${enc(doctype)}/${enc(name)}`).then(asDoc),\n create: (doctype, data) => t.post(enc(doctype), data).then(asDoc),\n update: (doctype, name, data) => t.put(`${enc(doctype)}/${enc(name)}`, data).then(asDoc),\n remove: (doctype, name) => t.del(`${enc(doctype)}/${enc(name)}`),\n submit: (doctype, name) => t.post(`${enc(doctype)}/${enc(name)}/submit`).then(asDoc),\n cancel: (doctype, name) => t.post(`${enc(doctype)}/${enc(name)}/cancel`).then(asDoc),\n },\n\n modules: {\n list: () =>\n t.get('modules').then((r) =>\n rows(r).map((m) => ({\n module: String(m.module ?? ''),\n doctypes: Array.isArray(m.doctypes) ? (m.doctypes as string[]) : [],\n })),\n ),\n get: (module) =>\n t.get(`modules/${enc(module)}`).then((v) => {\n const r = asRecord(v)\n return {\n module: String(r.module ?? module),\n doctypes: Array.isArray(r.doctypes) ? (r.doctypes as string[]) : [],\n installed: Array.isArray(r.installed) ? (r.installed as string[]) : [],\n }\n }),\n install: (module) =>\n t.post(`modules/${enc(module)}/install`).then((v) => {\n const r = asRecord(v)\n return {\n module: String(r.module ?? module),\n created: Array.isArray(r.created) ? (r.created as string[]) : [],\n existing: Array.isArray(r.existing) ? (r.existing as string[]) : [],\n }\n }),\n },\n\n roles: {\n list: () =>\n t.get('roles').then((r) =>\n rows(r).map((x) => ({ user: String(x.user ?? ''), role: String(x.role ?? '') })),\n ),\n assign: (user, role) => t.post('roles', { user, role }).then(() => undefined),\n revoke: (user, role) => t.del(`roles/${enc(user)}/${enc(role)}`),\n },\n\n summary: () => t.get('summary').then(asRecord),\n }\n}\n","/**\n * Pure mapping between the Hanzo Framework DocType metadata and @hanzo/data's\n * render model — the brain of the generic DocType renderer. It is the ONE place\n * that translates the engine's Frappe field vocabulary into @hanzo/data's, so\n * EVERY app lane (CMS / ERP / CRM / Helpdesk) renders list, card, form and detail\n * identically with zero per-doctype code. A new DocType — or a whole new lane —\n * \"just works\".\n *\n * No I/O, no React — data in, data out, trivially testable (the @hanzo/data\n * imports are `import type`, erased at build, so the unit test runs in plain Node).\n */\nimport type { FieldDefinition, FieldType, SelectOption } from '@hanzo/data'\nimport type { DocField, DocType, FrameworkDoc } from './types'\nimport { DRAFT, REDACTED_MARKER } from './types'\n\n/**\n * Frappe fieldtype → @hanzo/data field type. 1:1 cases; the value shape each\n * needs is handled in `toRecord`/`savePayload` (currency object, boolean, etc).\n * Attach is a single asset URL → `url` (a clickable link + text input); a Table /\n * JSON renders as raw JSON (honest — no silent wrong guess). Password → `text`\n * (write-only; the value is never surfaced, only set).\n */\nconst TYPE_MAP: Record<DocField['fieldtype'], FieldType> = {\n Data: 'text',\n SmallText: 'text',\n Text: 'longText',\n LongText: 'longText',\n RichText: 'richText',\n Int: 'number',\n Float: 'number',\n Currency: 'currency',\n Check: 'boolean',\n Date: 'date',\n Datetime: 'dateTime',\n Select: 'select',\n Link: 'relation',\n Table: 'json',\n Attach: 'url',\n JSON: 'json',\n Password: 'text',\n}\n\nconst ACRONYMS = new Set(['id', 'url', 'seo', 'api', 'ip'])\n\n/** `first_name` / `firstName` → \"First Name\"; known acronyms upper-cased. */\nexport function humanize(name: string): string {\n return name\n .replace(/[_-]+/g, ' ')\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => (ACRONYMS.has(w.toLowerCase()) ? w.toUpperCase() : w.charAt(0).toUpperCase() + w.slice(1)))\n .join(' ')\n}\n\n/** Select field's newline-separated choices → @hanzo/data options (blank dropped). */\nfunction selectOptions(options: string | undefined): SelectOption[] {\n return (options ?? '')\n .split('\\n')\n .map((s) => s.replace(/\\r$/, '').trim())\n .filter(Boolean)\n .map((v) => ({ value: v, label: v }))\n}\n\n/** Per-field @hanzo/data metadata (select options, currency code, relation target). */\nfunction metadataFor(f: DocField): FieldDefinition['metadata'] | undefined {\n switch (f.fieldtype) {\n case 'Select':\n return { options: selectOptions(f.options) }\n case 'Currency':\n return { currencyCode: 'USD' }\n case 'Int':\n return { decimals: 0 }\n case 'Link':\n return { objectName: f.options }\n default:\n return undefined\n }\n}\n\n/** The autoname source field for a `field:xxx` rule (`\"\"` otherwise). */\nexport function autonameSource(dt: DocType): string {\n const a = (dt.autoname ?? '').trim()\n return a.startsWith('field:') ? a.slice('field:'.length).trim() : ''\n}\n\nexport interface FieldMapOpts {\n /** Editing an existing record: the autoname-source field is fixed (the URL key). */\n editing?: boolean\n}\n\n/**\n * Map a DocType's fields to the ordered `FieldDefinition[]` every @hanzo/data view\n * renders from. Hidden fields are dropped; the engine's readOnly is honored; and\n * when editing an existing record the autoname source (e.g. `slug`) is made\n * read-only because it IS the document's immutable URL key.\n */\nexport function docTypeToFields(dt: DocType, opts: FieldMapOpts = {}): FieldDefinition[] {\n const src = autonameSource(dt)\n return (dt.fields ?? [])\n .filter((f) => !f.hidden)\n .map((f) => {\n const readOnly = f.readOnly || (opts.editing && f.fieldname === src) || undefined\n const metadata = metadataFor(f)\n return {\n name: f.fieldname,\n label: f.label || humanize(f.fieldname),\n type: TYPE_MAP[f.fieldtype] ?? 'text',\n ...(metadata ? { metadata } : {}),\n ...(readOnly ? { readOnly: true as const } : {}),\n }\n })\n}\n\n/** The status field a publishable content type uses (a Select including \"Published\"). */\nexport function statusField(dt: DocType): string {\n const f = (dt.fields ?? []).find(\n (x) => x.fieldtype === 'Select' && x.fieldname === 'status' && (x.options ?? '').includes('Published'),\n )\n return f ? f.fieldname : ''\n}\n\n/**\n * Field names hidden from the table grid: everything NOT flagged `inListView`\n * (when the DocType flags any). This is the engine's own column projection —\n * an ERP Sales Order declares 4 list columns out of 12 fields, so honoring it is\n * what keeps a wide DocType from becoming a horizontally-scrolling wall.\n */\nexport function listHiddenFields(dt: DocType): string[] {\n const anyListed = (dt.fields ?? []).some((f) => f.inListView)\n if (!anyListed) return []\n return (dt.fields ?? []).filter((f) => !f.inListView && !f.hidden).map((f) => f.fieldname)\n}\n\n/**\n * The fields shown on a MOBILE card, in order: the DocType's declared list columns\n * (`inListView`), else the first few visible fields. The title is rendered by the\n * card itself, so it is excluded here. Capped, because a card is a summary — the\n * full record is one tap away.\n */\nexport function cardFields(dt: DocType, fields: FieldDefinition[], max = 4): FieldDefinition[] {\n const title = dt.titleField ?? ''\n const listed = new Set(listedFieldNames(dt))\n const pick = listed.size ? fields.filter((f) => listed.has(f.name)) : fields\n return pick.filter((f) => f.name !== title).slice(0, max)\n}\n\n/** The `inListView` field names (empty when the DocType flags none). */\nexport function listedFieldNames(dt: DocType): string[] {\n return (dt.fields ?? []).filter((f) => f.inListView && !f.hidden).map((f) => f.fieldname)\n}\n\n/** True when a DocType is a media/asset library (a required Attach) → grid view. */\nexport function isMediaDoctype(dt: DocType): boolean {\n return (dt.fields ?? []).some((f) => f.fieldtype === 'Attach' && f.reqd)\n}\n\n/** The primary Attach field name (the asset URL) of a media doctype. */\nexport function mediaFileField(dt: DocType): string {\n const f =\n (dt.fields ?? []).find((x) => x.fieldtype === 'Attach' && x.reqd) ??\n (dt.fields ?? []).find((x) => x.fieldtype === 'Attach')\n return f ? f.fieldname : ''\n}\n\n/** The uploaded-asset facts a media DocType may want stored alongside the file. */\nexport interface MediaFacts {\n /** The `file`-field value (an object reference or URL). */\n fileRef: string\n filename: string\n mime: string\n size: number\n width: number\n height: number\n}\n\n/**\n * The create body for a media document — METADATA-DRIVEN, not a hardcoded CMS\n * schema. The file lands on the DocType's own Attach field, the filename on its\n * declared `titleField` (else `title` if it has one), and each optional fact\n * (`mime`/`size`/`width`/`height`) is written ONLY when the DocType actually\n * declares that field. A media collection that names its label `caption` gets a\n * captioned row instead of an untitled one, and a lane whose media DocType has no\n * dimensions never ships dead keys.\n */\nexport function mediaDocPayload(dt: DocType, facts: MediaFacts): Record<string, unknown> {\n const declared = new Set((dt.fields ?? []).map((f) => f.fieldname))\n const out: Record<string, unknown> = {}\n\n const fileField = mediaFileField(dt)\n if (fileField) out[fileField] = facts.fileRef\n\n const titleF = dt.titleField && declared.has(dt.titleField) ? dt.titleField : declared.has('title') ? 'title' : ''\n if (titleF && titleF !== fileField) out[titleF] = facts.filename\n\n const optional: [string, unknown][] = [\n ['mime', facts.mime],\n ['size', facts.size],\n ['width', facts.width],\n ['height', facts.height],\n ]\n for (const [k, v] of optional) if (declared.has(k) && k !== fileField && k !== titleF) out[k] = v\n\n return out\n}\n\n/** DocTypes belonging to an app lane (module) — a CMS \"collection\" is one of these. */\nexport function moduleDoctypes(dts: DocType[], module: string): DocType[] {\n return dts.filter((dt) => (dt.module ?? '') === module)\n}\n\n/** The conventional field a collection uses to scope documents to a project. */\nexport const PROJECT_FIELD = 'project'\n\n/** True when a DocType declares the `project` scope field (→ project filtering works). */\nexport function hasProjectField(dt: DocType): boolean {\n return (dt.fields ?? []).some((f) => f.fieldname === PROJECT_FIELD)\n}\n\n/**\n * The engine refuses to edit or delete a document that is no longer a draft\n * (`ops.go`: \"document is not a draft (docstatus %d); cannot edit\" and \"submitted\n * document must be cancelled before deletion\"). So the views ASK before offering\n * the affordance — a submitted invoice shows no Edit button rather than a full\n * form that errors on Save.\n */\nexport function isDraft(record: Record<string, unknown> | null | undefined): boolean {\n return Number(record?.docstatus ?? DRAFT) === DRAFT\n}\n\n/** A record's human title — the DocType's titleField, else its name. */\nexport function titleOf(doc: Record<string, unknown>, dt: DocType): string {\n if (dt.titleField && typeof doc[dt.titleField] === 'string' && doc[dt.titleField]) {\n return String(doc[dt.titleField])\n }\n return typeof doc.name === 'string' && doc.name ? doc.name : '(untitled)'\n}\n\n/**\n * URL-safe slug from arbitrary text: lower-case, any run of non-alphanumerics\n * collapsed to a single dash, ends trimmed. Guarantees a no-space, `%`-free\n * document name (the engine and a host's proxy path both require it).\n */\nexport function slugify(s: unknown): string {\n return String(s ?? '')\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '') // strip diacritics (accents → ASCII)\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\n/** Valid Pascal/slug DocType name (letters/digits/dash/underscore, alnum-led, no space). */\nexport function isValidDoctypeName(name: string): boolean {\n return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(name.trim())\n}\n\nconst secToMs = (v: unknown): number | undefined => {\n const n = Number(v)\n return Number.isFinite(n) && n > 0 ? n * 1000 : undefined\n}\nconst numOrNull = (v: unknown): number | null => {\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n}\n\n/** One field value, framework wire → @hanzo/data display shape. */\nfunction coerceForDisplay(f: DocField, v: unknown): unknown {\n switch (f.fieldtype) {\n case 'Currency':\n return { amount: numOrNull(v), currencyCode: 'USD' }\n case 'Check':\n return v === 1 || v === true || v === '1'\n case 'Datetime':\n return typeof v === 'string' ? v.replace(' ', 'T') : v\n case 'Password':\n return v === REDACTED_MARKER ? '' : v // never surface the marker\n default:\n return v\n }\n}\n\n/**\n * A framework document → a flat @hanzo/data record: the field values coerced to\n * their display shapes, plus `id` (the record key every view uses) and the managed\n * envelope. The ONE read mapping every DocType view shares.\n */\nexport function toRecord(doc: FrameworkDoc, dt: DocType): Record<string, unknown> {\n const rec: Record<string, unknown> = {\n id: doc.name,\n name: doc.name,\n doctype: doc.doctype,\n docstatus: doc.docstatus,\n createdAt: secToMs(doc.createdAt),\n updatedAt: secToMs(doc.updatedAt),\n }\n for (const f of dt.fields ?? []) {\n if (!(f.fieldname in doc)) continue\n rec[f.fieldname] = coerceForDisplay(f, doc[f.fieldname])\n }\n return rec\n}\n\n/** One draft value, @hanzo/data edit shape → framework wire. */\nfunction coerceForWrite(f: DocField, v: unknown): unknown {\n switch (f.fieldtype) {\n case 'Currency':\n return v && typeof v === 'object' && 'amount' in v ? Number((v as { amount: unknown }).amount) : Number(v)\n case 'Check':\n return Boolean(v)\n case 'Int':\n case 'Float':\n return Number(v)\n case 'Datetime':\n if (v instanceof Date) return v.toISOString()\n if (typeof v === 'number' && Number.isFinite(v)) return new Date(v).toISOString()\n return v\n case 'Link':\n // The picker stores a plain id (string); an unedited enriched value is\n // {id,label}; a cleared value is null. The engine wants the id string ('' = clear).\n if (v == null || v === '') return ''\n if (typeof v === 'object') {\n return String((v as { id?: unknown; value?: unknown }).id ?? (v as { value?: unknown }).value ?? '')\n }\n return v\n default:\n return v\n }\n}\n\n/**\n * Enrich a record's Link values with the target's human label ({id,label}), so a\n * relation renders as its title (not a raw id) in BOTH the list cell and the\n * detail — @hanzo/data's relation display reads `.label`, its input reads `.id`.\n * `optionsByField` is the loaded picker options per Link field (value=id, label=title).\n */\nexport function enrichLinks(\n record: Record<string, unknown>,\n dt: DocType,\n optionsByField: Record<string, SelectOption[]>,\n): Record<string, unknown> {\n const out = { ...record }\n for (const f of dt.fields ?? []) {\n if (f.fieldtype !== 'Link') continue\n const raw = out[f.fieldname]\n if (typeof raw === 'string' && raw) {\n const opt = (optionsByField[f.fieldname] ?? []).find((o) => o.value === raw)\n out[f.fieldname] = { id: raw, label: opt?.label ?? raw }\n }\n }\n return out\n}\n\n/** The Link fields of a DocType (their options must be loaded for the picker). */\nexport function linkFields(dt: DocType): DocField[] {\n return (dt.fields ?? []).filter((f) => f.fieldtype === 'Link')\n}\n\n/** A blank create-form draft seeded with each field's declared default (Check → bool). */\nexport function newDraft(dt: DocType): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const f of dt.fields ?? []) {\n if (f.default === undefined || f.default === '') continue\n out[f.fieldname] = f.fieldtype === 'Check' ? f.default === '1' || f.default === 'true' : f.default\n }\n return out\n}\n\n/**\n * A draft record → the framework write body: editable field values only (the\n * engine owns `name`/`docstatus`/timestamps), each coerced to its wire shape, and\n * the autoname source (e.g. `slug`) slugified so the document name is always URL-\n * safe. Fields left `undefined` are dropped — a partial edit never nulls a value.\n */\nexport function savePayload(draft: Record<string, unknown>, dt: DocType): Record<string, unknown> {\n const src = autonameSource(dt)\n const out: Record<string, unknown> = {}\n for (const f of dt.fields ?? []) {\n if (f.readOnly) continue // engine-owned; never written back\n let v = draft[f.fieldname]\n if (v === undefined) continue\n v = coerceForWrite(f, v)\n if (f.fieldname === src && typeof v === 'string') v = slugify(v)\n out[f.fieldname] = v\n }\n return out\n}\n","/**\n * Pure logic for the content-type builder — the model + validation + DocType\n * projection for defining a collection's fields on-page. No React, no I/O, so it\n * is unit-tested in plain Node. The builder UI is a thin shell over these.\n *\n * A \"collection\" is a framework DocType tagged with the lane module; a \"field\" is\n * a DocField. The builder offers exactly the engine's fieldtypes (mapped to\n * friendly labels), lets the author add/remove/reorder/require fields, and\n * projects the whole thing to a valid `DocType` create body. Names are slugified\n * to field-name rules so a save never 400s on a bad identifier.\n */\nimport type { DocType, DocField, Fieldtype } from './types'\nimport { slugify, isValidDoctypeName } from './fields'\n\n/**\n * The builder's field-type vocabulary — every framework fieldtype, with a friendly\n * label + hint. This is the ONE list the \"add field\" type picker renders, so the\n * builder always offers exactly what the engine accepts (no drift). Order is the\n * author-facing order (common types first).\n */\nexport const BUILDER_FIELD_TYPES: { type: Fieldtype; label: string; hint: string }[] = [\n { type: 'Data', label: 'Text', hint: 'Single line of text' },\n { type: 'RichText', label: 'Rich text', hint: 'Formatted body (WYSIWYG)' },\n { type: 'LongText', label: 'Long text', hint: 'Multi-line plain text' },\n { type: 'Int', label: 'Number', hint: 'Whole number' },\n { type: 'Float', label: 'Decimal', hint: 'Decimal number' },\n { type: 'Currency', label: 'Currency', hint: 'Money amount' },\n { type: 'Check', label: 'Checkbox', hint: 'True / false' },\n { type: 'Date', label: 'Date', hint: 'Calendar date' },\n { type: 'Datetime', label: 'Date & time', hint: 'Date with time' },\n { type: 'Select', label: 'Select', hint: 'One of a list of options' },\n { type: 'Link', label: 'Relation', hint: 'Reference another collection' },\n { type: 'Attach', label: 'Attachment', hint: 'A file / image URL' },\n { type: 'Table', label: 'Table', hint: 'Repeatable child rows (JSON)' },\n { type: 'JSON', label: 'JSON', hint: 'Arbitrary JSON' },\n]\n\nconst LABELS: Record<Fieldtype, string> = Object.fromEntries(\n BUILDER_FIELD_TYPES.map((t) => [t.type, t.label]),\n) as Record<Fieldtype, string>\n\n/** The friendly label for a fieldtype (falls back to the raw type). */\nexport function fieldTypeLabel(t: Fieldtype): string {\n return LABELS[t] ?? t\n}\n\n/** True when a fieldtype needs `options` (Select choices, Link/Table target). */\nexport function fieldNeedsOptions(t: Fieldtype): boolean {\n return t === 'Select' || t === 'Link' || t === 'Table'\n}\n\n/** One editable row in the builder — a superset of DocField the UI mutates. */\nexport interface BuilderField {\n /** Stable client key for React (not persisted). */\n key: string\n /** The field's label (author-facing); the fieldname is derived from it. */\n label: string\n type: Fieldtype\n required: boolean\n inListView: boolean\n /** Select → newline-joined choices; Link/Table → target collection name. */\n options: string\n}\n\nlet seq = 0\n/** A fresh, unique client key. */\nexport function newKey(): string {\n seq += 1\n return `f${seq}_${Math.random().toString(36).slice(2, 8)}`\n}\n\n/** A blank field row of a given type. */\nexport function blankField(type: Fieldtype = 'Data'): BuilderField {\n return { key: newKey(), label: '', type, required: false, inListView: false, options: '' }\n}\n\n/**\n * The default starter fields for a NEW content collection: a required Title, a URL\n * Slug (the autoname key), a rich Body, and a Draft/Published Status. The author\n * edits from here. Mirrors the cloud CMS seed so a hand-built collection matches a\n * seeded one.\n */\nexport function starterFields(): BuilderField[] {\n return [\n { key: newKey(), label: 'Title', type: 'Data', required: true, inListView: true, options: '' },\n { key: newKey(), label: 'Slug', type: 'Data', required: true, inListView: true, options: '' },\n { key: newKey(), label: 'Body', type: 'RichText', required: false, inListView: false, options: '' },\n { key: newKey(), label: 'Status', type: 'Select', required: false, inListView: true, options: 'Draft\\nPublished' },\n // Optional project scope — lets a host's org→project switcher filter this collection.\n { key: newKey(), label: 'Project', type: 'Data', required: false, inListView: false, options: '' },\n ]\n}\n\n/** An existing DocType → editable builder rows (drops engine-managed fields). */\nexport function fieldsFromDocType(dt: DocType): BuilderField[] {\n return (dt.fields ?? []).map((f) => ({\n key: newKey(),\n label: f.label || f.fieldname,\n type: f.fieldtype,\n required: Boolean(f.reqd),\n inListView: Boolean(f.inListView),\n options: f.options ?? '',\n }))\n}\n\n/** The fieldname derived from a label (slug with underscores; identifier-safe). */\nexport function fieldNameFromLabel(label: string): string {\n const slug = slugify(label).replace(/-/g, '_')\n // A leading digit isn't a valid identifier lead; prefix it.\n return /^[0-9]/.test(slug) ? `f_${slug}` : slug\n}\n\nexport interface BuilderValidation {\n ok: boolean\n /** Per-row error keyed by BuilderField.key. */\n fieldErrors: Record<string, string>\n /** A form-level error (name / no-fields). */\n formError: string | null\n}\n\n/**\n * Validate the whole builder: the collection name, at least one field, unique\n * non-empty field labels/names, and options present where required. Pure.\n */\nexport function validateBuilder(name: string, fields: BuilderField[]): BuilderValidation {\n const fieldErrors: Record<string, string> = {}\n let formError: string | null = null\n\n if (!isValidDoctypeName(name.trim())) {\n formError = 'Enter a collection name with letters, digits, dashes or underscores (no spaces).'\n } else if (fields.length === 0) {\n formError = 'Add at least one field.'\n }\n\n const seen = new Set<string>()\n for (const f of fields) {\n const label = f.label.trim()\n if (!label) {\n fieldErrors[f.key] = 'Name this field.'\n continue\n }\n const fname = fieldNameFromLabel(label)\n if (!fname) {\n fieldErrors[f.key] = 'Use letters or digits in the field name.'\n continue\n }\n if (seen.has(fname)) {\n fieldErrors[f.key] = `Duplicate field \"${fname}\".`\n continue\n }\n seen.add(fname)\n if ((f.type === 'Link' || f.type === 'Table') && !f.options.trim()) {\n fieldErrors[f.key] = f.type === 'Link' ? 'Choose the collection to relate to.' : 'Name the child collection.'\n } else if (f.type === 'Select' && !f.options.trim()) {\n fieldErrors[f.key] = 'Add at least one option.'\n }\n }\n\n return { ok: !formError && Object.keys(fieldErrors).length === 0, fieldErrors, formError }\n}\n\n/** A builder row → a framework DocField (drops UI-only bits, coerces options). */\nexport function toDocField(f: BuilderField): DocField {\n const fieldname = fieldNameFromLabel(f.label)\n const field: DocField = {\n fieldname,\n fieldtype: f.type,\n label: f.label.trim(),\n }\n if (f.required) field.reqd = true\n if (f.inListView) field.inListView = true\n if (fieldNeedsOptions(f.type) && f.options.trim()) field.options = f.options.trim()\n return field\n}\n\n/** Move a row within the ordered field list (a no-op at either end). Pure. */\nexport function moveField(fields: BuilderField[], key: string, dir: -1 | 1): BuilderField[] {\n const i = fields.findIndex((f) => f.key === key)\n const j = i + dir\n if (i < 0 || j < 0 || j >= fields.length) return fields\n const next = [...fields]\n ;[next[i], next[j]] = [next[j], next[i]]\n return next\n}\n\n/**\n * The builder → a `DocType` create body. Auto-derives `autoname`/`titleField` from\n * conventional fields when present (a `slug` field → `field:slug` naming; a `title`\n * field → the title). Tags the module so the collection joins the lane.\n */\nexport function toDocType(name: string, module: string, fields: BuilderField[]): DocType {\n const docFields = fields.map(toDocField)\n const byName = new Set(docFields.map((f) => f.fieldname))\n const dt: DocType = { name: name.trim(), module, fields: docFields }\n if (byName.has('slug')) dt.autoname = 'field:slug'\n if (byName.has('title')) dt.titleField = 'title'\n return dt\n}\n","/**\n * The DAM transport for a media DocType — as a PORT, not a binding. The library\n * knows the SHAPE of an object store (ensure a bucket, presign a PUT, presign a\n * GET, delete an object) and owns the key/reference grammar; the HOST supplies the\n * store. The console injects its org-scoped `/v1/s3` client (SeaweedFS); a native\n * app or a test injects something else. One media model, any storage.\n *\n * WHY STORE THE KEY, NOT A URL: a presigned object URL has a short TTL (the cloud\n * mints 5 minutes), and a stored presigned URL would break minutes later — fatal\n * for a media library whose references must persist. So the `file` field stores a\n * STABLE `s3://bucket/key` reference and every view resolves it to a fresh\n * presigned GET at render time. `isRef` keeps a legacy hand-typed absolute URL\n * working, so nothing that already exists breaks.\n */\nimport { slugify } from './fields'\nimport type { MediaFacts } from './fields'\n\n/** A presigned request the host's object store minted. */\nexport interface Presigned {\n url: string\n /** HTTP method the URL is signed for (upload must be `PUT`). */\n method?: string\n}\n\n/** The object-store seam a host injects. Every call is per-org on the host side. */\nexport interface MediaStore {\n /** Idempotent — an \"already exists\" is success, not an error. */\n ensureBucket: (bucket: string) => Promise<void>\n presignUpload: (bucket: string, key: string) => Promise<Presigned | null>\n presignDownload: (bucket: string, key: string) => Promise<Presigned | null>\n deleteObject: (bucket: string, key: string) => Promise<void>\n /** Transfer the bytes to a presigned URL. */\n put: (url: string, file: File) => Promise<void>\n}\n\n/** The prefix that marks a media `file` value as an object-store key (not a raw URL). */\nconst REF_PREFIX = 's3://'\n\n/** A bucket + stored object key → the `file`-field reference value. */\nexport function mediaRef(bucket: string, key: string): string {\n return `${REF_PREFIX}${bucket}/${key}`\n}\n\n/** True when a `file` value is an object reference (vs a hand-typed URL). */\nexport function isRef(value: unknown): value is string {\n return typeof value === 'string' && value.startsWith(REF_PREFIX)\n}\n\n/** Split an `s3://bucket/key` reference into its bucket + key. */\nexport function parseRef(ref: string): { bucket: string; key: string } | null {\n if (!ref.startsWith(REF_PREFIX)) return null\n const rest = ref.slice(REF_PREFIX.length)\n const slash = rest.indexOf('/')\n if (slash <= 0) return null\n return { bucket: rest.slice(0, slash), key: rest.slice(slash + 1) }\n}\n\n/** Join a folder prefix and a name into an object key (blank segments dropped). */\nexport function joinKey(...parts: string[]): string {\n return parts.filter(Boolean).join('/')\n}\n\n/** A safe, collision-resistant object key for an uploaded file (keeps the ext). */\nexport function mediaKey(filename: string, folder = ''): string {\n const dot = filename.lastIndexOf('.')\n const ext = dot > 0 ? filename.slice(dot + 1).toLowerCase().replace(/[^a-z0-9]/g, '') : ''\n const base = slugify(dot > 0 ? filename.slice(0, dot) : filename) || 'file'\n const stamp = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`\n const name = ext ? `${base}-${stamp}.${ext}` : `${base}-${stamp}`\n return folder ? joinKey(slugify(folder), name) : name\n}\n\n/** True when a value looks like a renderable image (by extension / data URL). */\nexport function looksLikeImage(value: string): boolean {\n return /\\.(png|jpe?g|gif|webp|svg|avif)(\\?|#|$)/i.test(value) || value.startsWith('data:image/')\n}\n\n/** The three operations a media view needs, bound to one bucket. */\nexport interface MediaUploader {\n bucket: string\n /** Upload a file and return the facts a media document is built from. */\n upload: (file: File, folder?: string) => Promise<MediaFacts>\n /** A `file` value → a viewable URL ('' when it can't resolve — never a broken img). */\n resolveUrl: (value: unknown) => Promise<string>\n /** Delete the object behind a `file` value (a no-op for a plain URL). */\n remove: (value: unknown) => Promise<void>\n}\n\n/**\n * Bind the media operations to a host store + a bucket. The bucket is a PARAMETER\n * (not a constant named after one lane), so ERP attachments and Helpdesk files do\n * not land in a bucket called `cms-media`.\n */\nexport function createMediaUploader(store: MediaStore, bucket: string): MediaUploader {\n return {\n bucket,\n\n async upload(file, folder = '') {\n // 1) Ensure the per-org bucket. A create that fails because it already\n // exists is expected on every upload after the first.\n await store.ensureBucket(bucket).catch(() => undefined)\n\n // 2) Presign a PUT for a stable key, then upload the bytes directly.\n const key = mediaKey(file.name, folder)\n const presigned = await store.presignUpload(bucket, key)\n if (!presigned || (presigned.method ?? 'PUT') !== 'PUT' || !presigned.url) {\n throw new Error('Could not start the upload (object storage not configured).')\n }\n await store.put(presigned.url, file)\n\n // 3) Intrinsic image dimensions (best-effort; 0×0 for non-images / failures).\n const { width, height } = await imageDimensions(file)\n\n return {\n fileRef: mediaRef(bucket, key),\n filename: file.name,\n mime: file.type || 'application/octet-stream',\n size: file.size,\n width,\n height,\n }\n },\n\n async resolveUrl(value) {\n if (typeof value !== 'string' || value === '') return ''\n if (!isRef(value)) return value // a hand-typed absolute URL\n const parsed = parseRef(value)\n if (!parsed) return ''\n const presigned = await store.presignDownload(parsed.bucket, parsed.key).catch(() => null)\n return presigned?.url ?? ''\n },\n\n async remove(value) {\n if (!isRef(value)) return\n const parsed = parseRef(value)\n if (!parsed) return\n await store.deleteObject(parsed.bucket, parsed.key).catch(() => undefined)\n },\n }\n}\n\n/** Read an image file's intrinsic width/height in the browser (0×0 if not an image). */\nexport function imageDimensions(file: File): Promise<{ width: number; height: number }> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined' || typeof Image === 'undefined' || !file.type.startsWith('image/')) {\n resolve({ width: 0, height: 0 })\n return\n }\n const url = URL.createObjectURL(file)\n const img = new Image()\n img.onload = () => {\n resolve({ width: img.naturalWidth, height: img.naturalHeight })\n URL.revokeObjectURL(url)\n }\n img.onerror = () => {\n resolve({ width: 0, height: 0 })\n URL.revokeObjectURL(url)\n }\n img.src = url\n })\n}\n","/**\n * Shared, non-React data helpers for the generic DocType renderer. A relation\n * (Link) field is a picker over the TARGET doctype's records, so before a view\n * can render or edit one it must load those records (+ the target's schema for\n * the human label). This is the ONE place that does it, used by the records list,\n * the mobile card list and the record detail — no per-view duplication.\n */\nimport type { SelectOption, FieldDefinition } from '@hanzo/data'\nimport type { DocType } from './types'\nimport type { FrameworkClient } from './client'\nimport { linkFields, titleOf } from './fields'\n\n/** The picker options for every Link field of `dt`: value = target id, label = its title. */\nexport async function loadLinkOptions(\n client: FrameworkClient,\n dt: DocType,\n): Promise<Record<string, SelectOption[]>> {\n const links = linkFields(dt)\n const out: Record<string, SelectOption[]> = {}\n await Promise.all(\n links.map(async (f) => {\n const target = f.options\n if (!target) return\n // A target the caller can't read (403) → no options → the field falls back\n // to a raw-id input (honest, never a fabricated candidate list).\n const [tdt, docs] = await Promise.all([\n client.doctypes.get(target).catch(() => null),\n client.records.list(target, { limit: 200 }).catch(() => []),\n ])\n out[f.fieldname] = docs.map((d) => ({\n value: String(d.name),\n label: tdt ? titleOf(d, tdt) : String(d.name),\n }))\n }),\n )\n return out\n}\n\n/**\n * The `fieldOptions` callback @hanzo/data's views take: relation fields get their\n * loaded target records; select fields get the choices declared in metadata (so\n * the table cell and the form input agree). Everything else → undefined.\n */\nexport function makeFieldOptions(\n linkOptions: Record<string, SelectOption[]>,\n): (field: FieldDefinition) => SelectOption[] | undefined {\n return (field) => {\n if (field.type === 'relation') return linkOptions[field.name] ?? []\n if (field.type === 'select' || field.type === 'multiSelect') {\n return (field.metadata as { options?: SelectOption[] } | undefined)?.options\n }\n return undefined\n }\n}\n"]}
@@ -0,0 +1,418 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var chunk7XDEUEWI_cjs = require('./chunk-7XDEUEWI.cjs');
5
+ var react = require('react');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var gui = require('@hanzo/gui');
8
+ var lucideIcons2 = require('@hanzogui/lucide-icons-2');
9
+
10
+ var HostCtx = react.createContext({});
11
+ var HostProvider = ({ actions, children }) => /* @__PURE__ */ jsxRuntime.jsx(HostCtx.Provider, { value: actions, children });
12
+ var useHost = () => react.useContext(HostCtx);
13
+ function classifyBackend(e) {
14
+ const status = typeof e?.status === "number" ? e.status : 0;
15
+ const message = e instanceof Error ? e.message : String(e);
16
+ if (status === 503) return { kind: "not-initialized", message };
17
+ if (status === 404 || status === 405) return { kind: "unavailable", message };
18
+ if (status === 501) return { kind: "not-implemented", message };
19
+ if (status === 402) return { kind: "billing", message };
20
+ if (status === 401) return { kind: "signin", message };
21
+ if (status === 403) return { kind: "access", message };
22
+ return { kind: "error", message };
23
+ }
24
+ function classifyRead(e) {
25
+ const s = classifyBackend(e);
26
+ return s.kind === "billing" ? null : s;
27
+ }
28
+ var TITLES = {
29
+ "not-initialized": "Backend not initialized",
30
+ unavailable: "Not available on this deployment yet",
31
+ "not-implemented": "Not yet available",
32
+ access: "Not enabled for your account",
33
+ signin: "Your session expired",
34
+ billing: "Add credits to continue",
35
+ error: "Could not reach the backend"
36
+ };
37
+ var BODIES = {
38
+ "not-initialized": "The /v1 route is mounted but its runtime (or the console API key it proxies to) is not configured on this deployment yet. Real data appears here once it is \u2014 no placeholder data is shown.",
39
+ unavailable: "This endpoint is not mounted at the gateway on this host yet. The view lights up automatically once the route is live.",
40
+ // 501 — a real, planned capability whose body ships in a later phase.
41
+ "not-implemented": "This capability is planned but not wired yet. The backend answers honestly rather than pretending it worked \u2014 nothing here is fabricated, and the view lights up automatically once it ships.",
42
+ // 403 for a SIGNED-IN user — never "sign in".
43
+ access: "You're signed in, but this isn't enabled for your organization on this deployment, or it's an admin-only surface. It appears here automatically once your account has access \u2014 nothing is fabricated.",
44
+ // 401 — the session itself lapsed; re-auth returns to this exact page.
45
+ signin: "Your session has expired or isn\u2019t recognized here. Sign in again to continue where you left off.",
46
+ // Empty → the card shows the backend's own message (the honest "Insufficient
47
+ // balance. Please add credits…" from the gateway billing gate).
48
+ billing: "",
49
+ error: ""
50
+ };
51
+ function BackendStateCard({
52
+ state,
53
+ onRetry,
54
+ hint
55
+ }) {
56
+ const { signIn, addCredits } = useHost();
57
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.Card, { borderWidth: 1, borderColor: "$borderColor", p: "$4", gap: "$2", maxWidth: 640, children: [
58
+ /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "center", children: [
59
+ /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.TriangleAlert, { size: 16 }),
60
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$4", fontWeight: "700", children: TITLES[state.kind] })
61
+ ] }),
62
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", children: BODIES[state.kind] || state.message }),
63
+ hint ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$color10", children: hint }) : null,
64
+ state.kind === "signin" && signIn ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", theme: "light", self: "flex-start", onPress: signIn, children: "Sign in again" }) : state.kind === "billing" && addCredits ? (
65
+ // 402 — the org has no funded balance. Offer a top-up CTA (and keep Retry so
66
+ // a returning, funded caller can reload in place).
67
+ /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "center", flexWrap: "wrap", children: [
68
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", theme: "light", self: "flex-start", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.CreditCard, { size: 14 }), onPress: addCredits, children: "Add credits" }),
69
+ onRetry ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", self: "flex-start", onPress: onRetry, children: "Retry" }) : null
70
+ ] })
71
+ ) : onRetry ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", self: "flex-start", onPress: onRetry, children: "Retry" }) : null
72
+ ] });
73
+ }
74
+ function PageHeader({
75
+ title,
76
+ subtitle,
77
+ actions
78
+ }) {
79
+ return (
80
+ // flexWrap lets the actions drop below the title on narrow screens; flex={1}
81
+ // minW={0} lets the title column shrink so a long subtitle WRAPS instead of
82
+ // running off the viewport (a flex child defaults to min-width:auto = content
83
+ // width, which would overflow on mobile).
84
+ /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { justify: "space-between", items: "flex-start", gap: "$3", flexWrap: "wrap", children: [
85
+ /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$1", flex: 1, minW: 200, children: [
86
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$7", fontWeight: "500", letterSpacing: -0.4, children: title }),
87
+ subtitle ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", children: subtitle }) : null
88
+ ] }),
89
+ actions ? /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { gap: "$2", items: "center", flexWrap: "wrap", width: "100%", $md: { width: "auto", justify: "flex-end" }, children: actions }) : null
90
+ ] })
91
+ );
92
+ }
93
+ function isHexColor(v) {
94
+ return typeof v === "string" && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v.trim());
95
+ }
96
+ function resolveAccent(theme) {
97
+ if (!theme || !theme.isEnabled) return null;
98
+ const hex = (theme.colorPrimary ?? "").trim();
99
+ return isHexColor(hex) ? hex : null;
100
+ }
101
+ function expandHex(hex) {
102
+ const h = hex.trim().toLowerCase();
103
+ if (h.length === 4) return `#${h[1]}${h[1]}${h[2]}${h[2]}${h[3]}${h[3]}`;
104
+ return h;
105
+ }
106
+ function contrastText(hex) {
107
+ if (!isHexColor(hex)) return "#ffffff";
108
+ const h = expandHex(hex);
109
+ const r = parseInt(h.slice(1, 3), 16) / 255;
110
+ const g = parseInt(h.slice(3, 5), 16) / 255;
111
+ const b = parseInt(h.slice(5, 7), 16) / 255;
112
+ const lin = (c) => c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
113
+ const luminance = 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
114
+ return luminance > 0.5 ? "#000000" : "#ffffff";
115
+ }
116
+ function accentFor(theme) {
117
+ const hex = resolveAccent(theme);
118
+ return { accent: hex, contrast: hex ? contrastText(hex) : "#ffffff" };
119
+ }
120
+ var DEFAULT = { accent: null, contrast: "#ffffff" };
121
+ var current = DEFAULT;
122
+ var listeners = /* @__PURE__ */ new Set();
123
+ function setOrgAccent(theme) {
124
+ const next = accentFor(theme);
125
+ if (next.accent === current.accent) return;
126
+ current = next.accent ? next : DEFAULT;
127
+ for (const l of listeners) l();
128
+ }
129
+ function subscribe(cb) {
130
+ listeners.add(cb);
131
+ return () => {
132
+ listeners.delete(cb);
133
+ };
134
+ }
135
+ function useAccent() {
136
+ return react.useSyncExternalStore(
137
+ subscribe,
138
+ () => current,
139
+ () => DEFAULT
140
+ );
141
+ }
142
+ function PrimaryButton({ onPress, ...rest }) {
143
+ const { accent, contrast } = useAccent();
144
+ const track = chunk7XDEUEWI_cjs.useEmit();
145
+ const press = (e) => {
146
+ track({
147
+ component: "PrimaryButton",
148
+ action: "click",
149
+ id: chunk7XDEUEWI_cjs.labelOf(rest.children) ?? rest["aria-label"]
150
+ });
151
+ onPress?.(e);
152
+ };
153
+ const handler = press;
154
+ if (accent) {
155
+ return /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { style: { backgroundColor: accent, color: contrast, borderColor: accent }, onPress: handler, ...rest });
156
+ }
157
+ return /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { theme: "light", onPress: handler, ...rest });
158
+ }
159
+ function openHref(href) {
160
+ if (typeof window !== "undefined") window.open(href, "_blank", "noopener");
161
+ }
162
+ function EmptyState({
163
+ icon: Icon,
164
+ title,
165
+ description,
166
+ bullets,
167
+ primary,
168
+ secondary
169
+ }) {
170
+ const track = chunk7XDEUEWI_cjs.useEmit();
171
+ return /* @__PURE__ */ jsxRuntime.jsxs(
172
+ gui.Card,
173
+ {
174
+ borderWidth: 1,
175
+ borderColor: "$borderColor",
176
+ borderStyle: "dashed",
177
+ p: "$6",
178
+ gap: "$4",
179
+ items: "center",
180
+ maxWidth: 640,
181
+ self: "center",
182
+ width: "100%",
183
+ children: [
184
+ /* @__PURE__ */ jsxRuntime.jsx(
185
+ gui.YStack,
186
+ {
187
+ width: 48,
188
+ height: 48,
189
+ items: "center",
190
+ justify: "center",
191
+ rounded: "$4",
192
+ bg: "$color3",
193
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: 24 })
194
+ }
195
+ ),
196
+ /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$2", items: "center", maxW: 480, children: [
197
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$6", fontWeight: "500", text: "center", letterSpacing: -0.3, children: title }),
198
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", text: "center", children: description })
199
+ ] }),
200
+ bullets && bullets.length ? /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { gap: "$2", self: "stretch", maxW: 420, mx: "auto", children: bullets.map((b) => /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "flex-start", children: [
201
+ /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { pt: "$1", children: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Check, { size: 14, color: "$color10" }) }),
202
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", flex: 1, children: b })
203
+ ] }, b)) }) : null,
204
+ primary || secondary ? /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "center", flexWrap: "wrap", justify: "center", children: [
205
+ primary ? /* @__PURE__ */ jsxRuntime.jsx(
206
+ PrimaryButton,
207
+ {
208
+ icon: primary.icon,
209
+ iconAfter: primary.href ? /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.ExternalLink, { size: 15 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.ArrowRight, { size: 15 }),
210
+ onPress: () => {
211
+ track({ component: "EmptyState", action: "click", id: title, value: primary.label });
212
+ if (primary.href) openHref(primary.href);
213
+ else primary.onPress?.();
214
+ },
215
+ children: primary.label
216
+ }
217
+ ) : null,
218
+ secondary ? /* @__PURE__ */ jsxRuntime.jsx(
219
+ gui.Button,
220
+ {
221
+ chromeless: true,
222
+ icon: secondary.icon,
223
+ iconAfter: secondary.href ? /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.ExternalLink, { size: 14 }) : void 0,
224
+ onPress: () => {
225
+ track({ component: "EmptyState", action: "click", id: title, value: secondary.label });
226
+ if (secondary.href) openHref(secondary.href);
227
+ else secondary.onPress?.();
228
+ },
229
+ children: secondary.label
230
+ }
231
+ ) : null
232
+ ] }) : null
233
+ ]
234
+ }
235
+ );
236
+ }
237
+ var FieldNameContext = react.createContext(void 0);
238
+ function useFieldTrack(component) {
239
+ const track = chunk7XDEUEWI_cjs.useEmit();
240
+ const name = react.useContext(FieldNameContext);
241
+ return (e) => track({ component, id: name, ...e });
242
+ }
243
+ function FieldRow({ label, children }) {
244
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldNameContext.Provider, { value: label, children: /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$3", items: "flex-start", flexWrap: "wrap", children: [
245
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Label, { width: "100%", pt: "$2", color: "$color11", fontSize: "$3", $md: { width: 180 }, children: label }),
246
+ /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { flex: 1, minW: 0, $md: { minW: 240 }, children })
247
+ ] }) });
248
+ }
249
+ function FieldText({
250
+ value,
251
+ onChange,
252
+ disabled,
253
+ secure,
254
+ placeholder
255
+ }) {
256
+ const track = useFieldTrack("FieldText");
257
+ return /* @__PURE__ */ jsxRuntime.jsx(
258
+ gui.Input,
259
+ {
260
+ value,
261
+ onChangeText: (v) => {
262
+ track({ action: "change", value: secure ? 0 : chunk7XDEUEWI_cjs.textSize(v) });
263
+ onChange(v);
264
+ },
265
+ disabled,
266
+ secureTextEntry: secure,
267
+ placeholder,
268
+ autoCapitalize: "none"
269
+ }
270
+ );
271
+ }
272
+ function FieldTextArea({
273
+ value,
274
+ onChange,
275
+ disabled,
276
+ rows = 6
277
+ }) {
278
+ const track = useFieldTrack("FieldTextArea");
279
+ return /* @__PURE__ */ jsxRuntime.jsx(
280
+ gui.TextArea,
281
+ {
282
+ value,
283
+ onChangeText: (v) => {
284
+ track({ action: "change", value: chunk7XDEUEWI_cjs.textSize(v) });
285
+ onChange(v);
286
+ },
287
+ disabled,
288
+ numberOfLines: rows
289
+ }
290
+ );
291
+ }
292
+ function FieldSwitch({
293
+ checked,
294
+ onChange,
295
+ disabled
296
+ }) {
297
+ const track = useFieldTrack("FieldSwitch");
298
+ return /* @__PURE__ */ jsxRuntime.jsx(
299
+ gui.Switch,
300
+ {
301
+ checked,
302
+ onCheckedChange: (v) => {
303
+ track({ action: "change", value: v });
304
+ onChange(v);
305
+ },
306
+ disabled,
307
+ size: "$3",
308
+ children: /* @__PURE__ */ jsxRuntime.jsx(gui.Switch.Thumb, {})
309
+ }
310
+ );
311
+ }
312
+ var CHEVRON = `data:image/svg+xml,${encodeURIComponent(
313
+ '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9a9a9a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>'
314
+ )}`;
315
+ function selectStyle(disabled) {
316
+ return {
317
+ width: "100%",
318
+ boxSizing: "border-box",
319
+ appearance: "none",
320
+ WebkitAppearance: "none",
321
+ MozAppearance: "none",
322
+ background: `var(--background) url("${CHEVRON}") no-repeat right 10px center`,
323
+ color: "var(--color12)",
324
+ border: "1px solid var(--borderColor)",
325
+ borderRadius: 9,
326
+ padding: "9px 34px 9px 12px",
327
+ fontSize: 14,
328
+ lineHeight: "20px",
329
+ fontFamily: "inherit",
330
+ height: 40,
331
+ outline: "none",
332
+ cursor: disabled ? "not-allowed" : "pointer",
333
+ opacity: disabled ? 0.5 : 1
334
+ };
335
+ }
336
+ var OPTION_STYLE = { background: "var(--color2)", color: "var(--color12)" };
337
+ function FieldSelect({
338
+ value,
339
+ options,
340
+ onChange,
341
+ disabled,
342
+ placeholder = "Select\u2026"
343
+ }) {
344
+ const track = useFieldTrack("FieldSelect");
345
+ const showPlaceholder = value === "" || !options.includes(value);
346
+ return /* @__PURE__ */ jsxRuntime.jsxs(
347
+ "select",
348
+ {
349
+ value: showPlaceholder ? "" : value,
350
+ onChange: (e) => {
351
+ track({ action: "change", value: e.currentTarget.value });
352
+ onChange(e.currentTarget.value);
353
+ },
354
+ disabled,
355
+ "aria-label": placeholder,
356
+ style: selectStyle(disabled),
357
+ children: [
358
+ showPlaceholder ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, style: OPTION_STYLE, children: placeholder }) : null,
359
+ options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, style: OPTION_STYLE, children: opt }, opt))
360
+ ]
361
+ }
362
+ );
363
+ }
364
+ function FieldSlider({
365
+ value,
366
+ min,
367
+ max,
368
+ step,
369
+ onChange,
370
+ disabled
371
+ }) {
372
+ const track = useFieldTrack("FieldSlider");
373
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$3", items: "center", children: [
374
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { width: 56, fontSize: "$3", color: "$color11", children: value }),
375
+ /* @__PURE__ */ jsxRuntime.jsxs(
376
+ gui.Slider,
377
+ {
378
+ flex: 1,
379
+ min,
380
+ max,
381
+ step,
382
+ value: [value],
383
+ onValueChange: (v) => {
384
+ track({ action: "change", value: v[0] ?? min });
385
+ onChange(v[0] ?? min);
386
+ },
387
+ disabled,
388
+ children: [
389
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Slider.Track, { children: /* @__PURE__ */ jsxRuntime.jsx(gui.Slider.TrackActive, {}) }),
390
+ /* @__PURE__ */ jsxRuntime.jsx(gui.Slider.Thumb, { index: 0, circular: true })
391
+ ]
392
+ }
393
+ )
394
+ ] });
395
+ }
396
+
397
+ exports.BackendStateCard = BackendStateCard;
398
+ exports.EmptyState = EmptyState;
399
+ exports.FieldRow = FieldRow;
400
+ exports.FieldSelect = FieldSelect;
401
+ exports.FieldSlider = FieldSlider;
402
+ exports.FieldSwitch = FieldSwitch;
403
+ exports.FieldText = FieldText;
404
+ exports.FieldTextArea = FieldTextArea;
405
+ exports.HostProvider = HostProvider;
406
+ exports.PageHeader = PageHeader;
407
+ exports.PrimaryButton = PrimaryButton;
408
+ exports.accentFor = accentFor;
409
+ exports.classifyBackend = classifyBackend;
410
+ exports.classifyRead = classifyRead;
411
+ exports.contrastText = contrastText;
412
+ exports.isHexColor = isHexColor;
413
+ exports.resolveAccent = resolveAccent;
414
+ exports.setOrgAccent = setOrgAccent;
415
+ exports.useAccent = useAccent;
416
+ exports.useHost = useHost;
417
+ //# sourceMappingURL=chunk-WHJR5S4L.cjs.map
418
+ //# sourceMappingURL=chunk-WHJR5S4L.cjs.map