@agent-native/core 0.44.3 → 0.45.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 (129) hide show
  1. package/dist/cli/connect.d.ts +2 -1
  2. package/dist/cli/connect.d.ts.map +1 -1
  3. package/dist/cli/connect.js +185 -5
  4. package/dist/cli/connect.js.map +1 -1
  5. package/dist/cli/index.js +27 -0
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/plan-local.d.ts +43 -0
  8. package/dist/cli/plan-local.d.ts.map +1 -0
  9. package/dist/cli/plan-local.js +477 -0
  10. package/dist/cli/plan-local.js.map +1 -0
  11. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  12. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  13. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  14. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  15. package/dist/cli/recap.d.ts +164 -0
  16. package/dist/cli/recap.d.ts.map +1 -1
  17. package/dist/cli/recap.js +657 -10
  18. package/dist/cli/recap.js.map +1 -1
  19. package/dist/cli/skills.d.ts +6 -2
  20. package/dist/cli/skills.d.ts.map +1 -1
  21. package/dist/cli/skills.js +440 -37
  22. package/dist/cli/skills.js.map +1 -1
  23. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  24. package/dist/client/blocks/library/AnnotatedCodeBlock.js +18 -4
  25. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  26. package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -1
  27. package/dist/client/blocks/library/ApiEndpointBlock.js +11 -7
  28. package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -1
  29. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  30. package/dist/client/blocks/library/DiffBlock.js +90 -7
  31. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  32. package/dist/client/blocks/library/HighlightedCode.d.ts +2 -1
  33. package/dist/client/blocks/library/HighlightedCode.d.ts.map +1 -1
  34. package/dist/client/blocks/library/HighlightedCode.js +2 -2
  35. package/dist/client/blocks/library/HighlightedCode.js.map +1 -1
  36. package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -1
  37. package/dist/client/blocks/library/JsonExplorerBlock.js +57 -13
  38. package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -1
  39. package/dist/client/blocks/library/annotation-rail.d.ts +15 -5
  40. package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
  41. package/dist/client/blocks/library/annotation-rail.js +35 -24
  42. package/dist/client/blocks/library/annotation-rail.js.map +1 -1
  43. package/dist/client/blocks/library/code-filename-label.d.ts +8 -0
  44. package/dist/client/blocks/library/code-filename-label.d.ts.map +1 -0
  45. package/dist/client/blocks/library/code-filename-label.js +15 -0
  46. package/dist/client/blocks/library/code-filename-label.js.map +1 -0
  47. package/dist/client/blocks/library/code.d.ts.map +1 -1
  48. package/dist/client/blocks/library/code.js +28 -6
  49. package/dist/client/blocks/library/code.js.map +1 -1
  50. package/dist/client/blocks/library/columns.d.ts.map +1 -1
  51. package/dist/client/blocks/library/columns.js +11 -1
  52. package/dist/client/blocks/library/columns.js.map +1 -1
  53. package/dist/client/blocks/library/diff.config.d.ts +1 -1
  54. package/dist/client/blocks/library/diff.config.js.map +1 -1
  55. package/dist/client/blocks/library/narrow-container.d.ts +13 -0
  56. package/dist/client/blocks/library/narrow-container.d.ts.map +1 -0
  57. package/dist/client/blocks/library/narrow-container.js +32 -0
  58. package/dist/client/blocks/library/narrow-container.js.map +1 -0
  59. package/dist/client/blocks/library/question-form.d.ts.map +1 -1
  60. package/dist/client/blocks/library/question-form.js +8 -9
  61. package/dist/client/blocks/library/question-form.js.map +1 -1
  62. package/dist/client/blocks/library/tabs.d.ts.map +1 -1
  63. package/dist/client/blocks/library/tabs.js +11 -5
  64. package/dist/client/blocks/library/tabs.js.map +1 -1
  65. package/dist/client/blocks/types.d.ts +2 -0
  66. package/dist/client/blocks/types.d.ts.map +1 -1
  67. package/dist/client/blocks/types.js.map +1 -1
  68. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  69. package/dist/client/composer/TiptapComposer.js +4 -1
  70. package/dist/client/composer/TiptapComposer.js.map +1 -1
  71. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  72. package/dist/client/db-admin/TableEditor.js +3 -1
  73. package/dist/client/db-admin/TableEditor.js.map +1 -1
  74. package/dist/db/client.d.ts +19 -0
  75. package/dist/db/client.d.ts.map +1 -1
  76. package/dist/db/client.js +43 -2
  77. package/dist/db/client.js.map +1 -1
  78. package/dist/db/migrations.d.ts.map +1 -1
  79. package/dist/db/migrations.js +9 -2
  80. package/dist/db/migrations.js.map +1 -1
  81. package/dist/deploy/build.d.ts.map +1 -1
  82. package/dist/deploy/build.js +8 -0
  83. package/dist/deploy/build.js.map +1 -1
  84. package/dist/extensions/html-shell.js +1 -1
  85. package/dist/extensions/html-shell.js.map +1 -1
  86. package/dist/jobs/scheduler.d.ts.map +1 -1
  87. package/dist/jobs/scheduler.js +5 -1
  88. package/dist/jobs/scheduler.js.map +1 -1
  89. package/dist/mcp/build-server.d.ts +1 -0
  90. package/dist/mcp/build-server.d.ts.map +1 -1
  91. package/dist/mcp/build-server.js +7 -3
  92. package/dist/mcp/build-server.js.map +1 -1
  93. package/dist/mcp/oauth-route.d.ts.map +1 -1
  94. package/dist/mcp/oauth-route.js +56 -19
  95. package/dist/mcp/oauth-route.js.map +1 -1
  96. package/dist/mcp/oauth-store.d.ts +1 -0
  97. package/dist/mcp/oauth-store.d.ts.map +1 -1
  98. package/dist/mcp/oauth-store.js +9 -0
  99. package/dist/mcp/oauth-store.js.map +1 -1
  100. package/dist/mcp/server.d.ts.map +1 -1
  101. package/dist/mcp/server.js +9 -4
  102. package/dist/mcp/server.js.map +1 -1
  103. package/dist/mcp-client/errors.js +3 -3
  104. package/dist/mcp-client/errors.js.map +1 -1
  105. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  106. package/dist/server/agent-chat-plugin.js +3 -1
  107. package/dist/server/agent-chat-plugin.js.map +1 -1
  108. package/dist/server/agent-teams.d.ts.map +1 -1
  109. package/dist/server/agent-teams.js +10 -2
  110. package/dist/server/agent-teams.js.map +1 -1
  111. package/dist/server/auth.d.ts.map +1 -1
  112. package/dist/server/auth.js +7 -3
  113. package/dist/server/auth.js.map +1 -1
  114. package/dist/server/recap-image-route.d.ts.map +1 -1
  115. package/dist/server/recap-image-route.js +3 -6
  116. package/dist/server/recap-image-route.js.map +1 -1
  117. package/dist/server/sentry.d.ts.map +1 -1
  118. package/dist/server/sentry.js +12 -5
  119. package/dist/server/sentry.js.map +1 -1
  120. package/dist/server/social-og-image.d.ts.map +1 -1
  121. package/dist/server/social-og-image.js +3 -1
  122. package/dist/server/social-og-image.js.map +1 -1
  123. package/dist/styles/blocks.css +36 -10
  124. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
  125. package/docs/content/plan-plugin.md +18 -1
  126. package/docs/content/pr-visual-recap.md +37 -10
  127. package/docs/content/template-plan.md +45 -1
  128. package/package.json +1 -1
  129. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
