diff --git a/.github/workflows/ci-internal-apps.yaml b/.github/workflows/ci-internal-apps.yaml index 3f1c6d65b5..8348b6908c 100644 --- a/.github/workflows/ci-internal-apps.yaml +++ b/.github/workflows/ci-internal-apps.yaml @@ -66,7 +66,7 @@ jobs: // keep this PR small while the remaining apps are made CI-ready. Remove an // app from this list once its checks pass, and delete the list entirely // once every application is covered. - const CI_EXCLUDED_APPLICATIONS = ['call-recording', 'people-data-labs', 'twenty-linear', 'twenty-meeting-bot', 'twenty-partners']; + const CI_EXCLUDED_APPLICATIONS = ['twenty-meeting-bot', 'twenty-partners']; const eventName = process.env.EVENT_NAME; const changedFiles = JSON.parse(process.env.CHANGED_FILES || '[]'); const changedApps = new Set(); diff --git a/packages/twenty-apps/internal/twenty-linear/.gitignore b/packages/twenty-apps/internal/twenty-linear/.gitignore new file mode 100644 index 0000000000..6cd0610624 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-linear/.gitignore @@ -0,0 +1,38 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn + +# codegen +generated + +# testing +/coverage + +# dev +/dist/ + +.twenty + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# typescript +*.tsbuildinfo +*.d.ts diff --git a/packages/twenty-apps/internal/twenty-linear/.nvmrc b/packages/twenty-apps/internal/twenty-linear/.nvmrc new file mode 100644 index 0000000000..341cb50613 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-linear/.nvmrc @@ -0,0 +1 @@ +24.5.0 diff --git a/packages/twenty-apps/internal/twenty-linear/.oxlintrc.json b/packages/twenty-apps/internal/twenty-linear/.oxlintrc.json index 34c54bff59..2c2035b0fe 100644 --- a/packages/twenty-apps/internal/twenty-linear/.oxlintrc.json +++ b/packages/twenty-apps/internal/twenty-linear/.oxlintrc.json @@ -1,20 +1,58 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", "extends": ["../../.oxlintrc.base.json"], - "plugins": ["typescript"], + "plugins": ["react", "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": "^_" } ], - "typescript/no-explicit-any": "off" + "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" } } diff --git a/packages/twenty-apps/internal/twenty-linear/.yarnrc.yml b/packages/twenty-apps/internal/twenty-linear/.yarnrc.yml new file mode 100644 index 0000000000..3186f3f079 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-linear/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/packages/twenty-apps/internal/twenty-linear/package.json b/packages/twenty-apps/internal/twenty-linear/package.json index 9d5042b9e9..0e443f9897 100644 --- a/packages/twenty-apps/internal/twenty-linear/package.json +++ b/packages/twenty-apps/internal/twenty-linear/package.json @@ -16,17 +16,25 @@ "twenty": "twenty", "lint": "oxlint -c .oxlintrc.json .", "lint:fix": "oxlint --fix -c .oxlintrc.json .", - "test": "vitest run --config vitest.unit.config.ts", - "test:watch": "vitest --config vitest.unit.config.ts" + "typecheck": "tsgo --noEmit -p tsconfig.spec.json", + "test": "vitest run", + "test:watch": "vitest", + "test:unit": "vitest run --config vitest.unit.config.ts" }, "dependencies": { "twenty-sdk": "2.13.0" }, "devDependencies": { "@types/node": "^24.7.2", + "@types/react": "^18.2.0", + "@typescript/native-preview": "^7.0.0-dev.20260116.1", "oxlint": "^0.16.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "twenty-client-sdk": "^2.14.0", + "twenty-sdk": "^2.14.0", "typescript": "^5.9.3", - "vite-tsconfig-paths": "^4.3.2", + "vite-tsconfig-paths": "^4.2.1", "vitest": "^4.0.0" } } diff --git a/packages/twenty-apps/internal/twenty-linear/src/__tests__/global-setup.ts b/packages/twenty-apps/internal/twenty-linear/src/__tests__/global-setup.ts new file mode 100644 index 0000000000..e0f8c23b05 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-linear/src/__tests__/global-setup.ts @@ -0,0 +1,87 @@ +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; + +import { appDevOnce, appUninstall } from 'twenty-sdk/cli'; + +const APP_PATH = process.cwd(); +const CONFIG_DIR = path.join(os.homedir(), '.twenty'); + +function validateEnv(): { apiUrl: string; apiKey: string } { + const apiUrl = process.env.TWENTY_API_URL; + const apiKey = process.env.TWENTY_API_KEY; + + if (!apiUrl || !apiKey) { + throw new Error( + 'TWENTY_API_URL and TWENTY_API_KEY must be set.\n' + + 'Start a local server: yarn twenty docker:start\n' + + 'Or set them in vitest env config.', + ); + } + + return { apiUrl, apiKey }; +} + +async function checkServer(apiUrl: string) { + let response: Response; + + try { + response = await fetch(`${apiUrl}/healthz`); + } catch { + throw new Error( + `Twenty server is not reachable at ${apiUrl}. ` + + 'Make sure the server is running before executing integration tests.', + ); + } + + if (!response.ok) { + throw new Error(`Server at ${apiUrl} returned ${response.status}`); + } +} + +function writeConfig(apiUrl: string, apiKey: string) { + const payload = JSON.stringify( + { + remotes: { + local: { apiUrl, apiKey, accessToken: apiKey }, + }, + defaultRemote: 'local', + }, + null, + 2, + ); + + fs.mkdirSync(CONFIG_DIR, { recursive: true }); + fs.writeFileSync(path.join(CONFIG_DIR, 'config.test.json'), payload); +} + +export async function setup() { + const { apiUrl, apiKey } = validateEnv(); + + await checkServer(apiUrl); + + writeConfig(apiUrl, apiKey); + + await appUninstall({ appPath: APP_PATH }).catch(() => {}); + + const result = await appDevOnce({ + appPath: APP_PATH, + onProgress: (message: string) => console.log(`[dev] ${message}`), + }); + + if (!result.success) { + throw new Error( + `Dev sync failed: ${result.error?.message ?? 'Unknown error'}`, + ); + } +} + +export async function teardown() { + const uninstallResult = await appUninstall({ appPath: APP_PATH }); + + if (!uninstallResult.success) { + console.warn( + `App uninstall failed: ${uninstallResult.error?.message ?? 'Unknown error'}`, + ); + } +} diff --git a/packages/twenty-apps/internal/twenty-linear/src/__tests__/twenty-linear.integration-test.ts b/packages/twenty-apps/internal/twenty-linear/src/__tests__/twenty-linear.integration-test.ts new file mode 100644 index 0000000000..a8a56aae14 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-linear/src/__tests__/twenty-linear.integration-test.ts @@ -0,0 +1,25 @@ +import { MetadataApiClient } from 'twenty-client-sdk/metadata'; +import { describe, expect, it } from 'vitest'; + +import { APPLICATION_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; + +describe('App installation', () => { + it('should find the installed Linear app in the applications list', async () => { + const client = new MetadataApiClient(); + + const result = await client.query({ + findManyApplications: { + id: true, + name: true, + universalIdentifier: true, + }, + }); + + const matchingApplication = result.findManyApplications.find( + (application: { universalIdentifier: string }) => + application.universalIdentifier === APPLICATION_UNIVERSAL_IDENTIFIER, + ); + + expect(matchingApplication).toBeDefined(); + }); +}); diff --git a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/__tests__/test-utils.ts b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/__tests__/test-utils.ts index d2e85fd473..3865a87dcf 100644 --- a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/__tests__/test-utils.ts +++ b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/__tests__/test-utils.ts @@ -2,6 +2,12 @@ import { vi } from 'vitest'; export const USER_WORKSPACE_ID = '11111111-1111-1111-1111-111111111111'; +type LinearFetchInit = { + method: string; + headers: Record; + body: string; +}; + export const buildConnection = ( overrides: Partial> = {}, ) => ({ @@ -18,19 +24,21 @@ export const buildConnection = ( ...overrides, }); -// Stubs `fetch` to first answer the SDK's `/apps/connections/list` call, then -// the handler's downstream Linear GraphQL request. +// Stubs `fetch` to first answer the SDK's `listConnections` GraphQL call to +// `/metadata`, then the handler's downstream Linear GraphQL request. export const stubConnectionsThenLinear = ( connections: ReturnType[], linearJson: unknown, ) => { - const fetchMock = vi.fn(async (url: string) => { - if (url.endsWith('/apps/connections/list')) { + const fetchMock = vi.fn(async (url: string, _init: LinearFetchInit) => { + if (url.endsWith('/metadata')) { + const connectionsJson = { data: { appConnections: connections } }; + return { ok: true, status: 200, - json: async () => connections, - text: async () => JSON.stringify(connections), + json: async () => connectionsJson, + text: async () => JSON.stringify(connectionsJson), }; } diff --git a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/create-linear-issue-route.ts b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/create-linear-issue-route.ts index d17832473e..98991e93f9 100644 --- a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/create-linear-issue-route.ts +++ b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/create-linear-issue-route.ts @@ -1,5 +1,4 @@ -import { defineLogicFunction } from 'twenty-sdk/define'; -import type { RoutePayload } from 'twenty-sdk/define'; +import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define'; import { CREATE_LINEAR_ISSUE_ROUTE_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { createLinearIssueHandler } from 'src/logic-functions/handlers/create-linear-issue-handler'; diff --git a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-issue-options-route.ts b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-issue-options-route.ts index 9df972fab8..693cafa514 100644 --- a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-issue-options-route.ts +++ b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-issue-options-route.ts @@ -1,5 +1,4 @@ -import { defineLogicFunction } from 'twenty-sdk/define'; -import type { RoutePayload } from 'twenty-sdk/define'; +import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define'; import { LIST_LINEAR_ISSUE_OPTIONS_ROUTE_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { listLinearIssueOptionsHandler } from 'src/logic-functions/handlers/list-linear-issue-options-handler'; diff --git a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-teams-route.ts b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-teams-route.ts index 984fb2e587..2c71b5f273 100644 --- a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-teams-route.ts +++ b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-teams-route.ts @@ -1,5 +1,4 @@ -import { defineLogicFunction } from 'twenty-sdk/define'; -import type { RoutePayload } from 'twenty-sdk/define'; +import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define'; import { LIST_LINEAR_TEAMS_ROUTE_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { listLinearTeamsHandler } from 'src/logic-functions/handlers/list-linear-teams-handler'; diff --git a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-workflow-states-route.ts b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-workflow-states-route.ts index a8e8f569e2..ec43e2cd44 100644 --- a/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-workflow-states-route.ts +++ b/packages/twenty-apps/internal/twenty-linear/src/logic-functions/list-linear-workflow-states-route.ts @@ -1,5 +1,4 @@ -import { defineLogicFunction } from 'twenty-sdk/define'; -import type { RoutePayload } from 'twenty-sdk/define'; +import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define'; import { LIST_LINEAR_WORKFLOW_STATES_ROUTE_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { listLinearWorkflowStatesHandler } from 'src/logic-functions/handlers/list-linear-workflow-states-handler'; diff --git a/packages/twenty-apps/internal/twenty-linear/src/roles/default-function.role.ts b/packages/twenty-apps/internal/twenty-linear/src/roles/default-function.role.ts index d268739c63..b445be0eb6 100644 --- a/packages/twenty-apps/internal/twenty-linear/src/roles/default-function.role.ts +++ b/packages/twenty-apps/internal/twenty-linear/src/roles/default-function.role.ts @@ -16,5 +16,5 @@ export default defineApplicationRole({ canBeAssignedToApiKeys: false, objectPermissions: [], fieldPermissions: [], - permissionFlags: [], + permissionFlagUniversalIdentifiers: [], }); diff --git a/packages/twenty-apps/internal/twenty-linear/tsconfig.json b/packages/twenty-apps/internal/twenty-linear/tsconfig.json index 80f5e7ceb0..abacf4dcf6 100644 --- a/packages/twenty-apps/internal/twenty-linear/tsconfig.json +++ b/packages/twenty-apps/internal/twenty-linear/tsconfig.json @@ -27,5 +27,16 @@ "~/*": ["./*"] } }, - "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"] + "exclude": [ + "node_modules", + "dist", + "**/*.test.ts", + "**/*.spec.ts", + "**/*.integration-test.ts" + ], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ] } diff --git a/packages/twenty-apps/internal/twenty-linear/tsconfig.spec.json b/packages/twenty-apps/internal/twenty-linear/tsconfig.spec.json index 27a0249ae3..ea69a6c010 100644 --- a/packages/twenty-apps/internal/twenty-linear/tsconfig.spec.json +++ b/packages/twenty-apps/internal/twenty-linear/tsconfig.spec.json @@ -4,6 +4,6 @@ "composite": true, "types": ["vitest/globals", "node"] }, - "include": ["src/**/*.ts"], + "include": ["src/**/*.ts", "src/**/*.tsx"], "exclude": ["node_modules", "dist"] } diff --git a/packages/twenty-apps/internal/twenty-linear/vitest.config.ts b/packages/twenty-apps/internal/twenty-linear/vitest.config.ts new file mode 100644 index 0000000000..055af77dbe --- /dev/null +++ b/packages/twenty-apps/internal/twenty-linear/vitest.config.ts @@ -0,0 +1,31 @@ +import tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; + +const TWENTY_API_URL = process.env.TWENTY_API_URL ?? 'http://localhost:2020'; +const TWENTY_API_KEY = + process.env.TWENTY_API_KEY ?? + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWMyNS00ZDAyLWJmMjUtNmFlY2NmN2VhNDE5IiwiaWF0IjoxNzM1Njg5NjAwLCJleHAiOjQ4OTE0NDk2MDAsImp0aSI6IjIwMjAyMDIwLWY0MDEtNGQ4YS1hNzMxLTY0ZDAwN2MyN2JhZCJ9.bfQjfyN0NEtTCLE_xPyNcwonDzlSXFoP8kdCQTdnuDc'; + +// Make env vars available to globalSetup (test.env only applies to workers) +process.env.TWENTY_API_URL = TWENTY_API_URL; +process.env.TWENTY_API_KEY = TWENTY_API_KEY; + +export default defineConfig({ + plugins: [ + tsconfigPaths({ + projects: ['tsconfig.spec.json'], + ignoreConfigErrors: true, + }), + ], + test: { + testTimeout: 120_000, + hookTimeout: 120_000, + fileParallelism: false, + include: ['src/**/*.integration-test.ts'], + globalSetup: ['src/__tests__/global-setup.ts'], + env: { + TWENTY_API_URL, + TWENTY_API_KEY, + }, + }, +}); diff --git a/packages/twenty-apps/internal/twenty-linear/vitest.unit.config.ts b/packages/twenty-apps/internal/twenty-linear/vitest.unit.config.ts index 57c5b5cd0f..e0d140015b 100644 --- a/packages/twenty-apps/internal/twenty-linear/vitest.unit.config.ts +++ b/packages/twenty-apps/internal/twenty-linear/vitest.unit.config.ts @@ -1,16 +1,6 @@ -import path from 'node:path'; - import tsconfigPaths from 'vite-tsconfig-paths'; import { defineConfig } from 'vitest/config'; -const TWENTY_SDK_SRC = path.resolve( - __dirname, - '../../../twenty-sdk/src/sdk', -); - -// twenty-sdk's `exports` map points at compiled `./dist/*`. Aliasing the -// subpaths to source keeps unit tests self-contained — no `yarn build` in -// twenty-sdk required before running them. export default defineConfig({ plugins: [ tsconfigPaths({ @@ -18,25 +8,6 @@ export default defineConfig({ ignoreConfigErrors: true, }), ], - resolve: { - alias: [ - { - find: 'twenty-sdk/logic-function', - replacement: path.join(TWENTY_SDK_SRC, 'logic-function/index.ts'), - }, - { - find: 'twenty-sdk/define', - replacement: path.join(TWENTY_SDK_SRC, 'define/index.ts'), - }, - // The SDK source uses `@/*` to refer to its own `src/`. Vitest - // doesn't pick up the SDK's tsconfig path mapping when resolving - // a different package, so map the alias here. - { - find: /^@\/(.*)$/, - replacement: path.resolve(__dirname, '../../../twenty-sdk/src/$1'), - }, - ], - }, test: { include: ['src/**/*.test.ts'], }, diff --git a/packages/twenty-apps/internal/twenty-linear/yarn.lock b/packages/twenty-apps/internal/twenty-linear/yarn.lock index 978ec5a213..c444e8540f 100644 --- a/packages/twenty-apps/internal/twenty-linear/yarn.lock +++ b/packages/twenty-apps/internal/twenty-linear/yarn.lock @@ -758,6 +758,13 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:*": + version: 15.7.15 + resolution: "@types/prop-types@npm:15.7.15" + checksum: 10c0/b59aad1ad19bf1733cf524fd4e618196c6c7690f48ee70a327eb450a42aab8e8a063fbe59ca0a5701aebe2d92d582292c0fb845ea57474f6a15f6994b0e260b2 + languageName: node + linkType: hard + "@types/qs@npm:^6.9.0": version: 6.15.1 resolution: "@types/qs@npm:6.15.1" @@ -765,6 +772,16 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^18.2.0": + version: 18.3.31 + resolution: "@types/react@npm:18.3.31" + dependencies: + "@types/prop-types": "npm:*" + csstype: "npm:^3.2.2" + checksum: 10c0/44180549dd045f536ececd39e39aacdf828e76adc1c4a90b132f453e23cc370c4648d9102ae401172ebd8fd8b1977a901a39e214e53ec77171b27514b588c179 + languageName: node + linkType: hard + "@types/ws@npm:^6.0.1": version: 6.0.4 resolution: "@types/ws@npm:6.0.4" @@ -774,6 +791,87 @@ __metadata: languageName: node linkType: hard +"@typescript/native-preview-darwin-arm64@npm:7.0.0-dev.20260619.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview-darwin-arm64@npm:7.0.0-dev.20260619.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/native-preview-darwin-x64@npm:7.0.0-dev.20260619.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview-darwin-x64@npm:7.0.0-dev.20260619.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@typescript/native-preview-linux-arm64@npm:7.0.0-dev.20260619.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview-linux-arm64@npm:7.0.0-dev.20260619.1" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/native-preview-linux-arm@npm:7.0.0-dev.20260619.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview-linux-arm@npm:7.0.0-dev.20260619.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@typescript/native-preview-linux-x64@npm:7.0.0-dev.20260619.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview-linux-x64@npm:7.0.0-dev.20260619.1" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@typescript/native-preview-win32-arm64@npm:7.0.0-dev.20260619.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview-win32-arm64@npm:7.0.0-dev.20260619.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/native-preview-win32-x64@npm:7.0.0-dev.20260619.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview-win32-x64@npm:7.0.0-dev.20260619.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@typescript/native-preview@npm:^7.0.0-dev.20260116.1": + version: 7.0.0-dev.20260619.1 + resolution: "@typescript/native-preview@npm:7.0.0-dev.20260619.1" + dependencies: + "@typescript/native-preview-darwin-arm64": "npm:7.0.0-dev.20260619.1" + "@typescript/native-preview-darwin-x64": "npm:7.0.0-dev.20260619.1" + "@typescript/native-preview-linux-arm": "npm:7.0.0-dev.20260619.1" + "@typescript/native-preview-linux-arm64": "npm:7.0.0-dev.20260619.1" + "@typescript/native-preview-linux-x64": "npm:7.0.0-dev.20260619.1" + "@typescript/native-preview-win32-arm64": "npm:7.0.0-dev.20260619.1" + "@typescript/native-preview-win32-x64": "npm:7.0.0-dev.20260619.1" + dependenciesMeta: + "@typescript/native-preview-darwin-arm64": + optional: true + "@typescript/native-preview-darwin-x64": + optional: true + "@typescript/native-preview-linux-arm": + optional: true + "@typescript/native-preview-linux-arm64": + optional: true + "@typescript/native-preview-linux-x64": + optional: true + "@typescript/native-preview-win32-arm64": + optional: true + "@typescript/native-preview-win32-x64": + optional: true + bin: + tsgo: bin/tsgo.js + checksum: 10c0/e8bc6cf171ee29131934f662c9b3577374d7e872247831da36a5723abe175998f1318a134ed8eb0ee5213887dbb1f1209fac5555cdf5b6b19d0d7da044d0cdc9 + languageName: node + linkType: hard + "@vitest/expect@npm:4.1.8": version: 4.1.8 resolution: "@vitest/expect@npm:4.1.8" @@ -1075,6 +1173,13 @@ __metadata: languageName: node linkType: hard +"csstype@npm:^3.2.2": + version: 3.2.3 + resolution: "csstype@npm:3.2.3" + checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce + languageName: node + linkType: hard + "debug@npm:4, debug@npm:^4.1.1": version: 4.4.3 resolution: "debug@npm:4.4.3" @@ -1651,6 +1756,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^3.0.0 || ^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed + languageName: node + linkType: hard + "jsonc-parser@npm:^3.2.0": version: 3.3.1 resolution: "jsonc-parser@npm:3.3.1" @@ -1785,6 +1897,17 @@ __metadata: languageName: node linkType: hard +"loose-envify@npm:^1.1.0": + version: 1.4.0 + resolution: "loose-envify@npm:1.4.0" + dependencies: + js-tokens: "npm:^3.0.0 || ^4.0.0" + bin: + loose-envify: cli.js + checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e + languageName: node + linkType: hard + "magic-string@npm:^0.30.21": version: 0.30.21 resolution: "magic-string@npm:0.30.21" @@ -2029,6 +2152,18 @@ __metadata: languageName: node linkType: hard +"react-dom@npm:^18.2.0": + version: 18.3.1 + resolution: "react-dom@npm:18.3.1" + dependencies: + loose-envify: "npm:^1.1.0" + scheduler: "npm:^0.23.2" + peerDependencies: + react: ^18.3.1 + checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 + languageName: node + linkType: hard + "react-dom@npm:^19.2.0": version: 19.2.7 resolution: "react-dom@npm:19.2.7" @@ -2051,6 +2186,15 @@ __metadata: languageName: node linkType: hard +"react@npm:^18.2.0": + version: 18.3.1 + resolution: "react@npm:18.3.1" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 + languageName: node + linkType: hard + "react@npm:^19.2.0": version: 19.2.7 resolution: "react@npm:19.2.7" @@ -2147,6 +2291,15 @@ __metadata: languageName: node linkType: hard +"scheduler@npm:^0.23.2": + version: 0.23.2 + resolution: "scheduler@npm:0.23.2" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 + languageName: node + linkType: hard + "scheduler@npm:^0.27.0": version: 0.27.0 resolution: "scheduler@npm:0.27.0" @@ -2379,16 +2532,16 @@ __metadata: languageName: node linkType: hard -"twenty-client-sdk@npm:2.13.0": - version: 2.13.0 - resolution: "twenty-client-sdk@npm:2.13.0" +"twenty-client-sdk@npm:2.14.0, twenty-client-sdk@npm:^2.14.0": + version: 2.14.0 + resolution: "twenty-client-sdk@npm:2.14.0" dependencies: "@genql/runtime": "npm:^2.10.0" esbuild: "npm:^0.28.1" graphql: "npm:^16.8.1" lodash: "npm:^4.17.21" prettier: "npm:^3.8.3" - checksum: 10c0/740464acec94c1d4cc5fa50ed6b190a7f1d1681963f61437a6c704835c05ffe0f5a13e254e57601a99b07bbe0f68483dee19211731853aafbcc15ec79f8039ce + checksum: 10c0/eb222a726e21fc98f3a624f9acac7d47f0c769b989911889036665dac7c7c88698ec99beb844bf51a42e1696ea0a067bae8cf47fd751965af52a3720835242f0 languageName: node linkType: hard @@ -2397,17 +2550,22 @@ __metadata: resolution: "twenty-linear@workspace:." dependencies: "@types/node": "npm:^24.7.2" + "@types/react": "npm:^18.2.0" + "@typescript/native-preview": "npm:^7.0.0-dev.20260116.1" oxlint: "npm:^0.16.0" - twenty-sdk: "npm:2.13.0" + react: "npm:^18.2.0" + react-dom: "npm:^18.2.0" + twenty-client-sdk: "npm:^2.14.0" + twenty-sdk: "npm:^2.14.0" typescript: "npm:^5.9.3" - vite-tsconfig-paths: "npm:^4.3.2" + vite-tsconfig-paths: "npm:^4.2.1" vitest: "npm:^4.0.0" languageName: unknown linkType: soft -"twenty-sdk@npm:2.13.0": - version: 2.13.0 - resolution: "twenty-sdk@npm:2.13.0" +"twenty-sdk@npm:^2.14.0": + version: 2.14.0 + resolution: "twenty-sdk@npm:2.14.0" dependencies: "@sniptt/guards": "npm:^0.2.0" axios: "npm:^1.16.0" @@ -2424,12 +2582,12 @@ __metadata: react: "npm:^19.2.0" react-dom: "npm:^19.2.0" tinyglobby: "npm:^0.2.15" - twenty-client-sdk: "npm:2.13.0" + twenty-client-sdk: "npm:2.14.0" typescript: "npm:^5.9.3" uuid: "npm:^13.0.2" bin: twenty: dist/cli.cjs - checksum: 10c0/51c350abe5d344fcad3c961a77632fd3cb2d91e357d0562b3eb02f05f66dbc41221c5463d0f91c022316a16af03a05ad43f038d9534c0ae31c060008d0e48672 + checksum: 10c0/c4211772f8dd2ba81074a74be5f616c4c264d6bf8a174c5724be6d1c9a8cb3ca68a2674653bb58c059dae4bf1b0f43f91991e73d6a01395807206f0ac44afb08 languageName: node linkType: hard @@ -2506,7 +2664,7 @@ __metadata: languageName: node linkType: hard -"vite-tsconfig-paths@npm:^4.3.2": +"vite-tsconfig-paths@npm:^4.2.1": version: 4.3.2 resolution: "vite-tsconfig-paths@npm:4.3.2" dependencies: