Fix lambda error (#21179)

- move twenty-sdk from dependencies to devDependencies
- add documentation about breaking
- add warning about moving the package to dev dependencies
This commit is contained in:
martmull
2026-06-03 18:45:51 +02:00
committed by GitHub
parent 7fcbc45017
commit 0671ff3de5
10 changed files with 144 additions and 7 deletions
@@ -120,7 +120,7 @@ jobs:
echo "--- Checking package.json references correct SDK version ---"
node -e "
const pkg = require('./package.json');
const sdkVersion = pkg.dependencies['twenty-sdk'];
const sdkVersion = pkg.devDependencies['twenty-sdk'];
if (!sdkVersion.startsWith('0.0.0-ci.')) {
console.error('Expected twenty-sdk version to start with 0.0.0-ci., got:', sdkVersion);
process.exit(1);
@@ -17,8 +17,7 @@
"test:watch": "vitest"
},
"dependencies": {
"twenty-client-sdk": "TO-BE-GENERATED",
"twenty-sdk": "TO-BE-GENERATED"
"twenty-client-sdk": "TO-BE-GENERATED"
},
"devDependencies": {
"@types/node": "^24.7.2",
@@ -26,6 +25,7 @@
"oxlint": "^0.16.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"twenty-sdk": "TO-BE-GENERATED",
"typescript": "^5.9.3",
"vite-tsconfig-paths": "^4.2.1",
"vitest": "^3.1.1"
@@ -33,9 +33,11 @@ const TEMPLATE_PACKAGE_JSON = {
license: 'MIT',
scripts: { twenty: 'twenty' },
dependencies: {
'twenty-sdk': '0.0.0',
'twenty-client-sdk': '0.0.0',
},
devDependencies: {
'twenty-sdk': '0.0.0',
},
};
describe('copyBaseApplicationProject', () => {
@@ -147,7 +149,7 @@ describe('copyBaseApplicationProject', () => {
join(testAppDirectory, 'package.json'),
);
expect(packageJson.name).toBe('my-test-app');
expect(packageJson.dependencies['twenty-sdk']).toBe(
expect(packageJson.devDependencies['twenty-sdk']).toBe(
createTwentyAppPackageJson.version,
);
expect(packageJson.dependencies['twenty-client-sdk']).toBe(
@@ -120,7 +120,8 @@ const updatePackageJson = async ({
const packageJson = await fs.readJson(join(appDirectory, 'package.json'));
packageJson.name = appName;
packageJson.dependencies['twenty-sdk'] = createTwentyAppPackageJson.version;
packageJson.devDependencies['twenty-sdk'] =
createTwentyAppPackageJson.version;
packageJson.dependencies['twenty-client-sdk'] =
createTwentyAppPackageJson.version;
@@ -8,5 +8,6 @@ icon: "wrench"
- **Wrong Node version** — Need 24+. Check with `node -v`.
- **Yarn 4 missing** — Run `corepack enable`.
- **Dependencies broken** — `rm -rf node_modules && yarn install`.
- **`twenty-sdk` errors after upgrading to v2.8.0** — It moved from `dependencies` to `devDependencies` in v2.8.0. See [Project Structure → Dependencies](/developers/extend/apps/getting-started/project-structure#dependencies).
Stuck? Ask on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
+25
View File
@@ -0,0 +1,25 @@
# Changelog
All notable changes to the [Twenty SDK](https://www.npmjs.com/package/twenty-sdk) are documented in this file.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.8.0]
### Breaking Changes
- **`twenty-sdk` must now be a dev dependency.** It ships the `twenty` CLI and the build/scaffolding tooling, which only run at development and build time — it is never imported by a published app's runtime. Newly scaffolded apps already place it under `devDependencies`. Apps created before `2.8.0` must move it when upgrading:
```diff
"dependencies": {
"twenty-client-sdk": "^2.8.0"
- "twenty-sdk": "^2.8.0"
},
"devDependencies": {
+ "twenty-sdk": "^2.8.0"
}
```
Then reinstall with `rm -rf node_modules && yarn install`. `twenty-client-sdk` stays under `dependencies` because app code imports it at runtime.
`twenty build` now emits a warning when `twenty-sdk` is still listed under `dependencies`, so existing apps are flagged automatically.
+1
View File
@@ -8,6 +8,7 @@
"files": [
"dist",
"README.md",
"CHANGELOG.md",
"package.json"
],
"scripts": {
@@ -1,6 +1,7 @@
import { type EntityFilePaths } from '@/cli/utilities/build/manifest/manifest-extract-config';
import { buildManifest } from '@/cli/utilities/build/manifest/manifest-build';
import { manifestValidate } from '@/cli/utilities/build/manifest/manifest-validate';
import { validatePackageJsonDependencies } from '@/cli/utilities/build/manifest/utils/validate-package-json-dependencies';
import { type Manifest } from 'twenty-shared/application';
export type BuildAndValidateManifestSuccess = {
@@ -43,10 +44,16 @@ export const buildAndValidateManifest = async (
};
}
const packageJsonWarnings = await validatePackageJsonDependencies(appPath);
return {
success: true,
manifest: result.manifest,
filePaths: result.filePaths,
warnings: [...result.warnings, ...validation.warnings],
warnings: [
...result.warnings,
...validation.warnings,
...packageJsonWarnings,
],
};
};
@@ -0,0 +1,70 @@
import { validatePackageJsonDependencies } from '@/cli/utilities/build/manifest/utils/validate-package-json-dependencies';
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
const writeTempPackageJson = async (
packageJson: Record<string, unknown> | null,
): Promise<string> => {
const appPath = await mkdtemp(join(tmpdir(), 'twenty-sdk-deps-'));
if (packageJson !== null) {
await writeFile(
join(appPath, 'package.json'),
JSON.stringify(packageJson, null, 2),
);
}
return appPath;
};
describe('validatePackageJsonDependencies', () => {
let appPath: string;
afterEach(async () => {
if (appPath) {
await rm(appPath, { recursive: true, force: true });
}
});
it('should warn when twenty-sdk is listed under dependencies', async () => {
appPath = await writeTempPackageJson({
dependencies: { 'twenty-sdk': '^2.8.0', 'twenty-client-sdk': '^2.8.0' },
});
const warnings = await validatePackageJsonDependencies(appPath);
expect(warnings).toHaveLength(1);
expect(warnings[0]).toContain('twenty-sdk');
expect(warnings[0]).toContain('devDependencies');
});
it('should not warn when twenty-sdk is listed under devDependencies', async () => {
appPath = await writeTempPackageJson({
dependencies: { 'twenty-client-sdk': '^2.8.0' },
devDependencies: { 'twenty-sdk': '^2.8.0' },
});
const warnings = await validatePackageJsonDependencies(appPath);
expect(warnings).toEqual([]);
});
it('should not warn when twenty-sdk is absent from dependencies', async () => {
appPath = await writeTempPackageJson({
dependencies: { 'twenty-client-sdk': '^2.8.0' },
});
const warnings = await validatePackageJsonDependencies(appPath);
expect(warnings).toEqual([]);
});
it('should not warn when package.json is missing', async () => {
appPath = await writeTempPackageJson(null);
const warnings = await validatePackageJsonDependencies(appPath);
expect(warnings).toEqual([]);
});
});
@@ -0,0 +1,30 @@
import { pathExists, readJson } from '@/cli/utilities/file/fs-utils';
import path from 'path';
import { isDefined } from 'twenty-shared/utils';
type PackageJsonDependencies = {
dependencies?: Record<string, string>;
};
// twenty-sdk ships the CLI and build/scaffolding tooling used only at dev and
// build time — it is never imported by the published app's runtime. Keeping it
// in "dependencies" ships dead weight, so it must live in "devDependencies".
export const validatePackageJsonDependencies = async (
appPath: string,
): Promise<string[]> => {
const packageJsonPath = path.join(appPath, 'package.json');
if (!(await pathExists(packageJsonPath))) {
return [];
}
const packageJson = await readJson<PackageJsonDependencies>(packageJsonPath);
if (isDefined(packageJson.dependencies?.['twenty-sdk'])) {
return [
'"twenty-sdk" is listed under "dependencies" in package.json. It is a build-time only tool and should be moved to "devDependencies".',
];
}
return [];
};