From df1990fc9356ef4712a9673f81edf95a127da101 Mon Sep 17 00:00:00 2001 From: Lovepreet Singh Date: Sun, 12 Jul 2026 11:40:53 +0530 Subject: [PATCH] fix: omit @strapi devDependencies for local plugins --- fix_test.patch | 56 +++++++++++++++++++ .../unit/init-file-generator.test.ts | 40 ++++++++++++- src/cli/commands/plugin/init/action.ts | 1 + src/cli/commands/utils/init/file-generator.ts | 13 +++-- src/cli/commands/utils/init/init.ts | 2 +- src/cli/commands/utils/init/types.ts | 1 + 6 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 fix_test.patch diff --git a/fix_test.patch b/fix_test.patch new file mode 100644 index 0000000..f2440e7 --- /dev/null +++ b/fix_test.patch @@ -0,0 +1,56 @@ +--- src/__tests__/unit/init-file-generator.test.ts ++++ src/__tests__/unit/init-file-generator.test.ts +@@ -53,7 +53,7 @@ + expect(serverControllerFile.contents).toContain(`.plugin('${pluginId}')`); + }); + +- it('should put admin runtime deps in peerDependencies (and devDependencies), not dependencies', async () => { ++ it('should put admin runtime deps in peerDependencies (and devDependencies) for standalone plugins', async () => { + const { generateFiles } = await import('../../cli/commands/utils/init/file-generator'); + + const logger = { +@@ -92,6 +92,44 @@ + expect(pkgJson.devDependencies?.['react-intl']).toBeDefined(); + }); + ++ it('should NOT put admin runtime deps in devDependencies for local plugins', async () => { ++ const { generateFiles } = await import('../../cli/commands/utils/init/file-generator'); ++ ++ const logger = { ++ info: jest.fn(), ++ debug: jest.fn(), ++ warn: jest.fn(), ++ error: jest.fn(), ++ log: jest.fn(), ++ }; ++ ++ const files = await generateFiles( ++ [ ++ { name: 'pkgName', answer: 'my-plugin' }, ++ { name: 'pluginId', answer: 'my-plugin' }, ++ { name: 'client-code', answer: true }, ++ { name: 'server-code', answer: false }, ++ { name: 'typescript', answer: true }, ++ ], ++ 'my-plugin', ++ logger as any, ++ true // isStrapiProject = true ++ ); ++ ++ const pkgJsonFile = getFile(files, 'package.json'); ++ const pkgJson = JSON.parse(pkgJsonFile.contents); ++ ++ expect(pkgJson.dependencies?.['@strapi/design-system']).toBeUndefined(); ++ expect(pkgJson.dependencies?.['@strapi/icons']).toBeUndefined(); ++ ++ expect(pkgJson.peerDependencies?.['@strapi/design-system']).toBeDefined(); ++ expect(pkgJson.peerDependencies?.['@strapi/icons']).toBeDefined(); ++ ++ expect(pkgJson.devDependencies?.['@strapi/design-system']).toBeUndefined(); ++ expect(pkgJson.devDependencies?.['@strapi/icons']).toBeUndefined(); ++ expect(pkgJson.devDependencies?.['@strapi/strapi']).toBeUndefined(); ++ }); ++ + it('should constrain react-intl to v6 range (compatible with React 18)', async () => { + const { getLatestVersion } = jest.requireMock('get-latest-version'); + getLatestVersion.mockClear(); diff --git a/src/__tests__/unit/init-file-generator.test.ts b/src/__tests__/unit/init-file-generator.test.ts index 16d7169..8615394 100644 --- a/src/__tests__/unit/init-file-generator.test.ts +++ b/src/__tests__/unit/init-file-generator.test.ts @@ -53,7 +53,7 @@ describe('init file generation', () => { expect(serverControllerFile.contents).toContain(`.plugin('${pluginId}')`); }); - it('should put admin runtime deps in peerDependencies (and devDependencies), not dependencies', async () => { + it('should put admin runtime deps in peerDependencies (and devDependencies) for standalone plugins', async () => { const { generateFiles } = await import('../../cli/commands/utils/init/file-generator'); const logger = { @@ -92,6 +92,44 @@ describe('init file generation', () => { expect(pkgJson.devDependencies?.['react-intl']).toBeDefined(); }); + it('should NOT put admin runtime deps in devDependencies for local plugins', async () => { + const { generateFiles } = await import('../../cli/commands/utils/init/file-generator'); + + const logger = { + info: jest.fn(), + debug: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + log: jest.fn(), + }; + + const files = await generateFiles( + [ + { name: 'pkgName', answer: 'my-plugin' }, + { name: 'pluginId', answer: 'my-plugin' }, + { name: 'client-code', answer: true }, + { name: 'server-code', answer: false }, + { name: 'typescript', answer: true }, + ], + 'my-plugin', + logger as any, + true // isStrapiProject = true + ); + + const pkgJsonFile = getFile(files, 'package.json'); + const pkgJson = JSON.parse(pkgJsonFile.contents); + + expect(pkgJson.dependencies?.['@strapi/design-system']).toBeUndefined(); + expect(pkgJson.dependencies?.['@strapi/icons']).toBeUndefined(); + + expect(pkgJson.peerDependencies?.['@strapi/design-system']).toBeDefined(); + expect(pkgJson.peerDependencies?.['@strapi/icons']).toBeDefined(); + + expect(pkgJson.devDependencies?.['@strapi/design-system']).toBeUndefined(); + expect(pkgJson.devDependencies?.['@strapi/icons']).toBeUndefined(); + expect(pkgJson.devDependencies?.['@strapi/strapi']).toBeUndefined(); + }); + it('should constrain react-intl to v6 range (compatible with React 18)', async () => { const { getLatestVersion } = jest.requireMock('get-latest-version'); getLatestVersion.mockClear(); diff --git a/src/cli/commands/plugin/init/action.ts b/src/cli/commands/plugin/init/action.ts index ffa4bab..2be6cfa 100644 --- a/src/cli/commands/plugin/init/action.ts +++ b/src/cli/commands/plugin/init/action.ts @@ -28,6 +28,7 @@ export default async ( const answers = await init({ cwd, path: pluginPath, + isStrapiProject, silent, debug, logger, diff --git a/src/cli/commands/utils/init/file-generator.ts b/src/cli/commands/utils/init/file-generator.ts index 13d95e8..96ae9cb 100644 --- a/src/cli/commands/utils/init/file-generator.ts +++ b/src/cli/commands/utils/init/file-generator.ts @@ -15,7 +15,8 @@ import type { PromptAnswer, TemplateFile } from './types'; export const generateFiles = async ( answers: PromptAnswer[], packageFolder: string, - logger: Logger + logger: Logger, + isStrapiProject: boolean = false ): Promise => { const author: string[] = []; const files: TemplateFile[] = []; @@ -47,7 +48,7 @@ export const generateFiles = async ( }, dependencies: {}, devDependencies: { - '@strapi/strapi': '^5.0.0', + ...(isStrapiProject ? {} : { '@strapi/strapi': '^5.0.0' }), '@strapi/sdk-plugin': '^6.0.0', prettier: '*', }, @@ -114,8 +115,12 @@ export const generateFiles = async ( pkgJson.devDependencies = { ...pkgJson.devDependencies, - '@strapi/design-system': '^2.0.0', - '@strapi/icons': '^2.0.0', + ...(isStrapiProject + ? {} + : { + '@strapi/design-system': '^2.0.0', + '@strapi/icons': '^2.0.0', + }), 'react-intl': '^6.0.0', react: '^18.0.0', 'react-dom': '^18.0.0', diff --git a/src/cli/commands/utils/init/init.ts b/src/cli/commands/utils/init/init.ts index 2438910..c67f4ba 100644 --- a/src/cli/commands/utils/init/init.ts +++ b/src/cli/commands/utils/init/init.ts @@ -51,7 +51,7 @@ export const init = async (options: InitOptions): Promise => { } // Generate files based on answers - const files = await generateFiles(answers, packageFolder, logger); + const files = await generateFiles(answers, packageFolder, logger, options.isStrapiProject); if (debug) { logger.debug(`Generated ${files.length} files`); diff --git a/src/cli/commands/utils/init/types.ts b/src/cli/commands/utils/init/types.ts index 0b11721..93abb12 100644 --- a/src/cli/commands/utils/init/types.ts +++ b/src/cli/commands/utils/init/types.ts @@ -32,6 +32,7 @@ export interface GitConfig { export interface InitOptions { cwd: string; path: string; + isStrapiProject?: boolean; silent?: boolean; debug?: boolean; logger: Logger;