@@ -1 +1 @@
1
- {"version":3,"file":"TableEditor.d.ts","sourceRoot":"","sources":["../../../src/client/db-admin/TableEditor.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAId,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,cAAc,CAAC;IACxB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;CACpE;AAKD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAO,EACP,cAAc,EACd,eAAe,GAChB,EAAE,gBAAgB,2CAielB"}
1
+ {"version":3,"file":"TableEditor.d.ts","sourceRoot":"","sources":["../../../src/client/db-admin/TableEditor.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAId,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,cAAc,CAAC;IACxB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;CACpE;AAKD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAO,EACP,cAAc,EACd,eAAe,GAChB,EAAE,gBAAgB,2CAqelB"}
@@ -173,7 +173,9 @@ export function TableEditor({ table, dialect, initialFilters, onNavigateToRow, }
173
173
  commitRef.current = handleCommit;
174
174
  useEffect(() => {
175
175
  const onKey = (e) => {
176
- if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "s") {
176
+ if ((e.metaKey || e.ctrlKey) &&
177
+ typeof e.key === "string" &&
178
+ e.key.toLowerCase() === "s") {
177
179
  e.preventDefault();
178
180
  if (changeset.isDirty)
179
181
  void commitRef.current();
@@ -1 +1 @@
1
- {"version":3,"file":"TableEditor.js","sourceRoot":"","sources":["../../../src/client/db-admin/TableEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n IconPlus,\n IconFilter,\n IconRefresh,\n IconTrash,\n IconAlertTriangle,\n IconCode,\n IconArrowBackUp,\n IconDeviceFloppy,\n IconChevronLeft,\n IconChevronRight,\n IconChevronsLeft,\n IconChevronsRight,\n IconLoader2,\n IconCheck,\n IconKeyOff,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport { useTableSchema, useTableRows, mutateTable } from \"./useDbAdmin.js\";\nimport { loadGridState, saveGridState } from \"./storage.js\";\nimport { useChangeset, pkStringFor } from \"./changeset.js\";\nimport { DataGrid, type GridRow, type ActiveCell } from \"./DataGrid.js\";\nimport { FilterBar } from \"./FilterBar.js\";\nimport { RowSidePanel, type RowSidePanelMode } from \"./RowSidePanel.js\";\nimport type {\n DbAdminDialect,\n DbAdminFilter,\n DbAdminForeignKey,\n DbAdminSort,\n DbAdminMutationResult,\n} from \"../../db-admin/types.js\";\n\nexport interface TableEditorProps {\n table: string;\n dialect: DbAdminDialect;\n initialFilters?: DbAdminFilter[];\n onNavigateToRow: (table: string, filters: DbAdminFilter[]) => void;\n}\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst PAGE_SIZES = [25, 50, 100, 250, 500];\n\nexport function TableEditor({\n table,\n dialect,\n initialFilters,\n onNavigateToRow,\n}: TableEditorProps) {\n // ─── Persisted view state ──────────────────────────────────────────────\n const persisted = useMemo(() => loadGridState(table), [table]);\n\n const [page, setPage] = useState(1);\n const [pageSize, setPageSize] = useState(\n persisted.pageSize ?? DEFAULT_PAGE_SIZE,\n );\n const [sort, setSort] = useState<DbAdminSort[]>(persisted.sort ?? []);\n const [filters, setFilters] = useState<DbAdminFilter[]>(\n initialFilters ?? persisted.filters ?? [],\n );\n const [columnWidths, setColumnWidths] = useState<Record<string, number>>(\n persisted.columnWidths ?? {},\n );\n const [selectedPks, setSelectedPks] = useState<Set<string>>(new Set());\n const [active, setActive] = useState<ActiveCell | null>(null);\n\n // Reset transient state when switching tables.\n useEffect(() => {\n const p = loadGridState(table);\n setPage(1);\n setPageSize(p.pageSize ?? DEFAULT_PAGE_SIZE);\n setSort(p.sort ?? []);\n setFilters(initialFilters ?? p.filters ?? []);\n setColumnWidths(p.columnWidths ?? {});\n setSelectedPks(new Set());\n setActive(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [table]);\n\n // Persist view state.\n useEffect(() => {\n saveGridState(table, { columnWidths, sort, filters, pageSize });\n }, [table, columnWidths, sort, filters, pageSize]);\n\n // ─── Data ────────────────────────────────────────────────────────────────\n const schemaState = useTableSchema(table);\n const rowsReq = useMemo(\n () => ({ page, pageSize, sort, filters }),\n [page, pageSize, sort, filters],\n );\n const rowsState = useTableRows(table, rowsReq);\n\n const schema = schemaState.data;\n const changeset = useChangeset(schema);\n\n // ─── Toolbar UI state ──────────────────────────────────────────────────\n const [panel, setPanel] = useState<{\n mode: RowSidePanelMode;\n pk?: string;\n } | null>(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [previewSql, setPreviewSql] = useState<string[] | null>(null);\n const [committing, setCommitting] = useState(false);\n const [commitError, setCommitError] = useState<string | null>(null);\n const [toast, setToast] = useState<string | null>(null);\n\n const showToast = useCallback((msg: string) => {\n setToast(msg);\n window.setTimeout(() => setToast(null), 2500);\n }, []);\n\n // ─── Original rows map (pk → fetched row) ──────────────────────────────\n const originalRows = useMemo(() => {\n const map = new Map<string, Record<string, unknown>>();\n for (const row of rowsState.data?.rows ?? []) {\n map.set(pkStringFor(schema, row), row);\n }\n return map;\n }, [rowsState.data, schema]);\n\n // ─── Build grid rows with staged edits applied ──────────────────────────\n const gridRows = useMemo<GridRow[]>(() => {\n const out: GridRow[] = [];\n // New rows first (top of grid, like Supabase).\n for (const nr of changeset.newRows) {\n out.push({\n pk: `new:${nr._localId}`,\n localId: nr._localId,\n isNew: true,\n values: { ...nr.values },\n });\n }\n for (const row of rowsState.data?.rows ?? []) {\n const pk = pkStringFor(schema, row);\n const staged = changeset.edits.get(pk);\n out.push({\n pk,\n values: staged ? { ...row, ...staged } : row,\n isDeleted: changeset.deletedKeys.has(pk),\n });\n }\n return out;\n }, [\n rowsState.data,\n schema,\n changeset.newRows,\n changeset.edits,\n changeset.deletedKeys,\n ]);\n\n // ─── Cell commit routing (existing rows vs new rows) ────────────────────\n const onCellCommit = useCallback(\n (row: GridRow, col: string, value: unknown) => {\n if (row.isNew && row.localId) {\n changeset.setNewRowCell(row.localId, col, value);\n } else {\n changeset.setCell(row.pk, col, value);\n }\n },\n [changeset],\n );\n\n const isCellDirty = useCallback(\n (row: GridRow, col: string) => {\n if (row.isNew) return true;\n return changeset.isCellDirty(row.pk, col);\n },\n [changeset],\n );\n\n const onToggleDelete = useCallback(\n (row: GridRow) => {\n if (row.isNew && row.localId) {\n changeset.removeNewRow(row.localId);\n return;\n }\n changeset.deleteRows([row.pk]);\n },\n [changeset],\n );\n\n // ─── FK navigation ───────────────────────────────────────────────────────\n const onFkNavigate = useCallback(\n (fk: DbAdminForeignKey, value: unknown) => {\n onNavigateToRow(fk.refTable, [{ column: fk.refColumn, op: \"eq\", value }]);\n },\n [onNavigateToRow],\n );\n\n // ─── Commit / preview ──────────────────────────────────────────────────\n const runCommit = useCallback(\n async (dryRun: boolean) => {\n const mutation = changeset.buildMutation(originalRows, dryRun);\n if (!mutation.inserts && !mutation.updates && !mutation.deletes) {\n return null;\n }\n return mutateTable(table, mutation);\n },\n [changeset, originalRows, table],\n );\n\n const handlePreview = useCallback(async () => {\n setCommitError(null);\n try {\n const res = await runCommit(true);\n setPreviewSql(res ? res.sql : []);\n } catch (err) {\n setCommitError(err instanceof Error ? err.message : String(err));\n }\n }, [runCommit]);\n\n const handleCommit = useCallback(async () => {\n const hasDeletes = changeset.deletedKeys.size > 0;\n if (hasDeletes && !confirmDelete) {\n setConfirmDelete(true);\n return;\n }\n setCommitting(true);\n setCommitError(null);\n try {\n const res: DbAdminMutationResult | null = await runCommit(false);\n changeset.discardAll();\n setSelectedPks(new Set());\n setConfirmDelete(false);\n rowsState.refetch();\n schemaState.refetch();\n if (res) {\n const parts: string[] = [];\n if (res.inserted) parts.push(`${res.inserted} inserted`);\n if (res.updated) parts.push(`${res.updated} updated`);\n if (res.deleted) parts.push(`${res.deleted} deleted`);\n showToast(parts.length ? parts.join(\", \") : \"No changes\");\n }\n } catch (err) {\n setCommitError(err instanceof Error ? err.message : String(err));\n } finally {\n setCommitting(false);\n }\n }, [changeset, confirmDelete, runCommit, rowsState, schemaState, showToast]);\n\n // ─── Cmd/Ctrl+S to commit ──────────────────────────────────────────────\n const commitRef = useRef(handleCommit);\n commitRef.current = handleCommit;\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === \"s\") {\n e.preventDefault();\n if (changeset.isDirty) void commitRef.current();\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [changeset.isDirty]);\n\n // ─── Bulk delete from selection ────────────────────────────────────────\n const onBulkDelete = useCallback(() => {\n const pks = [...selectedPks].filter((pk) => !pk.startsWith(\"new:\"));\n changeset.deleteRows(pks);\n setSelectedPks(new Set());\n }, [selectedPks, changeset]);\n\n // ─── Render ──────────────────────────────────────────────────────────────\n const total = rowsState.data?.total ?? schema?.rowCount ?? 0;\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n if (schemaState.error) {\n return (\n <div className=\"flex h-full items-center justify-center p-8 text-sm text-destructive\">\n <IconAlertTriangle className=\"mr-2 h-4 w-4\" />\n {schemaState.error.message}\n </div>\n );\n }\n\n if (!schema) {\n return (\n <div className=\"flex h-full items-center justify-center p-8 text-sm text-muted-foreground\">\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Loading {table}…\n </div>\n );\n }\n\n const noPk = schema.primaryKey.length === 0;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n {/* Toolbar */}\n <div className=\"flex flex-col gap-2 border-b border-border px-3 py-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">\n {table}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {total.toLocaleString()} rows\n </span>\n {schema.type === \"view\" && (\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n view\n </span>\n )}\n </div>\n\n <div className=\"ml-auto flex items-center gap-1.5\">\n <ToolbarButton\n icon={<IconRefresh className=\"h-3.5 w-3.5\" />}\n label=\"Refresh\"\n onClick={() => {\n rowsState.refetch();\n schemaState.refetch();\n }}\n />\n {!noPk && schema.type === \"table\" && (\n <ToolbarButton\n icon={<IconPlus className=\"h-3.5 w-3.5\" />}\n label=\"Insert\"\n onClick={() => setPanel({ mode: \"insert\" })}\n primary\n />\n )}\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"flex items-center gap-2\">\n <IconFilter className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <FilterBar\n columns={schema.columns}\n filters={filters}\n onChange={(f) => {\n setFilters(f);\n setPage(1);\n }}\n />\n </div>\n\n {/* No-PK warning */}\n {noPk && schema.type === \"table\" && (\n <div className=\"flex items-center gap-1.5 rounded-md bg-amber-500/10 px-2 py-1 text-[11px] text-amber-600 dark:text-amber-400\">\n <IconKeyOff className=\"h-3.5 w-3.5\" />\n This table has no primary key — editing and row deletion are\n disabled.\n </div>\n )}\n\n {/* Selection / changeset bar */}\n {(selectedPks.size > 0 || changeset.isDirty) && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {selectedPks.size > 0 && (\n <>\n <span className=\"text-xs text-muted-foreground\">\n {selectedPks.size} selected\n </span>\n {!noPk && (\n <button\n type=\"button\"\n onClick={onBulkDelete}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-destructive hover:bg-destructive/10\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n Delete selected\n </button>\n )}\n <span className=\"h-4 w-px bg-border\" />\n </>\n )}\n\n {changeset.isDirty && (\n <>\n <span className=\"inline-flex items-center gap-1 rounded-md bg-amber-500/15 px-2 py-1 text-xs font-medium text-amber-600 dark:text-amber-400\">\n {changeset.pendingCount} pending change\n {changeset.pendingCount === 1 ? \"\" : \"s\"}\n </span>\n <button\n type=\"button\"\n onClick={changeset.discardAll}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <IconArrowBackUp className=\"h-3.5 w-3.5\" />\n Discard\n </button>\n <PreviewSqlButton\n onPreview={handlePreview}\n sql={previewSql}\n onClear={() => setPreviewSql(null)}\n error={commitError}\n />\n <button\n type=\"button\"\n onClick={() => void handleCommit()}\n disabled={committing}\n className=\"inline-flex items-center gap-1 rounded-md bg-primary px-2.5 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-60\"\n >\n {committing ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconDeviceFloppy className=\"h-3.5 w-3.5\" />\n )}\n Commit\n </button>\n </>\n )}\n </div>\n )}\n\n {commitError && !previewSql && (\n <div className=\"flex items-center gap-1.5 rounded-md bg-destructive/10 px-2 py-1 text-[11px] text-destructive\">\n <IconAlertTriangle className=\"h-3.5 w-3.5\" />\n {commitError}\n </div>\n )}\n </div>\n\n {/* Grid */}\n <DataGrid\n schema={schema}\n rows={gridRows}\n isLoading={rowsState.isLoading}\n pageSize={pageSize}\n sort={sort}\n onSortChange={(s) => {\n setSort(s);\n setPage(1);\n }}\n selectedPks={selectedPks}\n onSelectionChange={setSelectedPks}\n columnWidths={columnWidths}\n onColumnWidthsChange={setColumnWidths}\n active={active}\n onActiveChange={setActive}\n editable={!noPk && schema.type === \"table\"}\n onCellCommit={onCellCommit}\n isCellDirty={isCellDirty}\n onToggleDelete={onToggleDelete}\n onNavigateToRow={onFkNavigate}\n />\n\n {/* Pagination footer */}\n <div className=\"flex items-center justify-between border-t border-border px-3 py-1.5 text-xs text-muted-foreground\">\n <div className=\"flex items-center gap-2\">\n <span>Rows per page</span>\n <select\n value={pageSize}\n onChange={(e) => {\n setPageSize(Number(e.target.value));\n setPage(1);\n }}\n className=\"h-6 rounded border border-border bg-background px-1 text-xs outline-none focus:ring-1 focus:ring-ring\"\n >\n {PAGE_SIZES.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"flex items-center gap-1\">\n <span className=\"mr-2\">\n Page {page} of {totalPages}\n </span>\n <PagerButton\n disabled={page <= 1}\n onClick={() => setPage(1)}\n icon={<IconChevronsLeft className=\"h-3.5 w-3.5\" />}\n />\n <PagerButton\n disabled={page <= 1}\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n icon={<IconChevronLeft className=\"h-3.5 w-3.5\" />}\n />\n <PagerButton\n disabled={page >= totalPages}\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\n icon={<IconChevronRight className=\"h-3.5 w-3.5\" />}\n />\n <PagerButton\n disabled={page >= totalPages}\n onClick={() => setPage(totalPages)}\n icon={<IconChevronsRight className=\"h-3.5 w-3.5\" />}\n />\n </div>\n </div>\n\n {/* Row side panel */}\n {panel && (\n <RowSidePanel\n schema={schema}\n mode={panel.mode}\n row={panel.pk ? originalRows.get(panel.pk) : undefined}\n staged={panel.pk ? changeset.edits.get(panel.pk) : undefined}\n onClose={() => setPanel(null)}\n onSave={(values) => {\n if (panel.mode === \"insert\") {\n changeset.addRow(values);\n } else if (panel.pk) {\n changeset.setCells(panel.pk, values);\n }\n }}\n />\n )}\n\n {/* Destructive commit confirmation */}\n {confirmDelete && (\n <ConfirmModal\n title=\"Commit deletions?\"\n body={`${changeset.deletedKeys.size} row${\n changeset.deletedKeys.size === 1 ? \"\" : \"s\"\n } will be permanently deleted along with any other pending changes. This cannot be undone.`}\n confirmLabel=\"Delete and commit\"\n destructive\n onCancel={() => setConfirmDelete(false)}\n onConfirm={() => void handleCommit()}\n />\n )}\n\n {/* Toast */}\n {toast &&\n typeof document !== \"undefined\" &&\n createPortal(\n <div className=\"fixed bottom-4 right-4 z-[500] flex items-center gap-2 rounded-md border border-border bg-card px-3 py-2 text-xs text-foreground shadow-lg\">\n <IconCheck className=\"h-4 w-4 text-emerald-500\" />\n {toast}\n </div>,\n document.body,\n )}\n </div>\n );\n}\n\n// ─── Small UI atoms ────────────────────────────────────────────────────────\n\nfunction ToolbarButton({\n icon,\n label,\n onClick,\n primary,\n}: {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n primary?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs\",\n primary\n ? \"bg-primary text-primary-foreground hover:bg-primary/90\"\n : \"border border-border text-muted-foreground hover:text-foreground\",\n )}\n >\n {icon}\n {label}\n </button>\n );\n}\n\nfunction PagerButton({\n disabled,\n onClick,\n icon,\n}: {\n disabled: boolean;\n onClick: () => void;\n icon: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n className=\"rounded border border-border p-1 text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n {icon}\n </button>\n );\n}\n\nfunction PreviewSqlButton({\n onPreview,\n sql,\n onClear,\n error,\n}: {\n onPreview: () => void;\n sql: string[] | null;\n onClear: () => void;\n error: string | null;\n}) {\n return (\n <Popover\n open={sql !== null}\n onOpenChange={(o) => {\n if (!o) onClear();\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n onClick={onPreview}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <IconCode className=\"h-3.5 w-3.5\" />\n Preview SQL\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-[34rem] p-0\">\n <div className=\"border-b border-border px-3 py-2 text-xs font-medium text-foreground\">\n Preview SQL\n </div>\n <div className=\"max-h-80 overflow-auto p-3\">\n {error ? (\n <div className=\"text-xs text-destructive\">{error}</div>\n ) : sql && sql.length > 0 ? (\n <pre className=\"whitespace-pre-wrap break-all font-mono text-[11px] leading-relaxed text-foreground\">\n {sql.join(\";\\n\")}\n </pre>\n ) : (\n <div className=\"text-xs text-muted-foreground\">\n No statements to run.\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction ConfirmModal({\n title,\n body,\n confirmLabel,\n destructive,\n onCancel,\n onConfirm,\n}: {\n title: string;\n body: string;\n confirmLabel: string;\n destructive?: boolean;\n onCancel: () => void;\n onConfirm: () => void;\n}) {\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onCancel();\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onCancel]);\n\n if (typeof document === \"undefined\") return null;\n return createPortal(\n <div className=\"fixed inset-0 z-[450] flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-black/40\" onClick={onCancel} />\n <div className=\"relative w-full max-w-sm rounded-lg border border-border bg-card p-4 shadow-xl\">\n <div className=\"mb-1 flex items-center gap-2\">\n {destructive && (\n <IconAlertTriangle className=\"h-4 w-4 text-destructive\" />\n )}\n <h2 className=\"text-sm font-semibold text-foreground\">{title}</h2>\n </div>\n <p className=\"mb-4 text-xs text-muted-foreground\">{body}</p>\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"rounded-md px-3 py-1.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={onConfirm}\n className={cn(\n \"rounded-md px-3 py-1.5 text-xs font-medium text-primary-foreground\",\n destructive\n ? \"bg-destructive hover:bg-destructive/90\"\n : \"bg-primary hover:bg-primary/90\",\n )}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n </div>,\n document.body,\n );\n}\n"]}
1
+ {"version":3,"file":"TableEditor.js","sourceRoot":"","sources":["../../../src/client/db-admin/TableEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n IconPlus,\n IconFilter,\n IconRefresh,\n IconTrash,\n IconAlertTriangle,\n IconCode,\n IconArrowBackUp,\n IconDeviceFloppy,\n IconChevronLeft,\n IconChevronRight,\n IconChevronsLeft,\n IconChevronsRight,\n IconLoader2,\n IconCheck,\n IconKeyOff,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport { useTableSchema, useTableRows, mutateTable } from \"./useDbAdmin.js\";\nimport { loadGridState, saveGridState } from \"./storage.js\";\nimport { useChangeset, pkStringFor } from \"./changeset.js\";\nimport { DataGrid, type GridRow, type ActiveCell } from \"./DataGrid.js\";\nimport { FilterBar } from \"./FilterBar.js\";\nimport { RowSidePanel, type RowSidePanelMode } from \"./RowSidePanel.js\";\nimport type {\n DbAdminDialect,\n DbAdminFilter,\n DbAdminForeignKey,\n DbAdminSort,\n DbAdminMutationResult,\n} from \"../../db-admin/types.js\";\n\nexport interface TableEditorProps {\n table: string;\n dialect: DbAdminDialect;\n initialFilters?: DbAdminFilter[];\n onNavigateToRow: (table: string, filters: DbAdminFilter[]) => void;\n}\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst PAGE_SIZES = [25, 50, 100, 250, 500];\n\nexport function TableEditor({\n table,\n dialect,\n initialFilters,\n onNavigateToRow,\n}: TableEditorProps) {\n // ─── Persisted view state ──────────────────────────────────────────────\n const persisted = useMemo(() => loadGridState(table), [table]);\n\n const [page, setPage] = useState(1);\n const [pageSize, setPageSize] = useState(\n persisted.pageSize ?? DEFAULT_PAGE_SIZE,\n );\n const [sort, setSort] = useState<DbAdminSort[]>(persisted.sort ?? []);\n const [filters, setFilters] = useState<DbAdminFilter[]>(\n initialFilters ?? persisted.filters ?? [],\n );\n const [columnWidths, setColumnWidths] = useState<Record<string, number>>(\n persisted.columnWidths ?? {},\n );\n const [selectedPks, setSelectedPks] = useState<Set<string>>(new Set());\n const [active, setActive] = useState<ActiveCell | null>(null);\n\n // Reset transient state when switching tables.\n useEffect(() => {\n const p = loadGridState(table);\n setPage(1);\n setPageSize(p.pageSize ?? DEFAULT_PAGE_SIZE);\n setSort(p.sort ?? []);\n setFilters(initialFilters ?? p.filters ?? []);\n setColumnWidths(p.columnWidths ?? {});\n setSelectedPks(new Set());\n setActive(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [table]);\n\n // Persist view state.\n useEffect(() => {\n saveGridState(table, { columnWidths, sort, filters, pageSize });\n }, [table, columnWidths, sort, filters, pageSize]);\n\n // ─── Data ────────────────────────────────────────────────────────────────\n const schemaState = useTableSchema(table);\n const rowsReq = useMemo(\n () => ({ page, pageSize, sort, filters }),\n [page, pageSize, sort, filters],\n );\n const rowsState = useTableRows(table, rowsReq);\n\n const schema = schemaState.data;\n const changeset = useChangeset(schema);\n\n // ─── Toolbar UI state ──────────────────────────────────────────────────\n const [panel, setPanel] = useState<{\n mode: RowSidePanelMode;\n pk?: string;\n } | null>(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [previewSql, setPreviewSql] = useState<string[] | null>(null);\n const [committing, setCommitting] = useState(false);\n const [commitError, setCommitError] = useState<string | null>(null);\n const [toast, setToast] = useState<string | null>(null);\n\n const showToast = useCallback((msg: string) => {\n setToast(msg);\n window.setTimeout(() => setToast(null), 2500);\n }, []);\n\n // ─── Original rows map (pk → fetched row) ──────────────────────────────\n const originalRows = useMemo(() => {\n const map = new Map<string, Record<string, unknown>>();\n for (const row of rowsState.data?.rows ?? []) {\n map.set(pkStringFor(schema, row), row);\n }\n return map;\n }, [rowsState.data, schema]);\n\n // ─── Build grid rows with staged edits applied ──────────────────────────\n const gridRows = useMemo<GridRow[]>(() => {\n const out: GridRow[] = [];\n // New rows first (top of grid, like Supabase).\n for (const nr of changeset.newRows) {\n out.push({\n pk: `new:${nr._localId}`,\n localId: nr._localId,\n isNew: true,\n values: { ...nr.values },\n });\n }\n for (const row of rowsState.data?.rows ?? []) {\n const pk = pkStringFor(schema, row);\n const staged = changeset.edits.get(pk);\n out.push({\n pk,\n values: staged ? { ...row, ...staged } : row,\n isDeleted: changeset.deletedKeys.has(pk),\n });\n }\n return out;\n }, [\n rowsState.data,\n schema,\n changeset.newRows,\n changeset.edits,\n changeset.deletedKeys,\n ]);\n\n // ─── Cell commit routing (existing rows vs new rows) ────────────────────\n const onCellCommit = useCallback(\n (row: GridRow, col: string, value: unknown) => {\n if (row.isNew && row.localId) {\n changeset.setNewRowCell(row.localId, col, value);\n } else {\n changeset.setCell(row.pk, col, value);\n }\n },\n [changeset],\n );\n\n const isCellDirty = useCallback(\n (row: GridRow, col: string) => {\n if (row.isNew) return true;\n return changeset.isCellDirty(row.pk, col);\n },\n [changeset],\n );\n\n const onToggleDelete = useCallback(\n (row: GridRow) => {\n if (row.isNew && row.localId) {\n changeset.removeNewRow(row.localId);\n return;\n }\n changeset.deleteRows([row.pk]);\n },\n [changeset],\n );\n\n // ─── FK navigation ───────────────────────────────────────────────────────\n const onFkNavigate = useCallback(\n (fk: DbAdminForeignKey, value: unknown) => {\n onNavigateToRow(fk.refTable, [{ column: fk.refColumn, op: \"eq\", value }]);\n },\n [onNavigateToRow],\n );\n\n // ─── Commit / preview ──────────────────────────────────────────────────\n const runCommit = useCallback(\n async (dryRun: boolean) => {\n const mutation = changeset.buildMutation(originalRows, dryRun);\n if (!mutation.inserts && !mutation.updates && !mutation.deletes) {\n return null;\n }\n return mutateTable(table, mutation);\n },\n [changeset, originalRows, table],\n );\n\n const handlePreview = useCallback(async () => {\n setCommitError(null);\n try {\n const res = await runCommit(true);\n setPreviewSql(res ? res.sql : []);\n } catch (err) {\n setCommitError(err instanceof Error ? err.message : String(err));\n }\n }, [runCommit]);\n\n const handleCommit = useCallback(async () => {\n const hasDeletes = changeset.deletedKeys.size > 0;\n if (hasDeletes && !confirmDelete) {\n setConfirmDelete(true);\n return;\n }\n setCommitting(true);\n setCommitError(null);\n try {\n const res: DbAdminMutationResult | null = await runCommit(false);\n changeset.discardAll();\n setSelectedPks(new Set());\n setConfirmDelete(false);\n rowsState.refetch();\n schemaState.refetch();\n if (res) {\n const parts: string[] = [];\n if (res.inserted) parts.push(`${res.inserted} inserted`);\n if (res.updated) parts.push(`${res.updated} updated`);\n if (res.deleted) parts.push(`${res.deleted} deleted`);\n showToast(parts.length ? parts.join(\", \") : \"No changes\");\n }\n } catch (err) {\n setCommitError(err instanceof Error ? err.message : String(err));\n } finally {\n setCommitting(false);\n }\n }, [changeset, confirmDelete, runCommit, rowsState, schemaState, showToast]);\n\n // ─── Cmd/Ctrl+S to commit ──────────────────────────────────────────────\n const commitRef = useRef(handleCommit);\n commitRef.current = handleCommit;\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (\n (e.metaKey || e.ctrlKey) &&\n typeof e.key === \"string\" &&\n e.key.toLowerCase() === \"s\"\n ) {\n e.preventDefault();\n if (changeset.isDirty) void commitRef.current();\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [changeset.isDirty]);\n\n // ─── Bulk delete from selection ────────────────────────────────────────\n const onBulkDelete = useCallback(() => {\n const pks = [...selectedPks].filter((pk) => !pk.startsWith(\"new:\"));\n changeset.deleteRows(pks);\n setSelectedPks(new Set());\n }, [selectedPks, changeset]);\n\n // ─── Render ──────────────────────────────────────────────────────────────\n const total = rowsState.data?.total ?? schema?.rowCount ?? 0;\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n if (schemaState.error) {\n return (\n <div className=\"flex h-full items-center justify-center p-8 text-sm text-destructive\">\n <IconAlertTriangle className=\"mr-2 h-4 w-4\" />\n {schemaState.error.message}\n </div>\n );\n }\n\n if (!schema) {\n return (\n <div className=\"flex h-full items-center justify-center p-8 text-sm text-muted-foreground\">\n <IconLoader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Loading {table}…\n </div>\n );\n }\n\n const noPk = schema.primaryKey.length === 0;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n {/* Toolbar */}\n <div className=\"flex flex-col gap-2 border-b border-border px-3 py-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-sm font-semibold text-foreground\">\n {table}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {total.toLocaleString()} rows\n </span>\n {schema.type === \"view\" && (\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n view\n </span>\n )}\n </div>\n\n <div className=\"ml-auto flex items-center gap-1.5\">\n <ToolbarButton\n icon={<IconRefresh className=\"h-3.5 w-3.5\" />}\n label=\"Refresh\"\n onClick={() => {\n rowsState.refetch();\n schemaState.refetch();\n }}\n />\n {!noPk && schema.type === \"table\" && (\n <ToolbarButton\n icon={<IconPlus className=\"h-3.5 w-3.5\" />}\n label=\"Insert\"\n onClick={() => setPanel({ mode: \"insert\" })}\n primary\n />\n )}\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"flex items-center gap-2\">\n <IconFilter className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <FilterBar\n columns={schema.columns}\n filters={filters}\n onChange={(f) => {\n setFilters(f);\n setPage(1);\n }}\n />\n </div>\n\n {/* No-PK warning */}\n {noPk && schema.type === \"table\" && (\n <div className=\"flex items-center gap-1.5 rounded-md bg-amber-500/10 px-2 py-1 text-[11px] text-amber-600 dark:text-amber-400\">\n <IconKeyOff className=\"h-3.5 w-3.5\" />\n This table has no primary key — editing and row deletion are\n disabled.\n </div>\n )}\n\n {/* Selection / changeset bar */}\n {(selectedPks.size > 0 || changeset.isDirty) && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {selectedPks.size > 0 && (\n <>\n <span className=\"text-xs text-muted-foreground\">\n {selectedPks.size} selected\n </span>\n {!noPk && (\n <button\n type=\"button\"\n onClick={onBulkDelete}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-destructive hover:bg-destructive/10\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n Delete selected\n </button>\n )}\n <span className=\"h-4 w-px bg-border\" />\n </>\n )}\n\n {changeset.isDirty && (\n <>\n <span className=\"inline-flex items-center gap-1 rounded-md bg-amber-500/15 px-2 py-1 text-xs font-medium text-amber-600 dark:text-amber-400\">\n {changeset.pendingCount} pending change\n {changeset.pendingCount === 1 ? \"\" : \"s\"}\n </span>\n <button\n type=\"button\"\n onClick={changeset.discardAll}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <IconArrowBackUp className=\"h-3.5 w-3.5\" />\n Discard\n </button>\n <PreviewSqlButton\n onPreview={handlePreview}\n sql={previewSql}\n onClear={() => setPreviewSql(null)}\n error={commitError}\n />\n <button\n type=\"button\"\n onClick={() => void handleCommit()}\n disabled={committing}\n className=\"inline-flex items-center gap-1 rounded-md bg-primary px-2.5 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-60\"\n >\n {committing ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconDeviceFloppy className=\"h-3.5 w-3.5\" />\n )}\n Commit\n </button>\n </>\n )}\n </div>\n )}\n\n {commitError && !previewSql && (\n <div className=\"flex items-center gap-1.5 rounded-md bg-destructive/10 px-2 py-1 text-[11px] text-destructive\">\n <IconAlertTriangle className=\"h-3.5 w-3.5\" />\n {commitError}\n </div>\n )}\n </div>\n\n {/* Grid */}\n <DataGrid\n schema={schema}\n rows={gridRows}\n isLoading={rowsState.isLoading}\n pageSize={pageSize}\n sort={sort}\n onSortChange={(s) => {\n setSort(s);\n setPage(1);\n }}\n selectedPks={selectedPks}\n onSelectionChange={setSelectedPks}\n columnWidths={columnWidths}\n onColumnWidthsChange={setColumnWidths}\n active={active}\n onActiveChange={setActive}\n editable={!noPk && schema.type === \"table\"}\n onCellCommit={onCellCommit}\n isCellDirty={isCellDirty}\n onToggleDelete={onToggleDelete}\n onNavigateToRow={onFkNavigate}\n />\n\n {/* Pagination footer */}\n <div className=\"flex items-center justify-between border-t border-border px-3 py-1.5 text-xs text-muted-foreground\">\n <div className=\"flex items-center gap-2\">\n <span>Rows per page</span>\n <select\n value={pageSize}\n onChange={(e) => {\n setPageSize(Number(e.target.value));\n setPage(1);\n }}\n className=\"h-6 rounded border border-border bg-background px-1 text-xs outline-none focus:ring-1 focus:ring-ring\"\n >\n {PAGE_SIZES.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"flex items-center gap-1\">\n <span className=\"mr-2\">\n Page {page} of {totalPages}\n </span>\n <PagerButton\n disabled={page <= 1}\n onClick={() => setPage(1)}\n icon={<IconChevronsLeft className=\"h-3.5 w-3.5\" />}\n />\n <PagerButton\n disabled={page <= 1}\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n icon={<IconChevronLeft className=\"h-3.5 w-3.5\" />}\n />\n <PagerButton\n disabled={page >= totalPages}\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\n icon={<IconChevronRight className=\"h-3.5 w-3.5\" />}\n />\n <PagerButton\n disabled={page >= totalPages}\n onClick={() => setPage(totalPages)}\n icon={<IconChevronsRight className=\"h-3.5 w-3.5\" />}\n />\n </div>\n </div>\n\n {/* Row side panel */}\n {panel && (\n <RowSidePanel\n schema={schema}\n mode={panel.mode}\n row={panel.pk ? originalRows.get(panel.pk) : undefined}\n staged={panel.pk ? changeset.edits.get(panel.pk) : undefined}\n onClose={() => setPanel(null)}\n onSave={(values) => {\n if (panel.mode === \"insert\") {\n changeset.addRow(values);\n } else if (panel.pk) {\n changeset.setCells(panel.pk, values);\n }\n }}\n />\n )}\n\n {/* Destructive commit confirmation */}\n {confirmDelete && (\n <ConfirmModal\n title=\"Commit deletions?\"\n body={`${changeset.deletedKeys.size} row${\n changeset.deletedKeys.size === 1 ? \"\" : \"s\"\n } will be permanently deleted along with any other pending changes. This cannot be undone.`}\n confirmLabel=\"Delete and commit\"\n destructive\n onCancel={() => setConfirmDelete(false)}\n onConfirm={() => void handleCommit()}\n />\n )}\n\n {/* Toast */}\n {toast &&\n typeof document !== \"undefined\" &&\n createPortal(\n <div className=\"fixed bottom-4 right-4 z-[500] flex items-center gap-2 rounded-md border border-border bg-card px-3 py-2 text-xs text-foreground shadow-lg\">\n <IconCheck className=\"h-4 w-4 text-emerald-500\" />\n {toast}\n </div>,\n document.body,\n )}\n </div>\n );\n}\n\n// ─── Small UI atoms ────────────────────────────────────────────────────────\n\nfunction ToolbarButton({\n icon,\n label,\n onClick,\n primary,\n}: {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n primary?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs\",\n primary\n ? \"bg-primary text-primary-foreground hover:bg-primary/90\"\n : \"border border-border text-muted-foreground hover:text-foreground\",\n )}\n >\n {icon}\n {label}\n </button>\n );\n}\n\nfunction PagerButton({\n disabled,\n onClick,\n icon,\n}: {\n disabled: boolean;\n onClick: () => void;\n icon: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n className=\"rounded border border-border p-1 text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n {icon}\n </button>\n );\n}\n\nfunction PreviewSqlButton({\n onPreview,\n sql,\n onClear,\n error,\n}: {\n onPreview: () => void;\n sql: string[] | null;\n onClear: () => void;\n error: string | null;\n}) {\n return (\n <Popover\n open={sql !== null}\n onOpenChange={(o) => {\n if (!o) onClear();\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n onClick={onPreview}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <IconCode className=\"h-3.5 w-3.5\" />\n Preview SQL\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-[34rem] p-0\">\n <div className=\"border-b border-border px-3 py-2 text-xs font-medium text-foreground\">\n Preview SQL\n </div>\n <div className=\"max-h-80 overflow-auto p-3\">\n {error ? (\n <div className=\"text-xs text-destructive\">{error}</div>\n ) : sql && sql.length > 0 ? (\n <pre className=\"whitespace-pre-wrap break-all font-mono text-[11px] leading-relaxed text-foreground\">\n {sql.join(\";\\n\")}\n </pre>\n ) : (\n <div className=\"text-xs text-muted-foreground\">\n No statements to run.\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction ConfirmModal({\n title,\n body,\n confirmLabel,\n destructive,\n onCancel,\n onConfirm,\n}: {\n title: string;\n body: string;\n confirmLabel: string;\n destructive?: boolean;\n onCancel: () => void;\n onConfirm: () => void;\n}) {\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onCancel();\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onCancel]);\n\n if (typeof document === \"undefined\") return null;\n return createPortal(\n <div className=\"fixed inset-0 z-[450] flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-black/40\" onClick={onCancel} />\n <div className=\"relative w-full max-w-sm rounded-lg border border-border bg-card p-4 shadow-xl\">\n <div className=\"mb-1 flex items-center gap-2\">\n {destructive && (\n <IconAlertTriangle className=\"h-4 w-4 text-destructive\" />\n )}\n <h2 className=\"text-sm font-semibold text-foreground\">{title}</h2>\n </div>\n <p className=\"mb-4 text-xs text-muted-foreground\">{body}</p>\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"rounded-md px-3 py-1.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={onConfirm}\n className={cn(\n \"rounded-md px-3 py-1.5 text-xs font-medium text-primary-foreground\",\n destructive\n ? \"bg-destructive hover:bg-destructive/90\"\n : \"bg-primary hover:bg-primary/90\",\n )}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n </div>,\n document.body,\n );\n}\n"]}
@@ -26,6 +26,17 @@ export interface DbExecConfig {
26
26
  export declare function getDatabaseUrl(fallback?: string): string;
27
27
  /** Same per-app resolution for DATABASE_AUTH_TOKEN (used by Turso/libsql). */
28
28
  export declare function getDatabaseAuthToken(): string | undefined;
29
+ /**
30
+ * Database URL to use for migrations — identical to DATABASE_URL but with the
31
+ * Neon connection-pooler suffix stripped. Neon's PgBouncer runs in transaction
32
+ * mode, which resets session-level ownership after each statement and causes
33
+ * `ALTER TABLE … ADD COLUMN` to fail with "must be owner of table <x>" even
34
+ * when the connecting role owns it. The direct endpoint bypasses PgBouncer so
35
+ * DDL honours the role's actual ownership.
36
+ *
37
+ * Non-Neon URLs and already-direct Neon URLs are returned unchanged.
38
+ */
39
+ export declare function getMigrationDatabaseUrl(): string;
29
40
  export declare function isLocalSqliteUrl(url: string): boolean;
30
41
  export declare function prepareLocalSqliteUrl(url: string): Promise<string>;
31
42
  export declare function sqliteFilenameFromUrl(url: string): string;
@@ -127,6 +138,14 @@ export declare function pgPoolOptions(url: string): Record<string, unknown>;
127
138
  * proceed when one connection is busy.
128
139
  */
129
140
  export declare function neonPoolMax(): number;
141
+ /**
142
+ * Render any rejection reason as a readable message. The Neon serverless
143
+ * driver surfaces WebSocket failures as raw DOM-style ErrorEvent objects (not
144
+ * Error instances), which stringify uselessly as "[object ErrorEvent]" — pull
145
+ * the message off the event (or its nested `.error`) instead so logs carry
146
+ * actual context.
147
+ */
148
+ export declare function describeDbError(err: unknown): string;
130
149
  export declare function attachNeonPoolErrorLogger(pool: unknown, label?: string): void;
131
150
  export declare function createDbExec(config?: DbExecConfig): Promise<DbExec>;
132
151
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"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"}
package/dist/db/client.js CHANGED
@@ -43,6 +43,26 @@ export function getDatabaseAuthToken() {
43
43
  }
44
44
  return process.env.DATABASE_AUTH_TOKEN;
45
45
  }
46
+ /**
47
+ * Database URL to use for migrations — identical to DATABASE_URL but with the
48
+ * Neon connection-pooler suffix stripped. Neon's PgBouncer runs in transaction
49
+ * mode, which resets session-level ownership after each statement and causes
50
+ * `ALTER TABLE … ADD COLUMN` to fail with "must be owner of table <x>" even
51
+ * when the connecting role owns it. The direct endpoint bypasses PgBouncer so
52
+ * DDL honours the role's actual ownership.
53
+ *
54
+ * Non-Neon URLs and already-direct Neon URLs are returned unchanged.
55
+ */
56
+ export function getMigrationDatabaseUrl() {
57
+ const url = getDatabaseUrl();
58
+ // Neon pooler hostname: ep-<id>-pooler.<region>.<cloud>.neon.tech
59
+ // Direct hostname: ep-<id>.<region>.<cloud>.neon.tech
60
+ // The region between `-pooler.` and `.neon.tech` can contain multiple
61
+ // dot-separated labels (e.g. `c-7.us-east-1.aws`), so the matched segment
62
+ // must allow dots — `[a-z0-9.-]+` — not just a single label. Anchoring on the
63
+ // stable `.neon.tech` suffix keeps this from touching non-Neon hosts.
64
+ return url.replace(/-pooler(\.[a-z0-9.-]+\.neon\.tech)/, "$1");
65
+ }
46
66
  export function isLocalSqliteUrl(url) {
47
67
  return url === "" || url.startsWith("file:") || !url.includes("://");
48
68
  }
@@ -435,6 +455,27 @@ export function pgPoolOptions(url) {
435
455
  export function neonPoolMax() {
436
456
  return isServerlessRuntime() ? 2 : 10;
437
457
  }
458
+ /**
459
+ * Render any rejection reason as a readable message. The Neon serverless
460
+ * driver surfaces WebSocket failures as raw DOM-style ErrorEvent objects (not
461
+ * Error instances), which stringify uselessly as "[object ErrorEvent]" — pull
462
+ * the message off the event (or its nested `.error`) instead so logs carry
463
+ * actual context.
464
+ */
465
+ export function describeDbError(err) {
466
+ if (err instanceof Error)
467
+ return err.message;
468
+ if (err && typeof err === "object") {
469
+ const evt = err;
470
+ const msg = evt.message ?? evt.error?.message;
471
+ if (typeof msg === "string" && msg)
472
+ return msg;
473
+ if (evt.type === "error") {
474
+ return "WebSocket ErrorEvent (connection failed; no message attached)";
475
+ }
476
+ }
477
+ return String(err);
478
+ }
438
479
  export function attachNeonPoolErrorLogger(pool, label = "db/neon") {
439
480
  if (!pool || typeof pool !== "object")
440
481
  return;
@@ -445,7 +486,7 @@ export function attachNeonPoolErrorLogger(pool, label = "db/neon") {
445
486
  return;
446
487
  loggedNeonPools.add(pool);
447
488
  withEvents.on("error", (err) => {
448
- console.warn(`[${label}] pool error (will reconnect on next query):`, err instanceof Error ? err.message : err);
489
+ console.warn(`[${label}] pool error (will reconnect on next query):`, describeDbError(err));
449
490
  });
450
491
  // Attach a persistent 'error' listener to EVERY client for its whole lifetime.
451
492
  //
@@ -468,7 +509,7 @@ export function attachNeonPoolErrorLogger(pool, label = "db/neon") {
468
509
  if (typeof clientEvents.on !== "function")
469
510
  return;
470
511
  clientEvents.on("error", (err) => {
471
- console.warn(`[${label}] client connection error (connection discarded, next query reconnects):`, err instanceof Error ? err.message : err);
512
+ console.warn(`[${label}] client connection error (connection discarded, next query reconnects):`, describeDbError(err));
472
513
  });
473
514
  });
474
515
  }