Update twenty-front commands (#4667)

# This PR

- Moves dev and ci scripts to the `project.json` file in the
twenty-front package
- Adds a project.json file in the root of the project with the main
start command that start both twenty-server and twenty-front
applications concurrently
- Updates the script command of the root project with the start:prod
command (replacing the start command which will be used in dev with the
help of nx)
- Add a start:prod command in the twenty-front app, replacing the start
command (now used for dev purpose)

Issue ref #4645 

@charlesBochet @FelixMalfait please let me know how can I improve it

---------

Co-authored-by: Thaïs Guigon <guigon.thais@gmail.com>
This commit is contained in:
Pacifique LINJANJA
2024-04-17 18:06:02 +02:00
committed by GitHub
parent 977927af04
commit 627a6bda29
40 changed files with 800 additions and 381 deletions

View File

@@ -1,3 +1,5 @@
var path = require('path');
module.exports = { module.exports = {
extends: [ extends: [
'plugin:@nx/react', 'plugin:@nx/react',
@@ -72,7 +74,9 @@ module.exports = {
rules: { rules: {
'storybook/no-uninstalled-addons': [ 'storybook/no-uninstalled-addons': [
'error', 'error',
{ packageJsonLocation: '../../package.json' }, {
packageJsonLocation: path.resolve(__dirname, './package.json'),
},
], ],
}, },
}, },

View File

@@ -74,13 +74,11 @@ jobs:
restore-keys: root-node_modules- restore-keys: root-node_modules-
- name: Install Playwright - name: Install Playwright
run: cd packages/twenty-front && npx playwright install run: cd packages/twenty-front && npx playwright install
- name: Build Storybook
run: yarn nx storybook:pages:build twenty-front --quiet
- name: Run storybook tests - name: Run storybook tests
run: | run: |
cd packages/twenty-front && npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \ npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook-static --silent --port 6006" \ "STORYBOOK_SCOPE=pages npx nx run twenty-front:storybook:static" \
"yarn storybook:pages:coverage" "npx wait-on tcp:6006 && STORYBOOK_SCOPE=pages npx nx run twenty-front:storybook:test"
front-modules-sb-test: front-modules-sb-test:
needs: front-yarn-install needs: front-yarn-install
runs-on: ci-4-cores runs-on: ci-4-cores
@@ -114,13 +112,11 @@ jobs:
restore-keys: root-node_modules- restore-keys: root-node_modules-
- name: Install Playwright - name: Install Playwright
run: cd packages/twenty-front && npx playwright install run: cd packages/twenty-front && npx playwright install
- name: Build Storybook
run: yarn nx storybook:modules:build twenty-front --quiet
- name: Run storybook tests - name: Run storybook tests
run: | run: |
cd packages/twenty-front && npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \ npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook-static --silent --port 6006" \ "STORYBOOK_SCOPE=modules npx nx run twenty-front:storybook:static" \
"yarn storybook:modules:coverage" "npx wait-on tcp:6006 && STORYBOOK_SCOPE=modules npx nx run twenty-front:storybook:test"
front-lint-tsc: front-lint-tsc:
needs: front-yarn-install needs: front-yarn-install
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -149,13 +145,13 @@ jobs:
key: root-node_modules-${{hashFiles('yarn.lock')}} key: root-node_modules-${{hashFiles('yarn.lock')}}
restore-keys: root-node_modules- restore-keys: root-node_modules-
- name: UI / Run linter - name: UI / Run linter
run: yarn nx lint twenty-ui run: npx nx lint twenty-ui
- name: UI / Run Typescript Check - name: UI / Run Typescript Check
run: yarn nx typecheck twenty-ui run: npx nx run twenty-ui:typecheck:ci
- name: Front / Run linter - name: Front / Run linter
run: yarn nx lint:ci twenty-front run: npx nx run twenty-front:lint:ci
- name: Front / Run Typescript Check - name: Front / Run Typescript Check
run: yarn nx tsc:ci twenty-front run: npx nx run twenty-front:typecheck:ci
front-jest: front-jest:
needs: front-yarn-install needs: front-yarn-install
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -184,4 +180,4 @@ jobs:
key: root-node_modules-${{hashFiles('yarn.lock')}} key: root-node_modules-${{hashFiles('yarn.lock')}}
restore-keys: root-node_modules- restore-keys: root-node_modules-
- name: Front / Run jest - name: Front / Run jest
run: yarn nx coverage twenty-front run: npx nx test twenty-front --configuration=ci

1
.gitignore vendored
View File

@@ -24,3 +24,4 @@ coverage
dist dist
storybook-static storybook-static
*.tsbuildinfo *.tsbuildinfo
.eslintcache

View File

@@ -70,7 +70,6 @@
"generators": { "generators": {
"@nx/react": { "@nx/react": {
"application": { "application": {
"babel": true,
"style": "@emotion/styled", "style": "@emotion/styled",
"linter": "eslint", "linter": "eslint",
"bundler": "vite", "bundler": "vite",

View File

@@ -270,6 +270,7 @@
"danger": "^11.3.0", "danger": "^11.3.0",
"dotenv-cli": "^7.2.1", "dotenv-cli": "^7.2.1",
"drizzle-kit": "^0.20.14", "drizzle-kit": "^0.20.14",
"esbuild": "^0.20.2",
"eslint": "^8.53.0", "eslint": "^8.53.0",
"eslint-config-next": "14.0.4", "eslint-config-next": "14.0.4",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
@@ -329,7 +330,7 @@
}, },
"version": "0.2.1", "version": "0.2.1",
"scripts": { "scripts": {
"start": "cross-env FORCE_COLOR=true concurrently -n \"twenty-server,twenty-front\" -c \"bgBlue.bold,bgGreen.bold\" \"yarn nx start twenty-server\" \"yarn nx start twenty-front\"" "start:prod": "cross-env FORCE_COLOR=true concurrently -n \"twenty-server,twenty-front\" -c \"bgBlue.bold,bgGreen.bold\" \"yarn nx start twenty-server\" \"yarn nx start twenty-front\""
}, },
"workspaces": { "workspaces": {
"packages": [ "packages": [

View File

@@ -191,6 +191,12 @@ yarn nx start twenty-server
yarn nx start twenty-front yarn nx start twenty-front
``` ```
Alternatively, you can start both applications at once:
```bash
yarn nx start
# or
yarn nx start twenty
```
Twenty's server will be up and running at [http://localhost:3000/graphql](http://localhost:3000/graphql). Twenty's server will be up and running at [http://localhost:3000/graphql](http://localhost:3000/graphql).
Twenty's frontend will be running at [http://localhost:3001](http://localhost:3001). Just login using the seeded demo account: `tim@apple.dev` (password: `Applecar2025`) to start using Twenty. Twenty's frontend will be running at [http://localhost:3001](http://localhost:3001). Just login using the seeded demo account: `tim@apple.dev` (password: `Applecar2025`) to start using Twenty.

View File

@@ -0,0 +1,2 @@
src/generated
src/generated-metadata

View File

@@ -1,6 +1,7 @@
import { JestConfigWithTsJest, pathsToModuleNameMapper } from 'ts-jest'; import { JestConfigWithTsJest, pathsToModuleNameMapper } from 'ts-jest';
import { compilerOptions } from './tsconfig.json'; // eslint-disable-next-line @typescript-eslint/no-var-requires
const tsConfig = require('./tsconfig.json');
const jestConfig: JestConfigWithTsJest = { const jestConfig: JestConfigWithTsJest = {
// to enable logs, comment out the following line // to enable logs, comment out the following line
@@ -17,7 +18,7 @@ const jestConfig: JestConfigWithTsJest = {
'\\.(jpg|jpeg|png|gif|webp|svg|svg\\?react)$': '\\.(jpg|jpeg|png|gif|webp|svg|svg\\?react)$':
'<rootDir>/__mocks__/imageMock.js', '<rootDir>/__mocks__/imageMock.js',
'\\.css$': '<rootDir>/__mocks__/styleMock.js', '\\.css$': '<rootDir>/__mocks__/styleMock.js',
...pathsToModuleNameMapper(compilerOptions.paths), ...pathsToModuleNameMapper(tsConfig.compilerOptions.paths),
}, },
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
extensionsToTreatAsEsm: ['.ts', '.tsx'], extensionsToTreatAsEsm: ['.ts', '.tsx'],

View File

@@ -4,43 +4,11 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"nx": "NX_DEFAULT_PROJECT=twenty-front node ../../node_modules/nx/bin/nx.js", "build": "npx nx exec -- vite build && sh ./scripts/inject-runtime-env.sh",
"start": "npx vite --host", "build:sourcemaps": "VITE_BUILD_SOURCEMAP=true NODE_OPTIONS=--max-old-space-size=3000 npx nx build",
"start:clean": "yarn start --force", "start:prod": "NODE_ENV=production npx nx exec -- vite --host",
"build": "yarn tsc && npx vite build && yarn build:inject-runtime-env", "storybook:build": "npx nx exec -- storybook build",
"build:sourcemaps": "VITE_BUILD_SOURCEMAP=true NODE_OPTIONS=--max-old-space-size=3000 yarn build", "tsup": "npx nx exec -- tsup"
"build:inject-runtime-env": "sh ./scripts/inject-runtime-env.sh",
"tsc": "npx tsc --project tsconfig.app.json",
"tsc:ci": "yarn tsc --project tsconfig.json",
"tsc:watch": "yarn tsc --watch",
"tsc:spec": "yarn tsc --project tsconfig.spec.json",
"preview": "vite preview",
"lint": "npx eslint . --report-unused-disable-directives --max-warnings 0 --config .eslintrc.cjs",
"lint:ci": "yarn lint --config .eslintrc-ci.cjs",
"fmt:fix": "prettier --cache --write \"src/**/*.ts\" \"src/**/*.tsx\"",
"fmt": "prettier --check \"src/**/*.ts\" \"src/**/*.tsx\"",
"test": "npx jest",
"test-watch": "jest --watch",
"tsup": "tsup",
"coverage": "jest --coverage",
"storybook:modules:dev": "STORYBOOK_SCOPE=modules yarn storybook:dev",
"storybook:dev": "npx storybook dev -p 6006 --no-open",
"storybook:pages:dev": "STORYBOOK_SCOPE=pages yarn storybook:dev",
"storybook:docs:dev": "STORYBOOK_SCOPE=ui-docs yarn storybook:dev",
"storybook:build": "npx storybook build",
"storybook:modules:build": "STORYBOOK_SCOPE=modules npx nx storybook:build",
"storybook:pages:build": "STORYBOOK_SCOPE=pages npx nx storybook:build",
"storybook:docs:build": "STORYBOOK_SCOPE=ui-docs npx nx storybook:build",
"storybook:test": "test-storybook",
"storybook:test-slow": "test-storybook --maxWorkers=3",
"storybook:test-single-worker": "test-storybook --maxWorkers=1",
"storybook:coverage": "yarn storybook:test-slow --coverage ; npx nyc report --reporter=lcov -t coverage/storybook --report-dir coverage/storybook --check-coverage",
"storybook:modules:coverage": "STORYBOOK_SCOPE=modules yarn storybook:coverage",
"storybook:pages:coverage": "STORYBOOK_SCOPE=pages yarn storybook:coverage",
"graphql:data:generate": "dotenv cross-var graphql-codegen -- --config codegen.cjs",
"graphql:metadata:generate": "dotenv cross-var graphql-codegen -- --config codegen-metadata.cjs",
"chromatic": "cross-var npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN --build-script-name=storybook:build",
"chromatic:ci": "cross-var npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN --build-script-name=storybook:build --exit-zero-on-changes"
}, },
"engines": { "engines": {
"node": "^18.17.1", "node": "^18.17.1",

View File

@@ -0,0 +1,159 @@
{
"name": "twenty-front",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"targets": {
"build": {
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "{projectRoot}/build"
}
},
"start": {
"executor": "@nx/vite:dev-server",
"options": {
"buildTarget": "twenty-front:build",
"hmr": true
}
},
"preview": {
"executor": "@nx/vite:preview-server",
"options": {
"buildTarget": "twenty-front:build",
"port": 3001,
"open": true
}
},
"typecheck": {
"executor": "nx:run-commands",
"options": {
"cwd": "{projectRoot}",
"command": "tsc -b tsconfig.json",
"incremental": true
},
"configurations": {
"ci": { "incremental": false },
"watch": { "watch": true }
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"eslintConfig": "{projectRoot}/.eslintrc.cjs",
"ignorePath": "{workspaceRoot}/.gitignore",
"lintFilePatterns": [
"{projectRoot}/src/**/*.{ts,tsx,json}",
"{projectRoot}/package.json"
],
"maxWarnings": 0,
"reportUnusedDisableDirectives": "error",
"cache": true
},
"configurations": {
"ci": {
"eslintConfig": "{projectRoot}/.eslintrc-ci.cjs",
"cache": false
},
"fix": {
"fix": true
}
}
},
"fmt": {
"executor": "nx:run-commands",
"inputs": ["{projectRoot}/src/**/*"],
"cache": true,
"options": {
"cwd": "{projectRoot}",
"command": "prettier src --check"
},
"configurations": {
"fix": { "args": ["--write"] }
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{projectRoot}/coverage"],
"options": {
"jestConfig": "{projectRoot}/jest.config.ts",
"coverage": true,
"coverageReporters": ["text-summary"]
},
"configurations": {
"ci": {
"ci": true,
"maxWorkers": 3
},
"coverage": {
"coverageReporters": ["lcov", "text"]
},
"watch": { "watch": true }
}
},
"storybook:dev": {
"executor": "@nx/storybook:storybook",
"options": {
"port": 6006,
"configDir": "{projectRoot}/.storybook"
}
},
"storybook:static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "twenty-front:storybook:build",
"staticFilePath": "{projectRoot}/storybook-static",
"port": 6006,
"watch": false
}
},
"storybook:test": {
"executor": "nx:run-commands",
"options": {
"cwd": "{projectRoot}",
"commands": [
"test-storybook --url http://localhost:6006 --maxWorkers=3 --coverage",
"nyc report --reporter=lcov --reporter=text-summary -t coverage/storybook --report-dir coverage/storybook --check-coverage"
],
"parallel": false
},
"configurations": {
"docs": {
"commands": ["STORYBOOK_SCOPE=ui-docs nx storybook:test"]
},
"modules": {
"commands": ["STORYBOOK_SCOPE=modules nx storybook:test"]
},
"pages": { "commands": ["STORYBOOK_SCOPE=pages nx storybook:test"] }
}
},
"graphql:generate": {
"executor": "nx:run-commands",
"defaultConfiguration": "data",
"options": {
"cwd": "{projectRoot}",
"command": "dotenv cross-var graphql-codegen -- --config={args.config}"
},
"configurations": {
"data": {
"args": ["--config=codegen.cjs"]
},
"metadata": {
"args": ["--config=codegen-metadata.cjs"]
}
}
},
"chromatic": {
"executor": "nx:run-commands",
"options": {
"cwd": "{projectRoot}",
"command": "cross-var chromatic --project-token=$CHROMATIC_PROJECT_TOKEN --build-script-name=storybook:build"
},
"configurations": {
"ci": {
"args": ["--exit-zero-on-changes"]
}
}
}
}
}

View File

@@ -8,6 +8,7 @@ describe('getDisplayNameFromParticipant', () => {
handle: '', handle: '',
role: 'from', role: 'from',
person: { person: {
__typename: 'Person',
id: '1', id: '1',
createdAt: '', createdAt: '',
updatedAt: '', updatedAt: '',
@@ -32,6 +33,7 @@ describe('getDisplayNameFromParticipant', () => {
companyId: '', companyId: '',
}, },
workspaceMember: { workspaceMember: {
__typename: 'WorkspaceMember',
id: '1', id: '1',
name: { name: {
firstName: 'Jane', firstName: 'Jane',

View File

@@ -4,7 +4,7 @@ import { groupEventsByMonth } from '../groupEventsByMonth';
describe('groupEventsByMonth', () => { describe('groupEventsByMonth', () => {
it('should group activities by month', () => { it('should group activities by month', () => {
const grouped = groupEventsByMonth(mockedEvents as unknown as Event[]); const grouped = groupEventsByMonth(mockedEvents);
expect(grouped).toHaveLength(2); expect(grouped).toHaveLength(2);
expect(grouped[0].items).toHaveLength(1); expect(grouped[0].items).toHaveLength(1);

View File

@@ -83,12 +83,10 @@ describe('useCreateActivityInCache', () => {
act(() => { act(() => {
const res = result.current.createActivityInCache({ const res = result.current.createActivityInCache({
type: 'Note', type: 'Note',
targetableObjects: [ targetObject: {
{ targetObjectNameSingular: 'person',
targetObjectNameSingular: 'person', id: '1234',
id: '1234', },
},
],
}); });
expect(res.createdActivityInCache).toHaveProperty('id'); expect(res.createdActivityInCache).toHaveProperty('id');

View File

@@ -4,7 +4,10 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus'; import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import {
CurrentWorkspace,
currentWorkspaceState,
} from '@/auth/states/currentWorkspaceState';
import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState'; import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState';
import { tokenPairState } from '@/auth/states/tokenPairState'; import { tokenPairState } from '@/auth/states/tokenPairState';
import { billingState } from '@/client-config/states/billingState'; import { billingState } from '@/client-config/states/billingState';
@@ -84,7 +87,7 @@ describe('useOnboardingStatus', () => {
setCurrentWorkspace({ setCurrentWorkspace({
...currentWorkspace, ...currentWorkspace,
subscriptionStatus: 'incomplete', subscriptionStatus: 'incomplete',
}); } as CurrentWorkspace);
setCurrentWorkspaceMember(currentWorkspaceMember); setCurrentWorkspaceMember(currentWorkspaceMember);
}); });
@@ -106,7 +109,7 @@ describe('useOnboardingStatus', () => {
setCurrentWorkspace({ setCurrentWorkspace({
...currentWorkspace, ...currentWorkspace,
subscriptionStatus: 'canceled', subscriptionStatus: 'canceled',
}); } as CurrentWorkspace);
setCurrentWorkspaceMember({ setCurrentWorkspaceMember({
...currentWorkspaceMember, ...currentWorkspaceMember,
name: { name: {
@@ -130,7 +133,7 @@ describe('useOnboardingStatus', () => {
...currentWorkspace, ...currentWorkspace,
activationStatus: 'inactive', activationStatus: 'inactive',
subscriptionStatus: 'active', subscriptionStatus: 'active',
}); } as CurrentWorkspace);
}); });
expect(result.current.onboardingStatus).toBe( expect(result.current.onboardingStatus).toBe(
@@ -153,7 +156,7 @@ describe('useOnboardingStatus', () => {
setCurrentWorkspace({ setCurrentWorkspace({
...currentWorkspace, ...currentWorkspace,
subscriptionStatus: 'active', subscriptionStatus: 'active',
}); } as CurrentWorkspace);
setCurrentWorkspaceMember(currentWorkspaceMember); setCurrentWorkspaceMember(currentWorkspaceMember);
}); });
@@ -175,7 +178,7 @@ describe('useOnboardingStatus', () => {
setCurrentWorkspace({ setCurrentWorkspace({
...currentWorkspace, ...currentWorkspace,
subscriptionStatus: 'active', subscriptionStatus: 'active',
}); } as CurrentWorkspace);
setCurrentWorkspaceMember({ setCurrentWorkspaceMember({
...currentWorkspaceMember, ...currentWorkspaceMember,
name: { name: {
@@ -203,7 +206,7 @@ describe('useOnboardingStatus', () => {
setCurrentWorkspace({ setCurrentWorkspace({
...currentWorkspace, ...currentWorkspace,
subscriptionStatus: 'past_due', subscriptionStatus: 'past_due',
}); } as CurrentWorkspace);
setCurrentWorkspaceMember({ setCurrentWorkspaceMember({
...currentWorkspaceMember, ...currentWorkspaceMember,
name: { name: {
@@ -231,7 +234,7 @@ describe('useOnboardingStatus', () => {
setCurrentWorkspace({ setCurrentWorkspace({
...currentWorkspace, ...currentWorkspace,
subscriptionStatus: 'unpaid', subscriptionStatus: 'unpaid',
}); } as CurrentWorkspace);
setCurrentWorkspaceMember({ setCurrentWorkspaceMember({
...currentWorkspaceMember, ...currentWorkspaceMember,
name: { name: {

View File

@@ -84,77 +84,77 @@ export const mocks = [
query: gql` query: gql`
mutation CreateOneFavorite($input: FavoriteCreateInput!) { mutation CreateOneFavorite($input: FavoriteCreateInput!) {
createFavorite(data: $input) { createFavorite(data: $input) {
__typename __typename
id id
companyId companyId
createdAt createdAt
personId personId
person { person {
__typename __typename
xLink { xLink {
label label
url url
}
id
createdAt
city
email
jobTitle
name {
firstName
lastName
}
phone
linkedinLink {
label
url
}
updatedAt
avatarUrl
companyId
}
position
workspaceMemberId
workspaceMember {
__typename
colorScheme
name {
firstName
lastName
}
locale
userId
avatarUrl
createdAt
updatedAt
id
}
company {
__typename
xLink {
label
url
}
linkedinLink {
label
url
}
domainName
annualRecurringRevenue {
amountMicros
currencyCode
}
createdAt
address
updatedAt
name
accountOwnerId
employees
id
idealCustomerProfile
}
updatedAt
} }
id
createdAt
city
email
jobTitle
name {
firstName
lastName
}
phone
linkedinLink {
label
url
}
updatedAt
avatarUrl
companyId
}
position
workspaceMemberId
workspaceMember {
__typename
colorScheme
name {
firstName
lastName
}
locale
userId
avatarUrl
createdAt
updatedAt
id
}
company {
__typename
xLink {
label
url
}
linkedinLink {
label
url
}
domainName
annualRecurringRevenue {
amountMicros
currencyCode
}
createdAt
address
updatedAt
name
accountOwnerId
employees
id
idealCustomerProfile
}
updatedAt
}
} }
`, `,
variables: { variables: {
@@ -201,77 +201,77 @@ export const mocks = [
$input: FavoriteUpdateInput! $input: FavoriteUpdateInput!
) { ) {
updateFavorite(id: $idToUpdate, data: $input) { updateFavorite(id: $idToUpdate, data: $input) {
__typename __typename
id id
companyId companyId
createdAt createdAt
personId personId
person { person {
__typename __typename
xLink { xLink {
label label
url url
}
id
createdAt
city
email
jobTitle
name {
firstName
lastName
}
phone
linkedinLink {
label
url
}
updatedAt
avatarUrl
companyId
}
position
workspaceMemberId
workspaceMember {
__typename
colorScheme
name {
firstName
lastName
}
locale
userId
avatarUrl
createdAt
updatedAt
id
}
company {
__typename
xLink {
label
url
}
linkedinLink {
label
url
}
domainName
annualRecurringRevenue {
amountMicros
currencyCode
}
createdAt
address
updatedAt
name
accountOwnerId
employees
id
idealCustomerProfile
}
updatedAt
} }
id
createdAt
city
email
jobTitle
name {
firstName
lastName
}
phone
linkedinLink {
label
url
}
updatedAt
avatarUrl
companyId
}
position
workspaceMemberId
workspaceMember {
__typename
colorScheme
name {
firstName
lastName
}
locale
userId
avatarUrl
createdAt
updatedAt
id
}
company {
__typename
xLink {
label
url
}
linkedinLink {
label
url
}
domainName
annualRecurringRevenue {
amountMicros
currencyCode
}
createdAt
address
updatedAt
name
accountOwnerId
employees
id
idealCustomerProfile
}
updatedAt
}
} }
`, `,
variables: { variables: {

View File

@@ -22,28 +22,38 @@ export const query = gql`
`; `;
export const findManyViewsQuery = gql` export const findManyViewsQuery = gql`
query FindManyViews($filter: ViewFilterInput, $orderBy: ViewOrderByInput, $lastCursor: String, $limit: Float) { query FindManyViews(
views(filter: $filter, orderBy: $orderBy, first: $limit, after: $lastCursor) { $filter: ViewFilterInput
edges { $orderBy: ViewOrderByInput
node { $lastCursor: String
__typename $limit: Float
id ) {
objectMetadataId views(
type filter: $filter
createdAt orderBy: $orderBy
name first: $limit
updatedAt after: $lastCursor
} ) {
cursor edges {
node {
__typename
id
objectMetadataId
type
createdAt
name
updatedAt
} }
pageInfo { cursor
hasNextPage
startCursor
endCursor
}
totalCount
} }
pageInfo {
hasNextPage
startCursor
endCursor
}
totalCount
} }
}
`; `;
export const variables = { export const variables = {

View File

@@ -4,7 +4,7 @@ import { act, renderHook } from '@testing-library/react';
import { RecoilRoot } from 'recoil'; import { RecoilRoot } from 'recoil';
import { useCreateOneRelationMetadataItem } from '@/object-metadata/hooks/useCreateOneRelationMetadataItem'; import { useCreateOneRelationMetadataItem } from '@/object-metadata/hooks/useCreateOneRelationMetadataItem';
import { RelationMetadataType } from '~/generated/graphql'; import { FieldMetadataType, RelationMetadataType } from '~/generated/graphql';
import { import {
query, query,
@@ -45,6 +45,7 @@ describe('useCreateOneRelationMetadataItem', () => {
relationType: RelationMetadataType.OneToOne, relationType: RelationMetadataType.OneToOne,
field: { field: {
label: 'label', label: 'label',
type: FieldMetadataType.Relation,
}, },
objectMetadataId: 'objectMetadataId', objectMetadataId: 'objectMetadataId',
connect: { connect: {

View File

@@ -159,6 +159,7 @@ describe('useFieldMetadataItem', () => {
const res = await result.current.editMetadataField({ const res = await result.current.editMetadataField({
id: fieldMetadataItem.id, id: fieldMetadataItem.id,
label: 'New label', label: 'New label',
type: FieldMetadataType.Text,
}); });
expect(res.data).toEqual({ expect(res.data).toEqual({

View File

@@ -6,27 +6,27 @@ export const query = gql`
mutation CreatePeople($data: [PersonCreateInput!]!) { mutation CreatePeople($data: [PersonCreateInput!]!) {
createPeople(data: $data) { createPeople(data: $data) {
__typename __typename
xLink { xLink {
label label
url url
} }
id id
createdAt createdAt
city city
email email
jobTitle jobTitle
name { name {
firstName firstName
lastName lastName
} }
phone phone
linkedinLink { linkedinLink {
label label
url url
} }
updatedAt updatedAt
avatarUrl avatarUrl
companyId companyId
} }
} }
`; `;

View File

@@ -4,27 +4,27 @@ export const query = gql`
mutation CreateOnePerson($input: PersonCreateInput!) { mutation CreateOnePerson($input: PersonCreateInput!) {
createPerson(data: $input) { createPerson(data: $input) {
__typename __typename
xLink { xLink {
label label
url url
} }
id id
createdAt createdAt
city city
email email
jobTitle jobTitle
name { name {
firstName firstName
lastName lastName
} }
phone phone
linkedinLink { linkedinLink {
label label
url url
} }
updatedAt updatedAt
avatarUrl avatarUrl
companyId companyId
} }
} }
`; `;

View File

@@ -6,27 +6,27 @@ export const query = gql`
mutation ExecuteQuickActionOnOnePerson($idToExecuteQuickActionOn: UUID!) { mutation ExecuteQuickActionOnOnePerson($idToExecuteQuickActionOn: UUID!) {
executeQuickActionOnPerson(id: $idToExecuteQuickActionOn) { executeQuickActionOnPerson(id: $idToExecuteQuickActionOn) {
__typename __typename
xLink { xLink {
label label
url url
} }
id id
createdAt createdAt
city city
email email
jobTitle jobTitle
name { name {
firstName firstName
lastName lastName
} }
phone phone
linkedinLink { linkedinLink {
label label
url url
} }
updatedAt updatedAt
avatarUrl avatarUrl
companyId companyId
} }
} }
`; `;

View File

@@ -6,27 +6,27 @@ export const query = gql`
query FindOnePerson($objectRecordId: UUID!) { query FindOnePerson($objectRecordId: UUID!) {
person(filter: { id: { eq: $objectRecordId } }) { person(filter: { id: { eq: $objectRecordId } }) {
__typename __typename
xLink { xLink {
label label
url url
} }
id id
createdAt createdAt
city city
email email
jobTitle jobTitle
name { name {
firstName firstName
lastName lastName
} }
phone phone
linkedinLink { linkedinLink {
label label
url url
} }
updatedAt updatedAt
avatarUrl avatarUrl
companyId companyId
} }
} }
`; `;

View File

@@ -4,27 +4,27 @@ export const query = gql`
mutation UpdateOnePerson($idToUpdate: UUID!, $input: PersonUpdateInput!) { mutation UpdateOnePerson($idToUpdate: UUID!, $input: PersonUpdateInput!) {
updatePerson(id: $idToUpdate, data: $input) { updatePerson(id: $idToUpdate, data: $input) {
__typename __typename
xLink { xLink {
label label
url url
} }
id id
createdAt createdAt
city city
email email
jobTitle jobTitle
name { name {
firstName firstName
lastName lastName
} }
phone phone
linkedinLink { linkedinLink {
label label
url url
} }
updatedAt updatedAt
avatarUrl avatarUrl
companyId companyId
} }
} }
`; `;

View File

@@ -23,5 +23,5 @@ export type FieldDefinition<T extends FieldMetadata> = {
type: FieldMetadataType; type: FieldMetadataType;
metadata: T; metadata: T;
infoTooltipContent?: string; infoTooltipContent?: string;
defaultValue: any; defaultValue?: any;
}; };

View File

@@ -8,6 +8,7 @@ import {
} from '@/object-record/record-field/__mocks__/fieldDefinitions'; } from '@/object-record/record-field/__mocks__/fieldDefinitions';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition'; import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldCurrencyMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { FieldCurrencyMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { FieldMetadataType } from '~/generated/graphql';
import { isFieldValueEmpty } from '../isFieldValueEmpty'; import { isFieldValueEmpty } from '../isFieldValueEmpty';
@@ -64,7 +65,7 @@ describe('isFieldValueEmpty', () => {
fieldMetadataId, fieldMetadataId,
label: 'Annual Income', label: 'Annual Income',
iconName: 'cashCow', iconName: 'cashCow',
type: 'CURRENCY', type: FieldMetadataType.Currency,
metadata: { metadata: {
fieldName: 'annualIncome', fieldName: 'annualIncome',
placeHolder: '100000', placeHolder: '100000',

View File

@@ -1,6 +1,6 @@
import { createContext } from 'react'; import { createContext } from 'react';
type RecordTableRowContextProps = { export type RecordTableRowContextProps = {
pathToShowPage: string; pathToShowPage: string;
recordId: string; recordId: string;
rowIndex: number; rowIndex: number;

View File

@@ -1,12 +1,14 @@
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { RecordTableRowContextProps } from '@/object-record/record-table/contexts/RecordTableRowContext';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { FieldMetadataType } from '~/generated-metadata/graphql'; import { FieldMetadataType } from '~/generated-metadata/graphql';
export const recordTableRow = { export const recordTableRow: RecordTableRowContextProps = {
rowIndex: 2, rowIndex: 2,
isSelected: false, isSelected: false,
recordId: 'recordId', recordId: 'recordId',
pathToShowPage: '/', pathToShowPage: '/',
isReadOnly: false,
}; };
export const recordTableCell: { export const recordTableCell: {

View File

@@ -20,6 +20,7 @@ describe('useLimitPerMetadataItem', () => {
isActive: true, isActive: true,
isCustom: true, isCustom: true,
isSystem: true, isSystem: true,
isRemote: false,
labelPlural: 'labelPlural', labelPlural: 'labelPlural',
labelSingular: 'labelSingular', labelSingular: 'labelSingular',
namePlural: 'namePlural', namePlural: 'namePlural',

View File

@@ -118,6 +118,7 @@ describe('useMultiObjectSearch', () => {
isActive: true, isActive: true,
isCustom: true, isCustom: true,
isSystem: false, isSystem: false,
isRemote: false,
labelPlural: 'labelPlural', labelPlural: 'labelPlural',
labelSingular: 'labelSingular', labelSingular: 'labelSingular',
namePlural: 'namePlural', namePlural: 'namePlural',
@@ -152,6 +153,7 @@ describe('useMultiObjectSearch', () => {
isActive: true, isActive: true,
isCustom: true, isCustom: true,
isSystem: false, isSystem: false,
isRemote: false,
labelPlural: 'labelPlural', labelPlural: 'labelPlural',
labelSingular: 'labelSingular', labelSingular: 'labelSingular',
namePlural: 'namePlural', namePlural: 'namePlural',

View File

@@ -72,6 +72,7 @@ describe('useFilteredSearchEntityQuery', () => {
setCurrentWorkspaceMember({ setCurrentWorkspaceMember({
id: '32219445-f587-4c40-b2b1-6d3205ed96da', id: '32219445-f587-4c40-b2b1-6d3205ed96da',
name: { firstName: 'John', lastName: 'Connor' }, name: { firstName: 'John', lastName: 'Connor' },
locale: 'en',
}); });
const mockObjectMetadataItems = getObjectMetadataItemsMock(); const mockObjectMetadataItems = getObjectMetadataItemsMock();

View File

@@ -21,8 +21,7 @@ Buttons are often used for form submissions and to toggle elements into view.
## Usage ## Usage
```js ```js
import { Button } from '@/ui/button/components/Button'; import { Button } from '@/ui/button/components/Button';
<Button title='Click me' /> <Button title="Click me" />;
``` ```

View File

@@ -17,6 +17,7 @@ const workspaceMember: Omit<
WorkspaceMember, WorkspaceMember,
'createdAt' | 'updatedAt' | 'userId' | 'userEmail' 'createdAt' | 'updatedAt' | 'userId' | 'userEmail'
> = { > = {
__typename: 'WorkspaceMember',
id: 'id', id: 'id',
name: { name: {
firstName: 'firstName', firstName: 'firstName',

View File

@@ -1,6 +1,7 @@
import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition'; import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { mapBoardFieldDefinitionsToViewFields } from '@/views/utils/mapBoardFieldDefinitionsToViewFields'; import { mapBoardFieldDefinitionsToViewFields } from '@/views/utils/mapBoardFieldDefinitionsToViewFields';
import { FieldMetadataType } from '~/generated/graphql';
describe('mapBoardFieldDefinitionsToViewFields', () => { describe('mapBoardFieldDefinitionsToViewFields', () => {
it('should map board field definitions to view fields', () => { it('should map board field definitions to view fields', () => {
@@ -9,7 +10,7 @@ describe('mapBoardFieldDefinitionsToViewFields', () => {
fieldMetadataId: 'fieldMetadataId', fieldMetadataId: 'fieldMetadataId',
label: 'label', label: 'label',
iconName: 'iconName', iconName: 'iconName',
type: 'BOOLEAN', type: FieldMetadataType.Boolean,
metadata: { metadata: {
objectMetadataNameSingular: 'objectMetadataNameSingular', objectMetadataNameSingular: 'objectMetadataNameSingular',
fieldName: 'fieldName', fieldName: 'fieldName',
@@ -22,7 +23,7 @@ describe('mapBoardFieldDefinitionsToViewFields', () => {
fieldMetadataId: 'fieldMetadataId1', fieldMetadataId: 'fieldMetadataId1',
label: 'label1', label: 'label1',
iconName: 'iconName1', iconName: 'iconName1',
type: 'NUMBER', type: FieldMetadataType.Number,
metadata: { metadata: {
objectMetadataNameSingular: 'objectMetadataNameSingular1', objectMetadataNameSingular: 'objectMetadataNameSingular1',
fieldName: 'fieldName1', fieldName: 'fieldName1',

View File

@@ -10,6 +10,7 @@ import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinit
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts'; import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
import { FieldMetadataType } from '~/generated/graphql';
const baseDefinition = { const baseDefinition = {
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482', fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
@@ -91,7 +92,7 @@ describe('mapViewFieldsToColumnDefinitions', () => {
metadata: { fieldName: 'fieldName 1' }, metadata: { fieldName: 'fieldName 1' },
infoTooltipContent: 'infoTooltipContent 1', infoTooltipContent: 'infoTooltipContent 1',
iconName: 'iconName 1', iconName: 'iconName 1',
type: 'TEXT', type: FieldMetadataType.Text,
position: 1, position: 1,
size: 1, size: 1,
isVisible: false, isVisible: false,
@@ -111,7 +112,7 @@ describe('mapViewFieldsToColumnDefinitions', () => {
metadata: { fieldName: 'fieldName 2' }, metadata: { fieldName: 'fieldName 2' },
infoTooltipContent: 'infoTooltipContent 2', infoTooltipContent: 'infoTooltipContent 2',
iconName: 'iconName 2', iconName: 'iconName 2',
type: 'TEXT', type: FieldMetadataType.Text,
position: 2, position: 2,
size: 1, size: 1,
isVisible: false, isVisible: false,
@@ -131,7 +132,7 @@ describe('mapViewFieldsToColumnDefinitions', () => {
metadata: { fieldName: 'fieldName 3' }, metadata: { fieldName: 'fieldName 3' },
infoTooltipContent: 'infoTooltipContent 3', infoTooltipContent: 'infoTooltipContent 3',
iconName: 'iconName 3', iconName: 'iconName 3',
type: 'TEXT', type: FieldMetadataType.Text,
position: 3, position: 3,
size: 1, size: 1,
isVisible: false, isVisible: false,
@@ -148,7 +149,7 @@ describe('mapViewFieldsToColumnDefinitions', () => {
metadata: { fieldName: 'fieldName 1' }, metadata: { fieldName: 'fieldName 1' },
infoTooltipContent: 'infoTooltipContent 1', infoTooltipContent: 'infoTooltipContent 1',
iconName: 'iconName 1', iconName: 'iconName 1',
type: 'TEXT', type: FieldMetadataType.Text,
size: 1, size: 1,
}, },
{ {
@@ -158,7 +159,7 @@ describe('mapViewFieldsToColumnDefinitions', () => {
metadata: { fieldName: 'fieldName 3' }, metadata: { fieldName: 'fieldName 3' },
infoTooltipContent: 'infoTooltipContent 3', infoTooltipContent: 'infoTooltipContent 3',
iconName: 'iconName 3', iconName: 'iconName 3',
type: 'TEXT', type: FieldMetadataType.Text,
size: 3, size: 3,
}, },
]; ];
@@ -170,7 +171,7 @@ describe('mapViewFieldsToColumnDefinitions', () => {
metadata: { fieldName: 'fieldName 1' }, metadata: { fieldName: 'fieldName 1' },
infoTooltipContent: 'infoTooltipContent 1', infoTooltipContent: 'infoTooltipContent 1',
iconName: 'iconName 1', iconName: 'iconName 1',
type: 'TEXT', type: FieldMetadataType.Text,
size: 1, size: 1,
position: 1, position: 1,
isVisible: false, isVisible: false,
@@ -182,7 +183,7 @@ describe('mapViewFieldsToColumnDefinitions', () => {
metadata: { fieldName: 'fieldName 3' }, metadata: { fieldName: 'fieldName 3' },
infoTooltipContent: 'infoTooltipContent 3', infoTooltipContent: 'infoTooltipContent 3',
iconName: 'iconName 3', iconName: 'iconName 3',
type: 'TEXT', type: FieldMetadataType.Text,
size: 3, size: 3,
position: 3, position: 3,
isVisible: true, isVisible: true,

View File

@@ -1,20 +1,8 @@
import { defineConfig } from "tsup"; import { defineConfig } from 'tsup';
import svgr from 'esbuild-plugin-svgr' import svgr from 'esbuild-plugin-svgr';
import { Config } from '@svgr/core';
export default defineConfig([
{
entry: {"index": './tsup.ui.index.tsx'},
treeshake: true,
minify: true,
verbose: true,
dts: true,
clean: true,
outDir: "../twenty-docs/src/ui/generated",
esbuildPlugins: [svgr({ template })],
},
]);
function template(variables, { tpl }) { const template: Config['template'] = (variables, { tpl }) => {
return tpl` return tpl`
${variables.imports}; ${variables.imports};
${variables.interfaces}; ${variables.interfaces};
@@ -24,4 +12,18 @@ function template(variables, { tpl }) {
${variables.exports}; ${variables.exports};
export const ReactComponent = ${variables.componentName}; export const ReactComponent = ${variables.componentName};
`; `;
}; };
export default defineConfig([
{
entry: { index: './tsup.ui.index.tsx' },
treeshake: true,
minify: true,
dts: true,
clean: true,
outDir: '../twenty-docs/src/ui/generated',
esbuildPlugins: [svgr({ template })],
},
]);

View File

@@ -1,6 +1,6 @@
import { ThemeType } from './src/modules/ui/theme/constants/ThemeLight'; import { ThemeType } from './src/modules/ui/theme/constants/ThemeLight';
export {ThemeProvider} from '@emotion/react'; export { ThemeProvider } from '@emotion/react';
export { THEME_DARK } from './src/modules/ui/theme/constants/ThemeDark'; export { THEME_DARK } from './src/modules/ui/theme/constants/ThemeDark';
export { THEME_LIGHT } from './src/modules/ui/theme/constants/ThemeLight'; export { THEME_LIGHT } from './src/modules/ui/theme/constants/ThemeLight';
@@ -10,13 +10,8 @@ declare module '@emotion/react' {
export interface Theme extends ThemeType {} export interface Theme extends ThemeType {}
} }
export * from './src/modules/ui/display/checkmark/components/Checkmark'; export * from 'twenty-ui';
export * from './src/modules/ui/display/checkmark/components/AnimatedCheckmark'
export * from './src/modules/ui/display/chip/components/Chip'
export * from './src/modules/ui/display/chip/components/EntityChip'
export * from './src/modules/ui/display/tag/components/Tag' export * from './src/modules/ui/display/tag/components/Tag'
export * from './src/modules/ui/display/tooltip/AppTooltip'
export * from './src/modules/ui/display/tooltip/OverflowingTextWithTooltip'
export * from './src/modules/ui/feedback/progress-bar/components/ProgressBar' export * from './src/modules/ui/feedback/progress-bar/components/ProgressBar'
export * from './src/modules/ui/feedback/progress-bar/components/CircularProgressBar' export * from './src/modules/ui/feedback/progress-bar/components/CircularProgressBar'
export * from './src/modules/ui/input/button/components/Button' export * from './src/modules/ui/input/button/components/Button'

View File

@@ -1,4 +1,5 @@
import react from '@vitejs/plugin-react-swc'; import react from '@vitejs/plugin-react-swc';
import path from 'path';
import { defineConfig, loadEnv } from 'vite'; import { defineConfig, loadEnv } from 'vite';
import checker from 'vite-plugin-checker'; import checker from 'vite-plugin-checker';
import svgr from 'vite-plugin-svgr'; import svgr from 'vite-plugin-svgr';
@@ -19,7 +20,7 @@ export default defineConfig(({ command, mode }) => {
const checkers: Checkers = { const checkers: Checkers = {
typescript: { typescript: {
tsconfigPath: 'tsconfig.app.json', tsconfigPath: path.resolve(__dirname, './tsconfig.app.json'),
}, },
overlay: false, overlay: false,
}; };

View File

@@ -28,7 +28,8 @@
"lintFilePatterns": [ "lintFilePatterns": [
"{projectRoot}/src/**/*.{ts,tsx,json}", "{projectRoot}/src/**/*.{ts,tsx,json}",
"{projectRoot}/package.json" "{projectRoot}/package.json"
] ],
"cache": true
}, },
"configurations": { "configurations": {
"fix": { "fix": true } "fix": { "fix": true }
@@ -45,7 +46,12 @@
"executor": "nx:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"cwd": "{projectRoot}", "cwd": "{projectRoot}",
"command": "tsc -b tsconfig.json --incremental" "command": "tsc -b tsconfig.json",
"incremental": true
},
"configurations": {
"ci": { "incremental": false },
"watch": { "watch": true }
} }
}, },
"storybook:dev": { "storybook:dev": {

12
project.json Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "twenty",
"$schema": "node_modules/nx/schemas/project-schema.json",
"targets": {
"start": {
"executor": "nx:run-script",
"options": {
"command": "nx run-many -t start -p twenty-server twenty-front"
}
}
}
}

242
yarn.lock
View File

@@ -4921,6 +4921,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/aix-ppc64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/aix-ppc64@npm:0.20.2"
conditions: os=aix & cpu=ppc64
languageName: node
linkType: hard
"@esbuild/android-arm64@npm:0.18.20": "@esbuild/android-arm64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/android-arm64@npm:0.18.20" resolution: "@esbuild/android-arm64@npm:0.18.20"
@@ -4942,6 +4949,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/android-arm64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/android-arm64@npm:0.20.2"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
"@esbuild/android-arm@npm:0.18.20": "@esbuild/android-arm@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/android-arm@npm:0.18.20" resolution: "@esbuild/android-arm@npm:0.18.20"
@@ -4963,6 +4977,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/android-arm@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/android-arm@npm:0.20.2"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
"@esbuild/android-x64@npm:0.18.20": "@esbuild/android-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/android-x64@npm:0.18.20" resolution: "@esbuild/android-x64@npm:0.18.20"
@@ -4984,6 +5005,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/android-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/android-x64@npm:0.20.2"
conditions: os=android & cpu=x64
languageName: node
linkType: hard
"@esbuild/darwin-arm64@npm:0.18.20": "@esbuild/darwin-arm64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/darwin-arm64@npm:0.18.20" resolution: "@esbuild/darwin-arm64@npm:0.18.20"
@@ -5005,6 +5033,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/darwin-arm64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/darwin-arm64@npm:0.20.2"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@esbuild/darwin-x64@npm:0.18.20": "@esbuild/darwin-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/darwin-x64@npm:0.18.20" resolution: "@esbuild/darwin-x64@npm:0.18.20"
@@ -5026,6 +5061,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/darwin-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/darwin-x64@npm:0.20.2"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@esbuild/freebsd-arm64@npm:0.18.20": "@esbuild/freebsd-arm64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/freebsd-arm64@npm:0.18.20" resolution: "@esbuild/freebsd-arm64@npm:0.18.20"
@@ -5047,6 +5089,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/freebsd-arm64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/freebsd-arm64@npm:0.20.2"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/freebsd-x64@npm:0.18.20": "@esbuild/freebsd-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/freebsd-x64@npm:0.18.20" resolution: "@esbuild/freebsd-x64@npm:0.18.20"
@@ -5068,6 +5117,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/freebsd-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/freebsd-x64@npm:0.20.2"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/linux-arm64@npm:0.18.20": "@esbuild/linux-arm64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-arm64@npm:0.18.20" resolution: "@esbuild/linux-arm64@npm:0.18.20"
@@ -5089,6 +5145,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-arm64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-arm64@npm:0.20.2"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
"@esbuild/linux-arm@npm:0.18.20": "@esbuild/linux-arm@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-arm@npm:0.18.20" resolution: "@esbuild/linux-arm@npm:0.18.20"
@@ -5110,6 +5173,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-arm@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-arm@npm:0.20.2"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@esbuild/linux-ia32@npm:0.18.20": "@esbuild/linux-ia32@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-ia32@npm:0.18.20" resolution: "@esbuild/linux-ia32@npm:0.18.20"
@@ -5131,6 +5201,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-ia32@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-ia32@npm:0.20.2"
conditions: os=linux & cpu=ia32
languageName: node
linkType: hard
"@esbuild/linux-loong64@npm:0.18.20": "@esbuild/linux-loong64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-loong64@npm:0.18.20" resolution: "@esbuild/linux-loong64@npm:0.18.20"
@@ -5152,6 +5229,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-loong64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-loong64@npm:0.20.2"
conditions: os=linux & cpu=loong64
languageName: node
linkType: hard
"@esbuild/linux-mips64el@npm:0.18.20": "@esbuild/linux-mips64el@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-mips64el@npm:0.18.20" resolution: "@esbuild/linux-mips64el@npm:0.18.20"
@@ -5173,6 +5257,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-mips64el@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-mips64el@npm:0.20.2"
conditions: os=linux & cpu=mips64el
languageName: node
linkType: hard
"@esbuild/linux-ppc64@npm:0.18.20": "@esbuild/linux-ppc64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-ppc64@npm:0.18.20" resolution: "@esbuild/linux-ppc64@npm:0.18.20"
@@ -5194,6 +5285,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-ppc64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-ppc64@npm:0.20.2"
conditions: os=linux & cpu=ppc64
languageName: node
linkType: hard
"@esbuild/linux-riscv64@npm:0.18.20": "@esbuild/linux-riscv64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-riscv64@npm:0.18.20" resolution: "@esbuild/linux-riscv64@npm:0.18.20"
@@ -5215,6 +5313,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-riscv64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-riscv64@npm:0.20.2"
conditions: os=linux & cpu=riscv64
languageName: node
linkType: hard
"@esbuild/linux-s390x@npm:0.18.20": "@esbuild/linux-s390x@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-s390x@npm:0.18.20" resolution: "@esbuild/linux-s390x@npm:0.18.20"
@@ -5236,6 +5341,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-s390x@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-s390x@npm:0.20.2"
conditions: os=linux & cpu=s390x
languageName: node
linkType: hard
"@esbuild/linux-x64@npm:0.18.20": "@esbuild/linux-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/linux-x64@npm:0.18.20" resolution: "@esbuild/linux-x64@npm:0.18.20"
@@ -5257,6 +5369,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/linux-x64@npm:0.20.2"
conditions: os=linux & cpu=x64
languageName: node
linkType: hard
"@esbuild/netbsd-x64@npm:0.18.20": "@esbuild/netbsd-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/netbsd-x64@npm:0.18.20" resolution: "@esbuild/netbsd-x64@npm:0.18.20"
@@ -5278,6 +5397,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/netbsd-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/netbsd-x64@npm:0.20.2"
conditions: os=netbsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/openbsd-x64@npm:0.18.20": "@esbuild/openbsd-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/openbsd-x64@npm:0.18.20" resolution: "@esbuild/openbsd-x64@npm:0.18.20"
@@ -5299,6 +5425,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/openbsd-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/openbsd-x64@npm:0.20.2"
conditions: os=openbsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/sunos-x64@npm:0.18.20": "@esbuild/sunos-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/sunos-x64@npm:0.18.20" resolution: "@esbuild/sunos-x64@npm:0.18.20"
@@ -5320,6 +5453,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/sunos-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/sunos-x64@npm:0.20.2"
conditions: os=sunos & cpu=x64
languageName: node
linkType: hard
"@esbuild/win32-arm64@npm:0.18.20": "@esbuild/win32-arm64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/win32-arm64@npm:0.18.20" resolution: "@esbuild/win32-arm64@npm:0.18.20"
@@ -5341,6 +5481,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/win32-arm64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/win32-arm64@npm:0.20.2"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@esbuild/win32-ia32@npm:0.18.20": "@esbuild/win32-ia32@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/win32-ia32@npm:0.18.20" resolution: "@esbuild/win32-ia32@npm:0.18.20"
@@ -5362,6 +5509,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/win32-ia32@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/win32-ia32@npm:0.20.2"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@esbuild/win32-x64@npm:0.18.20": "@esbuild/win32-x64@npm:0.18.20":
version: 0.18.20 version: 0.18.20
resolution: "@esbuild/win32-x64@npm:0.18.20" resolution: "@esbuild/win32-x64@npm:0.18.20"
@@ -5383,6 +5537,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/win32-x64@npm:0.20.2":
version: 0.20.2
resolution: "@esbuild/win32-x64@npm:0.20.2"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0":
version: 4.4.0 version: 4.4.0
resolution: "@eslint-community/eslint-utils@npm:4.4.0" resolution: "@eslint-community/eslint-utils@npm:4.4.0"
@@ -25762,6 +25923,86 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"esbuild@npm:^0.20.2":
version: 0.20.2
resolution: "esbuild@npm:0.20.2"
dependencies:
"@esbuild/aix-ppc64": "npm:0.20.2"
"@esbuild/android-arm": "npm:0.20.2"
"@esbuild/android-arm64": "npm:0.20.2"
"@esbuild/android-x64": "npm:0.20.2"
"@esbuild/darwin-arm64": "npm:0.20.2"
"@esbuild/darwin-x64": "npm:0.20.2"
"@esbuild/freebsd-arm64": "npm:0.20.2"
"@esbuild/freebsd-x64": "npm:0.20.2"
"@esbuild/linux-arm": "npm:0.20.2"
"@esbuild/linux-arm64": "npm:0.20.2"
"@esbuild/linux-ia32": "npm:0.20.2"
"@esbuild/linux-loong64": "npm:0.20.2"
"@esbuild/linux-mips64el": "npm:0.20.2"
"@esbuild/linux-ppc64": "npm:0.20.2"
"@esbuild/linux-riscv64": "npm:0.20.2"
"@esbuild/linux-s390x": "npm:0.20.2"
"@esbuild/linux-x64": "npm:0.20.2"
"@esbuild/netbsd-x64": "npm:0.20.2"
"@esbuild/openbsd-x64": "npm:0.20.2"
"@esbuild/sunos-x64": "npm:0.20.2"
"@esbuild/win32-arm64": "npm:0.20.2"
"@esbuild/win32-ia32": "npm:0.20.2"
"@esbuild/win32-x64": "npm:0.20.2"
dependenciesMeta:
"@esbuild/aix-ppc64":
optional: true
"@esbuild/android-arm":
optional: true
"@esbuild/android-arm64":
optional: true
"@esbuild/android-x64":
optional: true
"@esbuild/darwin-arm64":
optional: true
"@esbuild/darwin-x64":
optional: true
"@esbuild/freebsd-arm64":
optional: true
"@esbuild/freebsd-x64":
optional: true
"@esbuild/linux-arm":
optional: true
"@esbuild/linux-arm64":
optional: true
"@esbuild/linux-ia32":
optional: true
"@esbuild/linux-loong64":
optional: true
"@esbuild/linux-mips64el":
optional: true
"@esbuild/linux-ppc64":
optional: true
"@esbuild/linux-riscv64":
optional: true
"@esbuild/linux-s390x":
optional: true
"@esbuild/linux-x64":
optional: true
"@esbuild/netbsd-x64":
optional: true
"@esbuild/openbsd-x64":
optional: true
"@esbuild/sunos-x64":
optional: true
"@esbuild/win32-arm64":
optional: true
"@esbuild/win32-ia32":
optional: true
"@esbuild/win32-x64":
optional: true
bin:
esbuild: bin/esbuild
checksum: 66398f9fb2c65e456a3e649747b39af8a001e47963b25e86d9c09d2a48d61aa641b27da0ce5cad63df95ad246105e1d83e7fee0e1e22a0663def73b1c5101112
languageName: node
linkType: hard
"escalade@npm:^3.1.1": "escalade@npm:^3.1.1":
version: 3.1.1 version: 3.1.1
resolution: "escalade@npm:3.1.1" resolution: "escalade@npm:3.1.1"
@@ -46266,6 +46507,7 @@ __metadata:
dotenv-cli: "npm:^7.2.1" dotenv-cli: "npm:^7.2.1"
drizzle-kit: "npm:^0.20.14" drizzle-kit: "npm:^0.20.14"
drizzle-orm: "npm:^0.29.3" drizzle-orm: "npm:^0.29.3"
esbuild: "npm:^0.20.2"
esbuild-plugin-svgr: "npm:^2.1.0" esbuild-plugin-svgr: "npm:^2.1.0"
eslint: "npm:^8.53.0" eslint: "npm:^8.53.0"
eslint-config-next: "npm:14.0.4" eslint-config-next: "npm:14.0.4"