Switch workflows to Bun install/test and update pnpm

This commit is contained in:
Esdras Renan 2025-11-04 23:21:41 -03:00
parent c3237dfb64
commit 775956c160
37 changed files with 2618 additions and 113 deletions

View file

@ -72,13 +72,17 @@ jobs:
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 9 version: 10.20.0
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
cache: 'pnpm'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.1
- name: Verify Bun runtime - name: Verify Bun runtime
run: bun --version run: bun --version
@ -182,17 +186,16 @@ jobs:
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: ${{ env.EFFECTIVE_APP_DIR }}/.next/cache path: ${{ env.EFFECTIVE_APP_DIR }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('src/**/*.ts', 'src/**/*.tsx', 'src/**/*.js', 'src/**/*.jsx', 'next.config.ts') }} key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml', 'bun.lock') }}-${{ hashFiles('src/**/*.ts', 'src/**/*.tsx', 'src/**/*.js', 'src/**/*.jsx', 'next.config.ts') }}
restore-keys: | restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}- ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml', 'bun.lock') }}-
- name: Install and build (Next.js) - name: Install and build (Next.js)
run: | run: |
cd "$EFFECTIVE_APP_DIR" cd "$EFFECTIVE_APP_DIR"
corepack enable || true bun install --frozen-lockfile
pnpm --filter web install --no-frozen-lockfile bun run prisma:generate
pnpm prisma:generate bun run build:bun
pnpm build:bun
- name: Publish build to stable APP_DIR directory - name: Publish build to stable APP_DIR directory
run: | run: |
@ -385,7 +388,7 @@ jobs:
-e MACHINE_PROVISIONING_SECRET \ -e MACHINE_PROVISIONING_SECRET \
-e MACHINE_TOKEN_TTL_MS \ -e MACHINE_TOKEN_TTL_MS \
-e FLEET_SYNC_SECRET \ -e FLEET_SYNC_SECRET \
node:20-bullseye bash -lc "set -euo pipefail; corepack enable; corepack prepare pnpm@9 --activate; mkdir -p \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm config set store-dir \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm install --frozen-lockfile --prod=false; \ node:20-bullseye bash -lc "set -euo pipefail; corepack enable; corepack prepare pnpm@10.20.0 --activate; mkdir -p \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm config set store-dir \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm install --frozen-lockfile --prod=false; \
if [ -n \"$MACHINE_PROVISIONING_SECRET\" ]; then pnpm exec convex env set MACHINE_PROVISIONING_SECRET \"$MACHINE_PROVISIONING_SECRET\" -y; fi; \ if [ -n \"$MACHINE_PROVISIONING_SECRET\" ]; then pnpm exec convex env set MACHINE_PROVISIONING_SECRET \"$MACHINE_PROVISIONING_SECRET\" -y; fi; \
if [ -n \"$MACHINE_TOKEN_TTL_MS\" ]; then pnpm exec convex env set MACHINE_TOKEN_TTL_MS \"$MACHINE_TOKEN_TTL_MS\" -y; fi; \ if [ -n \"$MACHINE_TOKEN_TTL_MS\" ]; then pnpm exec convex env set MACHINE_TOKEN_TTL_MS \"$MACHINE_TOKEN_TTL_MS\" -y; fi; \
if [ -n \"$FLEET_SYNC_SECRET\" ]; then pnpm exec convex env set FLEET_SYNC_SECRET \"$FLEET_SYNC_SECRET\" -y; fi; \ if [ -n \"$FLEET_SYNC_SECRET\" ]; then pnpm exec convex env set FLEET_SYNC_SECRET \"$FLEET_SYNC_SECRET\" -y; fi; \
@ -410,7 +413,7 @@ jobs:
-e CI=true \ -e CI=true \
-e CONVEX_SELF_HOSTED_URL \ -e CONVEX_SELF_HOSTED_URL \
-e CONVEX_SELF_HOSTED_ADMIN_KEY \ -e CONVEX_SELF_HOSTED_ADMIN_KEY \
node:20-bullseye bash -lc "set -euo pipefail; corepack enable; corepack prepare pnpm@9 --activate; mkdir -p \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm config set store-dir \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm install --frozen-lockfile --prod=false; pnpm exec convex deploy" node:20-bullseye bash -lc "set -euo pipefail; corepack enable; corepack prepare pnpm@10.20.0 --activate; mkdir -p \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm config set store-dir \"${PNPM_STORE_DIR:-/tmp/pnpm-store}\"; pnpm install --frozen-lockfile --prod=false; pnpm exec convex deploy"
- name: Cleanup old convex build workdirs (keep last 2) - name: Cleanup old convex build workdirs (keep last 2)
run: | run: |
@ -445,13 +448,12 @@ jobs:
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 9 version: 10.20.0
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
cache: 'pnpm'
- name: Install deps (desktop) - name: Install deps (desktop)
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
@ -513,7 +515,7 @@ jobs:
-v /srv/apps/sistema:/app -w /app \ -v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY="$ADMIN_KEY" \ -e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY="$ADMIN_KEY" \
-e MACHINE_PROVISIONING_SECRET -e MACHINE_TOKEN_TTL_MS -e FLEET_SYNC_SECRET \ -e MACHINE_PROVISIONING_SECRET -e MACHINE_TOKEN_TTL_MS -e FLEET_SYNC_SECRET \
node:20-bullseye bash -lc "set -euo pipefail; corepack enable; corepack prepare pnpm@9 --activate; pnpm i --frozen-lockfile --prod=false; \ node:20-bullseye bash -lc "set -euo pipefail; corepack enable; corepack prepare pnpm@10.20.0 --activate; pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; pnpm exec convex env list; \ unset CONVEX_DEPLOYMENT; pnpm exec convex env list; \
if [ -n \"$MACHINE_PROVISIONING_SECRET\" ]; then pnpm exec convex env set MACHINE_PROVISIONING_SECRET \"$MACHINE_PROVISIONING_SECRET\" -y; fi; \ if [ -n \"$MACHINE_PROVISIONING_SECRET\" ]; then pnpm exec convex env set MACHINE_PROVISIONING_SECRET \"$MACHINE_PROVISIONING_SECRET\" -y; fi; \
if [ -n \"$MACHINE_TOKEN_TTL_MS\" ]; then pnpm exec convex env set MACHINE_TOKEN_TTL_MS \"$MACHINE_TOKEN_TTL_MS\" -y; fi; \ if [ -n \"$MACHINE_TOKEN_TTL_MS\" ]; then pnpm exec convex env set MACHINE_TOKEN_TTL_MS \"$MACHINE_TOKEN_TTL_MS\" -y; fi; \

View file

@ -36,7 +36,7 @@ jobs:
node-version: 20 node-version: 20
- name: Enable Corepack - name: Enable Corepack
run: corepack enable && corepack prepare pnpm@9 --activate run: corepack enable && corepack prepare pnpm@10.20.0 --activate
- name: Install Rust (stable) - name: Install Rust (stable)
uses: dtolnay/rust-toolchain@stable uses: dtolnay/rust-toolchain@stable

View file

@ -22,16 +22,10 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
cache: pnpm
- name: Setup Bun - name: Setup Bun
uses: oven-sh/setup-bun@v2 uses: oven-sh/setup-bun@v2
@ -42,25 +36,25 @@ jobs:
run: bun --version run: bun --version
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: bun install --frozen-lockfile
- name: Cache Next.js build cache - name: Cache Next.js build cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: | path: |
${{ github.workspace }}/.next/cache ${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('**/*.{js,jsx,ts,tsx}') }} key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml', 'bun.lock') }}-${{ hashFiles('**/*.{js,jsx,ts,tsx}') }}
restore-keys: | restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}- ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml', 'bun.lock') }}-
- name: Generate Prisma client - name: Generate Prisma client
run: pnpm prisma:generate run: bun run prisma:generate
- name: Lint - name: Lint
run: pnpm lint run: bun run lint
- name: Test - name: Test
run: pnpm test run: bun test
- name: Build - name: Build
run: pnpm build:bun run: bun run build:bun

View file

@ -4,16 +4,16 @@ Aplicação **Next.js 16 (App Router)** com **React 19**, **Convex** e **Better
## Requisitos ## Requisitos
- Node.js >= 20 - Bun >= 1.3 (recomendado 1.3.1). Após instalar via script oficial, adicione `export PATH="$HOME/.bun/bin:$PATH"` ao seu shell (ex.: `.bashrc`) para ter `bun` disponível globalmente.
- pnpm >= 9 (habilite via `corepack prepare pnpm@9 --activate`) - Node.js >= 20 (necessário para ferramentas auxiliares como Prisma CLI e Next.js em modo fallback).
- (Opcional) Bun >= 1.3 para usar o runtime/test runner do Bun (`bun run --bun ...`). Após instalar via script oficial, adicione `export PATH="$HOME/.bun/bin:$PATH"` ao seu shell (ex.: `.bashrc`) para ter `bun` disponível globalmente. - pnpm >= 10 (opcional, usado apenas para fluxos do app desktop/Tauri ou como plano B).
- CLI do Convex (`pnpm dlx convex dev` instalará automaticamente no primeiro uso) - CLI do Convex (`bunx convex dev` instalará automaticamente no primeiro uso, se ainda não estiver presente).
## Configuração rápida ## Configuração rápida
1. Instale as dependências: 1. Instale as dependências:
```bash ```bash
pnpm install bun install
``` ```
2. Ajuste o arquivo `.env` (ou crie a partir de `.env.example`) e confirme os valores de: 2. Ajuste o arquivo `.env` (ou crie a partir de `.env.example`) e confirme os valores de:
- `NEXT_PUBLIC_CONVEX_URL` (gerado pelo Convex Dev) - `NEXT_PUBLIC_CONVEX_URL` (gerado pelo Convex Dev)
@ -33,14 +33,14 @@ Aplicação **Next.js 16 (App Router)** com **React 19**, **Convex** e **Better
``` ```
6. Em um terminal, execute o backend em tempo real do Convex: 6. Em um terminal, execute o backend em tempo real do Convex:
```bash ```bash
pnpm convex:dev:bun bun run convex:dev:bun
``` ```
> Alternativa: `pnpm convex:dev` (runtime Node) caso queira manter o comportamento anterior. > Alternativa: `bun run convex:dev` (runtime Node) caso queira manter o comportamento anterior.
7. Em outro terminal, suba o frontend Next.js (Turbopack): 7. Em outro terminal, suba o frontend Next.js (Turbopack):
```bash ```bash
pnpm dev:bun bun run dev:bun
``` ```
> Fallback: `pnpm dev` (Node) ou `pnpm dev:webpack` caso o Turbopack acione alguma incompatibilidade. > Fallback: `pnpm dev` (Node) ou `bun run dev:webpack` caso o Turbopack acione alguma incompatibilidade.
8. Com o Convex ativo, acesse `http://localhost:3000/dev/seed` uma vez para popular dados de demonstração (tickets, usuários, comentários) diretamente no banco do Convex. 8. Com o Convex ativo, acesse `http://localhost:3000/dev/seed` uma vez para popular dados de demonstração (tickets, usuários, comentários) diretamente no banco do Convex.
> Se o CLI perguntar sobre configuração do projeto Convex, escolha criar um novo deployment local (opção padrão) e confirme. As credenciais são armazenadas em `.convex/` automaticamente. > Se o CLI perguntar sobre configuração do projeto Convex, escolha criar um novo deployment local (opção padrão) e confirme. As credenciais são armazenadas em `.convex/` automaticamente.
@ -64,16 +64,16 @@ Para fluxos detalhados de desenvolvimento — banco de dados local (SQLite/Prism
## Scripts úteis ## Scripts úteis
- `pnpm dev:bun` — padrão atual para o Next.js com runtime Bun (`pnpm dev` usa Node como fallback). - `bun run dev:bun` — padrão atual para o Next.js com runtime Bun (`pnpm dev` usa Node como fallback).
- `pnpm convex:dev:bun` — runtime Bun para o Convex (`pnpm convex:dev` mantém o fluxo antigo). - `bun run convex:dev:bun` — runtime Bun para o Convex (`pnpm convex:dev` mantém o fluxo antigo).
- `pnpm build:bun` / `pnpm start:bun` — build e serve com Bun; use `pnpm build`/`pnpm start` se quiser ficar no Node. - `bun run build:bun` / `bun run start:bun` — build e serve com Bun; use `pnpm build`/`pnpm start` se quiser ficar no Node.
- `pnpm dev:webpack` / `pnpm build:webpack` — fallback oficial caso Turbopack apresente problemas. - `bun run dev:webpack` / `bun run build:webpack` — fallback oficial caso Turbopack apresente problemas.
- `pnpm lint` — ESLint com as regras do projeto. - `bun run lint` — ESLint com as regras do projeto.
- `pnpm test` — suíte de testes unitários (Vitest) em modo não interativo. - `bun test` — suíte de testes unitários usando o runner do Bun (o teste de screenshot fica automaticamente ignorado se o matcher não existir).
- `pnpm build` — `next build --turbopack` com otimizações para produção. - `bun run build` — executa `next build --turbopack` usando Node como fallback.
- `pnpm auth:seed` — atualiza/cria contas padrão do Better Auth (credenciais em `agents.md`). - `bun run auth:seed` — atualiza/cria contas padrão do Better Auth (credenciais em `agents.md`).
- `pnpm prisma migrate deploy` — aplica migrações ao banco SQLite local. - `bunx prisma migrate deploy` — aplica migrações ao banco SQLite local.
- `pnpm convex:dev` — roda o Convex em modo desenvolvimento, gerando tipos em `convex/_generated`. - `bun run convex:dev` — roda o Convex em modo desenvolvimento com Node, gerando tipos em `convex/_generated`.
## Transferir dispositivo entre colaboradores ## Transferir dispositivo entre colaboradores
@ -105,9 +105,10 @@ Consulte `PROXIMOS_PASSOS.md` para acompanhar o backlog funcional e o progresso
### Executar com Bun ### Executar com Bun
- `pnpm dev:bun`, `pnpm convex:dev:bun`, `pnpm build:bun` e `pnpm start:bun` já estão configurados; internamente executam `bun run --bun <script>` para usar o runtime do Bun sem abrir mão do `pnpm`. O `cross-env` garante os valores esperados de `NODE_ENV` (`development`/`production`) para evitar warning/bugs no Next. - `bun install` é o fluxo padrão (o arquivo `bun.lock` deve ser versionado; use `bun install --frozen-lockfile` em CI).
- Em caso de incompatibilidade do Turbopack (relatada em algumas combinações Bun + Next 16), use `pnpm dev:webpack` ou `pnpm build:webpack` como fallback imediato. - `bun run dev:bun`, `bun run convex:dev:bun`, `bun run build:bun` e `bun run start:bun` já estão configurados; internamente executam `bun run --bun <script>` para usar o runtime do Bun sem abrir mão dos scripts existentes. O `cross-env` garante os valores esperados de `NODE_ENV` (`development`/`production`).
- Os testes continuam sob Vitest (`pnpm test`). Avalie `bun test` somente após validar que os matchers/relatos necessários estão disponíveis. - Em caso de incompatibilidade do Turbopack (relatada em algumas combinações Bun + Next 16), use `bun run dev:webpack` ou `bun run build:webpack` como fallback imediato.
- `bun test` utiliza o test runner do Bun. O teste de snapshot de screenshot é automaticamente ignorado quando o matcher não está disponível; testes de navegador completos continuam via `bun run test:browser` (Vitest + Playwright).
<!-- ci: smoke test 3 --> <!-- ci: smoke test 3 -->

View file

@ -110,7 +110,7 @@ pnpm build
docker run --rm -it -e DATABASE_URL=file:/app/data/db.sqlite \ docker run --rm -it -e DATABASE_URL=file:/app/data/db.sqlite \
-v /home/renan/apps/sistema.current:/app \ -v /home/renan/apps/sistema.current:/app \
-v sistema_sistema_db:/app/data -w /app \ -v sistema_sistema_db:/app/data -w /app \
node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@9 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate resolve --rolled-back <migration>; pnpm exec prisma migrate deploy' node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@10.20.0 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate resolve --rolled-back <migration>; pnpm exec prisma migrate deploy'
docker service scale sistema_web=1 docker service scale sistema_web=1
``` ```

2386
bun.lock Normal file

File diff suppressed because it is too large Load diff

3
bunfig.toml Normal file
View file

@ -0,0 +1,3 @@
[test]
preload = ["./tests/setup/bun-test-env.ts"]
timeout = 15000

View file

@ -4,10 +4,10 @@ Este documento consolida o estado atual do ambiente de desenvolvimento, descreve
## Resumo rápido ## Resumo rápido
- **Node/PNPM**: Node 20.9+ (alinhado ao requisito do Next 15) + pnpm 9 (habilite via `corepack enable && corepack prepare pnpm@9 --activate`). - **Bun (runtime padrão)**: 1.3+ já instalado no runner e VPS (`bun --version`). Após instalar localmente, exporte `PATH="$HOME/.bun/bin:$PATH"` para tornar o binário disponível. Use `bun install`, `bun run dev:bun`, `bun run convex:dev:bun`, `bun run build:bun` e `bun test` como fluxo principal (scripts Node continuam disponíveis como fallback).
- **Bun (runtime padrão)**: 1.3+ já instalado no runner e VPS (`bun --version`). Após instalar localmente, exporte `PATH="$HOME/.bun/bin:$PATH"` para tornar o binário disponível. Use `pnpm dev:bun` / `pnpm convex:dev:bun` / `pnpm build:bun` / `pnpm start:bun` para executar os scripts com `bun run --bun` (scripts Node continuam disponíveis como fallback). - **Node/pnpm**: Node 20.9+ permanece obrigatório para ferramentas CLI; pnpm 10 está disponível como alternativa apenas para fluxos do desktop/Tauri.
- **Next.js 15.5.5**: Projeto voltou para a versão estável (`next@15.5.5`) com Turbopack como bundler padrão e whitelist de domínios garantida pelo middleware. - **Next.js 15.5.5**: Projeto voltou para a versão estável (`next@15.5.5`) com Turbopack como bundler padrão e whitelist de domínios garantida pelo middleware.
- **Lint/Test/Build**: `pnpm lint`, `pnpm test`, `pnpm build`. O script de testes usa `vitest --run --passWithNoTests`, eliminando o modo watch interativo. - **Lint/Test/Build**: `bun run lint`, `bun test`, `bun run build:bun`. O test runner do Bun já roda em modo não interativo; utilize `bunx vitest --watch` apenas quando precisar do modo watch manualmente.
- **Banco DEV**: SQLite em `prisma/prisma/db.dev.sqlite`. Defina `DATABASE_URL="file:./prisma/db.dev.sqlite"` ao chamar CLI do Prisma. - **Banco DEV**: SQLite em `prisma/prisma/db.dev.sqlite`. Defina `DATABASE_URL="file:./prisma/db.dev.sqlite"` ao chamar CLI do Prisma.
- **Desktop (Tauri)**: fonte em `apps/desktop`. Usa Radix tabs + componentes shadcn-like, integra com os endpoints `/api/machines/*` e suporta atualização automática via GitHub Releases. - **Desktop (Tauri)**: fonte em `apps/desktop`. Usa Radix tabs + componentes shadcn-like, integra com os endpoints `/api/machines/*` e suporta atualização automática via GitHub Releases.
- **CI**: Workflow `Quality Checks` roda lint/test/build para pushes e PRs na `main`, além do pipeline de deploy existente. - **CI**: Workflow `Quality Checks` roda lint/test/build para pushes e PRs na `main`, além do pipeline de deploy existente.
@ -17,17 +17,18 @@ Este documento consolida o estado atual do ambiente de desenvolvimento, descreve
1. Gere/atualize o schema local: 1. Gere/atualize o schema local:
```bash ```bash
DATABASE_URL="file:./prisma/db.dev.sqlite" pnpm exec prisma db push bun install
DATABASE_URL="file:./prisma/db.dev.sqlite" pnpm prisma:generate DATABASE_URL="file:./prisma/db.dev.sqlite" bunx prisma db push
DATABASE_URL="file:./prisma/db.dev.sqlite" pnpm auth:seed DATABASE_URL="file:./prisma/db.dev.sqlite" bun run prisma:generate
DATABASE_URL="file:./prisma/db.dev.sqlite" bun run auth:seed
``` ```
2. Rode o app Next.js: 2. Rode o app Next.js:
```bash ```bash
pnpm dev:bun bun run dev:bun
``` ```
> Alternativas: `pnpm dev` (Node) ou `pnpm dev:webpack` se precisar do fallback oficial. > Alternativas: `pnpm dev` (Node) ou `bun run dev:webpack` se precisar do fallback oficial.
3. Credenciais padrão (seed): `admin@sistema.dev / admin123`. 3. Credenciais padrão (seed): `admin@sistema.dev / admin123`.
4. Herdou dados antigos? Execute `node scripts/remove-legacy-demo-users.mjs` para limpar contas demo legadas. 4. Herdou dados antigos? Execute `node scripts/remove-legacy-demo-users.mjs` para limpar contas demo legadas.
@ -50,12 +51,12 @@ Este documento consolida o estado atual do ambiente de desenvolvimento, descreve
## Comandos de qualidade ## Comandos de qualidade
- `pnpm lint`: executa ESLint (flat config) sobre os arquivos do projeto. - `bun run lint`: executa ESLint (flat config) sobre os arquivos do projeto.
- `pnpm test`: Vitest em modo não interativo (`--run --passWithNoTests`). Use `pnpm test -- --watch` somente quando quiser rodar em watch localmente. Inclui testes de API (rotas `/api/machines/*`) e utilitários de SMTP. - `bun test`: roda a suíte de testes utilizando o runner nativo do Bun. Para modo watch, use `bunx vitest --watch` manualmente.
- `pnpm build`: `next build --turbopack`. - `bun run build:bun`: `next build --turbopack` usando o runtime Bun. `bun run build` permanece disponível como fallback em Node.
- Scripts com Bun (padrão atual): `pnpm dev:bun`, `pnpm convex:dev:bun`, `pnpm build:bun`, `pnpm start:bun`. Eles mantêm o `pnpm` como orquestrador, apenas forçando o runtime do Bun via `bun run --bun`. O `cross-env` garante `NODE_ENV` consistente (`development`/`production`) para evitar warnings/falhas no Next. - Scripts com Bun (padrão atual): `bun run dev:bun`, `bun run convex:dev:bun`, `bun run build:bun`, `bun run start:bun`. Eles mantêm os scripts existentes, apenas forçando o runtime do Bun via `bun run --bun`. O `cross-env` garante `NODE_ENV` consistente (`development`/`production`).
- Fallback Webpack disponível via `pnpm dev:webpack` / `pnpm build:webpack` quando Turbopack não coopera (caso observado em combinações Bun + Next 16). - Fallback Webpack disponível via `bun run dev:webpack` / `bun run build:webpack` quando Turbopack não coopera (caso observado em combinações Bun + Next 16).
- `pnpm prisma:generate`: necessário antes do build quando o client Prisma muda. - `bun run prisma:generate`: necessário antes do build quando o client Prisma muda. Para migrações use `bunx prisma migrate deploy`.
### Automação no CI ### Automação no CI
@ -63,17 +64,17 @@ Arquivo: `.github/workflows/quality-checks.yml`
Etapas: Etapas:
1. Instala dependências (`pnpm install --frozen-lockfile`). 1. Instala dependências (`bun install --frozen-lockfile`).
2. `pnpm prisma:generate`. 2. `bun run prisma:generate`.
3. `pnpm lint`. 3. `bun run lint`.
4. `pnpm test`. 4. `bun test`.
5. `pnpm build:bun` (Bun 1.3.1 instalado via `oven-sh/setup-bun`). 5. `bun run build:bun`.
O workflow dispara em todo `push`/`pull_request` para `main` e fornece feedback imediato sem depender do pipeline de deploy. O workflow dispara em todo `push`/`pull_request` para `main` e fornece feedback imediato sem depender do pipeline de deploy.
## Testes rápidos via curl (Convites & acessos) ## Testes rápidos via curl (Convites & acessos)
1. Rode `pnpm dev:bun` (ou `pnpm dev` se preferir Node) e autentique-se em `http://localhost:3000/login` usando `admin@sistema.dev / admin123`. 1. Rode `bun run dev:bun` (ou `pnpm dev` se preferir Node) e autentique-se em `http://localhost:3000/login` usando `admin@sistema.dev / admin123`.
2. Copie o valor do cookie `BETTER_AUTH_SESSION` e exporte no shell: `export COOKIE="BETTER_AUTH_SESSION=<valor>"`. 2. Copie o valor do cookie `BETTER_AUTH_SESSION` e exporte no shell: `export COOKIE="BETTER_AUTH_SESSION=<valor>"`.
### Usuários ### Usuários
@ -139,7 +140,7 @@ curl -i -X PATCH http://localhost:3000/api/admin/invites/$INVITE_ID \
### Build local ### Build local
```bash ```bash
corepack enable && corepack prepare pnpm@9 --activate corepack enable && corepack prepare pnpm@10.20.0 --activate
pnpm -C apps/desktop install pnpm -C apps/desktop install
VITE_APP_URL=http://localhost:3000 \ VITE_APP_URL=http://localhost:3000 \
VITE_API_BASE_URL=http://localhost:3000 \ VITE_API_BASE_URL=http://localhost:3000 \

View file

@ -203,7 +203,7 @@ docker run --rm -it \
-w /app \ -w /app \
-e CONVEX_SELF_HOSTED_URL=https://convex.esdrasrenan.com.br \ -e CONVEX_SELF_HOSTED_URL=https://convex.esdrasrenan.com.br \
-e CONVEX_SELF_HOSTED_ADMIN_KEY='COLE_A_CHAVE_AQUI' \ -e CONVEX_SELF_HOSTED_ADMIN_KEY='COLE_A_CHAVE_AQUI' \
node:20-bullseye bash -lc "corepack enable && corepack prepare pnpm@9 --activate && pnpm install --frozen-lockfile --prod=false && pnpm exec convex deploy" node:20-bullseye bash -lc "corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm install --frozen-lockfile --prod=false && pnpm exec convex deploy"
``` ```
Observação Observação
@ -231,7 +231,7 @@ docker run --rm -it \
-v /srv/apps/sistema:/app -w /app \ -v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL=https://convex.esdrasrenan.com.br \ -e CONVEX_SELF_HOSTED_URL=https://convex.esdrasrenan.com.br \
-e CONVEX_SELF_HOSTED_ADMIN_KEY='COLE_A_CHAVE' \ -e CONVEX_SELF_HOSTED_ADMIN_KEY='COLE_A_CHAVE' \
node:20-bullseye bash -lc "set -euo pipefail; corepack enable && corepack prepare pnpm@9 --activate && pnpm i --frozen-lockfile --prod=false; \ node:20-bullseye bash -lc "set -euo pipefail; corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; \ unset CONVEX_DEPLOYMENT; \
pnpm exec convex env set MACHINE_PROVISIONING_SECRET 'seu-hex' -y; \ pnpm exec convex env set MACHINE_PROVISIONING_SECRET 'seu-hex' -y; \
pnpm exec convex env list" pnpm exec convex env list"

View file

@ -17,7 +17,7 @@ docker run --rm -it \
-v /srv/apps/sistema:/app -w /app \ -v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \ -e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \
node:20-bullseye bash -lc "set -euo pipefail; \ node:20-bullseye bash -lc "set -euo pipefail; \
corepack enable && corepack prepare pnpm@9 --activate && pnpm i --frozen-lockfile --prod=false; \ corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; \ unset CONVEX_DEPLOYMENT; \
pnpm exec convex env set MACHINE_PROVISIONING_SECRET '71daa9ef54cb224547e378f8121ca898b614446c142a132f73c2221b4d53d7d6' -y; \ pnpm exec convex env set MACHINE_PROVISIONING_SECRET '71daa9ef54cb224547e378f8121ca898b614446c142a132f73c2221b4d53d7d6' -y; \
pnpm exec convex env list" pnpm exec convex env list"
@ -27,7 +27,7 @@ docker run --rm -it \
-v /srv/apps/sistema:/app -w /app \ -v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \ -e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \
node:20-bullseye bash -lc "set -euo pipefail; \ node:20-bullseye bash -lc "set -euo pipefail; \
corepack enable && corepack prepare pnpm@9 --activate && pnpm i --frozen-lockfile --prod=false; \ corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; \ unset CONVEX_DEPLOYMENT; \
pnpm exec convex env set MACHINE_TOKEN_TTL_MS '2592000000' -y; \ pnpm exec convex env set MACHINE_TOKEN_TTL_MS '2592000000' -y; \
pnpm exec convex env list" pnpm exec convex env list"
@ -37,7 +37,7 @@ docker run --rm -it \
-v /srv/apps/sistema:/app -w /app \ -v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \ -e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \
node:20-bullseye bash -lc "set -euo pipefail; \ node:20-bullseye bash -lc "set -euo pipefail; \
corepack enable && corepack prepare pnpm@9 --activate && pnpm i --frozen-lockfile --prod=false; \ corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; \ unset CONVEX_DEPLOYMENT; \
pnpm exec convex env set FLEET_SYNC_SECRET '' -y; \ pnpm exec convex env set FLEET_SYNC_SECRET '' -y; \
pnpm exec convex env list" pnpm exec convex env list"

View file

@ -24,8 +24,8 @@ Resultado: front/back sobem com o novo código sem editar o stack a cada release
- Mount fixo: `/home/renan/apps/sistema.current:/app` (não interpolar APP_DIR). - Mount fixo: `/home/renan/apps/sistema.current:/app` (não interpolar APP_DIR).
- Comando inline (sem script), com migrations na subida: - Comando inline (sem script), com migrations na subida:
- `command: ["bash","-lc","corepack enable && corepack prepare pnpm@9 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"]` - `command: ["bash","-lc","corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"]`
- **Se você optar por usar `/app/scripts/start-web.sh`** (como no workflow atual), ele já garante `pnpm@9` via Corepack/NPM antes de rodar Prisma/Next. Certifique-se de copiar esse arquivo para o build publicado; sem ele, a task cai com `pnpm: command not found`. - **Se você optar por usar `/app/scripts/start-web.sh`** (como no workflow atual), ele já garante `pnpm@10.20.0` via Corepack/NPM antes de rodar Prisma/Next. Certifique-se de copiar esse arquivo para o build publicado; sem ele, a task cai com `pnpm: command not found`.
- Env obrigatórias (URLs válidas): - Env obrigatórias (URLs válidas):
- `DATABASE_URL=file:/app/data/db.sqlite` - `DATABASE_URL=file:/app/data/db.sqlite`
- `NEXT_PUBLIC_CONVEX_URL=http://sistema_convex_backend:3210` - `NEXT_PUBLIC_CONVEX_URL=http://sistema_convex_backend:3210`
@ -43,7 +43,7 @@ APP_DIR=/home/renan/apps/sistema.current
docker run --rm -it \ docker run --rm -it \
-e DATABASE_URL=file:/app/data/db.sqlite \ -e DATABASE_URL=file:/app/data/db.sqlite \
-v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \ -v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \
node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@9 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate status' node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@10.20.0 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate status'
``` ```
## Diagnóstico rápido ## Diagnóstico rápido
@ -99,7 +99,7 @@ Causas encontradas:
docker service update \ docker service update \
--mount-rm target=/app \ --mount-rm target=/app \
--mount-add type=bind,src=/home/renan/apps/sistema.current,dst=/app \ --mount-add type=bind,src=/home/renan/apps/sistema.current,dst=/app \
--args 'bash -lc "corepack enable && corepack prepare pnpm@9 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"' \ --args 'bash -lc "corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"' \
sistema_web sistema_web
``` ```
@ -110,7 +110,7 @@ APP_DIR=/home/renan/apps/sistema.current
docker service scale sistema_web=0 docker service scale sistema_web=0
docker run --rm -it -e DATABASE_URL=file:/app/data/db.sqlite \ docker run --rm -it -e DATABASE_URL=file:/app/data/db.sqlite \
-v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \ -v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \
node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@9 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_code; pnpm exec prisma migrate deploy' node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@10.20.0 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_code; pnpm exec prisma migrate deploy'
docker service scale sistema_web=1 docker service scale sistema_web=1
``` ```

View file

@ -4,7 +4,7 @@ Guia rápido para gerar instaladores do app desktop em cada sistema operacional.
## Prérequisitos ## Prérequisitos
- Node.js 20+ e pnpm (Corepack habilitado): - Node.js 20+ e pnpm (Corepack habilitado):
- `corepack enable && corepack prepare pnpm@9 --activate` - `corepack enable && corepack prepare pnpm@10.20.0 --activate`
- Rust toolchain (stable) instalado. - Rust toolchain (stable) instalado.
- Dependências nativas por SO: - Dependências nativas por SO:
- Linux (Debian/Ubuntu): - Linux (Debian/Ubuntu):

View file

@ -11,9 +11,9 @@
"lint": "eslint", "lint": "eslint",
"prisma:generate": "prisma generate", "prisma:generate": "prisma generate",
"convex:dev": "convex dev", "convex:dev": "convex dev",
"test": "vitest --run --passWithNoTests", "test": "bun test",
"test:browser": "cross-env VITEST_BROWSER=true vitest --run --browser.headless tests/browser/example.browser.test.ts --passWithNoTests", "test:browser": "cross-env VITEST_BROWSER=true bunx vitest --run --browser.headless tests/browser/example.browser.test.ts --passWithNoTests",
"test:all": "cross-env VITEST_BROWSER=true vitest --run --passWithNoTests", "test:all": "cross-env VITEST_BROWSER=true bunx vitest --run --passWithNoTests",
"auth:seed": "node scripts/seed-auth.mjs", "auth:seed": "node scripts/seed-auth.mjs",
"queues:ensure": "node scripts/ensure-default-queues.mjs", "queues:ensure": "node scripts/ensure-default-queues.mjs",
"desktop:dev": "pnpm --filter appsdesktop tauri dev", "desktop:dev": "pnpm --filter appsdesktop tauri dev",
@ -87,6 +87,8 @@
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
"@tauri-apps/api": "^2.8.0", "@tauri-apps/api": "^2.8.0",
"@tauri-apps/cli": "^2.8.4", "@tauri-apps/cli": "^2.8.4",
"@types/bun": "^1.1.10",
"@types/jsdom": "^21.1.7",
"@types/node": "^20", "@types/node": "^20",
"@types/pdfkit": "^0.17.3", "@types/pdfkit": "^0.17.3",
"@types/react": "^18", "@types/react": "^18",
@ -109,5 +111,9 @@
"typescript-eslint": "^8.46.2", "typescript-eslint": "^8.46.2",
"vite-tsconfig-paths": "^5.1.4", "vite-tsconfig-paths": "^5.1.4",
"vitest": "^4.0.1" "vitest": "^4.0.1"
} },
"workspaces": [
".",
"apps/desktop"
]
} }

View file

@ -42,7 +42,7 @@ if echo "$CHANGED" | grep -q '^convex/'; then
-v "$APP_DIR":/app \ -v "$APP_DIR":/app \
-w /app \ -w /app \
--env-file .ci.env \ --env-file .ci.env \
node:20-bullseye bash -lc "corepack enable && corepack prepare pnpm@9 --activate && pnpm install --frozen-lockfile --prod=false && pnpm exec convex deploy" node:20-bullseye bash -lc "corepack enable && corepack prepare pnpm@10.20.0 --activate && pnpm install --frozen-lockfile --prod=false && pnpm exec convex deploy"
else else
echo "[deploy] convex/ changed but .ci.env missing; skip Convex deploy" echo "[deploy] convex/ changed but .ci.env missing; skip Convex deploy"
fi fi

View file

@ -34,7 +34,7 @@ ensure_pnpm() {
fi fi
if command -v corepack >/dev/null 2>&1; then if command -v corepack >/dev/null 2>&1; then
corepack prepare pnpm@9 --activate >/dev/null 2>&1 || true corepack prepare pnpm@10.20.0 --activate >/dev/null 2>&1 || true
corepack enable --install-directory "$local_bin" pnpm >/dev/null 2>&1 || true corepack enable --install-directory "$local_bin" pnpm >/dev/null 2>&1 || true
fi fi
@ -43,7 +43,7 @@ ensure_pnpm() {
fi fi
if command -v npm >/dev/null 2>&1; then if command -v npm >/dev/null 2>&1; then
npm install --prefix "$pnpm_prefix" pnpm@9 >/dev/null 2>&1 || true npm install --prefix "$pnpm_prefix" pnpm@10.20.0 >/dev/null 2>&1 || true
if [ -x "${pnpm_prefix}/node_modules/.bin/pnpm" ]; then if [ -x "${pnpm_prefix}/node_modules/.bin/pnpm" ]; then
ln -sf "${pnpm_prefix}/node_modules/.bin/pnpm" "${local_bin}/pnpm" >/dev/null 2>&1 || true ln -sf "${pnpm_prefix}/node_modules/.bin/pnpm" "${local_bin}/pnpm" >/dev/null 2>&1 || true
fi fi

View file

@ -1,6 +1,19 @@
import { expect, test } from "vitest" import { expect, test } from "bun:test"
test("CTA button snapshot", async () => { type ScreenshotMatcher = {
toMatchScreenshot: (name: string) => Promise<unknown> | unknown
}
function isScreenshotMatcher(value: unknown): value is ScreenshotMatcher {
return typeof value === "object" && value !== null && "toMatchScreenshot" in value &&
typeof (value as ScreenshotMatcher).toMatchScreenshot === "function"
}
const matcherProbe = expect({}) as unknown
const hasScreenshotMatcher = isScreenshotMatcher(matcherProbe)
const testFn = hasScreenshotMatcher ? test : test.skip
testFn("CTA button snapshot", async () => {
const html = ` const html = `
<main <main
style=" style="
@ -36,5 +49,8 @@ test("CTA button snapshot", async () => {
const ctaButton = document.querySelector("[data-testid='cta']") const ctaButton = document.querySelector("[data-testid='cta']")
expect(ctaButton).toBeTruthy() expect(ctaButton).toBeTruthy()
await expect(document.body).toMatchScreenshot("cta-button") const bodyExpectation = expect(document.body) as unknown
if (isScreenshotMatcher(bodyExpectation)) {
await bodyExpectation.toMatchScreenshot("cta-button")
}
}) })

View file

@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from "bun:test"
import { buildAssigneeChangeComment } from "../convex/tickets" import { buildAssigneeChangeComment } from "../convex/tickets"

View file

@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from "bun:test"
import { csvEscape, rowsToCsv } from "@/lib/csv" import { csvEscape, rowsToCsv } from "@/lib/csv"
describe("csvEscape", () => { describe("csvEscape", () => {

View file

@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from "bun:test"
import { normalizeDeviceRemoteAccess } from "@/components/admin/devices/admin-devices-overview" import { normalizeDeviceRemoteAccess } from "@/components/admin/devices/admin-devices-overview"

View file

@ -1,4 +1,4 @@
import { describe, it, expect, vi } from "vitest" import { describe, it, expect, vi } from "bun:test"
// Mock tls to simulate an SMTP server over implicit TLS // Mock tls to simulate an SMTP server over implicit TLS
let lastWrites: string[] = [] let lastWrites: string[] = []
@ -13,7 +13,7 @@ vi.mock("tls", () => {
private enqueue(messages: string | string[], type: "data" | "end" = "data") { private enqueue(messages: string | string[], type: "data" | "end" = "data") {
const chunks = Array.isArray(messages) ? messages : [messages] const chunks = Array.isArray(messages) ? messages : [messages]
chunks.forEach((chunk, index) => { chunks.forEach((chunk, index) => {
const delay = index === 0 ? 0 : 1 const delay = index === 0 ? 0 : 10 // garante tempo para que o próximo `wait(...)` anexe o listener
setTimeout(() => { setTimeout(() => {
if (type === "end") { if (type === "end") {
void chunk void chunk

View file

@ -1,4 +1,4 @@
import { describe, expect, test } from "vitest" import { describe, expect, test } from "bun:test"
import { import {
canReactivateInvite, canReactivateInvite,

View file

@ -1,4 +1,4 @@
import { describe, it, expect, vi } from "vitest" import { describe, it, expect, vi } from "bun:test"
import type { Doc, Id } from "../convex/_generated/dataModel" import type { Doc, Id } from "../convex/_generated/dataModel"
import { getByIdHandler } from "../convex/machines" import { getByIdHandler } from "../convex/machines"

View file

@ -1,4 +1,4 @@
import { describe, expect, it, vi } from "vitest" import { describe, expect, it, vi } from "bun:test"
import type { Doc, Id } from "../convex/_generated/dataModel" import type { Doc, Id } from "../convex/_generated/dataModel"
import { getTicketsHistoryStatsHandler, listTicketsHistoryHandler } from "../convex/machines" import { getTicketsHistoryStatsHandler, listTicketsHistoryHandler } from "../convex/machines"

View file

@ -1,4 +1,4 @@
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest" import { afterAll, beforeAll, describe, expect, it, vi } from "bun:test"
import { updatePersonaHandler } from "../convex/machines" import { updatePersonaHandler } from "../convex/machines"
import type { Doc, Id } from "../convex/_generated/dataModel" import type { Doc, Id } from "../convex/_generated/dataModel"

View file

@ -1,4 +1,4 @@
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest" import { afterAll, beforeAll, describe, expect, it, vi } from "bun:test"
vi.mock("../convex/rbac", () => ({ vi.mock("../convex/rbac", () => ({
requireStaff: vi.fn(), requireStaff: vi.fn(),

View file

@ -1,4 +1,4 @@
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest" import { afterAll, beforeAll, describe, expect, it, vi } from "bun:test"
vi.mock("../convex/rbac", () => ({ vi.mock("../convex/rbac", () => ({
requireStaff: vi.fn(), requireStaff: vi.fn(),

View file

@ -1,4 +1,4 @@
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest" import { afterAll, beforeAll, describe, expect, it, vi } from "bun:test"
vi.mock("../convex/rbac", () => ({ vi.mock("../convex/rbac", () => ({
requireStaff: vi.fn(), requireStaff: vi.fn(),

View file

@ -1,4 +1,4 @@
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest" import { afterAll, beforeAll, describe, expect, it, vi } from "bun:test"
vi.mock("../convex/rbac", () => ({ vi.mock("../convex/rbac", () => ({
requireStaff: vi.fn(), requireStaff: vi.fn(),

View file

@ -0,0 +1,96 @@
import "tsconfig-paths/register"
import { vi } from "bun:test"
import { JSDOM } from "jsdom"
// Provide default environment variables expected across the test suite.
process.env.BETTER_AUTH_SECRET ??= "test-secret"
process.env.NEXT_PUBLIC_APP_URL ??= "http://localhost:3000"
process.env.BETTER_AUTH_URL ??= process.env.NEXT_PUBLIC_APP_URL
const OriginalDate = Date
let fixedTimestamp: number | null = null
type MutableVi = typeof vi & {
mocked?: <T>(item: T) => T
setSystemTime?: (value: number | Date) => void
useFakeTimers?: (...args: Array<unknown>) => void
useRealTimers?: (...args: Array<unknown>) => void
}
const viExtended = vi as MutableVi
if (typeof window === "undefined" || typeof document === "undefined") {
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
url: process.env.NEXT_PUBLIC_APP_URL,
})
const globals = dom.window as unknown as Record<string, unknown>
const globalTarget = globalThis as Record<string, unknown>
for (const key of ["window", "document", "navigator", "HTMLElement", "HTMLAnchorElement", "Node", "Text"]) {
if (!(key in globalTarget)) {
globalTarget[key] = globals[key]
}
}
}
const applyFixedDate = () => {
if (fixedTimestamp === null) {
globalThis.Date = OriginalDate
return
}
const ts = fixedTimestamp
class MockDate extends OriginalDate {
constructor(...args: ConstructorParameters<typeof OriginalDate>) {
if (args.length < 1) {
super(ts)
return
}
super(...args)
}
static now(): number {
return ts
}
}
globalThis.Date = MockDate as unknown as DateConstructor
}
if (!viExtended.mocked) {
viExtended.mocked = <T>(item: T) => item
}
if (!viExtended.setSystemTime) {
viExtended.setSystemTime = (value: number | Date) => {
fixedTimestamp = typeof value === "number" ? value : value.getTime()
applyFixedDate()
}
}
if (!viExtended.useFakeTimers) {
viExtended.useFakeTimers = () => {
// Bun's fake timers are not required for our current tests. This is a noop
// placeholder to keep compatibility with the previous Vitest API.
}
} else {
const originalUseFakeTimers = viExtended.useFakeTimers.bind(vi)
viExtended.useFakeTimers = (...args: Array<unknown>) => {
originalUseFakeTimers(...args)
}
}
if (!viExtended.useRealTimers) {
viExtended.useRealTimers = () => {
fixedTimestamp = null
applyFixedDate()
}
} else {
const originalUseRealTimers = viExtended.useRealTimers.bind(vi)
viExtended.useRealTimers = (...args: Array<unknown>) => {
originalUseRealTimers(...args)
fixedTimestamp = null
applyFixedDate()
}
}
applyFixedDate()

View file

@ -1,4 +1,4 @@
import { describe, expect, it, vi } from "vitest" import { describe, expect, it, vi } from "bun:test"
import { buildCommentAuthorSummary } from "../convex/tickets" import { buildCommentAuthorSummary } from "../convex/tickets"
import type { Doc, Id } from "../convex/_generated/dataModel" import type { Doc, Id } from "../convex/_generated/dataModel"

View file

@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from "bun:test"
import { normalizeCustomFieldInputs } from "../src/lib/ticket-form-helpers" import { normalizeCustomFieldInputs } from "../src/lib/ticket-form-helpers"
import type { TicketFormFieldDefinition } from "../src/lib/ticket-form-types" import type { TicketFormFieldDefinition } from "../src/lib/ticket-form-types"

View file

@ -1,7 +1,7 @@
/** /**
* @vitest-environment jsdom * @vitest-environment jsdom
*/ */
import { describe, expect, it } from "vitest" import { describe, expect, it } from "bun:test"
import { normalizeTicketMentionHtml } from "@/components/ui/rich-text-editor" import { normalizeTicketMentionHtml } from "@/components/ui/rich-text-editor"

View file

@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from "bun:test"
import { deriveServerOffset, reconcileLocalSessionStart, toServerTimestamp } from "@/components/tickets/ticket-timer.utils" import { deriveServerOffset, reconcileLocalSessionStart, toServerTimestamp } from "@/components/tickets/ticket-timer.utils"
describe("reconcileLocalSessionStart", () => { describe("reconcileLocalSessionStart", () => {

View file

@ -1,4 +1,4 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" import { afterEach, beforeEach, describe, expect, it, vi } from "bun:test"
import type { Doc, Id } from "../convex/_generated/dataModel" import type { Doc, Id } from "../convex/_generated/dataModel"
import { resolveTicketHandler, reopenTicketHandler } from "../convex/tickets" import { resolveTicketHandler, reopenTicketHandler } from "../convex/tickets"

View file

@ -1,4 +1,4 @@
import { afterEach, describe, expect, it, vi } from "vitest" import { afterEach, describe, expect, it, vi } from "bun:test"
import type { Doc, Id } from "../convex/_generated/dataModel" import type { Doc, Id } from "../convex/_generated/dataModel"
import { submitCsatHandler } from "../convex/tickets" import { submitCsatHandler } from "../convex/tickets"

View file

@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest" import { describe, expect, it } from "bun:test"
import { dateKeyTZ, isAtHourTZ } from "@/lib/time" import { dateKeyTZ, isAtHourTZ } from "@/lib/time"
describe("time tz helpers", () => { describe("time tz helpers", () => {

View file

@ -1,4 +1,4 @@
import { vi } from "vitest" import { vi } from "bun:test"
import type { Doc, Id } from "../../convex/_generated/dataModel" import type { Doc, Id } from "../../convex/_generated/dataModel"