Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb05c538b3 | ||
|
|
0d151571c8 | ||
|
|
1c898f36d6 | ||
|
|
364c944ca6 | ||
|
|
aa062644c8 | ||
|
|
3d7cb4499f | ||
|
|
9d808302aa | ||
|
|
514d0017ea | ||
|
|
90cced0e74 | ||
|
|
4d0b8a8644 | ||
|
|
9d57bc39e5 | ||
|
|
b421efbff7 | ||
|
|
e27a8b5107 | ||
|
|
4797f97a95 | ||
|
|
2f3399fd5f | ||
|
|
61f9cf9260 | ||
|
|
ef003fb929 | ||
|
|
62a634831d | ||
|
|
1ec7244d1b | ||
|
|
13e569eaac | ||
|
|
1affa1e004 | ||
|
|
c53a13417e | ||
|
|
e5e3132ddd | ||
|
|
4965790ecc | ||
|
|
fc2b1de860 | ||
|
|
12257f4cc7 | ||
|
|
57d8954973 | ||
|
|
cfeea43eaf | ||
|
|
5853891b02 | ||
|
|
38ad0820c0 | ||
|
|
647c32ff3e | ||
|
|
7293d4c1f8 | ||
|
|
1acbf28316 | ||
|
|
1decd40eea | ||
|
|
1b9d188e4a | ||
|
|
57499342f1 | ||
|
|
ecbc0ac013 | ||
|
|
c571473d67 | ||
|
|
2a82df7073 | ||
|
|
a2f80d882b | ||
|
|
abd9709291 | ||
|
|
9d4ff7820d | ||
|
|
4cfd738312 | ||
|
|
0e89c96170 | ||
|
|
bfa50f566e | ||
|
|
338a38682d | ||
|
|
6a2e0182ab | ||
|
|
72086fe111 | ||
|
|
228865bd94 | ||
|
|
2493adbb87 | ||
|
|
26f0a416a1 | ||
|
|
c41a8e2b23 | ||
|
|
4c001778c2 | ||
|
|
911a46aa45 | ||
|
|
c53d281960 | ||
|
|
7f6b270a76 | ||
|
|
c94657dc0a | ||
|
|
aeedcf3353 |
@@ -8,7 +8,7 @@ alwaysApply: true
|
||||
## Formatting Standards
|
||||
- **Prettier**: 2-space indentation, single quotes, trailing commas, semicolons
|
||||
- **Print width**: 80 characters
|
||||
- **ESLint**: No unused imports, consistent import ordering, prefer const over let
|
||||
- **Oxlint**: No unused imports, consistent import ordering, prefer const over let
|
||||
|
||||
## Naming Conventions
|
||||
```typescript
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
description: ESM dependency guidelines for twenty-sdk and create-twenty-app packages
|
||||
globs: ["packages/twenty-sdk/**", "packages/create-twenty-app/**"]
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# ESM Dependency Guidelines
|
||||
|
||||
## Context
|
||||
|
||||
`twenty-sdk` and `create-twenty-app` are published as dual-format npm packages (ESM `.mjs` + CJS `.cjs`). Dependencies listed in `dependencies` are **externalized** by the Vite/Rollup build — they are not bundled, and consumers resolve them from `node_modules` at runtime.
|
||||
|
||||
This means **CJS-only dependencies break the ESM output**. When Rollup emits `import { foo } from 'cjs-package'`, Node.js ESM cannot resolve named exports from CommonJS modules, causing `SyntaxError: Named export 'foo' not found`.
|
||||
|
||||
## Rules
|
||||
|
||||
### Only add ESM-compatible dependencies
|
||||
|
||||
Before adding a new dependency to `package.json`, verify it supports ESM:
|
||||
- Check for `"type": "module"` in its `package.json`
|
||||
- Or check for an `"exports"` map with ESM entries
|
||||
- Or check for a `"module"` field pointing to an ESM build
|
||||
|
||||
### Use native `node:fs/promises` for standard fs operations
|
||||
|
||||
```typescript
|
||||
// ✅ Import native fs functions directly
|
||||
import { readFile, writeFile, mkdir, rm, cp } from 'node:fs/promises';
|
||||
import { createWriteStream, existsSync } from 'node:fs';
|
||||
|
||||
// ✅ Import only custom helpers from fs-utils (no native re-exports)
|
||||
import { pathExists, ensureDir, emptyDir, copy, move, remove, readJson, writeJson, ensureFile } from '@/cli/utilities/file/fs-utils';
|
||||
|
||||
// ❌ Don't use fs-extra (CJS-only, breaks ESM bundle)
|
||||
import * as fs from 'fs-extra';
|
||||
|
||||
// ❌ Don't use import * as fs from fs-utils (it doesn't re-export native fs)
|
||||
import * as fs from '@/cli/utilities/file/fs-utils';
|
||||
```
|
||||
|
||||
### Use `@/cli/utilities/string/kebab-case` instead of lodash
|
||||
|
||||
```typescript
|
||||
// ✅ Use internal utility
|
||||
import { kebabCase } from '@/cli/utilities/string/kebab-case';
|
||||
|
||||
// ❌ Don't use lodash single-function packages (CJS-only, unmaintained)
|
||||
import kebabCase from 'lodash.kebabcase';
|
||||
```
|
||||
|
||||
### When no ESM alternative exists
|
||||
|
||||
If a CJS-only package has no ESM replacement (e.g. `archiver`), add it to the `cjsOnlyPackages` list in `vite.config.node.ts` so it gets inlined into the bundle instead of externalized.
|
||||
@@ -15,6 +15,9 @@ inputs:
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Fetch main branch for diff
|
||||
shell: bash
|
||||
run: git fetch origin main --depth=1
|
||||
- name: Get last successful commit
|
||||
uses: nrwl/nx-set-shas@v4
|
||||
- name: Run affected command
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Check for changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v45
|
||||
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
- name: Checkout current branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
|
||||
- name: Try to merge main into current branch
|
||||
id: merge_attempt
|
||||
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Build
|
||||
|
||||
@@ -21,7 +21,6 @@ jobs:
|
||||
files: |
|
||||
package.json
|
||||
packages/twenty-docs/**
|
||||
eslint.config.mjs
|
||||
|
||||
docs-lint:
|
||||
needs: changed-files-check
|
||||
@@ -37,11 +36,11 @@ jobs:
|
||||
- name: Fetch local actions
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
|
||||
- name: Docs / Lint English MDX files
|
||||
run: npx eslint "packages/twenty-docs/{developers,user-guide,twenty-ui,getting-started,snippets}/**/*.mdx" --max-warnings 0
|
||||
- name: Docs / Lint
|
||||
run: npx nx lint twenty-docs
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Build twenty-emails
|
||||
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
- name: Fetch local actions
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Diagnostic disk space issue
|
||||
@@ -62,6 +62,12 @@ jobs:
|
||||
run: npx nx reset:env twenty-front
|
||||
- name: Front / Build storybook
|
||||
run: npx nx storybook:build twenty-front
|
||||
- name: Upload storybook build
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: storybook-static
|
||||
path: packages/twenty-front/storybook-static
|
||||
retention-days: 1
|
||||
- name: Save storybook build cache
|
||||
uses: ./.github/actions/save-cache
|
||||
with:
|
||||
@@ -78,26 +84,41 @@ jobs:
|
||||
env:
|
||||
SHARD_COUNTER: 4
|
||||
REACT_APP_SERVER_BASE_URL: http://localhost:3000
|
||||
STORYBOOK_URL: http://localhost:6006
|
||||
steps:
|
||||
- name: Fetch local actions
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Restore storybook build cache
|
||||
uses: ./.github/actions/restore-cache
|
||||
with:
|
||||
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION }}
|
||||
- name: Clean stale storybook vitest cache
|
||||
run: rm -rf packages/twenty-front/node_modules/.cache/storybook
|
||||
- name: Build dependencies
|
||||
run: |
|
||||
npx nx build twenty-shared
|
||||
npx nx build twenty-ui
|
||||
npx nx build twenty-sdk
|
||||
- name: Download storybook build
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: storybook-static
|
||||
path: packages/twenty-front/storybook-static
|
||||
- name: Install Playwright
|
||||
run: |
|
||||
cd packages/twenty-front
|
||||
npx playwright install
|
||||
- name: Front / Write .env
|
||||
run: npx nx reset:env twenty-front
|
||||
- name: Run storybook tests
|
||||
run: npx nx storybook:test twenty-front --configuration=${{ matrix.storybook_scope }} --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }}
|
||||
- name: Serve storybook & run tests
|
||||
run: |
|
||||
npx http-server packages/twenty-front/storybook-static --port 6006 --silent &
|
||||
timeout 30 bash -c 'until curl -sf http://localhost:6006 > /dev/null 2>&1; do sleep 1; done'
|
||||
npx nx storybook:test twenty-front --configuration=${{ matrix.storybook_scope }} --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }}
|
||||
# - name: Rename coverage file
|
||||
# run: |
|
||||
# if [ -f "packages/twenty-front/coverage/storybook/coverage-final.json" ]; then
|
||||
@@ -125,7 +146,7 @@ jobs:
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# fetch-depth: 10
|
||||
# - name: Install dependencies
|
||||
# uses: ./.github/actions/yarn-install
|
||||
# - uses: actions/download-artifact@v4
|
||||
@@ -150,7 +171,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Restore storybook build cache
|
||||
@@ -184,7 +205,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Restore ${{ matrix.task }} cache
|
||||
@@ -214,6 +235,7 @@ jobs:
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=10240"
|
||||
ANALYZE: "true"
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/[email protected]
|
||||
@@ -222,7 +244,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Front / Write .env
|
||||
@@ -268,7 +290,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Build
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Build
|
||||
|
||||
@@ -13,7 +13,7 @@ concurrency:
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
env:
|
||||
SERVER_SETUP_CACHE_KEY: server-setup
|
||||
SERVER_BUILD_CACHE_KEY: server-build
|
||||
|
||||
jobs:
|
||||
changed-files-check:
|
||||
@@ -27,11 +27,59 @@ jobs:
|
||||
packages/twenty-front/src/generated-metadata/**
|
||||
packages/twenty-emails/**
|
||||
packages/twenty-shared/**
|
||||
server-setup:
|
||||
|
||||
server-build:
|
||||
needs: changed-files-check
|
||||
if: needs.changed-files-check.outputs.any_changed == 'true'
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
steps:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Restore server build cache
|
||||
id: restore-server-build-cache
|
||||
uses: ./.github/actions/restore-cache
|
||||
with:
|
||||
key: ${{ env.SERVER_BUILD_CACHE_KEY }}
|
||||
- name: Build twenty-shared
|
||||
run: npx nx build twenty-shared
|
||||
- name: Server / Write .env
|
||||
run: npx nx reset:env twenty-server
|
||||
- name: Server / Build
|
||||
run: npx nx build twenty-server
|
||||
- name: Save server build cache
|
||||
uses: ./.github/actions/save-cache
|
||||
with:
|
||||
key: ${{ steps.restore-server-build-cache.outputs.cache-primary-key }}
|
||||
|
||||
server-lint-typecheck:
|
||||
needs: changed-files-check
|
||||
if: needs.changed-files-check.outputs.any_changed == 'true'
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
steps:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Build twenty-shared
|
||||
run: npx nx build twenty-shared
|
||||
- name: Server / Run lint & typecheck
|
||||
uses: ./.github/actions/nx-affected
|
||||
with:
|
||||
tag: scope:backend
|
||||
tasks: lint,typecheck
|
||||
|
||||
server-validation:
|
||||
needs: server-build
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
services:
|
||||
postgres:
|
||||
image: twentycrm/twenty-postgres-spilo
|
||||
@@ -55,21 +103,15 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Restore server setup
|
||||
id: restore-server-setup-cache
|
||||
- name: Restore server build cache
|
||||
uses: ./.github/actions/restore-cache
|
||||
with:
|
||||
key: ${{ env.SERVER_SETUP_CACHE_KEY }}
|
||||
key: ${{ env.SERVER_BUILD_CACHE_KEY }}
|
||||
- name: Build twenty-shared
|
||||
run: npx nx build twenty-shared
|
||||
- name: Server / Run lint & typecheck
|
||||
uses: ./.github/actions/nx-affected
|
||||
with:
|
||||
tag: scope:backend
|
||||
tasks: lint,typecheck
|
||||
- name: Server / Write .env
|
||||
run: npx nx reset:env twenty-server
|
||||
- name: Server / Build
|
||||
@@ -84,10 +126,8 @@ jobs:
|
||||
run: |
|
||||
timeout 30s npx nx run twenty-server:worker || exit_code=$?
|
||||
if [ $exit_code -eq 124 ]; then
|
||||
# If timeout was reached (exit code 124), consider it a success
|
||||
exit 0
|
||||
elif [ $exit_code -ne 0 ]; then
|
||||
# If worker failed for other reasons, fail the build
|
||||
exit $exit_code
|
||||
fi
|
||||
- name: Server / Start
|
||||
@@ -120,11 +160,9 @@ jobs:
|
||||
fi
|
||||
- name: GraphQL / Check for Pending Generation
|
||||
run: |
|
||||
# Run GraphQL generation commands
|
||||
npx nx run twenty-front:graphql:generate
|
||||
npx nx run twenty-front:graphql:generate --configuration=metadata
|
||||
|
||||
# Check if GraphQL generated files were modified
|
||||
if ! git diff --quiet -- packages/twenty-front/src/generated packages/twenty-front/src/generated-metadata; then
|
||||
echo "::error::GraphQL schema changes detected. Please run 'npx nx run twenty-front:graphql:generate' and 'npx nx run twenty-front:graphql:generate --configuration=metadata' and commit the changes."
|
||||
echo ""
|
||||
@@ -137,25 +175,24 @@ jobs:
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
- name: Save server setup
|
||||
uses: ./.github/actions/save-cache
|
||||
with:
|
||||
key: ${{ steps.restore-server-setup-cache.outputs.cache-primary-key }}
|
||||
|
||||
server-test:
|
||||
needs: server-build
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
needs: server-setup
|
||||
steps:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Restore server setup
|
||||
- name: Restore server build cache
|
||||
uses: ./.github/actions/restore-cache
|
||||
with:
|
||||
key: ${{ env.SERVER_SETUP_CACHE_KEY }}
|
||||
key: ${{ env.SERVER_BUILD_CACHE_KEY }}
|
||||
- name: Build twenty-shared
|
||||
run: npx nx build twenty-shared
|
||||
- name: Server / Run Tests
|
||||
uses: ./.github/actions/nx-affected
|
||||
with:
|
||||
@@ -165,11 +202,11 @@ jobs:
|
||||
server-integration-test:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
needs: server-setup
|
||||
needs: server-build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
services:
|
||||
postgres:
|
||||
image: twentycrm/twenty-postgres-spilo
|
||||
@@ -207,12 +244,12 @@ jobs:
|
||||
ANALYTICS_ENABLED: true
|
||||
CLICKHOUSE_URL: "http://default:clickhousePassword@localhost:8123/twenty"
|
||||
CLICKHOUSE_PASSWORD: clickhousePassword
|
||||
SHARD_COUNTER: 8
|
||||
SHARD_COUNTER: 10
|
||||
steps:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Update .env.test for integrations tests
|
||||
@@ -223,10 +260,10 @@ jobs:
|
||||
echo "BILLING_STRIPE_BASE_PLAN_PRODUCT_ID=test-base-plan-product-id" >> .env.test
|
||||
echo "BILLING_STRIPE_WEBHOOK_SECRET=test-webhook-secret" >> .env.test
|
||||
echo "BILLING_PLAN_REQUIRED_LINK=http://localhost:3001/stripe-redirection" >> .env.test
|
||||
- name: Restore server setup
|
||||
- name: Restore server build cache
|
||||
uses: ./.github/actions/restore-cache
|
||||
with:
|
||||
key: ${{ env.SERVER_SETUP_CACHE_KEY }}
|
||||
key: ${{ env.SERVER_BUILD_CACHE_KEY }}
|
||||
- name: Server / Build
|
||||
run: npx nx build twenty-server
|
||||
- name: Build dependencies
|
||||
@@ -247,11 +284,20 @@ jobs:
|
||||
tasks: 'test:integration'
|
||||
configuration: 'with-db-reset'
|
||||
args: --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }}
|
||||
|
||||
ci-server-status-check:
|
||||
if: always() && !cancelled()
|
||||
timeout-minutes: 5
|
||||
runs-on: ubuntu-latest
|
||||
needs: [changed-files-check, server-setup, server-test, server-integration-test]
|
||||
needs:
|
||||
[
|
||||
changed-files-check,
|
||||
server-build,
|
||||
server-lint-typecheck,
|
||||
server-validation,
|
||||
server-test,
|
||||
server-integration-test,
|
||||
]
|
||||
steps:
|
||||
- name: Fail job if any needs failed
|
||||
if: contains(needs.*.result, 'failure')
|
||||
|
||||
@@ -36,13 +36,13 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Run ${{ matrix.task }} task
|
||||
uses: ./.github/actions/nx-affected
|
||||
with:
|
||||
tag: scope:frontend
|
||||
tag: scope:shared
|
||||
tasks: ${{ matrix.task }}
|
||||
ci-shared-status-check:
|
||||
if: always() && !cancelled()
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
- name: Fetch custom Github Actions and base branch history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 10
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/yarn-install
|
||||
- name: Build
|
||||
|
||||
@@ -164,4 +164,4 @@ jobs:
|
||||
token: ${{ secrets.CI_PRIVILEGED_DISPATCH_TOKEN }}
|
||||
repository: twentyhq/ci-privileged
|
||||
event-type: claude-cross-repo-response
|
||||
client-payload: '{"repo": ${{ toJSON(steps.prompt.outputs.repo) }}, "issue_number": ${{ toJSON(steps.prompt.outputs.issue_number) }}, "run_id": ${{ toJSON(github.run_id) }}, "run_url": ${{ toJSON(format('{0}/{1}/actions/runs/{2}', github.server_url, github.repository, github.run_id)) }}}'
|
||||
client-payload: '{"repo": ${{ toJSON(steps.prompt.outputs.repo) }}, "issue_number": ${{ toJSON(steps.prompt.outputs.issue_number) }}, "run_id": ${{ toJSON(github.run_id) }}, "run_url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}'
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ coverage
|
||||
dist
|
||||
storybook-static
|
||||
*.tsbuildinfo
|
||||
.eslintcache
|
||||
.oxlintcache
|
||||
.nyc_output
|
||||
test-results/
|
||||
dump.rdb
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"arcanis.vscode-zipfs",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"oxc.oxc-vscode",
|
||||
"esbenp.prettier-vscode",
|
||||
"figma.figma-vscode-extension",
|
||||
"firsttris.vscode-jest-runner",
|
||||
|
||||
Vendored
+10
-7
@@ -4,25 +4,28 @@
|
||||
"files.insertFinalNewline": true,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.oxc": "explicit",
|
||||
"source.addMissingImports": "always",
|
||||
"source.organizeImports": "always"
|
||||
}
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.oxc": "explicit",
|
||||
"source.addMissingImports": "always",
|
||||
"source.organizeImports": "always"
|
||||
}
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.oxc": "explicit",
|
||||
"source.addMissingImports": "always",
|
||||
"source.organizeImports": "always"
|
||||
}
|
||||
@@ -48,7 +51,7 @@
|
||||
"search.exclude": {
|
||||
"**/.yarn": true
|
||||
},
|
||||
"eslint.debug": true,
|
||||
"oxc.lint.enable": true,
|
||||
"files.associations": {
|
||||
".cursorrules": "markdown"
|
||||
},
|
||||
|
||||
Vendored
+13
-9
@@ -37,8 +37,8 @@
|
||||
"path": "../packages/twenty-zapier"
|
||||
},
|
||||
{
|
||||
"name": "tools/eslint-rules",
|
||||
"path": "../tools/eslint-rules"
|
||||
"name": "packages/twenty-oxlint-rules",
|
||||
"path": "../packages/twenty-oxlint-rules"
|
||||
},
|
||||
{
|
||||
"name": "packages/twenty-e2e-testing",
|
||||
@@ -49,23 +49,26 @@
|
||||
"editor.formatOnSave": false,
|
||||
"files.eol": "auto",
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.oxc": "explicit",
|
||||
"source.addMissingImports": "always"
|
||||
}
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.oxc": "explicit",
|
||||
"source.addMissingImports": "always"
|
||||
}
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.formatOnSave": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.oxc": "explicit",
|
||||
"source.addMissingImports": "always"
|
||||
}
|
||||
},
|
||||
@@ -88,7 +91,7 @@
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative",
|
||||
"[javascript][typescript][typescriptreact]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.oxc": "explicit",
|
||||
"source.addMissingImports": "always"
|
||||
}
|
||||
},
|
||||
@@ -98,6 +101,7 @@
|
||||
"files.exclude": {
|
||||
"packages/": true
|
||||
},
|
||||
"oxc.lint.enable": true,
|
||||
"jest.runMode": "on-demand",
|
||||
"jest.disabledWorkspaceFolders": [
|
||||
"ROOT",
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
import js from '@eslint/js';
|
||||
import nxPlugin from '@nx/eslint-plugin';
|
||||
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||
import typescriptParser from '@typescript-eslint/parser';
|
||||
import importPlugin from 'eslint-plugin-import';
|
||||
import linguiPlugin from 'eslint-plugin-lingui';
|
||||
import * as mdxPlugin from 'eslint-plugin-mdx';
|
||||
import preferArrowPlugin from 'eslint-plugin-prefer-arrow';
|
||||
import prettierPlugin from 'eslint-plugin-prettier';
|
||||
import unicornPlugin from 'eslint-plugin-unicorn';
|
||||
import unusedImportsPlugin from 'eslint-plugin-unused-imports';
|
||||
import jsoncParser from 'jsonc-eslint-parser';
|
||||
|
||||
const twentyRules = await nxPlugin.loadWorkspaceRules(
|
||||
'packages/twenty-eslint-rules',
|
||||
);
|
||||
|
||||
export default [
|
||||
// Base JavaScript configuration
|
||||
js.configs.recommended,
|
||||
|
||||
// Lingui recommended rules
|
||||
linguiPlugin.configs['flat/recommended'],
|
||||
|
||||
// Global ignores
|
||||
{
|
||||
ignores: ['**/node_modules/**'],
|
||||
},
|
||||
|
||||
// Base configuration for all files
|
||||
{
|
||||
files: ['**/*.{js,jsx,ts,tsx}'],
|
||||
plugins: {
|
||||
prettier: prettierPlugin,
|
||||
lingui: linguiPlugin,
|
||||
'@nx': nxPlugin,
|
||||
'prefer-arrow': preferArrowPlugin,
|
||||
import: importPlugin,
|
||||
'unused-imports': unusedImportsPlugin,
|
||||
unicorn: unicornPlugin,
|
||||
},
|
||||
rules: {
|
||||
// General rules
|
||||
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
|
||||
'no-console': [
|
||||
'warn',
|
||||
{ allow: ['group', 'groupCollapsed', 'groupEnd'] },
|
||||
],
|
||||
'no-control-regex': 0,
|
||||
'no-debugger': 'error',
|
||||
'no-duplicate-imports': 'error',
|
||||
'no-undef': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
|
||||
// Nx rules
|
||||
'@nx/enforce-module-boundaries': [
|
||||
'error',
|
||||
{
|
||||
enforceBuildableLibDependency: true,
|
||||
allow: [],
|
||||
depConstraints: [
|
||||
{
|
||||
sourceTag: 'scope:apps',
|
||||
onlyDependOnLibsWithTags: ['scope:apps', 'scope:sdk'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:sdk',
|
||||
onlyDependOnLibsWithTags: ['scope:sdk', 'scope:shared'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:create-app',
|
||||
onlyDependOnLibsWithTags: ['scope:create-app', 'scope:shared'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:shared',
|
||||
onlyDependOnLibsWithTags: ['scope:shared'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:backend',
|
||||
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:frontend',
|
||||
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:zapier',
|
||||
onlyDependOnLibsWithTags: ['scope:shared', 'scope:zapier'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Import rules
|
||||
'import/no-relative-packages': 'error',
|
||||
'import/no-useless-path-segments': 'error',
|
||||
'import/no-duplicates': ['error', { considerQueryString: true }],
|
||||
|
||||
// Prefer arrow functions
|
||||
'prefer-arrow/prefer-arrow-functions': [
|
||||
'error',
|
||||
{
|
||||
disallowPrototype: true,
|
||||
singleReturnOnly: false,
|
||||
classPropertiesAllowed: false,
|
||||
},
|
||||
],
|
||||
|
||||
// Unused imports
|
||||
'unused-imports/no-unused-imports': 'warn',
|
||||
'unused-imports/no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
vars: 'all',
|
||||
varsIgnorePattern: '^_',
|
||||
args: 'after-used',
|
||||
argsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
// TypeScript specific configuration
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
languageOptions: {
|
||||
parser: typescriptParser,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
'@typescript-eslint': typescriptEslint,
|
||||
},
|
||||
rules: {
|
||||
// TypeScript rules
|
||||
'no-redeclare': 'off', // Turn off base rule for TypeScript
|
||||
'@typescript-eslint/no-redeclare': 'error', // Use TypeScript-aware version
|
||||
'@typescript-eslint/ban-ts-comment': 'error',
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'error',
|
||||
{
|
||||
prefer: 'type-imports',
|
||||
fixStyle: 'inline-type-imports',
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/interface-name-prefix': 'off',
|
||||
'@typescript-eslint/no-empty-object-type': [
|
||||
'error',
|
||||
{
|
||||
allowInterfaces: 'with-single-extends',
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
},
|
||||
},
|
||||
|
||||
// JavaScript specific configuration
|
||||
{
|
||||
files: ['*.{js,jsx}'],
|
||||
rules: {
|
||||
// JavaScript-specific rules if needed
|
||||
},
|
||||
},
|
||||
|
||||
// Test files
|
||||
{
|
||||
files: [
|
||||
'*.spec.@(ts|tsx|js|jsx)',
|
||||
'*.integration-spec.@(ts|tsx|js|jsx)',
|
||||
'*.test.@(ts|tsx|js|jsx)',
|
||||
],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
jest: true,
|
||||
describe: true,
|
||||
it: true,
|
||||
expect: true,
|
||||
beforeEach: true,
|
||||
afterEach: true,
|
||||
beforeAll: true,
|
||||
afterAll: true,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
},
|
||||
},
|
||||
|
||||
// JSON files
|
||||
{
|
||||
files: ['**/*.json'],
|
||||
languageOptions: {
|
||||
parser: jsoncParser,
|
||||
},
|
||||
},
|
||||
|
||||
// MDX files
|
||||
{
|
||||
...mdxPlugin.flat,
|
||||
plugins: {
|
||||
...mdxPlugin.flat.plugins,
|
||||
'@nx': nxPlugin,
|
||||
twenty: { rules: twentyRules },
|
||||
},
|
||||
},
|
||||
mdxPlugin.flatCodeBlocks,
|
||||
{
|
||||
files: ['**/*.mdx'],
|
||||
rules: {
|
||||
'no-unused-vars': 'off',
|
||||
'unused-imports/no-unused-imports': 'off',
|
||||
'unused-imports/no-unused-vars': 'off',
|
||||
// Enforce JSX tags on separate lines to prevent Crowdin translation issues
|
||||
'twenty/mdx-component-newlines': 'error',
|
||||
// Disallow angle bracket placeholders to prevent Crowdin translation errors
|
||||
'twenty/no-angle-bracket-placeholders': 'error',
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -40,34 +40,30 @@
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"executor": "nx:run-commands",
|
||||
"cache": true,
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"eslintConfig": "{projectRoot}/eslint.config.mjs",
|
||||
"cache": true,
|
||||
"cacheLocation": "{workspaceRoot}/.cache/eslint"
|
||||
"cwd": "{projectRoot}",
|
||||
"command": "npx oxlint -c .oxlintrc.json ."
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"cacheStrategy": "content"
|
||||
},
|
||||
"ci": {},
|
||||
"fix": {
|
||||
"fix": true
|
||||
"command": "npx oxlint --fix -c .oxlintrc.json ."
|
||||
}
|
||||
},
|
||||
"dependsOn": ["^build"]
|
||||
"dependsOn": ["^build", "twenty-oxlint-rules:build"]
|
||||
},
|
||||
"lint:diff-with-main": {
|
||||
"executor": "nx:run-commands",
|
||||
"cache": false,
|
||||
"options": {
|
||||
"command": "git diff --name-only --diff-filter=d main | grep -E '{args.pattern}' | grep '^{projectRoot}/' | xargs sh -c 'if [ $# -gt 0 ]; then npx eslint --config {projectRoot}/eslint.config.mjs \"$@\"; fi' _",
|
||||
"command": "FILES=$(git diff --name-only --diff-filter=d main -- {projectRoot}/ | grep -E '{args.pattern}'); [ -z \"$FILES\" ] && echo 'No changed files.' || npx oxlint -c {projectRoot}/.oxlintrc.json $FILES",
|
||||
"pattern": "\\.(ts|tsx|js|jsx)$"
|
||||
},
|
||||
"configurations": {
|
||||
"fix": {
|
||||
"command": "git diff --name-only --diff-filter=d main | grep -E '{args.pattern}' | grep '^{projectRoot}/' | xargs sh -c 'if [ $# -gt 0 ]; then npx eslint --config {projectRoot}/eslint.config.mjs --fix \"$@\"; fi' _"
|
||||
"command": "FILES=$(git diff --name-only --diff-filter=d main -- {projectRoot}/ | grep -E '{args.pattern}'); [ -z \"$FILES\" ] && echo 'No changed files.' || npx oxlint --fix -c {projectRoot}/.oxlintrc.json $FILES"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -147,7 +143,7 @@
|
||||
"outputs": ["{projectRoot}/{options.output-dir}"],
|
||||
"options": {
|
||||
"cwd": "{projectRoot}",
|
||||
"command": "NODE_OPTIONS='--max-old-space-size=10240' VITE_DISABLE_TYPESCRIPT_CHECKER=true storybook build --test",
|
||||
"command": "NODE_OPTIONS='--max-old-space-size=10240' storybook build --test",
|
||||
"output-dir": "storybook-static",
|
||||
"config-dir": ".storybook"
|
||||
},
|
||||
@@ -255,14 +251,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@nx/eslint:lint": {
|
||||
"cache": true,
|
||||
"inputs": [
|
||||
"default",
|
||||
"{workspaceRoot}/eslint.config.mjs",
|
||||
"{workspaceRoot}/packages/twenty-eslint-rules/**/*"
|
||||
]
|
||||
},
|
||||
"@nx/vite:build": {
|
||||
"cache": true,
|
||||
"dependsOn": ["^build"],
|
||||
@@ -277,7 +265,6 @@
|
||||
"@nx/react": {
|
||||
"application": {
|
||||
"style": "@linaria/react",
|
||||
"linter": "eslint",
|
||||
"bundler": "vite",
|
||||
"compiler": "swc",
|
||||
"unitTestRunner": "jest",
|
||||
@@ -285,7 +272,6 @@
|
||||
},
|
||||
"library": {
|
||||
"style": "@linaria/react",
|
||||
"linter": "eslint",
|
||||
"bundler": "vite",
|
||||
"compiler": "swc",
|
||||
"unitTestRunner": "jest",
|
||||
|
||||
+14
-35
@@ -46,7 +46,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-responsive": "^9.0.2",
|
||||
"react-router-dom": "^6.4.4",
|
||||
"react-router-dom": "^6.30.3",
|
||||
"react-tooltip": "^5.13.1",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"rxjs": "^7.2.0",
|
||||
@@ -72,14 +72,13 @@
|
||||
"@graphql-codegen/typescript": "^3.0.4",
|
||||
"@graphql-codegen/typescript-operations": "^3.0.4",
|
||||
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
|
||||
"@nx/eslint": "22.3.3",
|
||||
"@nx/eslint-plugin": "22.3.3",
|
||||
"@nx/jest": "22.3.3",
|
||||
"@nx/js": "22.3.3",
|
||||
"@nx/react": "22.3.3",
|
||||
"@nx/storybook": "22.3.3",
|
||||
"@nx/vite": "22.3.3",
|
||||
"@nx/web": "22.3.3",
|
||||
"@nx/jest": "22.5.4",
|
||||
"@nx/js": "22.5.4",
|
||||
"@nx/react": "22.5.4",
|
||||
"@nx/storybook": "22.5.4",
|
||||
"@nx/vite": "22.5.4",
|
||||
"@nx/web": "22.5.4",
|
||||
"@oxlint/plugins": "^1.51.0",
|
||||
"@sentry/types": "^8",
|
||||
"@storybook-community/storybook-addon-cookie": "^5.0.0",
|
||||
"@storybook/addon-coverage": "^3.0.0",
|
||||
@@ -89,11 +88,10 @@
|
||||
"@storybook/icons": "^2.0.1",
|
||||
"@storybook/react-vite": "^10.2.13",
|
||||
"@storybook/test-runner": "^0.24.2",
|
||||
"@stylistic/eslint-plugin": "^1.5.0",
|
||||
"@swc-node/register": "1.11.1",
|
||||
"@swc/cli": "^0.3.12",
|
||||
"@swc/core": "1.15.11",
|
||||
"@swc/helpers": "~0.5.18",
|
||||
"@swc-node/register": "^1.11.1",
|
||||
"@swc/cli": "^0.7.10",
|
||||
"@swc/core": "^1.15.11",
|
||||
"@swc/helpers": "~0.5.19",
|
||||
"@swc/jest": "^0.2.39",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
@@ -132,9 +130,6 @@
|
||||
"@types/react-dom": "^18.2.15",
|
||||
"@types/supertest": "^2.0.11",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.39.0",
|
||||
"@typescript-eslint/parser": "^8.39.0",
|
||||
"@typescript-eslint/utils": "^8.39.0",
|
||||
"@typescript/native-preview": "^7.0.0-dev.20260116.1",
|
||||
"@vitejs/plugin-react-swc": "4.2.3",
|
||||
"@vitest/browser-playwright": "^4.0.18",
|
||||
@@ -146,22 +141,6 @@
|
||||
"danger": "^13.0.4",
|
||||
"dotenv-cli": "^7.4.4",
|
||||
"esbuild": "^0.25.10",
|
||||
"eslint": "^9.32.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-lingui": "^0.9.0",
|
||||
"eslint-plugin-mdx": "^3.6.2",
|
||||
"eslint-plugin-prefer-arrow": "^1.2.3",
|
||||
"eslint-plugin-prettier": "^5.1.2",
|
||||
"eslint-plugin-project-structure": "^3.9.1",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.4",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"eslint-plugin-storybook": "^10.2.13",
|
||||
"eslint-plugin-unicorn": "^56.0.1",
|
||||
"eslint-plugin-unused-imports": "^3.0.0",
|
||||
"http-server": "^14.1.1",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "30.0.0-beta.3",
|
||||
@@ -170,7 +149,7 @@
|
||||
"jsdom": "~22.1.0",
|
||||
"msw": "^2.12.7",
|
||||
"msw-storybook-addon": "^2.0.6",
|
||||
"nx": "22.3.3",
|
||||
"nx": "22.5.4",
|
||||
"prettier": "^3.1.1",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^5.0.5",
|
||||
@@ -230,7 +209,7 @@
|
||||
"packages/twenty-apps",
|
||||
"packages/twenty-cli",
|
||||
"packages/create-twenty-app",
|
||||
"packages/twenty-eslint-rules"
|
||||
"packages/twenty-oxlint-rules"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules", "dist"],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": "off",
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
"import/no-duplicates": "error",
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/ban-ts-comment": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ In interactive mode, you can pick from:
|
||||
- `roles/default-role.ts` — Default role for logic functions
|
||||
- `logic-functions/pre-install.ts` — Pre-install logic function (runs before app installation)
|
||||
- `logic-functions/post-install.ts` — Post-install logic function (runs after app installation)
|
||||
- TypeScript configuration, ESLint, package.json, .gitignore
|
||||
- TypeScript configuration, Oxlint, package.json, .gitignore
|
||||
- A prewired `twenty` script that delegates to the `twenty` CLI from twenty-sdk
|
||||
|
||||
**Example files (controlled by scaffolding mode):**
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import baseConfig from '../../eslint.config.mjs';
|
||||
|
||||
export default [
|
||||
...baseConfig,
|
||||
{
|
||||
ignores: ['**/dist/**'],
|
||||
},
|
||||
{
|
||||
files: ['**/*.{js,jsx,ts,tsx}'],
|
||||
rules: {
|
||||
'prettier/prettier': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
},
|
||||
ignores: ['src/**/*.ts', '!src/cli/**/*.ts'],
|
||||
},
|
||||
];
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-twenty-app",
|
||||
"version": "0.6.3",
|
||||
"version": "0.6.4",
|
||||
"description": "Command-line interface to create Twenty application",
|
||||
"main": "dist/cli.cjs",
|
||||
"bin": "dist/cli.cjs",
|
||||
|
||||
@@ -25,19 +25,7 @@
|
||||
}
|
||||
},
|
||||
"typecheck": {},
|
||||
"lint": {
|
||||
"options": {
|
||||
"lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
|
||||
"maxWarnings": 0
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
|
||||
"maxWarnings": 0
|
||||
},
|
||||
"fix": {}
|
||||
}
|
||||
},
|
||||
"lint": {},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules", "dist"],
|
||||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"argsIgnorePattern": "^_"
|
||||
}],
|
||||
"typescript/no-explicit-any": "off"
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default [
|
||||
// Base JS recommended rules
|
||||
js.configs.recommended,
|
||||
|
||||
// TypeScript recommended rules
|
||||
...tseslint.configs.recommended,
|
||||
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// Common TypeScript-friendly tweaks
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{ argsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'no-unused-vars': 'off', // handled by TS rule
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -553,8 +553,8 @@ const createPackageJson = async ({
|
||||
}) => {
|
||||
const scripts: Record<string, string> = {
|
||||
twenty: 'twenty',
|
||||
lint: 'eslint',
|
||||
'lint:fix': 'eslint --fix',
|
||||
lint: 'oxlint -c .oxlintrc.json .',
|
||||
'lint:fix': 'oxlint --fix -c .oxlintrc.json .',
|
||||
};
|
||||
|
||||
const devDependencies: Record<string, string> = {
|
||||
@@ -562,8 +562,7 @@ const createPackageJson = async ({
|
||||
'@types/node': '^24.7.2',
|
||||
'@types/react': '^18.2.0',
|
||||
react: '^18.2.0',
|
||||
eslint: '^9.32.0',
|
||||
'typescript-eslint': '^8.50.0',
|
||||
oxlint: '^0.16.0',
|
||||
'twenty-sdk': createTwentyAppPackageJson.version,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules"],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
"import/no-duplicates": "error",
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/ban-ts-comment": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default [
|
||||
// Base JS recommended rules
|
||||
js.configs.recommended,
|
||||
|
||||
// TypeScript recommended rules
|
||||
...tseslint.configs.recommended,
|
||||
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// Common TypeScript-friendly tweaks
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{ argsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'no-unused-vars': 'off', // handled by TS rule
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -10,8 +10,8 @@
|
||||
"packageManager": "[email protected]",
|
||||
"scripts": {
|
||||
"twenty": "twenty",
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix"
|
||||
"lint": "oxlint -c .oxlintrc.json .",
|
||||
"lint:fix": "oxlint --fix -c .oxlintrc.json ."
|
||||
},
|
||||
"dependencies": {
|
||||
"twenty-sdk": "latest"
|
||||
@@ -19,9 +19,8 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.7.2",
|
||||
"@types/react": "^18.2.0",
|
||||
"eslint": "^9.32.0",
|
||||
"oxlint": "^0.16.0",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.50.0"
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
-9
@@ -1,7 +1,6 @@
|
||||
import { defineLogicFunction, RoutePayload } from "twenty-sdk";
|
||||
import { MetadataApiClient } from 'twenty-sdk/generated';
|
||||
|
||||
|
||||
export const OAUTH_TOKEN_PAIRS_PATH = '/oauth/token-pairs';
|
||||
|
||||
type ApolloTokenResponse = {
|
||||
@@ -53,16 +52,8 @@ const handler = async (event: RoutePayload): Promise<any> => {
|
||||
const apolloClientSecret = process.env.APOLLO_CLIENT_SECRET ?? '';
|
||||
const applicationId = process.env.APPLICATION_ID ?? '';
|
||||
|
||||
|
||||
const metadataClient = new MetadataApiClient({});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const tokenPairs = await getAuthenticationTokenPairs(
|
||||
code,
|
||||
apolloClientId,
|
||||
|
||||
@@ -5,8 +5,6 @@ import {
|
||||
} from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/generated';
|
||||
|
||||
|
||||
|
||||
type CompanyRecord = {
|
||||
id: string;
|
||||
name?: string;
|
||||
@@ -38,8 +36,6 @@ type ApolloEnrichResponse = {
|
||||
organization?: ApolloOrganization;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const extractDomain = (
|
||||
domainName?: CompanyRecord['domainName'],
|
||||
): string | undefined => {
|
||||
@@ -172,7 +168,6 @@ const updateCompanyInTwenty = async (
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
type CompanyUpdateEvent = DatabaseEventPayload<
|
||||
ObjectRecordUpdateEvent<CompanyRecord>
|
||||
>;
|
||||
@@ -181,7 +176,6 @@ const handler = async (
|
||||
event: CompanyUpdateEvent,
|
||||
): Promise<object | undefined> => {
|
||||
|
||||
|
||||
const { recordId, properties } = event;
|
||||
const { after: companyAfter } = properties;
|
||||
|
||||
@@ -206,7 +200,6 @@ const handler = async (
|
||||
return { skipped: true, reason: 'no enrichment data to apply' };
|
||||
}
|
||||
|
||||
|
||||
await updateCompanyInTwenty(recordId, updateData);
|
||||
|
||||
const result = {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules"],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
|
||||
"import/no-duplicates": "error",
|
||||
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/ban-ts-comment": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -26,21 +26,6 @@
|
||||
"typecheck": {
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
],
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"packages/twenty-apps/community/fireflies/**/*.{ts,tsx,js,jsx}"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"fix": {
|
||||
"fix": true
|
||||
}
|
||||
}
|
||||
}
|
||||
"lint": {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Usage: yarn setup:fields
|
||||
*/
|
||||
|
||||
/* eslint-disable no-console */
|
||||
/* oxlint-disable no-console */
|
||||
|
||||
import * as dotenv from 'dotenv';
|
||||
import * as path from 'path';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* eslint-disable no-console */
|
||||
/* oxlint-disable no-console */
|
||||
import * as dotenv from 'dotenv';
|
||||
import * as path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* eslint-disable no-console */
|
||||
/* oxlint-disable no-console */
|
||||
import * as dotenv from 'dotenv';
|
||||
import * as path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* eslint-disable no-console */
|
||||
/* oxlint-disable no-console */
|
||||
/**
|
||||
* Fetch historical Fireflies meetings and insert into Twenty.
|
||||
*
|
||||
@@ -219,4 +219,3 @@ main().catch((error) => {
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* eslint-disable no-console */
|
||||
/* oxlint-disable no-console */
|
||||
/**
|
||||
* Fetch a Fireflies meeting by ID and insert it into Twenty using the same path
|
||||
* as the webhook handler.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* eslint-disable no-console */
|
||||
/* oxlint-disable no-console */
|
||||
/**
|
||||
* Test script for Fireflies webhook against local Twenty instance
|
||||
*
|
||||
|
||||
@@ -81,4 +81,3 @@ describe('HistoricalImporter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -158,4 +158,3 @@ export class HistoricalImporter {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ export class AppLogger {
|
||||
debug(message: string, ...args: unknown[]): void {
|
||||
this.captureLog('debug', message, ...args);
|
||||
if (this.shouldLog('debug')) {
|
||||
// eslint-disable-next-line no-console
|
||||
// oxlint-disable-next-line no-console
|
||||
console.log(`[${this.context}] ${message}`, ...args);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ export class AppLogger {
|
||||
info(message: string, ...args: unknown[]): void {
|
||||
this.captureLog('info', message, ...args);
|
||||
if (this.shouldLog('info')) {
|
||||
// eslint-disable-next-line no-console
|
||||
// oxlint-disable-next-line no-console
|
||||
console.log(`[${this.context}] ${message}`, ...args);
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ export class AppLogger {
|
||||
warn(message: string, ...args: unknown[]): void {
|
||||
this.captureLog('warn', message, ...args);
|
||||
if (this.shouldLog('warn')) {
|
||||
// eslint-disable-next-line no-console
|
||||
// oxlint-disable-next-line no-console
|
||||
console.warn(`[${this.context}] ${message}`, ...args);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ export class AppLogger {
|
||||
error(message: string, ...args: unknown[]): void {
|
||||
this.captureLog('error', message, ...args);
|
||||
if (this.shouldLog('error')) {
|
||||
// eslint-disable-next-line no-console
|
||||
// oxlint-disable-next-line no-console
|
||||
console.error(`[${this.context}] ${message}`, ...args);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ export class AppLogger {
|
||||
// For fatal errors, security issues, or data corruption - always visible
|
||||
critical(message: string, ...args: unknown[]): void {
|
||||
this.captureLog('error', `CRITICAL: ${message}`, ...args);
|
||||
// eslint-disable-next-line no-console
|
||||
// oxlint-disable-next-line no-console
|
||||
console.error(`[${this.context}] CRITICAL: ${message}`, ...args);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
export { Meeting } from './meeting';
|
||||
|
||||
|
||||
|
||||
@@ -330,7 +330,6 @@ export class WebhookHandler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async createFailedMeetingRecord(params: unknown, error: string): Promise<void> {
|
||||
try {
|
||||
const twentyApiKey = process.env.TWENTY_API_KEY || '';
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["react", "typescript", "import", "unicorn"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"node_modules"
|
||||
],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
|
||||
"import/no-duplicates": "error",
|
||||
|
||||
"react/no-unescaped-entities": "off",
|
||||
"react/prop-types": "off",
|
||||
"react/jsx-key": "off",
|
||||
"react/display-name": "off",
|
||||
"react/jsx-uses-react": "off",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/jsx-no-useless-fragment": "off",
|
||||
"react/jsx-props-no-spreading": ["error", { "explicitSpread": "ignore" }],
|
||||
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "warn",
|
||||
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/ban-ts-comment": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
import typescriptParser from '@typescript-eslint/parser';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import reactConfig from '../../../../twenty-eslint-rules/eslint.config.react.mjs';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
export default [
|
||||
// Extend shared React configuration
|
||||
...reactConfig,
|
||||
|
||||
// Global ignores
|
||||
{
|
||||
ignores: [
|
||||
'**/node_modules/**',
|
||||
],
|
||||
},
|
||||
|
||||
// TypeScript project-specific configuration
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
languageOptions: {
|
||||
parser: typescriptParser,
|
||||
parserOptions: {
|
||||
project: [path.resolve(__dirname, 'tsconfig.*.json')],
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@nx/enforce-module-boundaries': [
|
||||
'error',
|
||||
{
|
||||
enforceBuildableLibDependency: true,
|
||||
allow: [],
|
||||
depConstraints: [
|
||||
{
|
||||
sourceTag: 'scope:sdk',
|
||||
onlyDependOnLibsWithTags: ['scope:sdk'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:shared',
|
||||
onlyDependOnLibsWithTags: ['scope:shared'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:backend',
|
||||
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:frontend',
|
||||
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:zapier',
|
||||
onlyDependOnLibsWithTags: ['scope:shared'],
|
||||
},
|
||||
{
|
||||
sourceTag: 'scope:browser-extension',
|
||||
onlyDependOnLibsWithTags: ['scope:twenty-ui', 'scope:browser-extension']
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
-1
@@ -43,7 +43,6 @@ export default defineContentScript({
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
ctx.addEventListener(window, 'wxt:locationchange', ({newUrl, }) => {
|
||||
const injectedBtn = document.querySelector('[data-id="twenty-btn"]');
|
||||
if(personPattern.includes(newUrl) && !injectedBtn) ui.mount();
|
||||
|
||||
-2
@@ -8,7 +8,6 @@ const StyledButton = styled.button`
|
||||
--text-color: #0a66c2;
|
||||
--bg-color: #00000000;
|
||||
|
||||
|
||||
font-size: ${({theme}) => theme.spacing(3.5)};
|
||||
font-weight: ${({theme}) => theme.font.weight.semiBold};
|
||||
font-family: ${({theme}) => theme.font.family};
|
||||
@@ -26,7 +25,6 @@ const StyledButton = styled.button`
|
||||
transition-timing-function: cubic-bezier(.4, 0, .2, 1);
|
||||
transition-duration: 167ms;
|
||||
|
||||
|
||||
&:hover {
|
||||
background-color: var(--hover-bg-color);
|
||||
color: var(--hover-color);
|
||||
|
||||
+2
-7
@@ -1,6 +1,5 @@
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
import type React from 'react';
|
||||
import { THEME_DARK, ThemeContextProvider } from 'twenty-ui/theme';
|
||||
import { ColorSchemeProvider } from 'twenty-ui/theme-constants';
|
||||
|
||||
type ThemeContextProps = {
|
||||
children: React.ReactNode;
|
||||
@@ -8,10 +7,6 @@ type ThemeContextProps = {
|
||||
|
||||
export const ThemeContext = ({ children }: ThemeContextProps) => {
|
||||
return (
|
||||
<ThemeProvider theme={THEME_DARK}>
|
||||
<ThemeContextProvider theme={THEME_DARK}>
|
||||
{children}
|
||||
</ThemeContextProvider>
|
||||
</ThemeProvider>
|
||||
<ColorSchemeProvider colorScheme="dark">{children}</ColorSchemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import type { ThemeType } from 'twenty-ui/theme';
|
||||
|
||||
declare module '@emotion/react' {
|
||||
export interface Theme extends ThemeType {}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules"],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
"import/no-duplicates": "error",
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/ban-ts-comment": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default [
|
||||
// Base JS recommended rules
|
||||
js.configs.recommended,
|
||||
|
||||
// TypeScript recommended rules
|
||||
...tseslint.configs.recommended,
|
||||
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// Common TypeScript-friendly tweaks
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{ argsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'no-unused-vars': 'off', // handled by TS rule
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hello-world",
|
||||
"version": "0.1.0",
|
||||
"name": "@twentyhq/hello-world",
|
||||
"version": "0.2.2",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^24.5.0",
|
||||
@@ -10,19 +10,18 @@
|
||||
"packageManager": "[email protected]",
|
||||
"scripts": {
|
||||
"twenty": "twenty",
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix",
|
||||
"lint": "oxlint -c .oxlintrc.json .",
|
||||
"lint:fix": "oxlint --fix -c .oxlintrc.json .",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.7.2",
|
||||
"@types/react": "^18.2.0",
|
||||
"eslint": "^9.32.0",
|
||||
"oxlint": "^0.16.0",
|
||||
"react": "^18.2.0",
|
||||
"twenty-sdk": "0.6.3",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.50.0",
|
||||
"vite-tsconfig-paths": "^4.2.1",
|
||||
"vitest": "^3.1.1"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules"],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
"import/no-duplicates": "error",
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/ban-ts-comment": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default [
|
||||
// Base JS recommended rules
|
||||
js.configs.recommended,
|
||||
|
||||
// TypeScript recommended rules
|
||||
...tseslint.configs.recommended,
|
||||
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// Common TypeScript-friendly tweaks
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{ argsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'no-unused-vars': 'off', // handled by TS rule
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -10,8 +10,8 @@
|
||||
"packageManager": "[email protected]",
|
||||
"scripts": {
|
||||
"twenty": "twenty",
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix"
|
||||
"lint": "oxlint -c .oxlintrc.json .",
|
||||
"lint:fix": "oxlint --fix -c .oxlintrc.json ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
@@ -23,9 +23,8 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.7.2",
|
||||
"@types/react": "^18.2.0",
|
||||
"eslint": "^9.32.0",
|
||||
"oxlint": "^0.16.0",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.50.0"
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn"],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules"],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
|
||||
"import/no-duplicates": "error",
|
||||
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/ban-ts-comment": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,12 @@
|
||||
"packageManager": "[email protected]",
|
||||
"scripts": {
|
||||
"twenty": "twenty",
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix"
|
||||
"lint": "oxlint -c .oxlintrc.json .",
|
||||
"lint:fix": "oxlint --fix -c .oxlintrc.json ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.7.2",
|
||||
"oxlint": "^0.16.0",
|
||||
"twenty-sdk": "0.6.2"
|
||||
},
|
||||
"$schema": "https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-cli/src/constants/schemas/appManifest.schema.json",
|
||||
|
||||
@@ -45,8 +45,8 @@ typings/
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
# Optional oxlint cache
|
||||
.oxlintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
+602
-629
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ COPY ./yarn.lock .
|
||||
COPY ./.yarnrc.yml .
|
||||
COPY ./.yarn/releases /app/.yarn/releases
|
||||
COPY ./.yarn/patches /app/.yarn/patches
|
||||
COPY ./packages/twenty-eslint-rules /app/packages/twenty-eslint-rules
|
||||
COPY ./packages/twenty-oxlint-rules /app/packages/twenty-oxlint-rules
|
||||
COPY ./packages/twenty-ui/package.json /app/packages/twenty-ui/
|
||||
COPY ./packages/twenty-shared/package.json /app/packages/twenty-shared/
|
||||
COPY ./packages/twenty-website/package.json /app/packages/twenty-website/package.json
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn"],
|
||||
"ignorePatterns": ["node_modules", ".next", "storybook-static"],
|
||||
"rules": {
|
||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||
"no-console": ["warn", { "allow": ["group", "groupCollapsed", "groupEnd"] }],
|
||||
"no-control-regex": "off",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-redeclare": "off",
|
||||
"import/no-duplicates": "error",
|
||||
"typescript/no-redeclare": "error",
|
||||
"typescript/consistent-type-imports": ["error", {
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}],
|
||||
"typescript/explicit-function-return-type": "off",
|
||||
"typescript/explicit-module-boundary-types": "off",
|
||||
"typescript/no-empty-object-type": ["error", {
|
||||
"allowInterfaces": "with-single-extends"
|
||||
}],
|
||||
"typescript/no-empty-function": "off",
|
||||
"typescript/no-explicit-any": "off",
|
||||
"typescript/no-unused-vars": ["warn", {
|
||||
"vars": "all",
|
||||
"varsIgnorePattern": "^_",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_"
|
||||
}]
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -92,7 +92,7 @@ Here's what the tech stack now looks like.
|
||||
|
||||
**Tooling**
|
||||
- [Yarn](https://yarnpkg.com/)
|
||||
- [ESLint](https://eslint.org/)
|
||||
- [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
**Development**
|
||||
- [AWS EKS](https://aws.amazon.com/eks/)
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ The project has a clean and simple stack, with minimal boilerplate code.
|
||||
|
||||
- [Yarn](https://yarnpkg.com/)
|
||||
- [Craco](https://craco.js.org/docs/)
|
||||
- [ESLint](https://eslint.org/)
|
||||
- [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
## Architecture
|
||||
|
||||
|
||||
+4
-4
@@ -260,7 +260,7 @@ const StyledButton = styled.button`
|
||||
```
|
||||
## Enforcing No-Type Imports
|
||||
|
||||
Avoid type imports. To enforce this standard, an ESLint rule checks for and reports any type imports. This helps maintain consistency and readability in the TypeScript code.
|
||||
Avoid type imports. To enforce this standard, an Oxlint rule checks for and reports any type imports. This helps maintain consistency and readability in the TypeScript code.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
@@ -281,11 +281,11 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
- **Maintainability**: It enhances codebase maintainability because developers can identify and locate type-only imports when reviewing or modifying code.
|
||||
|
||||
### ESLint Rule
|
||||
### Oxlint Rule
|
||||
|
||||
An ESLint rule, `@typescript-eslint/consistent-type-imports`, enforces the no-type import standard. This rule will generate errors or warnings for any type import violations.
|
||||
An Oxlint rule, `typescript/consistent-type-imports`, enforces the no-type import standard. This rule will generate errors or warnings for any type import violations.
|
||||
|
||||
Please note that this rule specifically addresses rare edge cases where unintentional type imports occur. TypeScript itself discourages this practice, as mentioned in the [TypeScript 3.8 release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). In most situations, you should not need to use type-only imports.
|
||||
|
||||
To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow.
|
||||
To ensure your code complies with this rule, make sure to run Oxlint as part of your development workflow.
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ my-twenty-app/
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
eslint.config.mjs
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
@@ -129,7 +129,7 @@ At a high level:
|
||||
- **.gitignore**: Ignores common artifacts such as `node_modules`, `.yarn`, `generated/` (typed client), `dist/`, `build/`, coverage folders, log files, and `.env*` files.
|
||||
- **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Lock and configure the Yarn 4 toolchain used by the project.
|
||||
- **.nvmrc**: Pins the Node.js version expected by the project.
|
||||
- **eslint.config.mjs** and **tsconfig.json**: Provide linting and TypeScript configuration for your app's TypeScript sources.
|
||||
- **.oxlintrc.json** and **tsconfig.json**: Provide linting and TypeScript configuration for your app's TypeScript sources.
|
||||
- **README.md**: A short README in the app root with basic instructions.
|
||||
- **public/**: A folder for storing public assets (images, fonts, static files) that will be served with your application. Files placed here are uploaded during sync and accessible at runtime.
|
||||
- **src/**: The main place where you define your application-as-code
|
||||
|
||||
@@ -54,21 +54,18 @@ Make sure to run yarn in the root directory and then run `npx nx server:dev twen
|
||||
|
||||
#### Lint on Save not working
|
||||
|
||||
This should work out of the box with the eslint extension installed. If this doesn't work try adding this to your vscode setting (on the dev container scope):
|
||||
This should work out of the box with the Oxc extension (`oxc.oxc-vscode`) installed. If this doesn't work try adding this to your vscode setting (on the dev container scope):
|
||||
|
||||
```
|
||||
"editor.codeActionsOnSave": {
|
||||
|
||||
"source.fixAll.eslint": "explicit"
|
||||
"source.fixAll.oxc": "explicit"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### While running `npx nx start` or `npx nx start twenty-front`, Out of memory error is thrown
|
||||
|
||||
In `packages/twenty-front/.env` uncomment `VITE_DISABLE_TYPESCRIPT_CHECKER=true` to disable background checks thus reducing amount of needed RAM.
|
||||
|
||||
**If it does not work:**
|
||||
Run only the services you need, instead of `npx nx start`. For instance, if you work on the server, run only `npx nx worker twenty-server`
|
||||
|
||||
**If it does not work:**
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import baseConfig from '../../eslint.config.mjs';
|
||||
|
||||
export default [...baseConfig];
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ Prisma كان أول ORM استخدمناه. ولكن للسماح للمستخ
|
||||
**الأدوات**
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
**التطوير**
|
||||
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ title: أوامر الواجهة الأمامية
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* "[Craco](https://craco.js.org/docs/)"
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
## "الهيكلية"
|
||||
|
||||
|
||||
+4
-4
@@ -260,7 +260,7 @@ const StyledButton = styled.button`
|
||||
|
||||
## تطبيق قاعدة "عدم استيراد الأنواع"
|
||||
|
||||
تجنب استيراد الأنواع. للحد من هذه الممارسة، تتحقق قاعدة ESLint وتبلغ عن أي استيرادات من هذا النوع. يساعد هذا على الحفاظ على الاتساق وقابلية القراءة في كود TypeScript.
|
||||
تجنب استيراد الأنواع. لفرض هذا المعيار، تتحقق قاعدة Oxlint وتبلغ عن أي استيرادات للأنواع. يساعد هذا على الحفاظ على الاتساق وقابلية القراءة في كود TypeScript.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
@@ -281,10 +281,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
* **الصيانة**: يعزز الصيانة داخل قاعدة الكود لأن المطوّرين يمكنهم تحديد مواقع استيرادات الأنواع فقط عند استعراض أو تعديل الكود.
|
||||
|
||||
### قاعدة ESLint
|
||||
### قاعدة Oxlint
|
||||
|
||||
تفرض قاعدة ESLint، `@typescript-eslint/consistent-type-imports`, معيار عدم استيراد الأنواع. ستولد هذه القاعدة تحذيرات أو أخطاء عن أي انتهاكات لاستيراد الأنواع.
|
||||
تفرض قاعدة Oxlint، `typescript/consistent-type-imports`, معيار عدم استيراد الأنواع. ستولد هذه القاعدة تحذيرات أو أخطاء عن أي انتهاكات لاستيراد الأنواع.
|
||||
|
||||
يرجى ملاحظة أن هذه القاعدة تتناول بشكل خاص حالات الحافة النادرة حيث تحدث استيرادات الأنواع دون قصد. يمنع TypeScript نفسه هذه الممارسة، كما هو موضح في [ملاحظات إصدار TypeScript 3.8](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). في معظم الحالات، لا ينبغي لك أن تستخدم استيرادات الأنواع وحدها.
|
||||
|
||||
لضمان امتثال الكود الخاص بك لهذه القاعدة، تأكد من تشغيل ESLint كجزء من سير العمل الخاص بالتطوير لديك.
|
||||
لضمان امتثال الكود الخاص بك لهذه القاعدة، تأكد من تشغيل Oxlint كجزء من سير العمل الخاص بالتطوير لديك.
|
||||
|
||||
@@ -96,7 +96,7 @@ my-twenty-app/
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
eslint.config.mjs
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # مجلد الأصول العامة (صور، خطوط، إلخ)
|
||||
@@ -119,7 +119,7 @@ my-twenty-app/
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # رابط تنقّل في الشريط الجانبي — مثال
|
||||
└── skills/
|
||||
└── example-skill.ts # تعريف مهارة لوكيل الذكاء الاصطناعي — مثال
|
||||
└── example-skill.ts # تعريف مهارة لوكيل الذكاء الاصطناعي — مثال},{
|
||||
```
|
||||
|
||||
مع `--minimal`، سيتم إنشاء الملفات الأساسية فقط (`application-config.ts`، `roles/default-role.ts`، `logic-functions/pre-install.ts`، و`logic-functions/post-install.ts`). مع `--interactive`، تختار ملفات الأمثلة التي تريد تضمينها.
|
||||
@@ -130,7 +130,7 @@ my-twenty-app/
|
||||
* **.gitignore**: يتجاهل العناصر الشائعة مثل `node_modules` و`.yarn` و`generated/` (عميل مضبوط الأنواع) و`dist/` و`build/` ومجلدات التغطية وملفات السجلات وملفات `.env*`.
|
||||
* **yarn.lock**، **.yarnrc.yml**، **.yarn/**: تقوم بقفل وتكوين حزمة أدوات Yarn 4 المستخدمة في المشروع.
|
||||
* **.nvmrc**: يثبّت إصدار Node.js المتوقع للمشروع.
|
||||
* **eslint.config.mjs** و**tsconfig.json**: يقدّمان إعدادات الفحص والتهيئة لـ TypeScript لمصادر TypeScript في تطبيقك.
|
||||
* **.oxlintrc.json** و **tsconfig.json**: يقدّمان إعدادات الفحص والتهيئة لـ TypeScript لمصادر TypeScript في تطبيقك.
|
||||
* **README.md**: ملف README قصير في جذر التطبيق يتضمن تعليمات أساسية.
|
||||
* **public/**: مجلد لتخزين الأصول العامة (صور، خطوط، ملفات ثابتة) التي سيتم تقديمها مع تطبيقك. الملفات الموضوعة هنا تُرفع أثناء المزامنة وتكون متاحة أثناء وقت التشغيل.
|
||||
* **src/**: المكان الرئيسي حيث تعرّف تطبيقك ككود
|
||||
|
||||
@@ -53,22 +53,19 @@ git config --global core.autocrlf false
|
||||
|
||||
#### التحقق من العمليات عند الحفظ لا يعمل
|
||||
|
||||
هذا يجب أن يعمل تلقائيًا مع تثبيت إضافة eslint. إذا لم يعمل ذلك، حاول إضافة هذا إلى إعدادات vscode (ضمن نطاق حاوية التطوير):
|
||||
هذا يجب أن يعمل تلقائيًا مع تثبيت إضافة Oxc (`oxc.oxc-vscode`). إذا لم يعمل ذلك، حاول إضافة هذا إلى إعدادات vscode (ضمن نطاق حاوية التطوير):
|
||||
|
||||
```
|
||||
"editor.codeActionsOnSave": {
|
||||
|
||||
"source.fixAll.eslint": "explicit"
|
||||
"source.fixAll.oxc": "explicit"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### أثناء تشغيل `npx nx start` أو `npx nx start twenty-front`، ظهرت خطأ نفاد الذاكرة
|
||||
|
||||
في `packages/twenty-front/.env` قم بإزالة تعليق على `VITE_DISABLE_TYPESCRIPT_CHECKER=true` و`VITE_DISABLE_ESLINT_CHECKER=true` لتعطيل فحوصات الخلفية مما يقلل من كمية الذاكرة المطلوبة.
|
||||
|
||||
**إذا لم يعمل ذلك:**
|
||||
قم بتشغيل الخدمات التي تحتاجها فقط، بدلاً من `npx nx start`. على سبيل المثال، إذا كنت تعمل على الخادم، قم بتشغيل `npx nx worker twenty-server` فقط
|
||||
Run only the services you need, instead of `npx nx start`. على سبيل المثال، إذا كنت تعمل على الخادم، قم بتشغيل `npx nx worker twenty-server` فقط
|
||||
|
||||
**إذا لم يعمل ذلك:**
|
||||
إذا حاولت تشغيل `npx nx run twenty-server:start` فقط على WSL وفشل مع خطأ الذاكرة أدناه:
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ Takto nyní vypadá technologický stack.
|
||||
**Nástroje**
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
**Vývoj**
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ Projekt má čistý a jednoduchý stack s minimálním počtem šablonových kó
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [Craco](https://craco.js.org/docs/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
## Architektura
|
||||
|
||||
|
||||
+4
-4
@@ -260,7 +260,7 @@ const StyledButton = styled.button`
|
||||
|
||||
## Prosazování Zákazu Importů Typů
|
||||
|
||||
Vyhýbejte se typovým importům. K prosazení tohoto standardu pravidlo ESLint kontroluje a hlásí jakékoli typové importy. To pomáhá udržovat konzistenci a čitelnost v TypeScript kódu.
|
||||
Vyhýbejte se typovým importům. K prosazení tohoto standardu pravidlo Oxlint kontroluje a hlásí jakékoli typové importy. To pomáhá udržovat konzistenci a čitelnost v TypeScript kódu.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
@@ -281,10 +281,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
* **Udržovatelnost**: Zvyšuje udržovatelnost kódové základny, protože vývojáři mohou při revizi nebo úpravách kódu identifikovat a najít importy pouze typů.
|
||||
|
||||
### Pravidlo ESLint
|
||||
### Pravidlo Oxlint
|
||||
|
||||
Pravidlo ESLint, `@typescript-eslint/consistent-type-imports`, prosazuje standard zákazu importů typů. Toto pravidlo generuje chyby nebo varování pro jakékoli porušení typového importu.
|
||||
Pravidlo Oxlint, `typescript/consistent-type-imports`, prosazuje standard zákazu importů typů. Toto pravidlo generuje chyby nebo varování pro jakékoli porušení typového importu.
|
||||
|
||||
Upozorňujeme, že toto pravidlo konkrétně řeší vzácné okrajové případy, kdy dochází k neúmyslným typovým importům. TypeScript sám odrazuje tuto praxi, jak je uvedeno v [poznámkách k verzi TypeScript 3.8](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). Ve většině případů byste neměli potřebovat používat pouze typové importy.
|
||||
|
||||
Aby váš kód splňoval toto pravidlo, spusťte ESLint jako součást svého vývojového pracovního postupu.
|
||||
Aby váš kód splňoval toto pravidlo, spusťte Oxlint jako součást svého vývojového pracovního postupu.
|
||||
|
||||
@@ -96,7 +96,7 @@ my-twenty-app/
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
eslint.config.mjs
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Složka s veřejnými prostředky (obrázky, písma apod.)
|
||||
@@ -130,7 +130,7 @@ V kostce:
|
||||
* **.gitignore**: Ignoruje běžné artefakty jako `node_modules`, `.yarn`, `generated/` (typovaný klient), `dist/`, `build/`, složky s coverage, logy a soubory `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Zamykají a konfigurují nástrojový řetězec Yarn 4 používaný projektem.
|
||||
* **.nvmrc**: Fixuje verzi Node.js požadovanou projektem.
|
||||
* **eslint.config.mjs** a **tsconfig.json**: Poskytují lintování a konfiguraci TypeScriptu pro zdrojové soubory vaší aplikace v TypeScriptu.
|
||||
* **.oxlintrc.json** and **tsconfig.json**: Provide linting and TypeScript configuration for your app's TypeScript sources.
|
||||
* **README.md**: Krátké README v kořeni aplikace se základními pokyny.
|
||||
* **public/**: Složka pro ukládání veřejných prostředků (obrázky, písma, statické soubory), které bude vaše aplikace poskytovat. Soubory umístěné zde se během synchronizace nahrají a jsou za běhu dostupné.
|
||||
* **src/**: Hlavní místo, kde definujete svou aplikaci jako kód
|
||||
|
||||
@@ -54,21 +54,18 @@ Ujistěte se, že v kořenovém adresáři spouštíte `yarn` a poté spusťte `
|
||||
|
||||
#### Lint při ukládání nefunguje
|
||||
|
||||
Toto by mělo fungovat přímo s nainstalovaným rozšířením eslint. Pokud to nefunguje, zkuste přidat toto do svého nastavení vscode (v rozsahu dev containeru):
|
||||
Toto by mělo fungovat přímo s nainstalovaným rozšířením Oxc (`oxc.oxc-vscode`). Pokud to nefunguje, zkuste přidat toto do svého nastavení vscode (v rozsahu dev containeru):
|
||||
|
||||
```
|
||||
"editor.codeActionsOnSave": {
|
||||
|
||||
"source.fixAll.eslint": "explicit"
|
||||
"source.fixAll.oxc": "explicit"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### Při spuštění `npx nx start` nebo `npx nx start twenty-front` došlo k chybě nedostatku paměti
|
||||
|
||||
In `packages/twenty-front/.env` uncomment `VITE_DISABLE_TYPESCRIPT_CHECKER=true` and `VITE_DISABLE_ESLINT_CHECKER=true` to disable background checks thus reducing amount of needed RAM.
|
||||
|
||||
**Pokud to nefunguje:**
|
||||
Spusťte pouze služby, které potřebujete, místo `npx nx start`. Například pokud pracujete na serveru, spusťte pouze `npx nx worker twenty-server`
|
||||
|
||||
**Pokud to nefunguje:**
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ So sieht der Tech-Stack jetzt aus.
|
||||
**Tools**
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
**Entwicklung**
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ Das Projekt hat einen sauberen und einfachen Stack mit minimalem Boilerplate-Cod
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [Craco](https://craco.js.org/docs/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
## Architektur
|
||||
|
||||
|
||||
+4
-4
@@ -260,7 +260,7 @@ const StyledButton = styled.button`
|
||||
|
||||
## Durchsetzung von No-Type Imports
|
||||
|
||||
Vermeiden Sie Typ-Importe. Um diesen Standard durchzusetzen, überprüft eine ESLint-Regel alle Typ-Importe und meldet sie. Dies trägt zur Konsistenz und Lesbarkeit des TypeScript-Codes bei.
|
||||
Vermeiden Sie Typ-Importe. Um diesen Standard durchzusetzen, überprüft eine Oxlint-Regel alle Typ-Importe und meldet sie. Dies trägt zur Konsistenz und Lesbarkeit des TypeScript-Codes bei.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
@@ -281,10 +281,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
* **Wartbarkeit**: Es verbessert die Wartbarkeit der Codebasis, da Entwickler Typ-Only-Imports beim Überprüfen oder Ändern von Code identifizieren und lokalisieren können.
|
||||
|
||||
### ESLint-Regel
|
||||
### Oxlint-Regel
|
||||
|
||||
Eine ESLint-Regel, `@typescript-eslint/consistent-type-imports`, setzt den No-Type-Import-Standard durch. Diese Regel generiert Fehler oder Warnungen bei Verstößen gegen Typ-Importe.
|
||||
Eine Oxlint-Regel, `typescript/consistent-type-imports`, setzt den No-Type-Import-Standard durch. Diese Regel generiert Fehler oder Warnungen bei Verstößen gegen Typ-Importe.
|
||||
|
||||
Bitte beachten Sie, dass diese Regel speziell seltene Randfälle behandelt, in denen unbeabsichtigte Typ-Importe auftreten. TypeScript selbst lehnt diese Praxis ab, wie in den [TypeScript 3.8 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html) erwähnt. In den meisten Situationen sollten Typ-Only-Imports nicht benötigt werden.
|
||||
|
||||
Um sicherzustellen, dass Ihr Code mit dieser Regel übereinstimmt, achten Sie darauf, ESLint als Teil Ihres Entwicklungsworkflows auszuführen.
|
||||
Um sicherzustellen, dass Ihr Code mit dieser Regel übereinstimmt, achten Sie darauf, Oxlint als Teil Ihres Entwicklungsworkflows auszuführen.
|
||||
|
||||
@@ -96,30 +96,30 @@ my-twenty-app/
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
eslint.config.mjs
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Ordner für öffentliche Assets (Bilder, Schriftarten usw.)
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
src/
|
||||
├── application-config.ts # Erforderlich - Hauptkonfiguration der Anwendung
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── roles/
|
||||
│ └── default-role.ts # Standardrolle für Logikfunktionen
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
├── objects/
|
||||
│ └── example-object.ts # Beispiel für eine benutzerdefinierte Objektdefinition
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
├── fields/
|
||||
│ └── example-field.ts # Beispiel für eine eigenständige Felddefinition
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Beispiel für eine Logikfunktion
|
||||
│ ├── pre-install.ts # Pre-Installations-Logikfunktion
|
||||
│ └── post-install.ts # Post-Installations-Logikfunktion
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Beispiel für eine Frontend-Komponente
|
||||
│ └── hello-world.tsx # Example front component
|
||||
├── views/
|
||||
│ └── example-view.ts # Beispiel für eine gespeicherte View-Definition
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Beispiel für einen Navigationslink in der Seitenleiste
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
└── skills/
|
||||
└── example-skill.ts # Beispiel für eine Skill-Definition eines KI-Agenten
|
||||
└── example-skill.ts # Example AI agent skill definition
|
||||
```
|
||||
|
||||
Mit `--minimal` werden nur die Kerndateien erstellt (`application-config.ts`, `roles/default-role.ts`, `logic-functions/pre-install.ts` und `logic-functions/post-install.ts`). Mit `--interactive` wählst du aus, welche Beispieldateien enthalten sein sollen.
|
||||
@@ -130,7 +130,7 @@ Auf hoher Ebene:
|
||||
* **.gitignore**: Ignoriert übliche Artefakte wie `node_modules`, `.yarn`, `generated/` (typisierter Client), `dist/`, `build/`, Coverage-Ordner, Logdateien und `.env*`-Dateien.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Fixieren und konfigurieren die vom Projekt verwendete Yarn-4-Toolchain.
|
||||
* **.nvmrc**: Legt die vom Projekt erwartete Node.js-Version fest.
|
||||
* **eslint.config.mjs** und **tsconfig.json**: Stellen Linting und TypeScript-Konfiguration für die TypeScript-Quellen Ihrer App bereit.
|
||||
* **.oxlintrc.json** and **tsconfig.json**: Provide linting and TypeScript configuration for your app's TypeScript sources.
|
||||
* **README.md**: Ein kurzes README im App-Root mit grundlegenden Anweisungen.
|
||||
* **public/**: Ein Ordner zum Speichern öffentlicher Assets (Bilder, Schriftarten, statische Dateien), die zusammen mit Ihrer Anwendung bereitgestellt werden. Hier abgelegte Dateien werden während der Synchronisierung hochgeladen und sind zur Laufzeit zugänglich.
|
||||
* **src/**: Der Hauptort, an dem Sie Ihre Anwendung als Code definieren
|
||||
|
||||
@@ -53,21 +53,18 @@ Stellen Sie sicher, dass Sie `yarn` im Root-Verzeichnis ausführen und dann `npx
|
||||
|
||||
#### Lint beim Speichern funktioniert nicht
|
||||
|
||||
Normalerweise sollte dies sofort mit der installierten eslint-Erweiterung funktionieren. Wenn es nicht funktioniert, versuchen Sie, dies zu Ihren vscode-Einstellungen hinzuzufügen (im Entwicklungscontainer-Bereich):
|
||||
Normalerweise sollte dies sofort mit der installierten Oxc-Erweiterung (`oxc.oxc-vscode`) funktionieren. Wenn es nicht funktioniert, versuchen Sie, dies zu Ihren vscode-Einstellungen hinzuzufügen (im Entwicklungscontainer-Bereich):
|
||||
|
||||
```
|
||||
"editor.codeActionsOnSave": {
|
||||
|
||||
"source.fixAll.eslint": "explicit"
|
||||
"source.fixAll.oxc": "explicit"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### Beim Ausführen von `npx nx start` oder `npx nx start twenty-front` wird ein Speicherfehler angezeigt
|
||||
|
||||
Kommentieren Sie in `packages/twenty-front/.env` `VITE_DISABLE_TYPESCRIPT_CHECKER=true` und `VITE_DISABLE_ESLINT_CHECKER=true` aus, um Hintergrundprüfungen zu deaktivieren und den RAM-Bedarf zu reduzieren.
|
||||
|
||||
**Wenn es nicht funktioniert:**
|
||||
Führen Sie nur die Services aus, die Sie benötigen, anstatt `npx nx start`. Wenn Sie zum Beispiel am Server arbeiten, führen Sie nur `npx nx worker twenty-server` aus.
|
||||
|
||||
**Wenn es nicht funktioniert:**
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ Así es como se ve la pila tecnológica ahora.
|
||||
**Herramientas**
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
**Desarrollo**
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ El proyecto tiene un stack limpio y sencillo, con un código boilerplate mínimo
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [Craco](https://craco.js.org/docs/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
## Arquitectura
|
||||
|
||||
|
||||
+4
-4
@@ -260,7 +260,7 @@ const StyledButton = styled.button`
|
||||
|
||||
## Aplicando No-Type Imports
|
||||
|
||||
Evita las importaciones de tipo. Para reforzar este estándar, una regla de ESLint verifica y reporta cualquier importación de tipo. Esto ayuda a mantener la consistencia y la legibilidad en el código TypeScript.
|
||||
Evita las importaciones de tipo. Para reforzar este estándar, una regla de Oxlint verifica y reporta cualquier importación de tipo. Esto ayuda a mantener la consistencia y la legibilidad en el código TypeScript.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
@@ -281,10 +281,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
* **Mantenibilidad**: Mejora la mantenibilidad de la base de código porque los desarrolladores pueden identificar y localizar importaciones solo de tipo al revisar o modificar el código.
|
||||
|
||||
### Regla de ESLint
|
||||
### regla de Oxlint
|
||||
|
||||
Una regla de ESLint, `@typescript-eslint/consistent-type-imports`, impone el estándar de no usar "type" en las importaciones. Esta regla generará errores o advertencias sobre cualquier violación de importación de tipo.
|
||||
Una regla de Oxlint, `typescript/consistent-type-imports`, impone el estándar de no usar "type" en las importaciones. Esta regla generará errores o advertencias sobre cualquier violación de importación de tipo.
|
||||
|
||||
Por favor, ten en cuenta que esta regla específicamente aborda extraños casos límite donde ocurren importaciones de tipo no intencionadas. TypeScript en sí mismo desaconseja esta práctica, como se menciona en las [notas de lanzamiento de TypeScript 3.8](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). En la mayoría de situaciones, no deberías necesitar usar importaciones solo de tipo.
|
||||
|
||||
Para asegurarte de que tu código cumpla con esta regla, asegúrate de ejecutar ESLint como parte de tu flujo de trabajo de desarrollo.
|
||||
Para asegurarte de que tu código cumpla con esta regla, asegúrate de ejecutar Oxlint como parte de tu flujo de trabajo de desarrollo.
|
||||
|
||||
@@ -87,7 +87,7 @@ my-twenty-app/
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
eslint.config.mjs
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Carpeta de recursos públicos (imágenes, fuentes, etc.)
|
||||
@@ -158,7 +158,7 @@ A grandes rasgos:
|
||||
* **.gitignore**: Ignora artefactos comunes como `node_modules`, `.yarn`, `generated/` (cliente tipado), `dist/`, `build/`, carpetas de cobertura, archivos de registro y archivos `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloquean y configuran la cadena de herramientas Yarn 4 utilizada por el proyecto.
|
||||
* **.nvmrc**: Fija la versión de Node.js esperada por el proyecto.
|
||||
* **eslint.config.mjs** y **tsconfig.json**: Proporcionan linting y configuración de TypeScript para las fuentes de TypeScript de tu aplicación.
|
||||
* **.oxlintrc.json** y **tsconfig.json**: Proporcionan linting y configuración de TypeScript para las fuentes de TypeScript de tu aplicación.
|
||||
* **README.md**: Un README breve en la raíz de la aplicación con instrucciones básicas.
|
||||
* **public/**: Una carpeta para almacenar recursos públicos (imágenes, fuentes, archivos estáticos) que se servirán con tu aplicación. Los archivos colocados aquí se cargan durante la sincronización y son accesibles en tiempo de ejecución.
|
||||
* **src/**: El lugar principal donde defines tu aplicación como código:
|
||||
|
||||
@@ -53,21 +53,18 @@ Asegúrese de ejecutar yarn en el directorio raíz y luego ejecute `npx nx serve
|
||||
|
||||
#### Lint on Save no funciona
|
||||
|
||||
Esto debería funcionar sin configuración adicional con la extensión de ESLint instalada. Si esto no funciona, intente agregar esto a su configuración de vscode (en el ámbito del contenedor de desarrollo):
|
||||
Esto debería funcionar sin configuración adicional con la extensión de Oxlint instalada. Si esto no funciona, intente agregar esto a su configuración de vscode (en el ámbito del contenedor de desarrollo):
|
||||
|
||||
```
|
||||
"editor.codeActionsOnSave": {
|
||||
|
||||
"source.fixAll.eslint": "explicit"
|
||||
"source.fixAll.oxc": "explicit"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### Al ejecutar `npx nx start` o `npx nx start twenty-front`, se produce un error de falta de memoria
|
||||
|
||||
En `packages/twenty-front/.env` descomente `VITE_DISABLE_TYPESCRIPT_CHECKER=true` y `VITE_DISABLE_ESLINT_CHECKER=true` para deshabilitar las comprobaciones en segundo plano y así reducir la cantidad de RAM necesaria.
|
||||
|
||||
**Si no funciona:**
|
||||
Ejecute solo los servicios que necesite, en lugar de `npx nx start`. Por ejemplo, si trabaja en el servidor, ejecute solo `npx nx worker twenty-server`
|
||||
|
||||
**Si no funciona:**
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ Voici à quoi ressemble maintenant la pile technologique.
|
||||
**Outils**
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
**Développement**
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ Le projet a une stack simple et propre, avec un code boilerplate minimal.
|
||||
|
||||
* [Yarn](https://yarnpkg.com/)
|
||||
* [Craco](https://craco.js.org/docs/)
|
||||
* [ESLint](https://eslint.org/)
|
||||
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
||||
|
||||
## Architecture
|
||||
|
||||
|
||||
+4
-4
@@ -260,7 +260,7 @@ const StyledButton = styled.button`
|
||||
|
||||
## Application d'interdiction d'importations de type
|
||||
|
||||
Évitez les importations de type. Pour appliquer cette norme, une règle ESLint vérifie et signale toutes les importations de type. Cela aide à maintenir la cohérence et la lisibilité dans le code TypeScript.
|
||||
Évitez les importations de type. Pour appliquer cette norme, une règle Oxlint vérifie et signale toutes les importations de type. Cela aide à maintenir la cohérence et la lisibilité dans le code TypeScript.
|
||||
|
||||
```tsx
|
||||
// ❌ Bad
|
||||
@@ -281,10 +281,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
* **Maintenabilité** : Cela améliore la maintenabilité de la base de code car les développeurs peuvent identifier et localiser les importations uniquement de type lors de la révision ou de la modification du code.
|
||||
|
||||
### Règle ESLint
|
||||
### règle Oxlint
|
||||
|
||||
Une règle ESLint, `@typescript-eslint/consistent-type-imports`, impose la convention des imports "type-only". Cette règle génère des erreurs ou des avertissements pour toutes les violations d'importations de type.
|
||||
Une règle Oxlint, `typescript/consistent-type-imports`, impose la convention des imports "type-only". Cette règle génère des erreurs ou des avertissements pour toutes les violations d'importations de type.
|
||||
|
||||
Veillez à ce que cette règle aborde spécifiquement les rares cas particuliers où se produisent des importations de type involontaires. TypeScript lui-même déconseille cette pratique, comme mentionné dans les [notes de version de TypeScript 3.8](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). Dans la majorité des situations, vous ne devriez pas avoir besoin d'utiliser des importations uniquement de type.
|
||||
|
||||
Pour garantir la conformité de votre code avec cette règle, assurez-vous d'exécuter ESLint dans le cadre de votre flux de travail de développement.
|
||||
Pour garantir la conformité de votre code avec cette règle, assurez-vous d'exécuter Oxlint dans le cadre de votre flux de travail de développement.
|
||||
|
||||
@@ -87,7 +87,7 @@ my-twenty-app/
|
||||
.yarnrc.yml
|
||||
.yarn/
|
||||
install-state.gz
|
||||
eslint.config.mjs
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Dossier de ressources publiques (images, polices, etc.)
|
||||
@@ -158,7 +158,7 @@ Dans les grandes lignes :
|
||||
* **.gitignore** : Ignore les artefacts courants tels que `node_modules`, `.yarn`, `generated/` (client typé), `dist/`, `build/`, les dossiers de couverture, les fichiers journaux et les fichiers `.env*`.
|
||||
* **yarn.lock**, **.yarnrc.yml**, **.yarn/** : Verrouillent et configurent la chaîne d’outils Yarn 4 utilisée par le projet.
|
||||
* **.nvmrc** : Fige la version de Node.js attendue par le projet.
|
||||
* **eslint.config.mjs** et **tsconfig.json** : Fournissent la configuration de linting et TypeScript pour les sources TypeScript de votre application.
|
||||
* **.oxlintrc.json** et **tsconfig.json** : Fournissent la configuration de linting et TypeScript pour les sources TypeScript de votre application.
|
||||
* **README.md** : Un bref README à la racine de l’application avec des instructions de base.
|
||||
* **public/**: Un dossier pour stocker des ressources publiques (images, polices, fichiers statiques) qui seront servies avec votre application. Les fichiers placés ici sont téléversés lors de la synchronisation et accessibles à l'exécution.
|
||||
* **src/** : L’endroit principal où vous définissez votre application sous forme de code :
|
||||
|
||||
@@ -53,21 +53,18 @@ Assurez-vous d'exécuter yarn dans le répertoire racine, puis d'exécuter `npx
|
||||
|
||||
#### Lint à l'enregistrement ne fonctionne pas
|
||||
|
||||
Cela devrait fonctionner directement avec l'extension eslint installée. Si cela ne fonctionne pas, essayez d'ajouter ceci aux paramètres de votre vscode (dans le champ du conteneur de développement) :
|
||||
Cela devrait fonctionner directement avec l'extension Oxc (`oxc.oxc-vscode`) installée. Si cela ne fonctionne pas, essayez d'ajouter ceci aux paramètres de votre vscode (dans le champ du conteneur de développement) :
|
||||
|
||||
```
|
||||
"editor.codeActionsOnSave": {
|
||||
|
||||
"source.fixAll.eslint": "explicit"
|
||||
"source.fixAll.oxc": "explicit"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### Pendant l'exécution de `npx nx start` ou `npx nx start twenty-front`, une erreur de mémoire est renvoyée
|
||||
|
||||
Dans `packages/twenty-front/.env`, décommentez `VITE_DISABLE_TYPESCRIPT_CHECKER=true` et `VITE_DISABLE_ESLINT_CHECKER=true` pour désactiver les vérifications en arrière-plan, réduisant ainsi la quantité de RAM nécessaire.
|
||||
|
||||
**Si cela ne fonctionne pas :**
|
||||
Lancez uniquement les services dont vous avez besoin, au lieu de `npx nx start`. Par exemple, si vous travaillez sur le serveur, lancez seulement `npx nx worker twenty-server`
|
||||
|
||||
**Si cela ne fonctionne pas :**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user