{{ message }}
Tags: synle/sqlui-native
Tags
feat(migration): support Salesforce target + UPSERT + disable-FK opti… …ons (#3) - Wires the `sfdc` case into MigrationBox so Salesforce-as-target is no longer a no-op. Schema step emits an explanatory comment (SObjects pre-exist in the org); data step generates `conn.sobject('<Name>').create([...])` via the existing Salesforce `getBulkInsert`. - Adds a "Use UPSERT" checkbox + key-column picker. Routes RDBMS targets to a new `getBulkUpsert` helper that emits ON CONFLICT (sqlite / postgres), ON DUPLICATE KEY UPDATE (mysql / mariadb), or MERGE (mssql) — so re-running a migration is idempotent. - Adds a "Disable foreign-key constraints" checkbox. New `getForeignKeyToggle` helper returns dialect-specific session toggles (`PRAGMA foreign_keys` for sqlite, `SET FOREIGN_KEY_CHECKS` for mysql/mariadb, `session_replication_role` for postgres, `sp_msforeachtable` for mssql) that wrap the data step. - Regression coverage: 20 new tests across the script generators and the MigrationBox top-level `generateMigrationScript`. Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
test(e2e): skip github-pages-links assertion when Pages 404 (#1) The github-pages-links.spec.ts smoke test waits for `#download-buttons-container a.btn` on the live GitHub Pages site. On a fresh repo (or any repo whose Pages site has not yet been deployed) the goto resolves to a 404 page that has no such element, and the 15s waitForSelector times out — failing the release E2E suite and triggering a rollback. That rollback then also prevents Pages from being deployed, so the test never has a chance to succeed: classic chicken-and-egg. Detect the 404 from the goto response and short-circuit with a console.warn (same shape as the existing "all binaries missing" short-circuit). Once Pages is published, the test resumes its normal full assertion path. Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
test: cover import/export flow (ImportModal, utils, file upload) (#36) ## Summary Expands frontend + server-side test coverage for the import/export flow on top of PR #34. - **ImportModal component** (16 new tests, new file `src/frontend/components/ImportModal/index.spec.tsx`): validation states (empty, invalid JSON, unknown `_type`, single-object wrapping), Import-mode radio toggle, hidden-file-input loading, drag-and-drop happy/error paths (single .json, non-.json, multi-file, empty-drop), and button-disabled assertions. Uses a CodeEditorBox textarea shim and a deterministic FileReader mock keyed by a WeakMap of seeded contents. - **importExportUtils** (12 new tests in `src/frontend/utils/importExportUtils.spec.ts`): Postman edge cases (empty collection, 3-level nesting, null auth, raw non-JSON body, string URL, urlencoded body, v2.0 schema), HAR with no entries, Postman-export edge cases (zero requests, special-char variables, disabled-variable drop, orphan-folder routing), and a full round-trip stability test (import -> export -> re-import preserves count/methods/folders). - **/api/file server stress** (4 new tests in `src/sqlui-server/server.spec.ts`): ~1MB payload (no truncation, spot-checked start/middle/end), utf-8 unicode/special-char round-trip, three sequential uploads with no state leak. - **Platform wrappers** (7 new tests, new file `src/frontend/platform/file-upload.spec.ts`): exercises `readFileContent` on `browser.ts`, `electron.ts` (both fetch-fallback and `fs.readFileSync` paths), and `tauri.ts` (sidecar port + relative-URL fallbacks). Verifies FormData field name `file`, POST method, target URL, and that fetch rejections propagate. Test counts: - Total new tests: ~39 - Total existing tests still passing locally: 1583 (`npm run test-ci`). No production code is modified; tests only. No bugs found in production code during this pass. ## Test plan - [x] `npx vitest run src/frontend/components/ImportModal/index.spec.tsx` -> 16/16 pass - [x] `npx vitest run src/frontend/utils/importExportUtils.spec.ts` -> all pass (incl. round-trip) - [x] `npx vitest run src/frontend/platform/file-upload.spec.ts` -> 7/7 pass - [x] `npx vitest run src/sqlui-server/server.spec.ts` -> 57/57 pass - [x] `npm run test-ci` -> 1583/1583 pass - [x] `npm run format` applied - [x] No lint/format/typecheck regressions versus main (pre-existing `package.json` typecheck warnings only) Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
ci(portal): ship only sqlui-portal.tar.gz; drop versioned filename (#30)
## Summary
The build_portal job was uploading two byte-identical files to every
release: \`sqlui-portal-<version>.tar.gz\` and \`sqlui-portal.tar.gz\`
(alias). The versioned filename was redundant.
Pinning a specific version still works — just put the tag in the URL
path; the filename stays constant:
\`\`\`
releases/download/v3.1.4/sqlui-portal.tar.gz # pinned
releases/latest/download/sqlui-portal.tar.gz # always latest
\`\`\`
## Changes
- \`mv\` (not \`cp\`) the build output to \`sqlui-portal.tar.gz\` and
upload just that file
- \`EXPECTED_RELEASE_ASSETS\`: 7 → 6
- Release-notes template: pin URL uses the same filename with the tag in
the path
- README: pin-version snippet drops \`-\${VERSION}\` from the filename
## Test plan
- [ ] CI green
- [ ] Next official release ships 6 assets (5 desktop + 1 portal)
- [ ] \`releases/download/v3.1.5/sqlui-portal.tar.gz\` and
\`releases/latest/download/sqlui-portal.tar.gz\` both work
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
fix(portal): default --host to 0.0.0.0 for LAN sharing (3.1.4) (#23) ## Summary - Default the `sqlui-portal` bind host to `0.0.0.0` so the portal is reachable on the LAN out of the box — primary use case is sharing a running portal with teammates / other devices. - Boxed banner now shows the loopback URL as the primary `URL` and the discovered LAN IP as a second `LAN` line (cleaner than `http://0.0.0.0:port`). - Pass `--host 127.0.0.1` to restrict to loopback only. - Bump to 3.1.4 (package.json, tauri.conf.json, README pin example, package-lock.json). ## Test plan - [ ] CI green - [ ] `npm run build:portal && ./dist/portal/sqlui-portal ./tmp.sqlite` → banner shows both `URL` (127.0.0.1) and `LAN` (LAN IP) lines, portal reachable from another device on the LAN - [ ] `sqlui-portal --host 127.0.0.1 ./tmp.sqlite` → only `URL` line, not reachable from LAN - [ ] `sqlui-portal --help` reflects the new default 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
fix(portal): defer storageLocation + sync writes + boxed banner + por… …tal-tinted top bar (3.1.3) (#22) Triage uncovered two interlocking bugs in the released portal artifact, plus a write-not-flushing regression. Polish on top adds the storage-dir CLI flag (--home-dir / --config-path / --use-desktop-storage), boxed startup banner, portal-tinted AppBar (MUI primary blue + enableColorOnDark), server PID in the title bar, app version in banner + --version flag, and expanded help triggers (case-insensitive, including bare ?, /help, etc.). Single .tar.gz now serves both curl|tar and npx flows; versionless alias for stable URLs.
fix(portal): isolate storage + serialize JSON writes + add npx varian… …t (3.1.2) (#21) Triage of a user-reported "PersistentStorageJsonFile.ts:parse SyntaxError" uncovered two real bugs hiding behind 3.1.0 / 3.1.1: - Storage isolation in portal mode never worked — Vite/Rollup hoists imports, so portal.ts's env-set ran AFTER PersistentStorageJsonFile had already captured baseDir to ~/.sqlui-native. Real users wrote to the desktop dir while stdout claimed otherwise. Fixed via lazy getStorageDir() resolution + bash launcher env default. - Concurrent fs.promises.writeFile calls from setData interleaved on disk, producing classic JSON corruption. Added per-file write queue. Plus: npx tarball variant (dist/sqlui-portal-<v>.tgz with proper npm package layout) shipping alongside the existing tar.gz/zip. README documents both flows. EXPECTED_RELEASE_ASSETS bumped 7 → 8.
ci(release): publish sqlui-portal tarball + zip as release assets (3.… …1.1) (#20) 3.1.0 shipped portal mode but the GitHub Release only attached desktop installers. This wires npm run build:portal into package.yml so every official release also publishes sqlui-portal-<version>.tar.gz and .zip alongside the installers. - New build_portal job in package.yml (Linux runner, single artifact pair). - EXPECTED_RELEASE_ASSETS bumped 5 → 7; rollback + publish wait on build_portal. - Release notes template gains a Portal row with a curl|tar one-liner. - README quick-start with curl|tar (pinned + latest) and Windows .zip path. - Bump 3.1.0 → 3.1.1.
feat(sidecar): embed frontend assets in desktop sidecar bundle (3.1.0…
…) (#19)
Reuses the portal's asset-embed plugin in the sidecar config so the desktop
sidecar bundle ships with the React frontend baked in. The sidecar gains
`mountStaticAssets` capability — same code path as portal mode, just two callers.
- vite-plugin-embed-frontend: extract reusable emitEmbeddedAssetsPlugin;
walker skips sqlui-server*.{js,json} (avoids self-embedding) and node_modules.
- vite.sqlui-server.sidecar.config.ts: emits build/sqlui-server-assets.json.
- vite.sqlui-portal.config.ts: switched to the shared plugin.
- src/sqlui-server/index.ts: decodes sibling JSON at startup → mountStaticAssets.
- scripts/prepare-sidecar.js: copies the assets JSON into src-tauri/resources/.
Plus tests + docs:
- Extracted pure portal helpers into portalHelpers.ts so they can be
unit-tested without triggering portal.ts's IIFE main.
- 17 new vitest cases (portalHelpers + embed walker).
- README: new Portal Mode section. CLAUDE.md: Three Runtime Modes.
CI / CD - Format code
PreviousNext
