W0b web shared follow-ups: one copy of shared pieces, per-locale amounts, chunks
Build Kvitt images / build (push) Has been cancelled
Build Kvitt images / build (push) Has been cancelled
- Shared once, features import them: components/AccountTile (+ lib/accountColors), components/PageStates (LoadingState, ErrorState), components/Timeline + lib/timeline, components/OverflowMenu, components/SwitchRow, app/useToday (useToday, useTodayIso), lib/categories (categoryName), api/errors (apiErrorKey/Text, isNetworkError, rejectionMessage/Text, allocationErrorKey), api/invites (useInvites), components/editor peopleOf, editorPeopleOf, accountBpOf. Local copies deleted. - AmountField: separators follow the page language (en "3,250.00" editable), hideLabel and placeholder props; settle's ungrouped amountText and CSS label hiding removed. - W5's recurring editor uses the shared editor fields (D-148); recurring/fields deleted. - routes.ts: 'bucket' in DrillDownKind, QUERY, expensesNewPath, settlePath, settlementEditPath; accounts/links.ts and settle/links.ts deleted. - vectors.test.ts runs resolve_range and spend_series (analytics port); the duplicate runner is gone. - vite.config.ts: /analytics in the dev proxy, Recharts in a charts chunk (vendor 516 kB -> 132 kB), version code from git rev-list --count HEAD (else KVITT_VERSION_CODE, else 1), Vitest fsModuleCache off. - ids.ts: random typed (bytes: Uint8Array<ArrayBuffer>) => void. - test/setup.ts: findBy and waitFor wait up to 5 s (first lazy renders time out at 1 s when parallel agents load the Mac). - Strings: web_editor_paid_by_toggle (click wording), web_reject_clock_skew shared; catalog.test.ts fails when a feature uses another feature's web_ key. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
+39
-2
@@ -1,14 +1,41 @@
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
interface PackageJson {
|
||||
version: string;
|
||||
kvitt: { versionCode: number };
|
||||
}
|
||||
|
||||
const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf-8')) as PackageJson;
|
||||
|
||||
/**
|
||||
* `X-Kvitt-App-Version` (SPEC §14.3.1): the commit count of the checkout at build time (`git rev-list --count HEAD`,
|
||||
* as the app's release builds count). Without git or `.git` (the image's Node stage), `KVITT_VERSION_CODE` when set,
|
||||
* else 1.
|
||||
*/
|
||||
function versionCode(): number {
|
||||
const counted = gitCommitCount();
|
||||
if (counted !== null) return counted;
|
||||
const fromEnv = process.env.KVITT_VERSION_CODE;
|
||||
return fromEnv !== undefined && /^[1-9]\d*$/.test(fromEnv) ? Number(fromEnv) : 1;
|
||||
}
|
||||
|
||||
function gitCommitCount(): number | null {
|
||||
try {
|
||||
const count = execFileSync('git', ['rev-list', '--count', 'HEAD'], {
|
||||
cwd: fileURLToPath(new URL('.', import.meta.url)),
|
||||
encoding: 'utf-8',
|
||||
stdio: ['ignore', 'pipe', 'ignore'],
|
||||
}).trim();
|
||||
return /^[1-9]\d*$/.test(count) ? Number(count) : null;
|
||||
} catch {
|
||||
// No git binary, or no repository around web/.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** API paths of contracts/openapi.yaml; `npm run dev` forwards them to a local kvitt-server (README). */
|
||||
const API_PREFIXES = [
|
||||
'/health',
|
||||
@@ -23,6 +50,7 @@ const API_PREFIXES = [
|
||||
'/sync',
|
||||
'/settlements',
|
||||
'/apk',
|
||||
'/analytics',
|
||||
];
|
||||
const devApi = process.env.KVITT_DEV_API ?? 'http://localhost:8080';
|
||||
|
||||
@@ -31,7 +59,7 @@ export default defineConfig({
|
||||
plugins: [react()],
|
||||
define: {
|
||||
__KVITT_VERSION_NAME__: JSON.stringify(pkg.version),
|
||||
__KVITT_VERSION_CODE__: JSON.stringify(pkg.kvitt.versionCode),
|
||||
__KVITT_VERSION_CODE__: JSON.stringify(versionCode()),
|
||||
},
|
||||
server: {
|
||||
// web/ itself, plus contracts/ for the one contract file the app imports at build time: W2's keyword table
|
||||
@@ -49,6 +77,12 @@ export default defineConfig({
|
||||
codeSplitting: {
|
||||
groups: [
|
||||
{ name: 'react', test: /node_modules[\\/](react|react-dom|scheduler)[\\/]/ },
|
||||
// Recharts and its dependencies, loaded only by the analytics pages (S-11, S-12, Insights), so the
|
||||
// shared vendor chunk stays small (it was 516 kB with them).
|
||||
{
|
||||
name: 'charts',
|
||||
test: /node_modules[\\/](recharts|victory-vendor|d3-[a-z-]+|internmap|@reduxjs|redux|redux-thunk|react-redux|reselect|immer|decimal\.js-light|es-toolkit|eventemitter3|tiny-invariant|clsx|use-sync-external-store)[\\/]/,
|
||||
},
|
||||
{ name: 'vendor', test: /node_modules[\\/]/ },
|
||||
],
|
||||
},
|
||||
@@ -60,5 +94,8 @@ export default defineConfig({
|
||||
setupFiles: ['src/test/setup.ts'],
|
||||
include: ['src/**/*.test.{ts,tsx}'],
|
||||
css: { modules: { classNameStrategy: 'non-scoped' } },
|
||||
// No file-system module cache (node_modules/.vitest-cache): it once served a stale `import.meta.glob` of
|
||||
// catalog.ts (fixed in 83f5293), and the whole suite runs in seconds without it, so every run transforms afresh.
|
||||
fsModuleCache: false,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user