{ "name": "flo-desktop", "version": "3.13.23", "description": "Free, open-source, offline-first restaurant POS with KDS, SQLite, and thermal printer support.", "engines": { "node": ">=22.12.0" }, "main": "dist/main/index.js", "scripts": { "clean": "node kill-ports.js 3001 3002 3003", "predev": "", "dev": "npm run clean && npm run build:frontend && npm run build && electron .", "dev:restart": "bash scripts/dev/restart.sh", "dev:reset": "bash scripts/dev/nuclear-reset.sh", "dev:frontend": "cd frontend && npm run dev", "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc && node scripts/copy-runtime-assets.cjs", "lint:backend": "oxlint main/ shared/", "lint": "npm run lint:backend && npm --prefix frontend run lint", "lint:budget": "node scripts/ci/check-lint-budget.cjs", "format": "npm run format:backend && npm --prefix frontend run format", "format:backend": "oxfmt \"main/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"shared/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"scripts/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"tests/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"dev-server.js\" \"kill-ports.js\" \"lint-staged.config.mjs\" \".husky/install.mjs\"", "format:check": "npm run format:check:backend && npm --prefix frontend run format:check", "format:check:backend": "oxfmt --check \"main/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"shared/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"scripts/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"tests/**/*.{js,jsx,ts,tsx,mjs,cjs,mts,cts}\" \"dev-server.js\" \"kill-ports.js\" \"lint-staged.config.mjs\" \".husky/install.mjs\"", "format:check:changed": "node scripts/ci/check-changed-format.cjs", "docs:check": "npm run docs:check:structure && npm run docs:check:policy", "docs:check:structure": "markdownlint-cli2 && node scripts/docs/check-docs.cjs --links --index", "docs:check:policy": "node scripts/docs/check-docs.cjs --policy", "docs:demo": "node scripts/docs/demo-server.cjs", "docs:screenshots": "node scripts/docs/capture-screenshots.cjs", "build:frontend": "node scripts/build-frontend.cjs", "showcase:record": "node scripts/demo/record-showcase.cjs", "showcase:verify": "node scripts/demo/verify-showcase.cjs", "build:all-platforms": "npm run build:frontend && npm run build && electron-builder --win --mac --linux", "postinstall": "install-electron && electron-builder install-app-deps && npm run verify:electron && node scripts/prepare-snap-build.cjs", "prepare": "node .husky/install.mjs", "verify:electron": "node scripts/verify-electron-runtime.cjs", "verify:release-artifacts": "node scripts/assert-release-artifact-names.cjs", "changelog": "npx --yes git-cliff@2.8.0 --unreleased", "changelog:generate": "npx --yes git-cliff@2.8.0 --prepend CHANGELOG.md", "build:win": "npm run build:frontend && npm run build && electron-builder --win", "build:appx": "npm run build:frontend && npm run build && electron-builder --win appx --x64 --arm64 --config.npmRebuild=false", "build:mac": "npm run build:frontend && npm run build && electron-builder --mac", "build:mas": "MAS_BUILD=1 npm run build:frontend && MAS_BUILD=1 npm run build && MAS_BUILD=1 electron-builder --mac mas --universal --publish never", "build:mas-dev": "MAS_BUILD=1 npm run build:frontend && MAS_BUILD=1 npm run build && MAS_BUILD=1 electron-builder --mac masDev", "build:linux": "npm run build:frontend && npm run build && electron-builder --linux", "sourcemaps:posthog": "node scripts/posthog-sourcemaps.cjs", "release:linux": "npm run build:frontend && npm run build && npm run sourcemaps:posthog && electron-builder --linux --publish never", "release:mac": "npm run build:frontend && npm run build && npm run sourcemaps:posthog && electron-builder --mac --publish never", "release:win": "npm run build:frontend && npm run build && npm run sourcemaps:posthog && electron-builder --win --publish never", "pack": "electron-builder --dir && node scripts/mark-unpacked-artifact.cjs", "pretest": "npm run test:script-coverage && node scripts/run-test.cjs npm run test:payment-methods-split && node scripts/run-test.cjs npm run test:unified-split-check-ux && node scripts/run-test.cjs npm run test:release-regressions && node scripts/run-test.cjs npm run test:product-variants-db && node scripts/run-test.cjs npm run test:product-variants-api", "start": "electron .", "rebuild": "HOME=~/.electron-gyp node-gyp rebuild --target=$(node -p \"require('./node_modules/electron/package.json').version\") --arch=$(node -p \"process.arch\") --dist-url=https://electronjs.org/headers --runtime=electron --directory node_modules/better-sqlite3", "test": "node scripts/run-test.cjs npm run test:smoke && node scripts/run-test.cjs npm run test:server-port-collision && node scripts/run-test.cjs npm run test:kds-integration && node scripts/run-test.cjs npm run test:kds-broadcast-grouping && node scripts/run-test.cjs npm run test:kds-contract && node scripts/run-test.cjs npm run test:kds-frontend-conflict && node scripts/run-test.cjs npm run test:kds-window-hardening && node scripts/run-test.cjs npm run test:electron-api-contract && node scripts/run-test.cjs npm run test:titlebar-window-options && node scripts/run-test.cjs npm run test:update-ipc-sender-validation && node scripts/run-test.cjs npm run test:settings-ipc-rbac && node scripts/run-test.cjs npm run test:menu-surface && node scripts/run-test.cjs npm run test:pos-keyboard-shortcuts && node scripts/run-test.cjs npm run test:window-readiness && node scripts/run-test.cjs npm run test:window-load-retry && node scripts/run-test.cjs npm run test:cors && node scripts/run-test.cjs npm run test:csp-lan && node scripts/run-test.cjs npm run test:release-config && node scripts/run-test.cjs npm run test:update-state && node scripts/run-test.cjs npm run test:update-ui && node scripts/run-test.cjs npm run test:update-channel && node scripts/run-test.cjs npm run test:telemetry && node scripts/run-test.cjs npm run test:telemetry-install-provenance && node scripts/run-test.cjs npm run test:country-provenance && node scripts/run-test.cjs npm run test:first-run && node scripts/run-test.cjs npm run test:phase7-setup-i18n && node scripts/run-test.cjs npm run test:security && node scripts/run-test.cjs npm run test:jwt-secret-cache-identity && node scripts/run-test.cjs npm run test:jwt-secret-persist-before-cache && node scripts/run-test.cjs npm run test:jwt-secret-safe-storage && node scripts/run-test.cjs npm run test:staff-authz && node scripts/run-test.cjs npm run test:self-service-credentials && node scripts/run-test.cjs npm run test:orders-authz && node scripts/run-test.cjs npm run test:order-item-cancel-restore && node scripts/run-test.cjs npm run test:order-item-edit && node scripts/run-test.cjs npm run test:item-price-override && node scripts/run-test.cjs npm run test:offline-mode && node scripts/run-test.cjs npm run test:product-variants-orders && node scripts/run-test.cjs npm run test:addon-inventory-pos-surface && node scripts/run-test.cjs npm run test:addon-inventory-orders && node scripts/run-test.cjs npm run test:addon-inventory-lifecycle && node scripts/run-test.cjs npm run test:order-totals-recompute && node scripts/run-test.cjs npm run test:issue-718-whatsapp-order-status && node scripts/run-test.cjs npm run test:order-audit-log && node scripts/run-test.cjs npm run test:authz-phase3 && node scripts/run-test.cjs npm run test:authorization-permissions && node scripts/run-test.cjs npm run test:auth-ui-deterministic && node scripts/run-test.cjs npm run test:desktop-trailing-slash-routing && node scripts/run-test.cjs npm run test:customer-auth && node scripts/run-test.cjs npm run test:customer-soft-reactivate-bindings && node scripts/run-test.cjs npm run test:customer-pagination && node scripts/run-test.cjs npm run test:customer-top-items && node scripts/run-test.cjs npm run test:server-app-server-role && node scripts/run-test.cjs npm run test:backup && node scripts/run-test.cjs npm run test:issue-278-fail-closed-db && node scripts/run-test.cjs npm run test:recovery-cloud && node scripts/run-test.cjs npm run test:cloud-account-status && node scripts/run-test.cjs npm run test:cloud-live-orders-batching && node scripts/run-test.cjs npm run test:printer && node scripts/run-test.cjs npm run test:printing-settings && node scripts/run-test.cjs npm run test:printer-width-refresh && node scripts/run-test.cjs npm run test:printer-migrations && node scripts/run-test.cjs npm run test:printer-text-size && node scripts/run-test.cjs npm run test:print-parity && node scripts/run-test.cjs npm run test:delivery-slip && node scripts/run-test.cjs npm run test:delivery-address && node scripts/run-test.cjs npm run test:thermal-capabilities && node scripts/run-test.cjs npm run test:raster && node scripts/run-test.cjs npm run test:merchant-print-templates && node scripts/run-test.cjs npm run test:merchant-template-transfer && node scripts/run-test.cjs npm run test:print-document && node scripts/run-test.cjs npm run test:menu-printing && node scripts/run-test.cjs npm run test:print-kernel && node scripts/run-test.cjs npm run test:translations && node scripts/run-test.cjs npm run test:print-labels && node scripts/run-test.cjs npm run test:locale-chunks && node scripts/run-test.cjs npm run test:rtl-foundation && node scripts/run-test.cjs npm run test:rtl-setup-auth-settings && node scripts/run-test.cjs npm run test:rtl-dashboard-pos-common && node scripts/run-test.cjs npm run test:rtl-kds-server-whatsapp && node scripts/run-test.cjs npm run test:phone && node scripts/run-test.cjs npm run test:country-localization && node scripts/run-test.cjs npm run test:e2e-argentina-flow && node scripts/run-test.cjs npm run test:charges && node scripts/run-test.cjs npm run test:charges-engine && node scripts/run-test.cjs npm run test:currency && node scripts/run-test.cjs npm run test:tax-engine && node scripts/run-test.cjs npm run test:tax-components && node scripts/run-test.cjs npm run test:tax-pack-catalog && node scripts/run-test.cjs npm run test:tax-pack-management && node scripts/run-test.cjs npm run test:manual-tax-config && node scripts/run-test.cjs npm run test:legacy-tax-pack-digest && node scripts/run-test.cjs npm run test:community-tax-packs && node scripts/run-test.cjs npm run test:support-ticket && node scripts/run-test.cjs npm run test:customer-phone-search && node scripts/run-test.cjs npm run test:phone-search-integration && node scripts/run-test.cjs npm run test:orders-search && node scripts/run-test.cjs npm run test:settings-search && node scripts/run-test.cjs npm run test:orders-layout-settings && node scripts/run-test.cjs npm run test:pos-catalog-sort && node scripts/run-test.cjs npm run test:pos-sort-settings && node scripts/run-test.cjs npm run test:receipt-column-width && node scripts/run-test.cjs npm run test:receipt-column-oracle && node scripts/run-test.cjs npm run test:notes-validation && node scripts/run-test.cjs npm run test:receipt-printing && node scripts/run-test.cjs npm run test:cancel-override && node scripts/run-test.cjs npm run test:refunds && node scripts/run-test.cjs npm run test:async-refund-pin-event-loop && node scripts/run-test.cjs npm run test:refund-completed-orders && node scripts/run-test.cjs npm run test:cash-closures && node scripts/run-test.cjs npm run test:cash-sessions && node scripts/run-test.cjs npm run test:kitchen-addons && node scripts/run-test.cjs npm run test:kot-order-notes && node scripts/run-test.cjs npm run test:pos-info-network-ranking && node scripts/run-test.cjs npm run test:order-item-addons && node scripts/run-test.cjs npm run test:issue-125-addon-reads && node scripts/run-test.cjs npm run test:windows-country-code-crash && node scripts/run-test.cjs npm run test:reports-insights && node scripts/run-test.cjs npm run test:reports-daily-stats-table-turn && node scripts/run-test.cjs npm run test:timezone-report-boundaries && node scripts/run-test.cjs npm run test:business-date && node scripts/run-test.cjs npm run test:dashboard-business-date && node scripts/run-test.cjs npm run test:sequence && node scripts/run-test.cjs npm run test:order-numbering-settings && node scripts/run-test.cjs npm run test:integration-happy && node scripts/run-test.cjs npm run test:integration-order-hold-payment && node scripts/run-test.cjs npm run test:integration-tax && node scripts/run-test.cjs npm run test:integration-payments && node scripts/run-test.cjs npm run test:kitchen-delivery-enforcement && node scripts/run-test.cjs npm run test:issue-214 && node scripts/run-test.cjs npm run test:issue-214-auth && node scripts/run-test.cjs npm run test:issue-214-migration && node scripts/run-test.cjs npm run test:issue-255 && node scripts/run-test.cjs npm run test:cart-variant-identity && node scripts/run-test.cjs npm run test:cart-price-override && node scripts/run-test.cjs npm run test:product-variants-screen && node scripts/run-test.cjs npm run test:variant-pos-surface && node scripts/run-test.cjs npm run test:issue-788-order-attempt-storage && node scripts/run-test.cjs npm run test:integration-lifecycle && node scripts/run-test.cjs npm run test:integration-reconciliation && node scripts/run-test.cjs npm run test:integration-loyalty && node scripts/run-test.cjs npm run test:integration-discount && node scripts/run-test.cjs npm run test:loyalty-toggle && node scripts/run-test.cjs npm run test:discount-system && node scripts/run-test.cjs npm run test:integration-discount-settings && node scripts/run-test.cjs npm run test:integration-loyalty-global && node scripts/run-test.cjs npm run test:issue-248-csv && node scripts/run-test.cjs npm run test:integration-loyalty-redemption && node scripts/run-test.cjs npm run test:bills-print-api && node scripts/run-test.cjs npm run test:issue-24 && node scripts/run-test.cjs npm run test:issue-134-routing && node scripts/run-test.cjs npm run test:server-app-station-routing && node scripts/run-test.cjs npm run test:issue-1442 && node scripts/run-test.cjs npm run test:issue-134-mgmt && node scripts/run-test.cjs npm run test:issue-137-barcode && node scripts/run-test.cjs npm run test:issue-244-product-addon-links && node scripts/run-test.cjs npm run test:issue-245-246-addon-groups && node scripts/run-test.cjs npm run test:issue-247-catalog-invariants && node scripts/run-test.cjs npm run test:issue-250-catalog-perf && node scripts/run-test.cjs npm run test:issue-252 && node scripts/run-test.cjs npm run test:inventory-ledger && node scripts/run-test.cjs npm run test:issue-printing-and-kds-resilience && node scripts/run-test.cjs npm run test:issue-258-bill-pagination && node scripts/run-test.cjs npm run test:issue-265-morocco-profile && node scripts/run-test.cjs npm run test:issue-266-currency-symbol-print && node scripts/run-test.cjs npm run test:tables-string-ids && node scripts/run-test.cjs npm run test:issue-646-floor-management && node scripts/run-test.cjs npm run test:held-orders && node scripts/run-test.cjs npm run test:product-images && node scripts/run-test.cjs npm run test:schema-health && node scripts/run-test.cjs npm run test:migration-registry && node scripts/run-test.cjs npm run test:upgrade-path && node scripts/run-test.cjs npm run test:upgrade-matrix-harness && node scripts/run-test.cjs npm run test:migration-v56-v57 && node scripts/run-test.cjs npm run test:migration-v71-repair && node scripts/run-test.cjs npm run test:migration-v80-cash-drawer-pulse && node scripts/run-test.cjs npm run test:migration-v81-cash-closures && node scripts/run-test.cjs npm run test:master-pin && node scripts/run-test.cjs npm run test:google-drive && node scripts/run-test.cjs npm run test:google-drive-qr-menu && node scripts/run-test.cjs npm run test:database-tools-api && node scripts/run-test.cjs npm run test:phone-validation && node scripts/run-test.cjs npm run test:phone-migration && node scripts/run-test.cjs npm run test:issue-133-kds-kot-toggles && node scripts/run-test.cjs npm run test:whatsapp-schema && node scripts/run-test.cjs npm run test:whatsapp-service && node scripts/run-test.cjs npm run test:whatsapp-middleware && node scripts/run-test.cjs npm run test:issue-127-password-recovery && node scripts/run-test.cjs npm run test:dev-tooling && node scripts/run-test.cjs npm run test:windows-uninstaller && node scripts/run-test.cjs npm run test:shutdown-lifecycle && node scripts/run-test.cjs npm run test:redos-hardening && node scripts/run-test.cjs npm run test:startup-cache && node scripts/run-test.cjs npm run test:service-worker && node scripts/run-test.cjs npm run test:issue-389-timezone-override && node scripts/run-test.cjs npm run test:issue-390-locale-preference-invariants && node scripts/run-test.cjs npm run test:issue-475-picker-highlight && node scripts/run-test.cjs npm run test:theme-mode-settings && node scripts/run-test.cjs npm run test:theme-fouc-script && node scripts/run-test.cjs npm run test:ui-regressions-621-623-626 && node scripts/run-test.cjs npm run test:issue-zero-balance-settlement && node scripts/run-test.cjs npm run test:daily-sales-export && node scripts/run-test.cjs npm run test:daily-invoices-export && node scripts/run-test.cjs npm run test:customer-sales-export && node scripts/run-test.cjs npm run test:card-transaction-id && node scripts/run-test.cjs npm run test:issue-terminal-state-guards && node scripts/run-test.cjs npm run test:issue-exact-balance-settlement && node scripts/run-test.cjs npm run test:financial-safety-remediation && node scripts/run-test.cjs npm run test:issue-payload-and-discount-bounds && node scripts/run-test.cjs npm run test:customer-display-config && node scripts/run-test.cjs npm run test:customer-display-settings-route && node scripts/run-test.cjs npm run test:customer-display-pairing && node scripts/run-test.cjs npm run test:customer-display-feed && node scripts/run-test.cjs npm run test:units && node scripts/run-test.cjs npm run test:db-timing && node scripts/run-test.cjs npm run test:supplies-service && node scripts/run-test.cjs npm run test:recipe-order-lifecycle && node scripts/run-test.cjs npm run test:ingredient-cost && node scripts/run-test.cjs npm run test:lint-engine && node scripts/run-test.cjs npm run test:oxc-contributor-checks && node scripts/run-test.cjs npm run test:expenses && node scripts/run-test.cjs npm run test:diagnostics && node scripts/run-test.cjs npm run test:reports-export && node scripts/run-test.cjs npm run test:category-addon-groups && node scripts/run-test.cjs npm run test:addon-inventory-db && node scripts/run-test.cjs npm run test:addon-inventory-api && node scripts/run-test.cjs npm run test:discount-kitchen-approver-identity && node scripts/run-test.cjs npm run test:staff-approvers-directory && node scripts/run-test.cjs npm run test:local-backup && node scripts/run-test.cjs npm run test:status-messages && npm run test:password-policy && npm run test:cloud-password-recovery && node scripts/run-test.cjs npm run test:scheduled-orders && node scripts/run-test.cjs npm run test:newer-db-recovery && node scripts/run-test.cjs npm run test:multi-counter-ordering && node scripts/run-test.cjs npm run test:impact-printer", "test:dev-tooling": "ts-node --transpile-only -P tests/tsconfig.json tests/dev-tooling-scripts.test.ts && npm run test:phase2 && npm run test:runtime-recovery && npm run test:backend-health && npm run test:url-allowlist && npm run test:static-routes", "test:script-coverage": "node scripts/ci/validate-test-script-coverage.cjs && node tests/test-script-coverage.test.cjs && ts-node --transpile-only -P tests/tsconfig.json tests/test-harness-assertions.test.ts", "test:lint-engine": "ts-node --transpile-only -P tests/tsconfig.json tests/lint-engine-parity.test.ts", "test:oxc-contributor-checks": "ts-node --transpile-only -P tests/tsconfig.json tests/oxc-contributor-checks.test.ts", "test:shutdown-lifecycle": "npm run build && node tests/run-electron-node-test.cjs tests/shutdown-lifecycle.test.ts", "test:redos-hardening": "node tests/run-electron-node-test.cjs tests/redos-hardening.test.ts", "test:phase2": "ts-node --transpile-only -P tests/tsconfig.json tests/auth-state-recovery.test.ts && node tests/run-electron-node-test.cjs tests/login-email-normalization.test.ts && node tests/run-electron-node-test.cjs tests/master-pin.test.ts && node tests/run-electron-node-test.cjs tests/manager-pin-verification.test.ts && node tests/run-electron-node-test.cjs tests/async-pin-event-loop.test.ts && node tests/run-electron-node-test.cjs tests/jwt-logout-lifecycle.test.ts && node tests/run-electron-node-test.cjs tests/kds-websocket-revalidation.test.ts && node tests/run-electron-node-test.cjs tests/token-revocation-fail-closed.test.ts && npm run test:cross-server-login-rate-limits && npm run test:pin-quick-switch", "test:pin-quick-switch": "node tests/run-electron-node-test.cjs tests/pin-quick-switch.test.ts", "test:cross-server-login-rate-limits": "node tests/run-electron-node-test.cjs tests/cross-server-login-rate-limits.test.ts", "test:url-allowlist": "ts-node --transpile-only -P tests/tsconfig.json tests/url-allowlist.test.ts", "test:startup-cache": "ts-node --transpile-only -P tests/tsconfig.json tests/startup-cache.test.ts", "test:service-worker": "node tests/service-worker.test.cjs", "test:issue-389-timezone-override": "node tests/run-electron-node-test.cjs tests/issue-389-timezone-override.test.ts", "test:issue-390-locale-preference-invariants": "node tests/run-electron-node-test.cjs tests/issue-390-locale-preference-invariants.test.ts", "test:issue-475-picker-highlight": "ts-node --transpile-only -P tests/tsconfig.json tests/issue-475-bill-template-picker-highlight.test.ts", "test:auth-ui-deterministic": "ts-node --transpile-only -P tests/tsconfig.json tests/auth-ui-deterministic.test.ts", "test:desktop-trailing-slash-routing": "ts-node --transpile-only -P tests/tsconfig.json tests/desktop-trailing-slash-routing.test.ts", "test:cors": "ts-node --transpile-only -P tests/tsconfig.json tests/cors-security.test.ts", "test:csp-lan": "ts-node --transpile-only -P tests/tsconfig.json tests/csp-lan-header.test.ts", "test:smoke": "node tests/run-electron-node-test.cjs tests/smoke-test.test.ts", "test:server-port-collision": "node tests/run-electron-node-test.cjs tests/server-port-collision.test.ts", "test:daily-sales-export": "node tests/run-electron-node-test.cjs tests/daily-sales-export.test.ts", "test:daily-invoices-export": "node tests/run-electron-node-test.cjs tests/daily-invoices-export.test.ts", "test:customer-sales-export": "node tests/run-electron-node-test.cjs tests/customer-sales-export.test.ts", "test:card-transaction-id": "node tests/run-electron-node-test.cjs tests/card-transaction-id.test.ts", "test:reports-export": "node tests/run-electron-node-test.cjs tests/reports-export.test.ts", "test:payment-methods-split": "node tests/run-electron-node-test.cjs tests/payment-methods-split-checks.test.ts", "test:unified-split-check-ux": "ts-node --transpile-only -P tests/tsconfig.json tests/unified-split-check-ux.test.ts", "test:kds-broadcast-grouping": "node tests/run-electron-node-test.cjs tests/kds-broadcast-grouping.test.ts", "test:kds-integration": "node tests/run-electron-node-test.cjs tests/kds-integration.test.ts", "test:kds-contract": "node tests/run-electron-node-test.cjs tests/kds-contract.test.ts", "test:kds-frontend-conflict": "ts-node --transpile-only -P tests/tsconfig.json tests/kds-frontend-conflict.test.ts", "test:kds-window-hardening": "ts-node --transpile-only -P tests/tsconfig.json tests/kds-window-hardening.test.ts", "test:electron-api-contract": "ts-node --transpile-only -P tests/tsconfig.json tests/electron-api-contract.test.ts", "test:titlebar-window-options": "ts-node --transpile-only -P tests/tsconfig.json tests/titlebar-window-options.test.ts", "test:update-ipc-sender-validation": "ts-node --transpile-only -P tests/tsconfig.json tests/update-ipc-sender-validation.test.ts", "test:settings-ipc-rbac": "node tests/run-electron-node-test.cjs tests/settings-ipc-rbac.test.ts", "test:menu-surface": "ts-node --transpile-only -P tests/tsconfig.json tests/menu-surface.test.ts", "test:pos-keyboard-shortcuts": "ts-node --transpile-only -P tests/tsconfig.json tests/pos-keyboard-shortcuts.test.ts", "test:theme-fouc-script": "ts-node --transpile-only -P tests/tsconfig.json tests/theme-fouc-script.test.ts", "test:ui-regressions-621-623-626": "ts-node --transpile-only -P tests/tsconfig.json tests/ui-regressions-621-623-626.test.ts", "test:window-readiness": "ts-node --transpile-only -P tests/tsconfig.json tests/window-readiness.test.ts", "test:window-load-retry": "ts-node --transpile-only -P tests/tsconfig.json tests/window-load-retry.test.ts", "test:runtime-recovery": "ts-node --transpile-only -P tests/tsconfig.json tests/runtime-recovery.test.ts", "test:backend-health": "ts-node --transpile-only -P tests/tsconfig.json tests/backend-health.test.ts", "test:e2e:server": "node tests/e2e-server.cjs", "test:e2e:browser": "npm run build && npm run build:frontend && cd frontend && npx playwright install chromium && npx playwright test --config=playwright.config.ts --project=chromium --grep-invert='FINDING:|a paid order offers a refund, and issuing it settles against the recorded sale|@ci-tier1|@ci-tier2|server-app-ordering\\.spec\\.ts' && npx playwright test server-app-ordering.spec.ts --config=playwright.config.ts --project=chromium --grep-invert='FINDING:|a paid order offers a refund, and issuing it settles against the recorded sale|@ci-tier1|@ci-tier2'", "test:e2e:browser:tier1": "cd frontend && npx playwright test --config=playwright.config.ts --project=chromium --retries=0 e2e/kitchen/kitchen-delivery-billing-gate.spec.ts", "test:e2e:browser:tier2": "cd frontend && npx playwright test --config=playwright.config.ts --project=chromium --retries=0 e2e/ops-admin/ e2e/qa-settings-permissions-roles.spec.ts e2e/qa-settings-receipts-printers.spec.ts e2e/qa-settings-store-locale.spec.ts e2e/qa-settings-tax.spec.ts e2e/qa-print-test-page.spec.ts --grep-invert='FINDING:|a paid order offers a refund, and issuing it settles against the recorded sale'", "test:e2e:electron": "npm run build && npm run build:frontend && cd frontend && npx playwright test --config=playwright.electron.config.ts --project=electron-desktop", "test:e2e": "npm run test:e2e:browser", "test:release-config": "ts-node --transpile-only -P tests/tsconfig.json tests/release-config.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/verify-electron-runtime-xattr.test.ts && node tests/release-asset-verifier.test.cjs && node tests/release-gate.test.cjs", "test:windows-uninstaller": "node tests/run-windows-uninstaller-tests.cjs", "test:telemetry": "node tests/run-electron-node-test.cjs tests/telemetry-delivery.test.ts && node tests/run-electron-node-test.cjs tests/anonymous-diagnostics-delivery.test.ts && node tests/run-electron-node-test.cjs tests/posthog-client.test.ts && node tests/run-electron-node-test.cjs tests/posthog-service.test.ts", "test:telemetry-install-provenance": "ts-node --transpile-only -P tests/tsconfig.json tests/telemetry-install-provenance.test.ts", "test:country-provenance": "node tests/run-electron-node-test.cjs tests/country-provenance.test.ts", "test:static-routes": "ts-node --transpile-only -P tests/tsconfig.json tests/path-containment.test.ts && node tests/run-electron-node-test.cjs tests/static-route-resolution.test.ts", "test:notes-validation": "ts-node --transpile-only -P tests/tsconfig.json tests/order-notes-validation.test.ts", "test:first-run": "node tests/run-electron-node-test.cjs tests/first-run-setup.test.ts && node tests/run-electron-node-test.cjs tests/setup-failure-recovery.test.ts", "test:security": "node tests/run-electron-node-test.cjs tests/security-hardening.test.ts && npm run test:api-path-casing-auth", "test:api-path-casing-auth": "ts-node --transpile-only -P tests/tsconfig.json tests/api-path-casing-auth.test.ts", "test:staff-authz": "node tests/run-electron-node-test.cjs tests/staff-authz.test.ts", "test:self-service-credentials": "node tests/run-electron-node-test.cjs tests/self-service-credentials.test.ts", "test:orders-authz": "node tests/run-electron-node-test.cjs tests/orders-authz.test.ts && node tests/run-electron-node-test.cjs tests/order-write-rate-limits.test.ts", "test:item-price-override": "node tests/run-electron-node-test.cjs tests/item-price-override.test.ts", "test:offline-mode": "node tests/run-electron-node-test.cjs tests/offline-mode.test.ts", "test:order-item-edit": "node tests/run-electron-node-test.cjs tests/order-item-edit.test.ts", "test:order-item-cancel-restore": "node tests/run-electron-node-test.cjs tests/order-item-cancel-restore.test.ts", "test:order-totals-recompute": "node tests/run-electron-node-test.cjs tests/order-totals-recompute.test.ts", "test:issue-718-whatsapp-order-status": "node tests/run-electron-node-test.cjs tests/issue-718-whatsapp-order-status.test.ts", "test:order-audit-log": "node tests/run-electron-node-test.cjs tests/order-audit-log.test.ts", "test:scheduled-orders": "node tests/run-electron-node-test.cjs tests/issue-360-scheduled-orders.test.ts", "test:multi-counter-ordering": "node tests/run-electron-node-test.cjs tests/multi-counter-ordering.test.ts", "test:authz-phase3": "node tests/run-electron-node-test.cjs tests/authz-matrix-phase3.test.ts", "test:authorization-permissions": "ts-node --transpile-only -P tests/tsconfig.json tests/permission-label-i18n.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/permission-matrix-self-access.test.ts && node tests/run-electron-node-test.cjs tests/authorization-permissions.test.ts && node tests/run-electron-node-test.cjs tests/authorization-api.test.ts && node tests/run-electron-node-test.cjs tests/authorization-static-audit.test.ts && node tests/run-electron-node-test.cjs tests/static-audit-posix-paths.test.ts", "test:customer-auth": "node tests/run-electron-node-test.cjs tests/customer-auth.test.ts", "test:backup": "ts-node --transpile-only -P tests/tsconfig.json tests/backup-restore.test.ts && node tests/run-electron-node-test.cjs tests/backup-restore-production.test.ts && node tests/run-electron-node-test.cjs tests/restore-managed-path.test.ts && node tests/run-electron-node-test.cjs tests/windows-backup-unlink-ebusy.test.ts && node tests/run-electron-node-test.cjs tests/restore-safety-copy.test.ts && node tests/run-electron-node-test.cjs tests/restore-from-file-api.test.ts", "test:issue-278-fail-closed-db": "node tests/run-electron-node-test.cjs tests/issue-278-fail-closed-missing-db.test.ts", "test:newer-db-recovery": "node tests/run-electron-node-test.cjs tests/newer-db-downgrade-recovery.test.ts", "test:recovery-cloud": "node tests/run-electron-node-test.cjs tests/recovery-legacy-fk.test.ts && node tests/run-electron-node-test.cjs tests/cloud-deletion-recovery.test.ts", "test:cloud-account-status": "node tests/run-electron-node-test.cjs tests/cloud-account-status.test.ts", "test:cloud-live-orders-batching": "node tests/run-electron-node-test.cjs tests/cloud-live-orders-batching.test.ts", "test:printer": "ts-node --transpile-only -P tests/tsconfig.json tests/printer.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/ipp-client.test.ts && npm run test:printer-api && npm run test:print-menu-printer-selection && npm run test:printer-ipc", "test:impact-printer": "node tests/run-electron-node-test.cjs tests/impact-printer-support.test.ts", "test:printing-settings": "node tests/run-electron-node-test.cjs tests/printing-settings.test.ts", "test:printer-api": "node tests/run-electron-node-test.cjs tests/printer-api.test.ts", "test:print-menu-printer-selection": "node tests/run-electron-node-test.cjs tests/print-menu-printer-selection.test.ts", "test:printer-ipc": "node tests/run-electron-node-test.cjs tests/printer-ipc.test.ts", "test:charges": "ts-node --transpile-only -P tests/tsconfig.json tests/charges-calculation.test.ts", "test:charges-engine": "ts-node --transpile-only -P tests/tsconfig.json tests/charges-engine-api.test.ts", "audit:db": "ts-node --transpile-only -P tests/tsconfig.json tests/db-audit.test.ts", "test:receipt-printing": "ts-node --transpile-only -P tests/tsconfig.json tests/receipt-printing.test.ts && npm run test:receipt-settings-hydration", "test:receipt-settings-hydration": "node tests/run-electron-node-test.cjs tests/receipt-settings-hydration.test.ts", "test:bills-print-api": "ts-node --transpile-only -P tests/tsconfig.json tests/bills-print-api.test.ts", "test:print-parity": "ts-node --transpile-only -P tests/tsconfig.json tests/print-parity.test.ts", "test:delivery-slip": "ts-node --transpile-only -P tests/tsconfig.json tests/delivery-slip-printing.test.ts", "test:delivery-address": "ts-node --transpile-only -P tests/tsconfig.json tests/delivery-address-egress.test.ts", "test:merchant-print-templates": "ts-node --transpile-only -P tests/tsconfig.json tests/merchant-print-templates.test.ts", "test:merchant-template-transfer": "ts-node --transpile-only -P tests/tsconfig.json tests/merchant-template-import-export.test.ts", "test:print-document": "ts-node --transpile-only -P tests/tsconfig.json tests/print-document.test.ts && node tests/run-electron-node-test.cjs tests/receipt-logo-printing.test.ts", "test:print-kernel": "ts-node --transpile-only -P tests/tsconfig.json tests/print-kernel.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/kernel-purity.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/print-language-settings.test.ts", "test:thermal-capabilities": "ts-node --transpile-only -P tests/tsconfig.json tests/thermal-capabilities.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/windows-print-stderr.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/windows-print-error-detail.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/printer-error-toast-clarity.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/network-print-chunking.test.ts", "test:raster": "ts-node --transpile-only -P tests/tsconfig.json tests/raster-printing.test.ts && npm run test:raster-electron", "test:raster-electron": "npm run build && electron --no-sandbox tests/raster-renderer-electron.test.cjs", "test:cancel-override": "node tests/run-electron-node-test.cjs tests/cancel-override.test.ts && node tests/run-electron-node-test.cjs tests/manager-pin-rate-limit-bypass.test.ts", "test:refunds": "node tests/run-electron-node-test.cjs tests/refunds.test.ts && node tests/run-electron-node-test.cjs tests/async-refund-pin-event-loop.test.ts", "test:async-refund-pin-event-loop": "node tests/run-electron-node-test.cjs tests/async-refund-pin-event-loop.test.ts", "test:refund-completed-orders": "node tests/run-electron-node-test.cjs tests/refund-completed-orders.test.ts", "test:cash-closures": "node tests/run-electron-node-test.cjs tests/cash-closures.test.ts && node tests/run-electron-node-test.cjs tests/reports-whatsapp.test.ts", "test:cash-sessions": "node tests/run-electron-node-test.cjs tests/cash-sessions.test.ts", "test:pos-info-network-ranking": "ts-node --transpile-only -P tests/tsconfig.json tests/pos-info-network-ranking.test.ts", "test:kot-order-notes": "ts-node --transpile-only -P tests/tsconfig.json tests/kot-order-notes.test.ts", "test:kitchen-addons": "node tests/run-electron-node-test.cjs tests/kitchen-addons-parsing.test.ts", "test:order-item-addons": "node tests/run-electron-node-test.cjs tests/order-item-addons.test.ts && node tests/run-electron-node-test.cjs tests/addon-price-integrity.test.ts && node tests/run-electron-node-test.cjs tests/issue-122-addon-quantities.test.ts", "test:issue-125-addon-reads": "node tests/run-electron-node-test.cjs tests/issue-125-addon-read-paths.test.ts", "test:windows-country-code-crash": "node tests/run-electron-node-test.cjs tests/issue-windows-country-code-crash.test.ts", "test:reports-insights": "node tests/run-electron-node-test.cjs tests/reports-insights.test.ts", "test:reports-daily-stats-table-turn": "node tests/run-electron-node-test.cjs tests/reports-daily-stats-table-turn.test.ts", "test:timezone-report-boundaries": "node tests/run-electron-node-test.cjs tests/timezone-report-boundaries.test.ts", "test:business-date": "node tests/run-electron-node-test.cjs tests/business-date.test.ts", "test:dashboard-business-date": "ts-node --transpile-only -P tests/tsconfig.json tests/dashboard-business-date.test.ts", "test:integration-happy": "node tests/run-electron-node-test.cjs tests/integration-happy-path.test.ts", "test:integration-order-hold-payment": "node tests/run-electron-node-test.cjs tests/integration-order-hold-payment.test.ts", "test:integration-tax": "node tests/run-electron-node-test.cjs tests/integration-tax.test.ts && node tests/run-electron-node-test.cjs tests/integration-inclusive-tax.test.ts", "test:integration-payments": "node tests/run-electron-node-test.cjs tests/integration-payments.test.ts && node tests/run-electron-node-test.cjs tests/issue-689-cashier-payments.test.ts && npm run test:payment-method-correction", "test:payment-method-correction": "node tests/run-electron-node-test.cjs tests/payment-method-correction.test.ts", "test:issue-214": "node tests/run-electron-node-test.cjs tests/issue-214-payment-integrity.test.ts", "test:issue-214-auth": "node tests/run-electron-node-test.cjs tests/issue-214-auth-migration.test.ts", "test:issue-214-migration": "node tests/run-electron-node-test.cjs tests/issue-214-migration-integrity.test.ts", "test:issue-255-cart": "ts-node --transpile-only -P tests/tsconfig.json tests/issue-255-pos-cart-retry.test.ts", "test:issue-255-append": "node tests/run-electron-node-test.cjs tests/issue-255-append-idempotency.test.ts", "test:issue-255": "npm run test:issue-255-cart && npm run test:issue-255-append", "test:issue-788-order-attempt-storage": "ts-node --transpile-only -P tests/tsconfig.json tests/issue-788-order-attempt-storage.test.ts", "test:integration-lifecycle": "node tests/run-electron-node-test.cjs tests/integration-order-lifecycle.test.ts", "test:integration-reconciliation": "node tests/run-electron-node-test.cjs tests/integration-bill-reconciliation.test.ts", "test:integration-loyalty": "node tests/run-electron-node-test.cjs tests/integration-loyalty.test.ts", "test:integration-discount": "node tests/run-electron-node-test.cjs tests/integration-discount-edge.test.ts", "test:sequence": "node tests/run-electron-node-test.cjs tests/sequence-generation.test.ts && npm run test:sequence-repair-performance", "test:sequence-repair-performance": "node tests/run-electron-node-test.cjs tests/sequence-repair-performance.test.ts", "test:order-numbering-settings": "node tests/run-electron-node-test.cjs tests/order-numbering-settings.test.ts", "test:loyalty-toggle": "node tests/run-electron-node-test.cjs tests/loyalty-toggle.test.ts", "test:discount-system": "node tests/run-electron-node-test.cjs tests/discount-system.test.ts", "test:integration-discount-settings": "node tests/run-electron-node-test.cjs tests/integration-discount-settings.test.ts", "test:theme-mode-settings": "node tests/run-electron-node-test.cjs tests/theme-mode-settings.test.ts", "test:integration-loyalty-global": "node tests/run-electron-node-test.cjs tests/integration-loyalty-global-rate.test.ts", "test:issue-248-csv": "node tests/run-electron-node-test.cjs tests/issue-248-menu-csv.test.ts && node tests/run-electron-node-test.cjs tests/menu-csv-formula-export.test.ts", "test:integration-loyalty-redemption": "node tests/run-electron-node-test.cjs tests/integration-loyalty-redemption.test.ts", "test:issue-24": "node tests/run-electron-node-test.cjs tests/issue-24-cancel-item-checkout.test.ts", "test:issue-zero-balance-settlement": "node tests/run-electron-node-test.cjs tests/issue-zero-balance-settlement.test.ts", "test:issue-terminal-state-guards": "node tests/run-electron-node-test.cjs tests/issue-terminal-state-guards.test.ts", "test:issue-exact-balance-settlement": "node tests/run-electron-node-test.cjs tests/issue-exact-balance-settlement.test.ts", "test:financial-safety-remediation": "node tests/run-electron-node-test.cjs tests/financial-safety-remediation.test.ts && npm run test:bills-settlement-idempotency", "test:bills-settlement-idempotency": "node tests/run-electron-node-test.cjs tests/bills-settlement-idempotency.test.ts", "test:issue-payload-and-discount-bounds": "node tests/run-electron-node-test.cjs tests/issue-payload-and-discount-bounds.test.ts", "test:issue-134-routing": "node tests/run-electron-node-test.cjs tests/issue-134-station-routing.test.ts", "test:issue-134-mgmt": "node tests/run-electron-node-test.cjs tests/issue-134-station-management.test.ts", "test:issue-133-kds-kot-toggles": "node tests/run-electron-node-test.cjs tests/issue-133-kds-kot-toggles.test.ts", "test:issue-137-barcode": "node tests/run-electron-node-test.cjs tests/issue-137-barcode.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/issue-365-scale-barcode.test.ts", "test:issue-244-product-addon-links": "node tests/run-electron-node-test.cjs tests/issue-244-product-addon-links.test.ts", "test:issue-245-246-addon-groups": "node tests/run-electron-node-test.cjs tests/issue-245-246-addon-groups.test.ts", "test:issue-247-catalog-invariants": "node tests/run-electron-node-test.cjs tests/issue-247-catalog-invariants.test.ts", "test:category-addon-groups": "node tests/run-electron-node-test.cjs tests/category-addon-groups.test.ts", "test:addon-inventory-db": "node tests/run-electron-node-test.cjs tests/addon-inventory-db.test.ts", "test:addon-inventory-api": "node tests/run-electron-node-test.cjs tests/addon-inventory-api.test.ts", "test:discount-kitchen-approver-identity": "node tests/run-electron-node-test.cjs tests/discount-kitchen-approver-identity.test.ts", "test:staff-approvers-directory": "node tests/run-electron-node-test.cjs tests/staff-approvers-directory.test.ts", "test:addon-inventory-orders": "node tests/run-electron-node-test.cjs tests/addon-inventory-orders.test.ts", "test:addon-inventory-lifecycle": "node tests/run-electron-node-test.cjs tests/addon-inventory-lifecycle.test.ts", "test:addon-inventory-pos-surface": "ts-node --transpile-only -P tests/tsconfig.json tests/addon-inventory-pos-surface.test.ts", "test:product-variants-db": "node tests/run-electron-node-test.cjs tests/product-variants-db.test.ts", "test:product-variants-api": "node tests/run-electron-node-test.cjs tests/product-variants-api.test.ts", "test:issue-250-catalog-perf": "node tests/run-electron-node-test.cjs tests/issue-250-catalog-perf.test.ts", "test:issue-258-bill-pagination": "node tests/run-electron-node-test.cjs tests/issue-258-bill-pagination.test.ts", "test:issue-265-morocco-profile": "node tests/run-electron-node-test.cjs tests/issue-265-morocco-profile.test.ts", "test:issue-266-currency-symbol-print": "node tests/run-electron-node-test.cjs tests/issue-266-currency-symbol-print.test.ts", "test:tables-string-ids": "node tests/run-electron-node-test.cjs tests/tables-string-ids.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/table-move-ui.test.ts", "test:issue-646-floor-management": "node tests/run-electron-node-test.cjs tests/issue-646-floor-management.test.ts", "test:held-orders": "node tests/run-electron-node-test.cjs tests/held-orders.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/held-orders-store.test.ts", "test:product-images": "node tests/run-electron-node-test.cjs tests/product-images.test.ts", "test:schema-reference-cache": "node tests/run-electron-node-test.cjs tests/schema-reference-cache.test.ts", "test:schema-health": "node tests/run-electron-node-test.cjs tests/schema-health.test.ts && npm run test:schema-reference-cache", "test:upgrade-path": "node tests/run-electron-node-test.cjs tests/upgrade-path.test.ts", "test:upgrade-matrix-harness": "node tests/upgrade-matrix-harness.test.cjs && node tests/upgrade-matrix-offline-fixture.test.cjs", "test:upgrade-regression": "npm run test:upgrade-path", "test:migration-v56-v57": "node tests/run-electron-node-test.cjs tests/migration-v56-to-v57.test.ts", "test:migration-v71-repair": "node tests/run-electron-node-test.cjs tests/migration-v71-revoked-tokens-repair.test.ts", "test:migration-v80-cash-drawer-pulse": "node tests/run-electron-node-test.cjs tests/migration-v80-cash-drawer-pulse.test.ts", "test:migration-v81-cash-closures": "node tests/run-electron-node-test.cjs tests/migration-v81-cash-closures.test.ts", "test:master-pin": "node tests/run-electron-node-test.cjs tests/master-pin.test.ts", "test:google-drive": "node tests/run-electron-node-test.cjs tests/google-drive.test.ts", "test:google-drive-qr-menu": "node tests/run-electron-node-test.cjs tests/google-drive-qr-menu.test.ts", "test:status-messages": "ts-node --transpile-only -P tests/tsconfig.json tests/status-messages.test.ts", "test:local-backup": "node tests/run-electron-node-test.cjs tests/local-backup.test.ts", "test:database-tools-api": "node tests/run-electron-node-test.cjs tests/database-tools-api.test.ts && node tests/run-electron-node-test.cjs tests/db-initialize-drive-boundary.test.ts && node tests/run-electron-node-test.cjs tests/database-maintenance-lock.test.ts && node tests/run-electron-node-test.cjs tests/database-maintenance-allowlist.test.ts", "test:issue-127-password-recovery": "node tests/run-electron-node-test.cjs tests/issue-127-password-recovery.test.ts", "test:cloud-password-recovery": "node tests/run-electron-node-test.cjs tests/cloud-password-recovery.test.ts", "test:password-policy": "ts-node --transpile-only -P tests/tsconfig.json tests/password-policy.test.ts", "test:server-app-server-role": "node tests/run-electron-node-test.cjs tests/server-app-server-role.test.ts && npm run test:server-app-maintenance-handoff", "test:server-app-maintenance-handoff": "node tests/run-electron-node-test.cjs tests/server-app-maintenance-handoff.test.ts", "test:server-app-station-routing": "node tests/run-electron-node-test.cjs tests/server-app-station-routing.test.ts", "test:issue-1442": "node tests/run-electron-node-test.cjs tests/issue-1442-kot-and-58mm-print.test.ts", "test:customer-soft-reactivate-bindings": "ts-node --transpile-only -P tests/tsconfig.json tests/customer-soft-reactivate-bindings.test.ts", "test:customer-phone-search": "node tests/run-electron-node-test.cjs tests/customer-phone-search.test.ts", "test:customer-pagination": "node tests/run-electron-node-test.cjs tests/customer-pagination.test.ts", "test:customer-top-items": "node tests/run-electron-node-test.cjs tests/customer-top-items.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/customer-top-items-ui.test.ts", "test:phone-search-integration": "node tests/run-electron-node-test.cjs tests/phone-search-integration.test.ts", "test:e2e-argentina-flow": "ts-node --transpile-only -P tests/tsconfig.json tests/e2e-argentina-flow.test.ts", "test:translations": "ts-node --transpile-only -P tests/tsconfig.json tests/translations.test.ts", "test:print-labels": "ts-node --transpile-only -P tests/tsconfig.json tests/print-labels.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/phase3-print-regressions.test.ts && node scripts/generate-print-labels.cjs --check", "test:locale-chunks": "ts-node --transpile-only -P tests/tsconfig.json tests/locale-chunk-splitting.test.ts", "test:browser-receipts": "ts-node --transpile-only -P tests/tsconfig.json tests/browser-receipts.test.ts", "test:decoupled-ui-locale": "ts-node --transpile-only -P tests/tsconfig.json tests/decoupled-ui-locale.test.ts", "test:i18n-audit-remediations": "ts-node --transpile-only -P tests/tsconfig.json tests/i18n-audit-remediations.test.ts", "test:i18n-ssr-timezone": "ts-node --transpile-only -P tests/tsconfig.json tests/i18n-ssr-timezone.test.ts", "test:issue-241-localized-errors": "ts-node --transpile-only -P tests/tsconfig.json tests/issue-241-localized-errors.test.ts", "test:payment-modal-currency-adapter": "ts-node --transpile-only -P tests/tsconfig.json tests/payment-modal-currency-adapter.test.ts", "test:printer-fallback-and-popup-verification": "ts-node --transpile-only -P tests/tsconfig.json tests/printer-fallback-and-popup-verification.ts", "test:kot-locale-cold-start": "ts-node --transpile-only -P tests/tsconfig.json tests/kot-locale-cold-start.test.ts", "test:phase6-locale-loading": "ts-node --transpile-only -P tests/tsconfig.json tests/phase6-locale-loading.test.ts", "test:phase7-setup-i18n": "node tests/run-electron-node-test.cjs tests/phase7-setup-i18n.test.ts", "test:auth-print-bootstrap-race": "ts-node --transpile-only -P tests/tsconfig.json tests/auth-print-bootstrap-race.test.ts", "test:release-regressions": "npm run test:browser-receipts && npm run test:decoupled-ui-locale && npm run test:i18n-audit-remediations && npm run test:i18n-ssr-timezone && npm run test:issue-241-localized-errors && npm run test:payment-modal-currency-adapter && npm run test:printer-fallback-and-popup-verification && npm run test:kot-locale-cold-start && npm run test:phase6-locale-loading && npm run test:auth-print-bootstrap-race", "generate:print-labels": "node scripts/generate-print-labels.cjs", "i18n:add": "node scripts/i18n-add.cjs", "i18n:check": "npm run test:translations && npm run generate:print-labels -- --check && tsc --noEmit -p frontend/tsconfig.json", "test:rtl-foundation": "ts-node --transpile-only -P tests/tsconfig.json tests/rtl-foundation.test.ts", "test:rtl-setup-auth-settings": "ts-node --transpile-only -P tests/tsconfig.json tests/rtl-setup-auth-settings.test.ts", "test:rtl-dashboard-pos-common": "ts-node --transpile-only -P tests/tsconfig.json tests/rtl-dashboard-pos-common.test.ts", "test:rtl-kds-server-whatsapp": "ts-node --transpile-only -P tests/tsconfig.json tests/rtl-kds-server-whatsapp.test.ts", "test:phone": "ts-node --transpile-only -P tests/tsconfig.json tests/phone.test.ts", "test:orders-search": "ts-node --transpile-only -P tests/tsconfig.json tests/orders-search.test.ts && node tests/run-electron-node-test.cjs tests/orders-search-api.test.ts && npm run test:orders-search-performance", "test:settings-search": "ts-node --transpile-only -P tests/tsconfig.json tests/settings-search.test.ts", "test:orders-search-performance": "node tests/run-electron-node-test.cjs tests/orders-search-performance.test.ts", "test:country-localization": "ts-node --transpile-only -P tests/tsconfig.json tests/country-localization.test.ts", "test:currency": "ts-node --transpile-only -P tests/tsconfig.json tests/currency.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/country-profile.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/locale-iran.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/regional-snapshot.test.ts && node tests/run-electron-node-test.cjs tests/currency-split-checks.test.ts && node tests/run-electron-node-test.cjs tests/currency-payments-refunds-minor-units.test.ts && node tests/run-electron-node-test.cjs tests/currency-reset.test.ts", "test:currency-split": "node tests/run-electron-node-test.cjs tests/currency-split-checks.test.ts", "test:update-state": "ts-node --transpile-only -P tests/tsconfig.json tests/update-state.test.ts", "test:update-ui": "ts-node --transpile-only -P tests/tsconfig.json tests/update-ui.test.ts", "test:update-channel": "ts-node --transpile-only -P tests/tsconfig.json tests/update-channel.test.ts", "test:tax-engine": "ts-node --transpile-only -P tests/tsconfig.json tests/tax-engine.test.ts", "test:tax-components": "ts-node --transpile-only -P tests/tsconfig.json tests/tax-components.test.ts", "test:tax-pack-catalog": "ts-node --transpile-only -P tests/tsconfig.json tests/tax-pack-catalog.test.ts", "test:tax-pack-management": "node tests/run-electron-node-test.cjs tests/tax-pack-management.test.ts", "test:manual-tax-config": "node tests/run-electron-node-test.cjs tests/manual-tax-config.test.ts", "test:legacy-tax-pack-digest": "node tests/run-electron-node-test.cjs tests/legacy-tax-pack-digest.test.ts", "test:community-tax-packs": "node tests/run-electron-node-test.cjs tests/community-tax-packs.test.ts", "test:support-ticket": "node tests/run-electron-node-test.cjs tests/support-ticket.test.ts", "test:receipt-column-width": "ts-node --transpile-only -P tests/tsconfig.json tests/receipt-column-width.test.ts", "test:phone-validation": "node tests/run-electron-node-test.cjs tests/phone-validation.test.ts && node tests/run-electron-node-test.cjs tests/issue-263-phone-normalization.test.ts", "test:phone-migration": "node tests/run-electron-node-test.cjs tests/phone-migration.test.ts", "test:whatsapp-schema": "node tests/run-electron-node-test.cjs tests/whatsapp-schema.test.ts", "test:whatsapp-service": "ts-node --transpile-only -P tests/tsconfig.json tests/whatsapp-template-placeholder-cursor.test.ts && ts-node --transpile-only -P tests/tsconfig.json tests/whatsapp-service.test.ts && node tests/run-electron-node-test.cjs tests/whatsapp-shutdown-timeout.test.ts", "test:whatsapp-middleware": "node tests/run-electron-node-test.cjs tests/whatsapp-middleware.test.ts", "test:printer-width-refresh": "node tests/run-electron-node-test.cjs tests/printer-width-refresh.test.ts", "test:printer-migrations": "node tests/run-electron-node-test.cjs tests/printer-usb-device-path-migration.test.ts", "test:issue-252": "node tests/run-electron-node-test.cjs tests/issue-252-order-lifecycle-inventory.test.ts", "test:inventory-ledger": "node tests/run-electron-node-test.cjs tests/inventory-ledger.test.ts && node tests/run-electron-node-test.cjs tests/volume-units-inventory-links.test.ts && npm run test:inventory-legacy-precision-backup", "test:inventory-legacy-precision-backup": "node tests/run-electron-node-test.cjs tests/inventory-legacy-precision-backup.test.ts", "test:issue-printing-and-kds-resilience": "node tests/run-electron-node-test.cjs tests/issue-printing-and-kds-resilience.test.ts", "test:diagnostics-event": "node tests/run-electron-node-test.cjs tests/diagnostics-event.test.ts", "test:diagnostic-signature": "node tests/run-electron-node-test.cjs tests/diagnostic-signature.test.ts", "test:diagnostics-outbox-bounds": "node tests/run-electron-node-test.cjs tests/diagnostics-outbox-bounds.test.ts", "test:diagnostic-wire-producer": "node tests/run-electron-node-test.cjs tests/diagnostic-wire-producer.test.ts", "test:diagnostics-screen": "node tests/run-electron-node-test.cjs tests/diagnostics-screen.test.ts", "test:telemetry-leakage-prevention": "node tests/run-electron-node-test.cjs tests/telemetry-leakage-prevention.test.ts", "test:diagnostics": "node scripts/run-test.cjs npm run test:diagnostics-event && node scripts/run-test.cjs npm run test:diagnostic-signature && node scripts/run-test.cjs npm run test:diagnostics-outbox-bounds && node scripts/run-test.cjs npm run test:diagnostic-wire-producer && node scripts/run-test.cjs npm run test:diagnostics-screen && node scripts/run-test.cjs npm run test:diagnostics-feature-coverage && node scripts/run-test.cjs npm run test:telemetry-leakage-prevention", "test:diagnostics-feature-coverage": "node tests/run-electron-node-test.cjs tests/diagnostics-feature-coverage.test.ts", "test:customer-display-config": "ts-node --transpile-only -P tests/tsconfig.json tests/customer-display-config.test.ts", "test:customer-display-settings-route": "node tests/run-electron-node-test.cjs tests/customer-display-settings-route.test.ts", "test:customer-display-pairing": "node tests/run-electron-node-test.cjs tests/customer-display-pairing.test.ts", "test:customer-display-feed": "node tests/run-electron-node-test.cjs tests/customer-display-feed.test.ts", "test:units": "ts-node --transpile-only -P tests/tsconfig.json tests/units.test.ts", "test:db-timing": "ts-node --transpile-only -P tests/tsconfig.json tests/db-timing.test.ts", "test:supplies-service": "node tests/run-electron-node-test.cjs tests/supplies-service.test.ts", "test:expenses": "ts-node --transpile-only -P tests/tsconfig.json tests/expense-attempt.test.ts && node tests/run-electron-node-test.cjs tests/expense-records.test.ts && node tests/run-electron-node-test.cjs tests/expense-api.test.ts && node tests/run-electron-node-test.cjs tests/expense-payments.test.ts", "test:recipe-order-lifecycle": "node tests/run-electron-node-test.cjs tests/recipe-order-lifecycle.test.ts", "test:ingredient-cost": "node tests/run-electron-node-test.cjs tests/ingredient-cost-lifecycle.test.ts", "test:receipt-column-oracle": "ts-node --transpile-only -P tests/tsconfig.json tests/receipt-column-oracle.test.ts", "test:jwt-secret-cache-identity": "node tests/run-electron-node-test.cjs tests/jwt-secret-cache-identity.test.ts", "test:jwt-secret-safe-storage": "node tests/run-electron-node-test.cjs tests/jwt-secret-safe-storage.test.ts", "test:jwt-secret-persist-before-cache": "node tests/run-electron-node-test.cjs tests/jwt-secret-persist-before-cache.test.ts", "test:migration-registry": "node tests/run-electron-node-test.cjs tests/migration-registry.test.ts", "test:kitchen-delivery-enforcement": "node tests/run-electron-node-test.cjs tests/kitchen-delivery-enforcement.test.ts", "test:pos-catalog-sort": "ts-node --transpile-only -P tests/tsconfig.json tests/pos-catalog-sort.test.ts", "test:pos-sort-settings": "node tests/run-electron-node-test.cjs tests/pos-sort-settings.test.ts", "test:orders-layout-settings": "node tests/run-electron-node-test.cjs tests/orders-layout-settings.test.ts", "test:menu-printing": "ts-node --transpile-only -P tests/tsconfig.json tests/menu-printing.test.ts", "test:cart-price-override": "ts-node --transpile-only -P tests/tsconfig.json tests/cart-price-override.test.ts", "test:cart-variant-identity": "ts-node --transpile-only -P tests/tsconfig.json tests/cart-variant-identity.test.ts", "test:product-variants-orders": "node tests/run-electron-node-test.cjs tests/product-variants-orders.test.ts", "test:variant-pos-surface": "ts-node --transpile-only -P tests/tsconfig.json tests/variant-pos-surface.test.ts", "test:product-variants-screen": "ts-node --transpile-only -P tests/tsconfig.json tests/product-variants-screen.test.ts", "test:printer-text-size": "ts-node --transpile-only -P tests/tsconfig.json tests/printer-text-size.test.ts && node tests/run-electron-node-test.cjs tests/migration-printer-text-size.test.ts" }, "author": { "name": "Flo", "email": "support@flo.local" }, "homepage": "https://flopos.com", "repository": { "type": "git", "url": "https://github.com/FreeOpenSourcePOS/FloCafe.git" }, "bugs": { "url": "https://github.com/FreeOpenSourcePOS/FloCafe/issues" }, "license": "MIT", "overrides": { "app-builder-lib": { "@electron/get": "^5.1.0" }, "@electron/asar": { ".": "^4.3.1", "glob": "^14.0.3" }, "@electron/universal": "^3.0.6", "node-abi": "^4.40.0", "brace-expansion": "^5.0.12", "js-yaml@^4": "^4.3.2", "minimatch": "^11.0.4", "re2js": "^2.8.7", "undici@<7": "^6.28.1", "undici@>=7": "^7.29.1", "ip-address": "^10.7.4", "fast-uri": "^3.1.8", "uuid": "^11.1.1", "http-cache-semantics": "^4.3.0", "katex": "^0.18.2", "smol-toml": "^1.9.0" }, "devDependencies": { "@electron/rebuild": "^4.2.1", "@formatjs/icu-messageformat-parser": "^3.5.22", "@types/bcryptjs": "^3.0.0", "@types/better-sqlite3": "^9.6.0", "@types/bonjour": "^3.5.13", "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/jsonwebtoken": "^9.0.10", "@types/node": "^26.6.6", "@types/qrcode": "^1.5.6", "@types/supertest": "^7.2.1", "@types/ws": "^8.18.2", "cross-env": "10.1.0", "electron": "^45.2.3", "electron-builder": "^26.18.0", "husky": "9.1.7", "js-yaml": "^5.5.0", "lint-staged": "17.6.0", "markdownlint-cli2": "^0.24.0", "node-abi": "^4.40.0", "oxfmt": "0.76.0", "oxlint": "1.91.0", "supertest": "^7.3.1", "ts-node": "^10.9.2", "typescript": "^5.4.5" }, "dependencies": { "@googleapis/drive": "^27.0.0", "@point-of-sale/codepage-encoder": "3.0.2", "@whiskeysockets/baileys": "^7.0.0-rc14", "bcryptjs": "^3.0.3", "better-sqlite3": "^13.0.3", "bonjour-service": "^1.4.4", "builder-util-runtime": "9.7.0", "cors": "^2.8.5", "decimal.js": "^10.6.0", "electron-log": "^5.4.4", "electron-updater": "^6.8.11", "exceljs": "^4.4.0", "express": "^5.3.0", "express-rate-limit": "^8.7.3", "jsonwebtoken": "^9.0.2", "libphonenumber-js": "^1.13.15", "posthog-node": "^5.63.0", "qrcode": "^1.5.3", "ws": "^8.22.1" }, "build": { "appId": "com.flo.desktop", "productName": "Flo Cafe", "icon": "assets/icon-512.png", "afterPack": "scripts/afterPack.js", "asar": true, "asarUnpack": "**/node_modules/better-sqlite3/**/*", "directories": { "output": "release" }, "files": [ "dist/**/*", "node_modules/**/*", "!**/better-sqlite3/build/Release/test_extension.node" ], "publish": { "provider": "github", "owner": "FreeOpenSourcePOS", "repo": "FloCafe", "releaseType": "release", "channel": "latest" }, "detectUpdateChannel": false, "generateUpdatesFilesForAllChannels": true, "extraResources": [ { "from": "assets", "to": "assets" }, { "from": "frontend/out", "to": "frontend-out" } ], "win": { "target": [ { "target": "nsis", "arch": [ "x64" ] }, { "target": "appx", "arch": [ "x64", "arm64" ] } ], "icon": "assets/icon.ico", "artifactName": "flocafe-${version}-win-${arch}.${ext}" }, "appx": { "applicationId": "FloCafe", "backgroundColor": "#1e1e2e", "publisherDisplayName": "Codify Apps Private Limited", "identityName": "CodifyAppsPrivateLimited.FloCafe", "publisher": "CN=34AFD24D-EC88-44B8-B309-08BB8A6BB5F7", "displayName": "Flo Cafe", "languages": [ "en-US" ] }, "mac": { "target": [ { "target": "dmg", "arch": [ "x64", "arm64" ] }, { "target": "zip", "arch": [ "x64", "arm64" ] } ], "icon": "assets/icon.icns", "category": "public.app-category.business", "identity": "Codify Apps Private Limited (BKDY677XJA)", "entitlements": "build/entitlements.plist", "entitlementsInherit": "build/entitlements.plist", "hardenedRuntime": true, "gatekeeperAssess": false, "notarize": true, "artifactName": "flocafe-${version}-mac-${arch}.${ext}", "extendInfo": { "NSLocalNetworkUsageDescription": "Flo Cafe connects to thermal printers, KDS displays, and the Waiter & Table Terminal on your local network.", "NSBonjourServices": [ "_http._tcp" ] } }, "mas": { "category": "public.app-category.business", "identity": "Codify Apps Private Limited (BKDY677XJA)", "entitlements": "build/entitlements.mas.plist", "entitlementsInherit": "build/entitlements.mas.inherit.plist", "entitlementsLoginHelper": "build/entitlements.mas.loginhelper.plist", "provisioningProfile": "build/flo.provisionprofile", "hardenedRuntime": false, "gatekeeperAssess": false, "type": "distribution", "extendInfo": { "ITSAppUsesNonExemptEncryption": false, "NSLocalNetworkUsageDescription": "Flo Cafe connects to thermal printers, KDS displays, and the Waiter & Table Terminal on your local network.", "NSBonjourServices": [ "_http._tcp" ] }, "target": [ { "target": "mas", "arch": "universal" } ], "x64ArchFiles": "**/*.node" }, "masDev": { "identity": "Apple Development: Codify Apps Private Limited (BKDY677XJA)" }, "linux": { "synopsis": "Self-hosted Point of Sale for cafes and restaurants", "description": "Flo is a free, open-source point-of-sale system for cafes, restaurants, and small kitchens. Local-first, offline-capable, no cloud lock-in, no per-seat fees.", "target": [ { "target": "AppImage", "arch": [ "x64", "arm64" ] }, { "target": "deb", "arch": [ "x64", "arm64" ] }, { "target": "rpm", "arch": [ "x64", "arm64" ] }, { "target": "snap", "arch": [ "x64", "arm64" ] } ], "icon": "assets", "category": "Office", "executableName": "flocafe", "artifactName": "flocafe-${version}-linux.${ext}", "extraFiles": [ { "from": "assets/com.flo.desktop.metainfo.xml", "to": "usr/share/metainfo/com.flo.desktop.metainfo.xml" }, { "from": "assets/icons", "to": "usr/share/icons" } ], "desktop": { "entry": { "Name": "Flo Cafe", "Comment": "Free, open-source POS for cafes and restaurants", "GenericName": "Point of Sale", "Keywords": "pos;point of sale;restaurant;cafe;billing;invoice;", "StartupWMClass": "flo-desktop" } } }, "appImage": { "artifactName": "flocafe-${version}-linux.appimage" }, "snapcraft": { "base": "core24", "core24": { "confinement": "strict", "useLXD": true, "extensions": [ "gnome" ], "stagePackages": [ "default" ], "plugs": [ "default", "browser-support", "cups-control", "avahi-observe", "avahi-control", "raw-usb", "removable-media", "network-bind", "screen-inhibit-control" ], "environment": { "TMPDIR": "$XDG_RUNTIME_DIR" } } }, "nsis": { "oneClick": false, "allowToChangeInstallationDirectory": true, "createDesktopShortcut": true, "createStartMenuShortcut": true } }, "allowScripts": { "electron-winstaller@5.4.0": true, "protobufjs@7.6.5": true, "@whiskeysockets/baileys@7.0.0-rc14": true } }