diff --git a/.github/workflows/ci-internal-apps.yaml b/.github/workflows/ci-internal-apps.yaml index 7e42243aa2..f1f51d8292 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', 'self-hosting', 'twenty-fireflies', 'twenty-for-twenty', 'twenty-linear', 'twenty-meeting-bot', 'twenty-partners']; + const CI_EXCLUDED_APPLICATIONS = ['call-recording', 'people-data-labs', 'self-hosting', 'twenty-for-twenty', 'twenty-linear', '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-fireflies/.gitignore b/packages/twenty-apps/internal/twenty-fireflies/.gitignore new file mode 100644 index 0000000000..6cd0610624 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/.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-fireflies/.nvmrc b/packages/twenty-apps/internal/twenty-fireflies/.nvmrc new file mode 100644 index 0000000000..341cb50613 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/.nvmrc @@ -0,0 +1 @@ +24.5.0 diff --git a/packages/twenty-apps/internal/twenty-fireflies/.oxlintrc.json b/packages/twenty-apps/internal/twenty-fireflies/.oxlintrc.json index 958be72869..2c2035b0fe 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/.oxlintrc.json +++ b/packages/twenty-apps/internal/twenty-fireflies/.oxlintrc.json @@ -1,19 +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-fireflies/.yarnrc.yml b/packages/twenty-apps/internal/twenty-fireflies/.yarnrc.yml new file mode 100644 index 0000000000..3186f3f079 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/packages/twenty-apps/internal/twenty-fireflies/package.json b/packages/twenty-apps/internal/twenty-fireflies/package.json index bf5c18ee81..3b84b93580 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/package.json +++ b/packages/twenty-apps/internal/twenty-fireflies/package.json @@ -16,17 +16,22 @@ "twenty": "twenty", "lint": "oxlint -c .oxlintrc.json .", "lint:fix": "oxlint --fix -c .oxlintrc.json .", + "typecheck": "tsgo --noEmit -p tsconfig.spec.json", "test": "vitest run", - "test:watch": "vitest" - }, - "dependencies": { - "twenty-client-sdk": "2.13.0", - "twenty-sdk": "2.13.0" + "test:watch": "vitest", + "test:unit": "vitest run --config vitest.unit.config.ts" }, "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.2.1", "vitest": "^4.0.0" } } diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/__tests__/global-setup.ts b/packages/twenty-apps/internal/twenty-fireflies/src/__tests__/global-setup.ts new file mode 100644 index 0000000000..e0f8c23b05 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/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-fireflies/src/__tests__/twenty-fireflies.integration-test.ts b/packages/twenty-apps/internal/twenty-fireflies/src/__tests__/twenty-fireflies.integration-test.ts new file mode 100644 index 0000000000..d81520194f --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/src/__tests__/twenty-fireflies.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 Fireflies 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-fireflies/src/logic-functions/fireflies-list-calls-by-participant.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-list-calls-by-participant.ts index ec670e9d3d..8da50dbfba 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-list-calls-by-participant.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-list-calls-by-participant.ts @@ -1,5 +1,5 @@ import { defineLogicFunction } from 'twenty-sdk/define'; -import { jsonSchemaToInputSchema } from 'twenty-shared/logic-function'; +import { jsonSchemaToInputSchema } from 'src/logic-functions/utils/json-schema-to-input-schema'; import { FIREFLIES_LIST_CALLS_BY_PARTICIPANT_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { firefliesListCallsByParticipantHandler } from 'src/logic-functions/handlers/fireflies-list-calls-by-participant-handler'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-search-calls.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-search-calls.ts index 5a2aacf285..1462464ec1 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-search-calls.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-search-calls.ts @@ -1,5 +1,5 @@ import { defineLogicFunction } from 'twenty-sdk/define'; -import { jsonSchemaToInputSchema } from 'twenty-shared/logic-function'; +import { jsonSchemaToInputSchema } from 'src/logic-functions/utils/json-schema-to-input-schema'; import { FIREFLIES_SEARCH_CALLS_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { firefliesSearchCallsHandler } from 'src/logic-functions/handlers/fireflies-search-calls-handler'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-sync-call.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-sync-call.ts index 6434980ff9..92c7d21f88 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-sync-call.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-sync-call.ts @@ -1,5 +1,5 @@ import { defineLogicFunction } from 'twenty-sdk/define'; -import { jsonSchemaToInputSchema } from 'twenty-shared/logic-function'; +import { jsonSchemaToInputSchema } from 'src/logic-functions/utils/json-schema-to-input-schema'; import { FIREFLIES_SYNC_CALL_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { firefliesSyncCallHandler } from 'src/logic-functions/handlers/fireflies-sync-call-handler'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-webhook.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-webhook.ts index c300136eb9..48d8fa986d 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-webhook.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/fireflies-webhook.ts @@ -1,5 +1,5 @@ import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define'; -import { isDefined } from 'twenty-shared/utils'; +import { isDefined } from 'src/utils/is-defined'; import { FIREFLIES_WEBHOOK_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER } from 'src/constants/universal-identifiers'; import { firefliesWebhookHandler } from 'src/logic-functions/handlers/fireflies-webhook-handler'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/find-matching-calendar-event.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/find-matching-calendar-event.ts index 6ad25bbe58..58ee50a3e0 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/find-matching-calendar-event.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/find-matching-calendar-event.ts @@ -1,6 +1,6 @@ import { isNonEmptyString } from '@sniptt/guards'; -import { CoreApiClient } from 'twenty-client-sdk/core'; -import { isDefined } from 'twenty-shared/utils'; +import { type CoreApiClient } from 'twenty-client-sdk/core'; +import { isDefined } from 'src/utils/is-defined'; import { type FirefliesTranscript } from 'src/logic-functions/types/fireflies-transcript.type'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/fireflies-api-request.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/fireflies-api-request.ts index b51d7c2540..d26be77386 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/fireflies-api-request.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/fireflies-api-request.ts @@ -1,4 +1,4 @@ -import { isDefined } from 'twenty-shared/utils'; +import { isDefined } from 'src/utils/is-defined'; const FIREFLIES_API_URL = 'https://api.fireflies.ai/graphql'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-summary-as-markdown.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-summary-as-markdown.ts index 5f47a59d58..4a846c036e 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-summary-as-markdown.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-summary-as-markdown.ts @@ -1,5 +1,5 @@ import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards'; -import { isDefined } from 'twenty-shared/utils'; +import { isDefined } from 'src/utils/is-defined'; import { type FirefliesTranscript } from 'src/logic-functions/types/fireflies-transcript.type'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-transcript-as-markdown.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-transcript-as-markdown.ts index e551ea0100..18dfbbbd90 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-transcript-as-markdown.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/format-transcript-as-markdown.ts @@ -1,5 +1,5 @@ import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards'; -import { isDefined } from 'twenty-shared/utils'; +import { isDefined } from 'src/utils/is-defined'; import { type FirefliesTranscript } from 'src/logic-functions/types/fireflies-transcript.type'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/json-schema-to-input-schema.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/json-schema-to-input-schema.ts new file mode 100644 index 0000000000..d89e400dcb --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/json-schema-to-input-schema.ts @@ -0,0 +1,66 @@ +import { type InputJsonSchema } from 'twenty-sdk/logic-function'; + +type InputSchemaProperty = { + type: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'unknown'; + enum?: string[]; + items?: InputSchemaProperty; + properties?: Record; + multiline?: boolean; + label?: string; +}; + +const convertProperty = (jsonSchema: InputJsonSchema): InputSchemaProperty => { + const property: InputSchemaProperty = { type: 'unknown' }; + + switch (jsonSchema.type) { + case 'string': + property.type = 'string'; + break; + case 'number': + case 'integer': + property.type = 'number'; + break; + case 'boolean': + property.type = 'boolean'; + break; + case 'array': + property.type = 'array'; + if (jsonSchema.items) { + property.items = convertProperty(jsonSchema.items); + } + break; + case 'object': + property.type = 'object'; + if (jsonSchema.properties) { + property.properties = Object.fromEntries( + Object.entries(jsonSchema.properties).map(([key, value]) => [ + key, + convertProperty(value), + ]), + ); + } + break; + default: + property.type = 'unknown'; + } + + if (Array.isArray(jsonSchema.enum)) { + property.enum = jsonSchema.enum.filter( + (value): value is string => typeof value === 'string', + ); + } + + if (jsonSchema.multiline === true) { + property.multiline = true; + } + + if (typeof jsonSchema.label === 'string' && jsonSchema.label.length > 0) { + property.label = jsonSchema.label; + } + + return property; +}; + +export const jsonSchemaToInputSchema = ( + jsonSchema: InputJsonSchema, +): InputSchemaProperty[] => [convertProperty(jsonSchema)]; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/list-fireflies-transcripts.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/list-fireflies-transcripts.ts index bce0663c66..5f3e44abcd 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/list-fireflies-transcripts.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/list-fireflies-transcripts.ts @@ -1,4 +1,4 @@ -import { isDefined } from 'twenty-shared/utils'; +import { isDefined } from 'src/utils/is-defined'; import { type FirefliesCallSummary } from 'src/logic-functions/types/fireflies-call-list-result.type'; import { type FirefliesTranscript } from 'src/logic-functions/types/fireflies-transcript.type'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/sync-fireflies-field-to-calendar-event.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/sync-fireflies-field-to-calendar-event.ts index 1643e6cf49..abfd4462a0 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/sync-fireflies-field-to-calendar-event.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/sync-fireflies-field-to-calendar-event.ts @@ -1,4 +1,4 @@ -import { CoreApiClient } from 'twenty-client-sdk/core'; +import { type CoreApiClient } from 'twenty-client-sdk/core'; import { type FirefliesTranscript } from 'src/logic-functions/types/fireflies-transcript.type'; import { fetchFirefliesSummary } from 'src/logic-functions/utils/fetch-fireflies-summary'; diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-summary.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-summary.ts index 30ed2627bf..6d997b812e 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-summary.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-summary.ts @@ -1,4 +1,4 @@ -import { CoreApiClient } from 'twenty-client-sdk/core'; +import { type CoreApiClient } from 'twenty-client-sdk/core'; export const updateCalendarEventSummary = async ({ client, diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-transcript.ts b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-transcript.ts index 4cdbf92e41..117737c07d 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-transcript.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/logic-functions/utils/update-calendar-event-transcript.ts @@ -1,4 +1,4 @@ -import { CoreApiClient } from 'twenty-client-sdk/core'; +import { type CoreApiClient } from 'twenty-client-sdk/core'; export const updateCalendarEventTranscript = async ({ client, diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/roles/default-function.role.ts b/packages/twenty-apps/internal/twenty-fireflies/src/roles/default-function.role.ts index 66699f03fe..07caa9ab20 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/src/roles/default-function.role.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/src/roles/default-function.role.ts @@ -38,5 +38,5 @@ export default defineApplicationRole({ }, ], fieldPermissions: [], - permissionFlags: [], + permissionFlagUniversalIdentifiers: [], }); diff --git a/packages/twenty-apps/internal/twenty-fireflies/src/utils/is-defined.ts b/packages/twenty-apps/internal/twenty-fireflies/src/utils/is-defined.ts new file mode 100644 index 0000000000..79ce700ad9 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/src/utils/is-defined.ts @@ -0,0 +1,3 @@ +export const isDefined = ( + value: T | null | undefined, +): value is NonNullable => value !== null && value !== undefined; diff --git a/packages/twenty-apps/internal/twenty-fireflies/tsconfig.json b/packages/twenty-apps/internal/twenty-fireflies/tsconfig.json index 80f5e7ceb0..abacf4dcf6 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/tsconfig.json +++ b/packages/twenty-apps/internal/twenty-fireflies/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-fireflies/tsconfig.spec.json b/packages/twenty-apps/internal/twenty-fireflies/tsconfig.spec.json new file mode 100644 index 0000000000..ea69a6c010 --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": true, + "types": ["vitest/globals", "node"] + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/twenty-apps/internal/twenty-fireflies/vitest.config.ts b/packages/twenty-apps/internal/twenty-fireflies/vitest.config.ts index 6ec74eee27..055af77dbe 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/vitest.config.ts +++ b/packages/twenty-apps/internal/twenty-fireflies/vitest.config.ts @@ -1,7 +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: { - include: ['src/**/*.test.ts'], + 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-fireflies/vitest.unit.config.ts b/packages/twenty-apps/internal/twenty-fireflies/vitest.unit.config.ts new file mode 100644 index 0000000000..e0d140015b --- /dev/null +++ b/packages/twenty-apps/internal/twenty-fireflies/vitest.unit.config.ts @@ -0,0 +1,14 @@ +import tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [ + tsconfigPaths({ + projects: ['tsconfig.spec.json'], + ignoreConfigErrors: true, + }), + ], + test: { + include: ['src/**/*.test.ts'], + }, +}); diff --git a/packages/twenty-apps/internal/twenty-fireflies/yarn.lock b/packages/twenty-apps/internal/twenty-fireflies/yarn.lock index c031082507..7580d365b8 100644 --- a/packages/twenty-apps/internal/twenty-fireflies/yarn.lock +++ b/packages/twenty-apps/internal/twenty-fireflies/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,7 +1173,14 @@ __metadata: languageName: node linkType: hard -"debug@npm:4": +"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" dependencies: @@ -1444,6 +1549,13 @@ __metadata: languageName: node linkType: hard +"globrex@npm:^0.1.2": + version: 0.1.2 + resolution: "globrex@npm:0.1.2" + checksum: 10c0/a54c029520cf58bda1d8884f72bd49b4cd74e977883268d931fd83bcbd1a9eb96d57c7dbd4ad80148fb9247467ebfb9b215630b2ed7563b2a8de02e1ff7f89d1 + languageName: node + linkType: hard + "gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" @@ -1644,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" @@ -1778,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" @@ -2022,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" @@ -2044,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" @@ -2140,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" @@ -2344,6 +2504,20 @@ __metadata: languageName: node linkType: hard +"tsconfck@npm:^3.0.3": + version: 3.1.6 + resolution: "tsconfck@npm:3.1.6" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + bin: + tsconfck: bin/tsconfck.js + checksum: 10c0/269c3c513540be44844117bb9b9258fe6f8aeab026d32aeebf458d5299125f330711429dbb556dbf125a0bc25f4a81e6c24ac96de2740badd295c3fb400f66c4 + languageName: node + linkType: hard + "tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -2358,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 @@ -2376,17 +2550,22 @@ __metadata: resolution: "twenty-fireflies@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-client-sdk: "npm:2.13.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.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" @@ -2403,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 @@ -2485,6 +2664,22 @@ __metadata: languageName: node linkType: hard +"vite-tsconfig-paths@npm:^4.2.1": + version: 4.3.2 + resolution: "vite-tsconfig-paths@npm:4.3.2" + dependencies: + debug: "npm:^4.1.1" + globrex: "npm:^0.1.2" + tsconfck: "npm:^3.0.3" + peerDependencies: + vite: "*" + peerDependenciesMeta: + vite: + optional: true + checksum: 10c0/f390ac1d1c3992fc5ac50f9274c1090f8b55ab34a89ea88893db9a6924a3b26c9f64bc1163615150ad100749db73b6b2cf1d57f6cd60df6e762ceb5b8ad30024 + languageName: node + linkType: hard + "vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": version: 8.0.16 resolution: "vite@npm:8.0.16"