diff --git a/src/application/project/code/transformation/javascript/nextJsMiddlewareCodemod.ts b/src/application/project/code/transformation/javascript/nextJsProxyCodemod.ts similarity index 76% rename from src/application/project/code/transformation/javascript/nextJsMiddlewareCodemod.ts rename to src/application/project/code/transformation/javascript/nextJsProxyCodemod.ts index 8e6858ce..5d1748f3 100644 --- a/src/application/project/code/transformation/javascript/nextJsMiddlewareCodemod.ts +++ b/src/application/project/code/transformation/javascript/nextJsProxyCodemod.ts @@ -19,39 +19,40 @@ type VariableMatch = { declaration: t.VariableDeclarator, }; -export type MiddlewareConfiguration = { +export type ProxyConfiguration = { matcherPattern: string, + exportName: string, import: { module: string, - middlewareFactoryName: string, - middlewareName: string, + proxyFactoryName: string, + proxyName: string, }, }; /** - * Refactors the middleware wrapping it with necessary configuration. + * Refactors the proxy wrapping it with necessary configuration. * - * This transformer wraps the existing middleware function with a higher-order - * function that provides the necessary configuration for the middleware to - * work correctly. It can also detect if the middleware is already configured + * This transformer wraps the existing proxy function with a higher-order + * function that provides the necessary configuration for the proxy to + * work correctly. It can also detect if the proxy is already configured * or missing configuration and apply the necessary changes. */ -export class NextJsMiddlewareCodemod implements Codemod { - private readonly configuration: MiddlewareConfiguration; +export class NextJsProxyCodemod implements Codemod { + private readonly configuration: ProxyConfiguration; - public constructor(options: MiddlewareConfiguration) { + public constructor(options: ProxyConfiguration) { this.configuration = options; } public apply(input: t.File): Promise> { const {body} = input.program; - const isMiddlewareReexported = hasReexport(input, { + const isProxyReexported = hasReexport(input, { moduleName: this.configuration.import.module, - importName: this.configuration.import.middlewareName, + importName: this.configuration.import.proxyName, }); - const localConfig = NextJsMiddlewareCodemod.findConfig(input); + const localConfig = NextJsProxyCodemod.findConfig(input); const addConfigExport = (): void => { // Add a configuration object with the matcher pattern @@ -70,10 +71,10 @@ export class NextJsMiddlewareCodemod implements Codemod { )); }; - if (isMiddlewareReexported) { + if (isProxyReexported) { if (localConfig !== null) { - // Middleware is re-exported and config found in the source code, - // consider the middleware configured + // Proxy is re-exported and config found in the source code, + // consider the proxy configured return Promise.resolve({ modified: false, result: input, @@ -89,48 +90,49 @@ export class NextJsMiddlewareCodemod implements Codemod { }); } - const middlewareFactoryName = getImportLocalName(input, { + const proxyFactoryName = getImportLocalName(input, { moduleName: this.configuration.import.module, - importName: this.configuration.import.middlewareFactoryName, + importName: this.configuration.import.proxyFactoryName, }); - const middlewareName = getImportLocalName(input, { + const proxyName = getImportLocalName(input, { moduleName: this.configuration.import.module, - importName: this.configuration.import.middlewareName, + importName: this.configuration.import.proxyName, }); const existingImports: string[] = []; - if (middlewareFactoryName !== null) { - existingImports.push(middlewareFactoryName); + if (proxyFactoryName !== null) { + existingImports.push(proxyFactoryName); } - if (middlewareName !== null) { - existingImports.push(middlewareName); + if (proxyName !== null) { + existingImports.push(proxyName); } - if (existingImports.length > 0 && NextJsMiddlewareCodemod.isCalled(input, existingImports)) { - // The middleware is already called in the source code, consider it refactored + if (existingImports.length > 0 && NextJsProxyCodemod.isCalled(input, existingImports)) { + // The proxy is already called in the source code, consider it refactored return Promise.resolve({ modified: false, result: input, }); } - let middlewareNode = NextJsMiddlewareCodemod.refactorMiddleware( + let proxyNode = NextJsProxyCodemod.refactorProxy( input, - middlewareFactoryName ?? this.configuration.import.middlewareFactoryName, + this.configuration.exportName, + proxyFactoryName ?? this.configuration.import.proxyFactoryName, localConfig !== null && localConfig.matcher ? localConfig.name : undefined, ); - if (middlewareNode === null) { + if (proxyNode === null) { if (localConfig === null) { - // No middleware found or configuration object, - // just add middleware re-export + // No proxy found or configuration object, + // just add proxy re-export addReexport(input, { type: 'value', moduleName: this.configuration.import.module, - importName: this.configuration.import.middlewareName, + importName: this.configuration.import.proxyName, }); addConfigExport(); @@ -141,10 +143,10 @@ export class NextJsMiddlewareCodemod implements Codemod { }); } - // Configurations found but no middleware, add the middleware - middlewareNode = t.exportDefaultDeclaration( + // Configurations found but no proxy, add the proxy + proxyNode = t.exportDefaultDeclaration( t.callExpression( - t.identifier(middlewareFactoryName ?? this.configuration.import.middlewareFactoryName), + t.identifier(proxyFactoryName ?? this.configuration.import.proxyFactoryName), [ t.objectExpression([ t.objectProperty( @@ -159,7 +161,7 @@ export class NextJsMiddlewareCodemod implements Codemod { ), ); - body.push(middlewareNode); + body.push(proxyNode); } if (localConfig !== null) { @@ -167,11 +169,11 @@ export class NextJsMiddlewareCodemod implements Codemod { this.configureMatcher(localConfig.object, this.configuration.matcherPattern); const configPosition = body.indexOf(localConfig.root as t.Statement); - const middlewarePosition = body.indexOf(middlewareNode as t.Statement); + const proxyPosition = body.indexOf(proxyNode as t.Statement); - if (configPosition > middlewarePosition) { + if (configPosition > proxyPosition) { /* - The middleware references the config object, so the config should be moved before it. + The proxy references the config object, so the config should be moved before it. Any variable or function used by the config object should be moved alongside it. The current logic handles most cases, including edge cases with multiple references. @@ -179,25 +181,25 @@ export class NextJsMiddlewareCodemod implements Codemod { and unlikely to occur as Next.js requires the config to be static for analysis at build time. */ - body.splice(middlewarePosition, 0, ...body.splice(configPosition, 1)); + body.splice(proxyPosition, 0, ...body.splice(configPosition, 1)); // Move any references of the config object alongside it - for (const reference of NextJsMiddlewareCodemod.findReferencesFrom(localConfig.root, input.program)) { + for (const reference of NextJsProxyCodemod.findReferencesFrom(localConfig.root, input.program)) { const referencePosition = body.indexOf(reference as t.Statement); - if (referencePosition > middlewarePosition) { - body.splice(middlewarePosition, 0, ...body.splice(referencePosition, 1)); + if (referencePosition > proxyPosition) { + body.splice(proxyPosition, 0, ...body.splice(referencePosition, 1)); } } } } - if (middlewareFactoryName === null) { - // If no import for the middleware factory was found, add it + if (proxyFactoryName === null) { + // If no import for the proxy factory was found, add it addImport(input, { type: 'value', moduleName: this.configuration.import.module, - importName: this.configuration.import.middlewareFactoryName, + importName: this.configuration.import.proxyFactoryName, }); } @@ -208,7 +210,7 @@ export class NextJsMiddlewareCodemod implements Codemod { } /** - * Adds the middleware matcher to the config object. + * Adds the proxy matcher to the config object. * * @param configObject The object expression representing the configuration. * @param pattern The pattern to add to the matcher. @@ -281,14 +283,20 @@ export class NextJsMiddlewareCodemod implements Codemod { } /** - * Refactors the middleware wrapping it with necessary configuration. + * Refactors the proxy wrapping it with necessary configuration. * * @param ast The AST representing the source code. - * @param functionName The name of the middleware function. + * @param exportName The name of the proxy identifier. + * @param functionName The name of the proxy function. * @param configName Optional name of the configuration object variable. - * @return The root node of the refactored middleware or null if not found. + * @return The root node of the refactored proxy or null if not found. */ - private static refactorMiddleware(ast: t.File, functionName: string, configName?: string): t.Node | null { + private static refactorProxy( + ast: t.File, + exportName: string, + functionName: string, + configName?: string, + ): t.Node | null { let rootNode: t.Node | null = null; traverse(ast, { @@ -296,21 +304,21 @@ export class NextJsMiddlewareCodemod implements Codemod { const {node} = path; const {declaration, specifiers = []} = node; - // export function middleware() {} + // export function proxy() {} if (t.isFunctionDeclaration(declaration)) { if ( t.isFunctionDeclaration(node.declaration) && t.isIdentifier(node.declaration.id) - && node.declaration.id.name === 'middleware' + && node.declaration.id.name === exportName ) { path.replaceWith( t.exportNamedDeclaration( t.variableDeclaration('const', [ t.variableDeclarator( - t.identifier('middleware'), - NextJsMiddlewareCodemod.wrapMiddleware( + t.identifier(exportName), + NextJsProxyCodemod.wrapProxy( t.isFunctionDeclaration(node.declaration) - ? NextJsMiddlewareCodemod.createFunctionExpression(node.declaration) + ? NextJsProxyCodemod.createFunctionExpression(node.declaration) : node.declaration, functionName, configName, @@ -321,7 +329,7 @@ export class NextJsMiddlewareCodemod implements Codemod { ), ); - rootNode = NextJsMiddlewareCodemod.getRootNode(path); + rootNode = NextJsProxyCodemod.getRootNode(path); return path.stop(); } @@ -329,23 +337,23 @@ export class NextJsMiddlewareCodemod implements Codemod { return path.skip(); } - // export const middleware = function() {} + // export const proxy = function() {} if (t.isVariableDeclaration(declaration)) { for (const declarator of declaration.declarations) { if ( t.isVariableDeclarator(declarator) && t.isIdentifier(declarator.id) - && declarator.id.name === 'middleware' + && declarator.id.name === exportName ) { const initializer = declarator.init ?? null; if (initializer !== null) { - declarator.init = NextJsMiddlewareCodemod.wrapMiddleware( + declarator.init = NextJsProxyCodemod.wrapProxy( initializer, functionName, configName, ); - rootNode = NextJsMiddlewareCodemod.getRootNode(path); + rootNode = NextJsProxyCodemod.getRootNode(path); return path.stop(); } @@ -353,15 +361,15 @@ export class NextJsMiddlewareCodemod implements Codemod { } } - // export {middleware} + // export {proxy} for (const specifier of specifiers) { if ( t.isExportSpecifier(specifier) && t.isIdentifier(specifier.exported) && t.isIdentifier(specifier.local) - && (['middleware', 'default']).includes(specifier.exported.name) + && ([exportName, 'default']).includes(specifier.exported.name) ) { - rootNode = NextJsMiddlewareCodemod.replaceMiddlewareDeclaration( + rootNode = NextJsProxyCodemod.replaceProxyDeclaration( ast, specifier.local.name, functionName, @@ -382,7 +390,7 @@ export class NextJsMiddlewareCodemod implements Codemod { if (t.isArrowFunctionExpression(declaration)) { path.replaceWith( t.exportDefaultDeclaration( - NextJsMiddlewareCodemod.wrapMiddleware( + NextJsProxyCodemod.wrapProxy( declaration, functionName, configName, @@ -390,7 +398,7 @@ export class NextJsMiddlewareCodemod implements Codemod { ), ); - rootNode = NextJsMiddlewareCodemod.getRootNode(path); + rootNode = NextJsProxyCodemod.getRootNode(path); return path.stop(); } @@ -399,22 +407,22 @@ export class NextJsMiddlewareCodemod implements Codemod { if (t.isFunctionDeclaration(declaration)) { path.replaceWith( t.exportDefaultDeclaration( - NextJsMiddlewareCodemod.wrapMiddleware( - NextJsMiddlewareCodemod.createFunctionExpression(declaration, true), + NextJsProxyCodemod.wrapProxy( + NextJsProxyCodemod.createFunctionExpression(declaration, true), functionName, configName, ), ), ); - rootNode = NextJsMiddlewareCodemod.getRootNode(path); + rootNode = NextJsProxyCodemod.getRootNode(path); return path.stop(); } - // export default middleware + // export default proxy if (t.isIdentifier(declaration)) { - rootNode = NextJsMiddlewareCodemod.replaceMiddlewareDeclaration( + rootNode = NextJsProxyCodemod.replaceProxyDeclaration( ast, declaration.name, functionName, @@ -431,7 +439,7 @@ export class NextJsMiddlewareCodemod implements Codemod { return rootNode; } - private static replaceMiddlewareDeclaration( + private static replaceProxyDeclaration( file: t.File, name: string, functionName: string, @@ -447,8 +455,8 @@ export class NextJsMiddlewareCodemod implements Codemod { const initializer = node.init ?? null; if (initializer !== null) { - node.init = NextJsMiddlewareCodemod.wrapMiddleware(initializer, functionName, configName); - rootNode = NextJsMiddlewareCodemod.getRootNode(path); + node.init = NextJsProxyCodemod.wrapProxy(initializer, functionName, configName); + rootNode = NextJsProxyCodemod.getRootNode(path); } return path.stop(); @@ -461,7 +469,7 @@ export class NextJsMiddlewareCodemod implements Codemod { if (t.isIdentifier(node.id) && node.id.name === name) { path.replaceWith( - NextJsMiddlewareCodemod.wrapFunctionDeclaration( + NextJsProxyCodemod.wrapFunctionDeclaration( node, functionName, configName, @@ -471,7 +479,7 @@ export class NextJsMiddlewareCodemod implements Codemod { ), ); - rootNode = NextJsMiddlewareCodemod.getRootNode(path); + rootNode = NextJsProxyCodemod.getRootNode(path); return path.stop(); } @@ -488,7 +496,7 @@ export class NextJsMiddlewareCodemod implements Codemod { * * @param file The AST representing the source code. * @param functionNames The names of the functions to search for. - * @return true if the middleware is called, false otherwise. + * @return true if the proxy is called, false otherwise. */ private static isCalled(file: t.File, functionNames: string[]): boolean { let wrapped = false; @@ -514,7 +522,7 @@ export class NextJsMiddlewareCodemod implements Codemod { } /** - * Finds the middleware configuration object in the t. + * Finds the proxy configuration object in the t. * * @param ast The AST representing the source code. * @return The information about the config object or null if not found. @@ -536,10 +544,10 @@ export class NextJsMiddlewareCodemod implements Codemod { ) { const match = t.isIdentifier(declarator.init) // export const config = variable - ? NextJsMiddlewareCodemod.findVariableDeclarator(ast, declarator.init.name) + ? NextJsProxyCodemod.findVariableDeclarator(ast, declarator.init.name) : { name: 'config', - root: NextJsMiddlewareCodemod.getRootNode(path), + root: NextJsProxyCodemod.getRootNode(path), declaration: declarator, }; @@ -552,7 +560,7 @@ export class NextJsMiddlewareCodemod implements Codemod { name: match.name, root: match.root, object: match.declaration.init, - matcher: NextJsMiddlewareCodemod.hasMatcherProperty(match.declaration.init), + matcher: NextJsProxyCodemod.hasMatcherProperty(match.declaration.init), }; return path.stop(); @@ -569,14 +577,14 @@ export class NextJsMiddlewareCodemod implements Codemod { && t.isIdentifier(specifier.local) && specifier.exported.name === 'config' ) { - const match = NextJsMiddlewareCodemod.findVariableDeclarator(ast, specifier.local.name); + const match = NextJsProxyCodemod.findVariableDeclarator(ast, specifier.local.name); if (match !== null && t.isObjectExpression(match.declaration.init)) { config = { name: match.name, root: match.root, object: match.declaration.init, - matcher: NextJsMiddlewareCodemod.hasMatcherProperty(match.declaration.init), + matcher: NextJsProxyCodemod.hasMatcherProperty(match.declaration.init), }; } @@ -639,11 +647,11 @@ export class NextJsMiddlewareCodemod implements Codemod { ) { if (t.isIdentifier(node.init)) { // If the initializer is an identifier, recursively search for the declaration - declarator = NextJsMiddlewareCodemod.findVariableDeclarator(ast, node.init.name); + declarator = NextJsProxyCodemod.findVariableDeclarator(ast, node.init.name); } else { declarator = { name: name, - root: NextJsMiddlewareCodemod.getRootNode(path), + root: NextJsProxyCodemod.getRootNode(path), declaration: node, }; } @@ -659,14 +667,14 @@ export class NextJsMiddlewareCodemod implements Codemod { } /** - * Wraps the given node with the HOC middleware. + * Wraps the given node with the HOC proxy. * - * @param node The node to wrap with the middleware. - * @param functionName The name of the middleware function. + * @param node The node to wrap with the proxy. + * @param functionName The name of the proxy function. * @param configName Optional name of the configuration object variable. - * @return The transformed middleware node. + * @return The transformed proxy node. */ - private static wrapMiddleware(node: t.Expression, functionName: string, configName?: string): t.CallExpression { + private static wrapProxy(node: t.Expression, functionName: string, configName?: string): t.CallExpression { return t.callExpression( t.identifier(functionName), [ @@ -690,27 +698,27 @@ export class NextJsMiddlewareCodemod implements Codemod { } /** - * Wraps a function declaration in a middleware expression as a variable declaration. + * Wraps a function declaration in a proxy expression as a variable declaration. * * @param functionDeclaration The function declaration to wrap. - * @param functionName The name of the middleware function. + * @param functionName The name of the proxy function. * @param configName Optional name of the configuration object variable. - * @param name The name of the constant variable to assign the middleware to. - * @return A variable declaration that assigns the wrapped middleware to a constant. + * @param name The name of the constant variable to assign the proxy to. + * @return A variable declaration that assigns the wrapped proxy to a constant. */ private static wrapFunctionDeclaration( functionDeclaration: t.FunctionDeclaration, functionName: string, configName?: string, - name = 'middleware', + name = 'proxy', ): t.VariableDeclaration { return t.variableDeclaration( 'const', [ t.variableDeclarator( t.identifier(name), - NextJsMiddlewareCodemod.wrapMiddleware( - NextJsMiddlewareCodemod.createFunctionExpression(functionDeclaration), + NextJsProxyCodemod.wrapProxy( + NextJsProxyCodemod.createFunctionExpression(functionDeclaration), functionName, configName, ), @@ -743,7 +751,7 @@ export class NextJsMiddlewareCodemod implements Codemod { Identifier: function acceptNested(nestedPath) { const identifier = nestedPath.node; - if (NextJsMiddlewareCodemod.isVariableReference(nestedPath.parent, identifier)) { + if (NextJsProxyCodemod.isVariableReference(nestedPath.parent, identifier)) { names.add(identifier.name); } @@ -767,7 +775,7 @@ export class NextJsMiddlewareCodemod implements Codemod { const {node} = path; if (t.isIdentifier(node.id) && names.has(node.id.name)) { - references.push(NextJsMiddlewareCodemod.getRootNode(path)); + references.push(NextJsProxyCodemod.getRootNode(path)); } return path.skip(); @@ -780,7 +788,7 @@ export class NextJsMiddlewareCodemod implements Codemod { const {node} = path; if (t.isIdentifier(node.id) && names.has(node.id.name)) { - references.push(NextJsMiddlewareCodemod.getRootNode(path)); + references.push(NextJsProxyCodemod.getRootNode(path)); } return path.skip(); @@ -793,7 +801,7 @@ export class NextJsMiddlewareCodemod implements Codemod { const {node} = path; if (t.isIdentifier(node.id) && names.has(node.id.name)) { - references.push(NextJsMiddlewareCodemod.getRootNode(path)); + references.push(NextJsProxyCodemod.getRootNode(path)); } return path.skip(); @@ -803,7 +811,7 @@ export class NextJsMiddlewareCodemod implements Codemod { return [ ...new Set(references.flatMap( // Recursively find references from the found references - reference => [reference, ...NextJsMiddlewareCodemod.findReferencesFrom(reference, root)], + reference => [reference, ...NextJsProxyCodemod.findReferencesFrom(reference, root)], )), ]; } diff --git a/src/application/project/sdk/plugNextSdk.ts b/src/application/project/sdk/plugNextSdk.ts index fc853af2..cc259762 100644 --- a/src/application/project/sdk/plugNextSdk.ts +++ b/src/application/project/sdk/plugNextSdk.ts @@ -28,6 +28,7 @@ import {ApiKeyPermission} from '@/application/model/application'; import {PlugReactExampleGenerator} from '@/application/project/code/generation/slot/plugReactExampleGenerator'; type CodemodConfiguration = { + proxy: Codemod, middleware: Codemod, fallbackProvider: Codemod, appRouterProvider: Codemod, @@ -50,7 +51,8 @@ type NextProjectInfo = { router: NextRouter, sourceDirectory: string, pageDirectory: string, - middleware: { + proxy: { + name: 'proxy' | 'middleware', file: string, }, provider: { @@ -181,10 +183,11 @@ export class PlugNextSdk extends JavaScriptSdk { } private async getProjectInfo(): Promise { - const [isTypescript, directory, fallbackMode] = await Promise.all([ + const [isTypescript, directory, fallbackMode, legacyMiddleware] = await Promise.all([ this.isTypeScriptProject(), this.getPageDirectory(), this.isFallbackMode(), + this.packageManager.hasDirectDependency('next', '<16'), ]); const project: Pick = { @@ -194,9 +197,11 @@ export class PlugNextSdk extends JavaScriptSdk { pageDirectory: directory, }; - const [middlewareFile, providerComponentFile] = await Promise.all([ + const proxyName = legacyMiddleware ? 'middleware' : 'proxy'; + + const [proxyFile, providerComponentFile] = await Promise.all([ this.locateFile( - ...['middleware.js', 'middleware.ts'] + ...[`${proxyName}.js`, `${proxyName}.ts`] .map(file => this.fileSystem.joinPaths(project.sourceDirectory, file)), ), this.locateFile( @@ -233,8 +238,9 @@ export class PlugNextSdk extends JavaScriptSdk { this.fileSystem.joinPaths(projectDirectory, '.env.production'), ), }, - middleware: { - file: middlewareFile ?? this.fileSystem.joinPaths(project.sourceDirectory, `middleware.${extension}`), + proxy: { + name: proxyName, + file: proxyFile ?? this.fileSystem.joinPaths(project.sourceDirectory, `${proxyName}.${extension}`), }, provider: { file: providerComponentFile @@ -251,17 +257,19 @@ export class PlugNextSdk extends JavaScriptSdk { const tasks: Task[] = []; if (!installation.project.fallbackMode) { + const proxyName = installation.project.proxy.name; + tasks.push({ - title: 'Configure middleware', + title: `Configure ${proxyName}`, task: async notifier => { - notifier.update('Configuring middleware'); + notifier.update(`Configuring ${proxyName}`); try { - await this.updateCode(this.codemod.middleware, installation.project.middleware.file); + await this.updateCode(this.codemod[proxyName], installation.project.proxy.file); - notifier.confirm('Middleware configured'); + notifier.confirm(`${PlugNextSdk.capitalize(proxyName)} configured`); } catch (error) { - notifier.alert('Failed to install middleware', HelpfulError.formatMessage(error)); + notifier.alert(`Failed to install ${proxyName}`, HelpfulError.formatMessage(error)); } }, }); @@ -440,4 +448,8 @@ export class PlugNextSdk extends JavaScriptSdk { private isFallbackMode(): Promise { return this.packageManager.hasDirectDependency('next', '<=13'); } + + private static capitalize(name: string): string { + return name.charAt(0).toUpperCase() + name.slice(1); + } } diff --git a/src/infrastructure/application/cli/cli.ts b/src/infrastructure/application/cli/cli.ts index 00d7e034..52baf985 100644 --- a/src/infrastructure/application/cli/cli.ts +++ b/src/infrastructure/application/cli/cli.ts @@ -48,7 +48,7 @@ import {Command, CommandInput} from '@/application/cli/command/command'; import {AdminCommand, AdminInput} from '@/application/cli/command/admin'; import {JsxWrapperCodemod} from '@/application/project/code/transformation/javascript/jsxWrapperCodemod'; import {JavaScriptCodemod} from '@/application/project/code/transformation/javascript/javaScriptCodemod'; -import {NextJsMiddlewareCodemod} from '@/application/project/code/transformation/javascript/nextJsMiddlewareCodemod'; +import {NextJsProxyCodemod} from '@/application/project/code/transformation/javascript/nextJsProxyCodemod'; import {CodeFormatter} from '@/application/project/code/formatting/formatter'; import {FormatCodemod} from '@/application/project/code/transformation/formatCodemod'; import {FileCodemod} from '@/application/project/code/transformation/fileCodemod'; @@ -1796,6 +1796,26 @@ export class Cli { }, }; + const createProxyCodemod = (proxyName: string): Codemod => new FormatCodemod( + formatter, + new FileCodemod({ + fileSystem: this.getFileSystem(), + codemod: new JavaScriptCodemod({ + languages: ['typescript', 'jsx'], + codemod: new NextJsProxyCodemod({ + // eslint-disable-next-line max-len -- Ignore for readability + matcherPattern: '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)', + exportName: proxyName, + import: { + module: `@croct/plug-next/${proxyName}`, + proxyName: proxyName, + proxyFactoryName: 'withCroct', + }, + }), + }), + }), + ); + return new PlugNextSdk({ ...config, plugins: [this.createStoryblokPlugin(Platform.NEXTJS)], @@ -1803,24 +1823,8 @@ export class Cli { applicationApi: this.getApplicationApi(), importResolver: importResolver, codemod: { - middleware: new FormatCodemod( - formatter, - new FileCodemod({ - fileSystem: this.getFileSystem(), - codemod: new JavaScriptCodemod({ - languages: ['typescript', 'jsx'], - codemod: new NextJsMiddlewareCodemod({ - // eslint-disable-next-line max-len -- Ignore for readability - matcherPattern: '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)', - import: { - module: '@croct/plug-next/middleware', - middlewareName: 'middleware', - middlewareFactoryName: 'withCroct', - }, - }), - }), - }), - ), + proxy: createProxyCodemod('proxy'), + middleware: createProxyCodemod('middleware'), appRouterProvider: new FormatCodemod( formatter, new FileCodemod({ @@ -2177,7 +2181,7 @@ export class Cli { return this.share( this.getJavaScriptFormatter, () => new JavaScriptFormatter({ - commandExecutor: this.getAsynchronousCommandExecutor(), + commandExecutor: this.getSynchronousCommandExecutor(), workingDirectory: this.workingDirectory, packageManager: this.getNodePackageManager(), fileSystem: this.getFileSystem(), diff --git a/src/infrastructure/application/project/javaScriptFormatter.ts b/src/infrastructure/application/project/javaScriptFormatter.ts index fc04ac5c..fd11316b 100644 --- a/src/infrastructure/application/project/javaScriptFormatter.ts +++ b/src/infrastructure/application/project/javaScriptFormatter.ts @@ -2,7 +2,7 @@ import {CodeFormatter, CodeFormatterError} from '@/application/project/code/form import {FileSystem} from '@/application/fs/fileSystem'; import {Dependency, PackageManager} from '@/application/project/packageManager/packageManager'; import {WorkingDirectory} from '@/application/fs/workingDirectory/workingDirectory'; -import {CommandExecutor} from '@/application/system/process/executor'; +import {SynchronousCommandExecutor} from '@/application/system/process/executor'; import {Command} from '@/application/system/process/command'; type FormatterTool = { @@ -15,7 +15,7 @@ export type Configuration = { workingDirectory: WorkingDirectory, fileSystem: FileSystem, packageManager: PackageManager, - commandExecutor: CommandExecutor, + commandExecutor: SynchronousCommandExecutor, timeout?: number, tools: FormatterTool[], }; @@ -41,17 +41,19 @@ export class JavaScriptFormatter implements CodeFormatter { } } - private async run(command: Command): Promise { + private run(command: Command): Promise { const {commandExecutor, workingDirectory, timeout} = this.configuration; - const execution = await commandExecutor.run(command, { + const execution = commandExecutor.runSync(command, { workingDirectory: workingDirectory.get(), timeout: timeout, }); - if (await execution.wait() !== 0) { + if (execution.exitCode !== 0) { throw new CodeFormatterError('Failed to format code.'); } + + return Promise.resolve(); } private async getCommand(files: string[]): Promise { diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportArrowFunction.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportArrowFunction.ts deleted file mode 100644 index 6d29ccfc..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportArrowFunction.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default () => { - console.log('middleware'); -} diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportClass.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportClass.ts deleted file mode 100644 index 6daca39a..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportClass.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default class Middleware { - // invalid -} diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingAliasedHofCall.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/existingAliasedHofCall.ts deleted file mode 100644 index 7b27ad66..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingAliasedHofCall.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { withCroct as croctMiddleware } from "@croct/plug-next/middleware"; - -export default croctMiddleware(function () { - console.log('middleware'); -}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingAliasedMiddlewareCall.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/existingAliasedMiddlewareCall.ts deleted file mode 100644 index dc8ef92d..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingAliasedMiddlewareCall.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { middleware } from "@croct/plug-next/middleware"; - -export default middleware(function () { - console.log('middleware'); -}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingHofCall.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/existingHofCall.ts deleted file mode 100644 index f176723c..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingHofCall.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { withCroct } from "@croct/plug-next/middleware"; - -export default withCroct(function () { - console.log('middleware'); -}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingImport.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/existingImport.ts deleted file mode 100644 index 75a297ac..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingImport.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { withCroct } from "@croct/plug-next/middleware"; - -export function middleware() { - console.log('middleware'); -} - -export const config = { - matcher: '.*' -}; diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingImportAliased.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/existingImportAliased.ts deleted file mode 100644 index f74fe09c..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingImportAliased.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { withCroct as croctMiddleware } from "@croct/plug-next/middleware"; - -export function middleware() { - console.log('middleware'); -} - -export const config = { - matcher: '.*' -}; diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingMiddlewareCall.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/existingMiddlewareCall.ts deleted file mode 100644 index 7d54062f..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingMiddlewareCall.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { middleware as croctMiddleware } from "@croct/plug-next/middleware"; - -export default croctMiddleware(function () { - console.log('middleware'); -}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingMiddlewareReexport.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/existingMiddlewareReexport.ts deleted file mode 100644 index 1fd02b66..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingMiddlewareReexport.ts +++ /dev/null @@ -1 +0,0 @@ -export { middleware } from "@croct/plug-next/middleware"; diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/matcherAlias.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/matcherAlias.ts deleted file mode 100644 index 76d3f540..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/matcherAlias.ts +++ /dev/null @@ -1,7 +0,0 @@ -export function middleware() { - console.log('middleware'); -} - -export const config = { - matcher: '.*' -}; diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportArrowFunction.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportArrowFunction.ts deleted file mode 100644 index ac53e59e..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportArrowFunction.ts +++ /dev/null @@ -1 +0,0 @@ -export const middleware = () => console.log('middleware'); diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportArrowFunctionWithBody.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportArrowFunctionWithBody.ts deleted file mode 100644 index f1e23737..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportArrowFunctionWithBody.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const middleware = () => { - console.log('middleware'); -} diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportFunctionDeclaration.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportFunctionDeclaration.ts deleted file mode 100644 index e05f5457..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportFunctionDeclaration.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function middleware() { - console.log('middleware'); -} diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportFunctionExpression.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportFunctionExpression.ts deleted file mode 100644 index 25994bf0..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedExportFunctionExpression.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const middleware = function() { - console.log('middleware'); -} diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedSpecifiedExport.ts b/test/application/project/code/transformation/fixtures/nextjs-middleware/namedSpecifiedExport.ts deleted file mode 100644 index 2312e638..00000000 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/namedSpecifiedExport.ts +++ /dev/null @@ -1,9 +0,0 @@ -const middleware = function() { - console.log('middleware'); -} - -const config = { - matcher: '.*' -}; - -export { middleware, config }; diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterDefaultExport.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterDefaultExport.ts similarity index 75% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterDefaultExport.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterDefaultExport.ts index 1bb230b2..4c5c822b 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterDefaultExport.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterDefaultExport.ts @@ -1,6 +1,6 @@ import type { NextRequest } from 'next/server' -export function middleware(request: NextRequest): void { +export function proxy(request: NextRequest): void { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterNamedExport.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterNamedExport.ts similarity index 72% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterNamedExport.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterNamedExport.ts index 2a02b05e..b499be93 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterNamedExport.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterNamedExport.ts @@ -1,6 +1,6 @@ import type { NextRequest } from 'next/server' -export default function middleware(request: NextRequest): void { +export default function proxy(request: NextRequest): void { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterMiddlewareWithReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterProxyWithReference.ts similarity index 90% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterMiddlewareWithReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterProxyWithReference.ts index 6f6ab230..2963150d 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configAfterMiddlewareWithReference.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configAfterProxyWithReference.ts @@ -1,7 +1,7 @@ import type { NextRequest } from 'next/server' -// middleware -export function middleware(request: NextRequest): void { +// proxy +export function proxy(request: NextRequest): void { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configInvalidReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configInvalidReference.ts similarity index 62% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configInvalidReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configInvalidReference.ts index 1be4f0ed..41a75c18 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configInvalidReference.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configInvalidReference.ts @@ -1,6 +1,6 @@ import type { NextRequest } from 'next/server' -export default function middleware(request: NextRequest): void { +export default function proxy(request: NextRequest): void { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithArrayMatcher.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithArrayMatcher.ts similarity index 75% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configWithArrayMatcher.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configWithArrayMatcher.ts index a162f048..39eb437a 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithArrayMatcher.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithArrayMatcher.ts @@ -4,6 +4,6 @@ export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], } -export function middleware(request: NextRequest): void { +export function proxy(request: NextRequest): void { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithIndirectVariableReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithIndirectVariableReference.ts similarity index 85% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configWithIndirectVariableReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configWithIndirectVariableReference.ts index 9dbbe4c0..344aac83 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithIndirectVariableReference.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithIndirectVariableReference.ts @@ -8,6 +8,6 @@ const indirectReference = configValue; export const config = indirectReference; -export function middleware(request) { +export function proxy(request) { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithStringMatcher.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithStringMatcher.ts similarity index 76% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configWithStringMatcher.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configWithStringMatcher.ts index 1aa003f7..3f5dbd0d 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithStringMatcher.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithStringMatcher.ts @@ -2,6 +2,6 @@ export const config = { matcher: '/((?!api|_next/static|_next/image|favicon.ico).*)', } -export function middleware(request) { +export function proxy(request) { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithVariableMatcher.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithVariableMatcher.ts similarity index 79% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configWithVariableMatcher.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configWithVariableMatcher.ts index f42008db..6cbfe24f 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithVariableMatcher.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithVariableMatcher.ts @@ -4,6 +4,6 @@ export const config = { matcher: regex, } -export function middleware(request) { +export function proxy(request) { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithVariableReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithVariableReference.ts similarity index 82% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configWithVariableReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configWithVariableReference.ts index 3fa545d7..c5ad37ce 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithVariableReference.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithVariableReference.ts @@ -6,6 +6,6 @@ const configValue = { export const config = configValue; -export function middleware(request) { +export function proxy(request) { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithoutMatcher.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithoutMatcher.ts similarity index 60% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/configWithoutMatcher.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/configWithoutMatcher.ts index 75cc3c30..9b9afbdf 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/configWithoutMatcher.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/configWithoutMatcher.ts @@ -1,6 +1,6 @@ export const config = { } -export function middleware(request) { +export function proxy(request) { console.log(request.url); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportAnonymousFunction.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportAnonymousFunction.ts similarity index 50% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportAnonymousFunction.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportAnonymousFunction.ts index 745cb850..e6a07f3b 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportAnonymousFunction.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportAnonymousFunction.ts @@ -1,3 +1,3 @@ export default function () { - console.log('middleware'); + console.log('proxy'); } diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportArrowFunction.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportArrowFunction.ts new file mode 100644 index 00000000..bfa2f607 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportArrowFunction.ts @@ -0,0 +1,3 @@ +export default () => { + console.log('proxy'); +} diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportArrowFunctionReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportArrowFunctionReference.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportArrowFunctionReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportArrowFunctionReference.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportArrowFunctionWithBodyReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportArrowFunctionWithBodyReference.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportArrowFunctionWithBodyReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportArrowFunctionWithBodyReference.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportClass.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportClass.ts new file mode 100644 index 00000000..a5db8ae2 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportClass.ts @@ -0,0 +1,3 @@ +export default class Proxy { + // invalid +} diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportFunctionDeclaration.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportFunctionDeclaration.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportFunctionDeclaration.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportFunctionDeclaration.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportFunctionDeclarationReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportFunctionDeclarationReference.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportFunctionDeclarationReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportFunctionDeclarationReference.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportFunctionExpressionReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportFunctionExpressionReference.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportFunctionExpressionReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportFunctionExpressionReference.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportIndirectReference.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportIndirectReference.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/defaultExportIndirectReference.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/defaultExportIndirectReference.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/empty.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/empty.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/empty.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/empty.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/existingAliasedHofCall.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingAliasedHofCall.ts new file mode 100644 index 00000000..502b1737 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingAliasedHofCall.ts @@ -0,0 +1,5 @@ +import { withCroct as croctProxy } from "@croct/plug-next/proxy"; + +export default croctProxy(function () { + console.log('proxy'); +}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/existingAliasedProxyCall.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingAliasedProxyCall.ts new file mode 100644 index 00000000..83100491 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingAliasedProxyCall.ts @@ -0,0 +1,5 @@ +import { proxy } from "@croct/plug-next/proxy"; + +export default proxy(function () { + console.log('proxy'); +}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingConfig.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingConfig.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/existingConfig.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/existingConfig.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingConfigArrayMatcher.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingConfigArrayMatcher.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/existingConfigArrayMatcher.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/existingConfigArrayMatcher.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/existingConfigMatcher.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingConfigMatcher.ts similarity index 100% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/existingConfigMatcher.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/existingConfigMatcher.ts diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/existingHofCall.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingHofCall.ts new file mode 100644 index 00000000..a9ccf314 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingHofCall.ts @@ -0,0 +1,5 @@ +import { withCroct } from "@croct/plug-next/proxy"; + +export default withCroct(function () { + console.log('proxy'); +}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/existingImport.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingImport.ts new file mode 100644 index 00000000..7e6d4f19 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingImport.ts @@ -0,0 +1,9 @@ +import { withCroct } from "@croct/plug-next/proxy"; + +export function proxy() { + console.log('proxy'); +} + +export const config = { + matcher: '.*' +}; diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/existingImportAliased.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingImportAliased.ts new file mode 100644 index 00000000..36f08927 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingImportAliased.ts @@ -0,0 +1,9 @@ +import { withCroct as croctProxy } from "@croct/plug-next/proxy"; + +export function proxy() { + console.log('proxy'); +} + +export const config = { + matcher: '.*' +}; diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/existingProxyCall.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingProxyCall.ts new file mode 100644 index 00000000..ce508472 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingProxyCall.ts @@ -0,0 +1,5 @@ +import { proxy as croctProxy } from "@croct/plug-next/proxy"; + +export default croctProxy(function () { + console.log('proxy'); +}); diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/existingProxyReexport.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingProxyReexport.ts new file mode 100644 index 00000000..a7c089d3 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/existingProxyReexport.ts @@ -0,0 +1 @@ +export { proxy } from "@croct/plug-next/proxy"; diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/matcherAlias.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/matcherAlias.ts new file mode 100644 index 00000000..eba327e4 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/matcherAlias.ts @@ -0,0 +1,7 @@ +export function proxy() { + console.log('proxy'); +} + +export const config = { + matcher: '.*' +}; diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportArrowFunction.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportArrowFunction.ts new file mode 100644 index 00000000..bc9a6e78 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportArrowFunction.ts @@ -0,0 +1 @@ +export const proxy = () => console.log('proxy'); diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportArrowFunctionWithBody.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportArrowFunctionWithBody.ts new file mode 100644 index 00000000..3e6d1ae5 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportArrowFunctionWithBody.ts @@ -0,0 +1,3 @@ +export const proxy = () => { + console.log('proxy'); +} diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportFunctionDeclaration.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportFunctionDeclaration.ts new file mode 100644 index 00000000..45a16915 --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportFunctionDeclaration.ts @@ -0,0 +1,3 @@ +export function proxy() { + console.log('proxy'); +} diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportFunctionExpression.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportFunctionExpression.ts new file mode 100644 index 00000000..488edfdd --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedExportFunctionExpression.ts @@ -0,0 +1,3 @@ +export const proxy = function() { + console.log('proxy'); +} diff --git a/test/application/project/code/transformation/fixtures/nextjs-proxy/namedSpecifiedExport.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedSpecifiedExport.ts new file mode 100644 index 00000000..9294b98c --- /dev/null +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/namedSpecifiedExport.ts @@ -0,0 +1,9 @@ +const proxy = function() { + console.log('proxy'); +} + +const config = { + matcher: '.*' +}; + +export { proxy, config }; diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/specifiedExportWithAliases.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/specifiedExportWithAliases.ts similarity index 51% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/specifiedExportWithAliases.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/specifiedExportWithAliases.ts index cb954de7..095d9a74 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/specifiedExportWithAliases.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/specifiedExportWithAliases.ts @@ -1,8 +1,8 @@ function unrelated() { } -const _middlewareFn = function() { - console.log('middleware'); +const _proxyFn = function() { + console.log('proxy'); } const _config = { @@ -10,6 +10,6 @@ const _config = { }; export { - _middlewareFn as default, + _proxyFn as default, _config as config }; diff --git a/test/application/project/code/transformation/fixtures/nextjs-middleware/unrelatedExports.ts b/test/application/project/code/transformation/fixtures/nextjs-proxy/unrelatedExports.ts similarity index 64% rename from test/application/project/code/transformation/fixtures/nextjs-middleware/unrelatedExports.ts rename to test/application/project/code/transformation/fixtures/nextjs-proxy/unrelatedExports.ts index 24361094..b9794271 100644 --- a/test/application/project/code/transformation/fixtures/nextjs-middleware/unrelatedExports.ts +++ b/test/application/project/code/transformation/fixtures/nextjs-proxy/unrelatedExports.ts @@ -5,5 +5,5 @@ export default () => { } -export function middleware() { +export function proxy() { } diff --git a/test/application/project/code/transformation/javascript/__snapshots__/nextJsMiddlewareCodemod.test.ts.snap b/test/application/project/code/transformation/javascript/__snapshots__/nextJsMiddlewareCodemod.test.ts.snap deleted file mode 100644 index 958f392d..00000000 --- a/test/application/project/code/transformation/javascript/__snapshots__/nextJsMiddlewareCodemod.test.ts.snap +++ /dev/null @@ -1,577 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NextJsMiddlewareCodemod should correctly transform configAfterDefaultExport.ts: configAfterDefaultExport.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -import type { NextRequest } from 'next/server' - -export const config = { - matcher: [ - '/((?!api|_next/static|_next/image|favicon.ico).*)', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export const middleware = withCroct({ - matcher: config.matcher, - - next: function(request: NextRequest) { - console.log(request.url); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configAfterMiddlewareWithReference.ts: configAfterMiddlewareWithReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -import type { NextRequest } from 'next/server' - -// pattern -const PATTERN = '/((?!api|_next/static|_next/image|favicon.ico).*)'; - -// matcher -class Matcher { - static readonly PATTERN = PATTERN; -} - -// getMatcher -function getMatcher() { - return Matcher.PATTERN; -} - -// currentMatcher -const currentMatcher = getMatcher(); - -// currentConfig -const currentConfig = { - matcher: [ - ...(Array.isArray(currentMatcher) ? currentMatcher : [currentMatcher]), - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export const middleware = withCroct({ - matcher: currentConfig.matcher, - - next: function(request: NextRequest) { - console.log(request.url); - } -}); - -function unrelated() { -} - -// Non-global scope -{ - // Different scope, should not be considered - const PATTERN = null; - - function getMatcher() { - } - - class Matcher { - } -} - -// config -export const config = currentConfig; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configAfterNamedExport.ts: configAfterNamedExport.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -import type { NextRequest } from 'next/server' - -export const config = { - matcher: [ - '/((?!api|_next/static|_next/image|favicon.ico).*)', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export default withCroct({ - matcher: config.matcher, - - next: function middleware(request: NextRequest) { - console.log(request.url); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configInvalidReference.ts: configInvalidReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -import type { NextRequest } from 'next/server' - -export default withCroct(function middleware(request: NextRequest) { - console.log(request.url); -}); - -export const config = bar; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configWithArrayMatcher.ts: configWithArrayMatcher.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -import type { NextRequest } from 'next/server' - -export const config = { - matcher: [ - '/((?!api|_next/static|_next/image|favicon.ico).*)', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export const middleware = withCroct({ - matcher: config.matcher, - - next: function(request: NextRequest) { - console.log(request.url); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configWithIndirectVariableReference.ts: configWithIndirectVariableReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -const regex = '/((?!api|_next/static|_next/image|favicon.ico).*)'; - -const configValue = { - matcher: [ - ...(Array.isArray(regex) ? regex : [regex]), - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -const indirectReference = configValue; -export const config = indirectReference; - -export const middleware = withCroct({ - matcher: configValue.matcher, - - next: function(request) { - console.log(request.url); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configWithStringMatcher.ts: configWithStringMatcher.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const config = { - matcher: [ - '/((?!api|_next/static|_next/image|favicon.ico).*)', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export const middleware = withCroct({ - matcher: config.matcher, - - next: function(request) { - console.log(request.url); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configWithVariableMatcher.ts: configWithVariableMatcher.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -const regex = '/((?!api|_next/static|_next/image|favicon.ico).*)'; - -export const config = { - matcher: [ - ...(Array.isArray(regex) ? regex : [regex]), - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export const middleware = withCroct({ - matcher: config.matcher, - - next: function(request) { - console.log(request.url); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configWithVariableReference.ts: configWithVariableReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -const regex = '/((?!api|_next/static|_next/image|favicon.ico).*)'; - -const configValue = { - matcher: [ - ...(Array.isArray(regex) ? regex : [regex]), - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export const config = configValue; - -export const middleware = withCroct({ - matcher: configValue.matcher, - - next: function(request) { - console.log(request.url); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform configWithoutMatcher.ts: configWithoutMatcher.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const config = { -} - -export const middleware = withCroct(function(request) { - console.log(request.url); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportAnonymousFunction.ts: defaultExportAnonymousFunction.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export default withCroct(function() { - console.log('middleware'); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportArrowFunction.ts: defaultExportArrowFunction.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export default withCroct(() => { - console.log('middleware'); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportArrowFunctionReference.ts: defaultExportArrowFunctionReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -const anything = withCroct((request) => console.log(request.url)); -export default anything; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportArrowFunctionWithBodyReference.ts: defaultExportArrowFunctionWithBodyReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -const anything = withCroct((request) => { - console.log(request.url); -}) - -export default anything; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportClass.ts: defaultExportClass.ts 1`] = ` -"export default class Middleware { - // invalid -} - -export { middleware } from "@croct/plug-next/middleware"; - -export const config = { - matcher: "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" -}; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportFunctionDeclaration.ts: defaultExportFunctionDeclaration.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export default withCroct(function anything(request) { - console.log(request.url); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportFunctionDeclarationReference.ts: defaultExportFunctionDeclarationReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -const anything = withCroct(function(request) { - console.log(request.url); -}); - -export default anything; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportFunctionExpressionReference.ts: defaultExportFunctionExpressionReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -const anything = withCroct(function (request) { - console.log(request.url); -}) - -export default anything; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform defaultExportIndirectReference.ts: defaultExportIndirectReference.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -const anything = function (request) { - console.log(request.url); -} - -const something = withCroct(anything); -export default something; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform empty.ts: empty.ts 1`] = ` -"export { middleware } from "@croct/plug-next/middleware"; - -export const config = { - matcher: "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" -};" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingAliasedHofCall.ts: existingAliasedHofCall.ts 1`] = ` -"import { withCroct as croctMiddleware } from "@croct/plug-next/middleware"; - -export default croctMiddleware(function () { - console.log('middleware'); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingAliasedMiddlewareCall.ts: existingAliasedMiddlewareCall.ts 1`] = ` -"import { middleware } from "@croct/plug-next/middleware"; - -export default middleware(function () { - console.log('middleware'); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingConfig.ts: existingConfig.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const config = { - matcher: [ - '/((?!api|_next/static|_next/image|favicon.ico).*)', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ], -} - -export default withCroct({ - matcher: config.matcher -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingConfigArrayMatcher.ts: existingConfigArrayMatcher.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const config = { - matcher: ['/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)'], -} - -export default withCroct({ - matcher: config.matcher -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingConfigMatcher.ts: existingConfigMatcher.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const config = { - matcher: '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)', -} - -export default withCroct({ - matcher: config.matcher -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingHofCall.ts: existingHofCall.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export default withCroct(function () { - console.log('middleware'); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingImport.ts: existingImport.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const config = { - matcher: [ - '.*', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ] -}; - -export const middleware = withCroct({ - matcher: config.matcher, - - next: function() { - console.log('middleware'); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingImportAliased.ts: existingImportAliased.ts 1`] = ` -"import { withCroct as croctMiddleware } from "@croct/plug-next/middleware"; - -export const config = { - matcher: [ - '.*', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ] -}; - -export const middleware = croctMiddleware({ - matcher: config.matcher, - - next: function() { - console.log('middleware'); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingMiddlewareCall.ts: existingMiddlewareCall.ts 1`] = ` -"import { middleware as croctMiddleware } from "@croct/plug-next/middleware"; - -export default croctMiddleware(function () { - console.log('middleware'); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform existingMiddlewareReexport.ts: existingMiddlewareReexport.ts 1`] = ` -"export { middleware } from "@croct/plug-next/middleware"; - -export const config = { - matcher: "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" -}; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform matcherAlias.ts: matcherAlias.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const config = { - matcher: [ - '.*', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ] -}; - -export const middleware = withCroct({ - matcher: config.matcher, - - next: function() { - console.log('middleware'); - } -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform namedExportArrowFunction.ts: namedExportArrowFunction.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; -export const middleware = withCroct(() => console.log('middleware')); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform namedExportArrowFunctionWithBody.ts: namedExportArrowFunctionWithBody.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const middleware = withCroct(() => { - console.log('middleware'); -}) -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform namedExportFunctionDeclaration.ts: namedExportFunctionDeclaration.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const middleware = withCroct(function() { - console.log('middleware'); -}); -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform namedExportFunctionExpression.ts: namedExportFunctionExpression.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export const middleware = withCroct(function() { - console.log('middleware'); -}) -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform namedSpecifiedExport.ts: namedSpecifiedExport.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -const config = { - matcher: [ - '.*', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ] -}; - -const middleware = withCroct({ - matcher: config.matcher, - - next: function() { - console.log('middleware'); - } -}) - -export { middleware, config }; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform specifiedExportWithAliases.ts: specifiedExportWithAliases.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -function unrelated() { -} - -const _config = { - matcher: [ - '.*', - "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" - ] -}; - -const _middlewareFn = withCroct({ - matcher: _config.matcher, - - next: function() { - console.log('middleware'); - } -}) - -export { - _middlewareFn as default, - _config as config -}; -" -`; - -exports[`NextJsMiddlewareCodemod should correctly transform unrelatedExports.ts: unrelatedExports.ts 1`] = ` -"import { withCroct } from "@croct/plug-next/middleware"; - -export function foo() { -} - -export default withCroct(() => { - -}); - -export function middleware() { -} -" -`; diff --git a/test/application/project/code/transformation/javascript/__snapshots__/nextJsProxyCodemod.test.ts.snap b/test/application/project/code/transformation/javascript/__snapshots__/nextJsProxyCodemod.test.ts.snap new file mode 100644 index 00000000..ccb35262 --- /dev/null +++ b/test/application/project/code/transformation/javascript/__snapshots__/nextJsProxyCodemod.test.ts.snap @@ -0,0 +1,577 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`NextJsProxyCodemod should correctly transform configAfterDefaultExport.ts: configAfterDefaultExport.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +import type { NextRequest } from 'next/server' + +export const config = { + matcher: [ + '/((?!api|_next/static|_next/image|favicon.ico).*)', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export const proxy = withCroct({ + matcher: config.matcher, + + next: function(request: NextRequest) { + console.log(request.url); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform configAfterNamedExport.ts: configAfterNamedExport.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +import type { NextRequest } from 'next/server' + +export const config = { + matcher: [ + '/((?!api|_next/static|_next/image|favicon.ico).*)', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export default withCroct({ + matcher: config.matcher, + + next: function proxy(request: NextRequest) { + console.log(request.url); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform configAfterProxyWithReference.ts: configAfterProxyWithReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +import type { NextRequest } from 'next/server' + +// pattern +const PATTERN = '/((?!api|_next/static|_next/image|favicon.ico).*)'; + +// matcher +class Matcher { + static readonly PATTERN = PATTERN; +} + +// getMatcher +function getMatcher() { + return Matcher.PATTERN; +} + +// currentMatcher +const currentMatcher = getMatcher(); + +// currentConfig +const currentConfig = { + matcher: [ + ...(Array.isArray(currentMatcher) ? currentMatcher : [currentMatcher]), + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export const proxy = withCroct({ + matcher: currentConfig.matcher, + + next: function(request: NextRequest) { + console.log(request.url); + } +}); + +function unrelated() { +} + +// Non-global scope +{ + // Different scope, should not be considered + const PATTERN = null; + + function getMatcher() { + } + + class Matcher { + } +} + +// config +export const config = currentConfig; +" +`; + +exports[`NextJsProxyCodemod should correctly transform configInvalidReference.ts: configInvalidReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +import type { NextRequest } from 'next/server' + +export default withCroct(function proxy(request: NextRequest) { + console.log(request.url); +}); + +export const config = bar; +" +`; + +exports[`NextJsProxyCodemod should correctly transform configWithArrayMatcher.ts: configWithArrayMatcher.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +import type { NextRequest } from 'next/server' + +export const config = { + matcher: [ + '/((?!api|_next/static|_next/image|favicon.ico).*)', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export const proxy = withCroct({ + matcher: config.matcher, + + next: function(request: NextRequest) { + console.log(request.url); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform configWithIndirectVariableReference.ts: configWithIndirectVariableReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +const regex = '/((?!api|_next/static|_next/image|favicon.ico).*)'; + +const configValue = { + matcher: [ + ...(Array.isArray(regex) ? regex : [regex]), + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +const indirectReference = configValue; +export const config = indirectReference; + +export const proxy = withCroct({ + matcher: configValue.matcher, + + next: function(request) { + console.log(request.url); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform configWithStringMatcher.ts: configWithStringMatcher.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const config = { + matcher: [ + '/((?!api|_next/static|_next/image|favicon.ico).*)', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export const proxy = withCroct({ + matcher: config.matcher, + + next: function(request) { + console.log(request.url); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform configWithVariableMatcher.ts: configWithVariableMatcher.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +const regex = '/((?!api|_next/static|_next/image|favicon.ico).*)'; + +export const config = { + matcher: [ + ...(Array.isArray(regex) ? regex : [regex]), + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export const proxy = withCroct({ + matcher: config.matcher, + + next: function(request) { + console.log(request.url); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform configWithVariableReference.ts: configWithVariableReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +const regex = '/((?!api|_next/static|_next/image|favicon.ico).*)'; + +const configValue = { + matcher: [ + ...(Array.isArray(regex) ? regex : [regex]), + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export const config = configValue; + +export const proxy = withCroct({ + matcher: configValue.matcher, + + next: function(request) { + console.log(request.url); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform configWithoutMatcher.ts: configWithoutMatcher.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const config = { +} + +export const proxy = withCroct(function(request) { + console.log(request.url); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportAnonymousFunction.ts: defaultExportAnonymousFunction.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export default withCroct(function() { + console.log('proxy'); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportArrowFunction.ts: defaultExportArrowFunction.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export default withCroct(() => { + console.log('proxy'); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportArrowFunctionReference.ts: defaultExportArrowFunctionReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +const anything = withCroct((request) => console.log(request.url)); +export default anything; +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportArrowFunctionWithBodyReference.ts: defaultExportArrowFunctionWithBodyReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +const anything = withCroct((request) => { + console.log(request.url); +}) + +export default anything; +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportClass.ts: defaultExportClass.ts 1`] = ` +"export default class Proxy { + // invalid +} + +export { proxy } from "@croct/plug-next/proxy"; + +export const config = { + matcher: "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" +}; +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportFunctionDeclaration.ts: defaultExportFunctionDeclaration.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export default withCroct(function anything(request) { + console.log(request.url); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportFunctionDeclarationReference.ts: defaultExportFunctionDeclarationReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +const anything = withCroct(function(request) { + console.log(request.url); +}); + +export default anything; +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportFunctionExpressionReference.ts: defaultExportFunctionExpressionReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +const anything = withCroct(function (request) { + console.log(request.url); +}) + +export default anything; +" +`; + +exports[`NextJsProxyCodemod should correctly transform defaultExportIndirectReference.ts: defaultExportIndirectReference.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +const anything = function (request) { + console.log(request.url); +} + +const something = withCroct(anything); +export default something; +" +`; + +exports[`NextJsProxyCodemod should correctly transform empty.ts: empty.ts 1`] = ` +"export { proxy } from "@croct/plug-next/proxy"; + +export const config = { + matcher: "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" +};" +`; + +exports[`NextJsProxyCodemod should correctly transform existingAliasedHofCall.ts: existingAliasedHofCall.ts 1`] = ` +"import { withCroct as croctProxy } from "@croct/plug-next/proxy"; + +export default croctProxy(function () { + console.log('proxy'); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingAliasedProxyCall.ts: existingAliasedProxyCall.ts 1`] = ` +"import { proxy } from "@croct/plug-next/proxy"; + +export default proxy(function () { + console.log('proxy'); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingConfig.ts: existingConfig.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const config = { + matcher: [ + '/((?!api|_next/static|_next/image|favicon.ico).*)', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ], +} + +export default withCroct({ + matcher: config.matcher +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingConfigArrayMatcher.ts: existingConfigArrayMatcher.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const config = { + matcher: ['/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)'], +} + +export default withCroct({ + matcher: config.matcher +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingConfigMatcher.ts: existingConfigMatcher.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const config = { + matcher: '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)', +} + +export default withCroct({ + matcher: config.matcher +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingHofCall.ts: existingHofCall.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export default withCroct(function () { + console.log('proxy'); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingImport.ts: existingImport.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const config = { + matcher: [ + '.*', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ] +}; + +export const proxy = withCroct({ + matcher: config.matcher, + + next: function() { + console.log('proxy'); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingImportAliased.ts: existingImportAliased.ts 1`] = ` +"import { withCroct as croctProxy } from "@croct/plug-next/proxy"; + +export const config = { + matcher: [ + '.*', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ] +}; + +export const proxy = croctProxy({ + matcher: config.matcher, + + next: function() { + console.log('proxy'); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingProxyCall.ts: existingProxyCall.ts 1`] = ` +"import { proxy as croctProxy } from "@croct/plug-next/proxy"; + +export default croctProxy(function () { + console.log('proxy'); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform existingProxyReexport.ts: existingProxyReexport.ts 1`] = ` +"export { proxy } from "@croct/plug-next/proxy"; + +export const config = { + matcher: "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" +}; +" +`; + +exports[`NextJsProxyCodemod should correctly transform matcherAlias.ts: matcherAlias.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const config = { + matcher: [ + '.*', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ] +}; + +export const proxy = withCroct({ + matcher: config.matcher, + + next: function() { + console.log('proxy'); + } +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform namedExportArrowFunction.ts: namedExportArrowFunction.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; +export const proxy = withCroct(() => console.log('proxy')); +" +`; + +exports[`NextJsProxyCodemod should correctly transform namedExportArrowFunctionWithBody.ts: namedExportArrowFunctionWithBody.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const proxy = withCroct(() => { + console.log('proxy'); +}) +" +`; + +exports[`NextJsProxyCodemod should correctly transform namedExportFunctionDeclaration.ts: namedExportFunctionDeclaration.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const proxy = withCroct(function() { + console.log('proxy'); +}); +" +`; + +exports[`NextJsProxyCodemod should correctly transform namedExportFunctionExpression.ts: namedExportFunctionExpression.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export const proxy = withCroct(function() { + console.log('proxy'); +}) +" +`; + +exports[`NextJsProxyCodemod should correctly transform namedSpecifiedExport.ts: namedSpecifiedExport.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +const config = { + matcher: [ + '.*', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ] +}; + +const proxy = withCroct({ + matcher: config.matcher, + + next: function() { + console.log('proxy'); + } +}) + +export { proxy, config }; +" +`; + +exports[`NextJsProxyCodemod should correctly transform specifiedExportWithAliases.ts: specifiedExportWithAliases.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +function unrelated() { +} + +const _config = { + matcher: [ + '.*', + "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)" + ] +}; + +const _proxyFn = withCroct({ + matcher: _config.matcher, + + next: function() { + console.log('proxy'); + } +}) + +export { + _proxyFn as default, + _config as config +}; +" +`; + +exports[`NextJsProxyCodemod should correctly transform unrelatedExports.ts: unrelatedExports.ts 1`] = ` +"import { withCroct } from "@croct/plug-next/proxy"; + +export function foo() { +} + +export default withCroct(() => { + +}); + +export function proxy() { +} +" +`; diff --git a/test/application/project/code/transformation/javascript/nextJsMiddlewareCodemod.test.ts b/test/application/project/code/transformation/javascript/nextJsProxyCodemod.test.ts similarity index 64% rename from test/application/project/code/transformation/javascript/nextJsMiddlewareCodemod.test.ts rename to test/application/project/code/transformation/javascript/nextJsProxyCodemod.test.ts index 4a5fe1dc..f8e185bd 100644 --- a/test/application/project/code/transformation/javascript/nextJsMiddlewareCodemod.test.ts +++ b/test/application/project/code/transformation/javascript/nextJsProxyCodemod.test.ts @@ -1,23 +1,24 @@ import {resolve} from 'path'; import { - MiddlewareConfiguration, - NextJsMiddlewareCodemod, -} from '@/application/project/code/transformation/javascript/nextJsMiddlewareCodemod'; + ProxyConfiguration, + NextJsProxyCodemod, +} from '@/application/project/code/transformation/javascript/nextJsProxyCodemod'; import {loadFixtures} from '../fixtures'; import {JavaScriptCodemod} from '@/application/project/code/transformation/javascript/javaScriptCodemod'; -describe('NextJsMiddlewareCodemod', () => { - const defaultOptions: MiddlewareConfiguration = { +describe('NextJsProxyCodemod', () => { + const defaultOptions: ProxyConfiguration = { matcherPattern: '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)', + exportName: 'proxy', import: { - module: '@croct/plug-next/middleware', - middlewareFactoryName: 'withCroct', - middlewareName: 'middleware', + module: '@croct/plug-next/proxy', + proxyFactoryName: 'withCroct', + proxyName: 'proxy', }, }; - const scenarios = loadFixtures( - resolve(__dirname, '../fixtures/nextjs-middleware'), + const scenarios = loadFixtures( + resolve(__dirname, '../fixtures/nextjs-proxy'), defaultOptions, { 'matcherAlias.ts': { @@ -31,7 +32,7 @@ describe('NextJsMiddlewareCodemod', () => { it.each(scenarios)('should correctly transform $name', async ({name, fixture, options}) => { const transformer = new JavaScriptCodemod({ languages: ['typescript'], - codemod: new NextJsMiddlewareCodemod(options), + codemod: new NextJsProxyCodemod(options), }); const output = await transformer.apply(fixture);