From 64888d3fa87f824b61c0832bf33cce5f2b3962fe Mon Sep 17 00:00:00 2001 From: Christian Capeans Date: Fri, 19 Jan 2024 11:23:52 +0100 Subject: [PATCH] chore: refactor codemod for better readability --- .../s3-keys-wrapped-in-credentials.code.ts | 156 ------------ .../s3-keys-wrapped-in-credentials.code.ts | 240 +++++++++++------- 2 files changed, 142 insertions(+), 254 deletions(-) delete mode 100644 packages/utils/upgrade/resources/codemods/4.16.5/s3-keys-wrapped-in-credentials.code.ts diff --git a/packages/utils/upgrade/resources/codemods/4.16.5/s3-keys-wrapped-in-credentials.code.ts b/packages/utils/upgrade/resources/codemods/4.16.5/s3-keys-wrapped-in-credentials.code.ts deleted file mode 100644 index 59ddea0e57..0000000000 --- a/packages/utils/upgrade/resources/codemods/4.16.5/s3-keys-wrapped-in-credentials.code.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { Transform, ASTPath, Property, ArrowFunctionExpression } from 'jscodeshift'; -import path from 'node:path'; - -/** - * This codemod only affects users that are using the `aws-s3` provider. - * It will wrap the `accessKeyId` and `secretAccessKey` properties inside a `credentials` object. - */ -const transform: Transform = (file, api) => { - // Check if the current file is 'config/plugins.js' - const cwd = process.cwd(); - const jsPluginsPath = path.join(cwd, 'config/plugins.js'); - const tsPluginsPath = path.join(cwd, 'config/plugins.ts'); - if (file.path !== jsPluginsPath && file.path !== tsPluginsPath) { - return file.source; - } - - const { j } = api; - const root = j(file.source); - - root - .find(j.ArrowFunctionExpression) - .forEach((arrowFunctionPath: ASTPath) => { - const body = arrowFunctionPath.node.body; - - if (j.ObjectExpression.check(body)) { - const uploadProperty = body.properties.find( - (prop) => - j.Property.check(prop) && j.Identifier.check(prop.key) && prop.key.name === 'upload' - ); - - if (j.Property.check(uploadProperty) && j.ObjectExpression.check(uploadProperty.value)) { - const configProperty = uploadProperty.value.properties.find( - (prop) => - j.Property.check(prop) && j.Identifier.check(prop.key) && prop.key.name === 'config' - ); - if (j.Property.check(configProperty) && j.ObjectExpression.check(configProperty.value)) { - const providerProperty = configProperty.value.properties.find( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name === 'provider' && - j.Literal.check(prop.value) && - prop.value.value === 'aws-s3' - ); - - if (providerProperty) { - const providerOptions = configProperty.value.properties.find( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name === 'providerOptions' - ); - - if ( - j.Property.check(providerOptions) && - j.ObjectExpression.check(providerOptions.value) - ) { - let accessKeyId: Property | undefined; - let secretAccessKey: Property | undefined; - - // Check for accessKeyId and secretAccessKey directly under providerOptions - const directAccessKeyId = providerOptions.value.properties.find( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name === 'accessKeyId' - ) as Property; - const directSecretAccessKey = providerOptions.value.properties.find( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name === 'secretAccessKey' - ) as Property; - - let s3Options = providerOptions.value.properties.find( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name === 's3Options' - ); - - if (!s3Options) { - // Create s3Options if it doesn't exist - s3Options = j.property('init', j.identifier('s3Options'), j.objectExpression([])); - providerOptions.value.properties.push(s3Options); - } - - if (directAccessKeyId && directSecretAccessKey) { - accessKeyId = directAccessKeyId; - secretAccessKey = directSecretAccessKey; - - // Remove these properties from providerOptions - providerOptions.value.properties = providerOptions.value.properties.filter( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name !== 'accessKeyId' && - prop.key.name !== 'secretAccessKey' - ); - } else if ( - j.Property.check(s3Options) && - j.ObjectExpression.check(s3Options.value) - ) { - // Look inside s3Options - accessKeyId = s3Options.value.properties.find( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name === 'accessKeyId' - ) as Property; - - secretAccessKey = s3Options.value.properties.find( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name === 'secretAccessKey' - ) as Property; - } - - if ( - accessKeyId && - secretAccessKey && - j.Property.check(s3Options) && - j.ObjectExpression.check(s3Options.value) - ) { - // Create the credentials object - const credentials = j.objectExpression([ - j.property('init', j.identifier('accessKeyId'), accessKeyId.value), - j.property('init', j.identifier('secretAccessKey'), secretAccessKey.value), - ]); - - // Remove the old properties from s3Options - s3Options.value.properties = s3Options.value.properties.filter( - (prop) => - j.Property.check(prop) && - j.Identifier.check(prop.key) && - prop.key.name !== 'accessKeyId' && - prop.key.name !== 'secretAccessKey' - ); - - // Add the new credentials object to s3Options - s3Options.value.properties.push( - j.property('init', j.identifier('credentials'), credentials) - ); - } - } - } - } - } - } - }); - - return root.toSource(); -}; - -export default transform; diff --git a/packages/utils/upgrade/resources/codemods/5.0.0/s3-keys-wrapped-in-credentials.code.ts b/packages/utils/upgrade/resources/codemods/5.0.0/s3-keys-wrapped-in-credentials.code.ts index 823f7cbfa1..a0826687a2 100644 --- a/packages/utils/upgrade/resources/codemods/5.0.0/s3-keys-wrapped-in-credentials.code.ts +++ b/packages/utils/upgrade/resources/codemods/5.0.0/s3-keys-wrapped-in-credentials.code.ts @@ -1,6 +1,49 @@ -import { Transform, ASTPath, Property } from 'jscodeshift'; +import core, { + Transform, + ASTPath, + Property, + ArrowFunctionExpression, + ObjectExpression, +} from 'jscodeshift'; import path from 'node:path'; +const findUploadPropertyInBody = (j: core.JSCodeshift, body: ObjectExpression) => { + return body.properties.find( + (prop: any) => + j.Property.check(prop) && j.Identifier.check(prop.key) && prop.key.name === 'upload' + ); +}; + +const findConfigInUpload = (j: core.JSCodeshift, upload: ObjectExpression) => { + return upload.properties.find( + (prop) => j.Property.check(prop) && j.Identifier.check(prop.key) && prop.key.name === 'config' + ); +}; + +const getProviderProperty = (j: core.JSCodeshift, config: ObjectExpression) => { + return config.properties.find( + (prop) => + j.Property.check(prop) && + j.Identifier.check(prop.key) && + prop.key.name === 'provider' && + j.Literal.check(prop.value) && + prop.value.value === 'aws-s3' + ); +}; + +const getProviderOptions = (j: core.JSCodeshift, config: ObjectExpression) => { + return config.properties.find( + (prop) => + j.Property.check(prop) && j.Identifier.check(prop.key) && prop.key.name === 'providerOptions' + ); +}; + +const getPropertyByKeyName = (j: core.JSCodeshift, object: ObjectExpression, keyName: string) => { + return object.properties.find( + (prop) => j.Property.check(prop) && j.Identifier.check(prop.key) && prop.key.name === keyName + ) as Property; +}; + /** * This codemod only affects users that are using the `aws-s3` provider. * It will wrap the `accessKeyId` and `secretAccessKey` properties inside a `credentials` object. @@ -8,116 +51,117 @@ import path from 'node:path'; const transform: Transform = (file, api) => { // Check if the current file is 'config/plugins.js' const cwd = process.cwd(); - const pluginsPath = path.join(cwd, 'config/plugins.js'); + const jsPluginsPath = path.join(cwd, 'config/plugins.js'); + const tsPluginsPath = path.join(cwd, 'config/plugins.ts'); - if (file.path !== pluginsPath) { + if (file.path !== jsPluginsPath && file.path !== tsPluginsPath) { return file.source; } const { j } = api; const root = j(file.source); - root.find(j.ArrowFunctionExpression).forEach((arrowFunctionPath: ASTPath) => { - const body = arrowFunctionPath.node.body; + root + .find(j.ArrowFunctionExpression) + .forEach((arrowFunctionPath: ASTPath) => { + const body = arrowFunctionPath.node.body; - if (body.type === 'ObjectExpression') { - const uploadProperty = body.properties.find( - (prop: Property) => prop.key.type === 'Identifier' && prop.key.name === 'upload' + // Check that the body of the arrow function is an object + if (!j.ObjectExpression.check(body)) { + return file.source; + } + + const uploadProperty = findUploadPropertyInBody(j, body); + + // Check that we found an upload property and that it is an object + if (!j.Property.check(uploadProperty) || !j.ObjectExpression.check(uploadProperty.value)) { + return file.source; + } + + const configProperty = findConfigInUpload(j, uploadProperty.value); + + if (!j.Property.check(configProperty) || !j.ObjectExpression.check(configProperty.value)) { + return file.source; + } + + const providerProperty = getProviderProperty(j, configProperty.value); + + // If there is not a provider property or it is not 'aws-s3', return the source + if (!providerProperty) { + return file.source; + } + + const providerOptions = getProviderOptions(j, configProperty.value); + + if (!j.Property.check(providerOptions) || !j.ObjectExpression.check(providerOptions.value)) { + return file.source; + } + + let accessKeyId: Property | undefined; + let secretAccessKey: Property | undefined; + + // Check for accessKeyId and secretAccessKey directly under providerOptions + const directAccessKeyId = getPropertyByKeyName(j, providerOptions.value, 'accessKeyId'); + + const directSecretAccessKey = getPropertyByKeyName( + j, + providerOptions.value, + 'secretAccessKey' ); - if (uploadProperty && uploadProperty.value.type === 'ObjectExpression') { - const configProperty = uploadProperty.value.properties.find( - (prop: Property) => prop.key.type === 'Identifier' && prop.key.name === 'config' + let s3Options = getPropertyByKeyName(j, providerOptions.value, 's3Options'); + + if (!s3Options) { + // Create s3Options if it doesn't exist + s3Options = j.property('init', j.identifier('s3Options'), j.objectExpression([])); + providerOptions.value.properties.push(s3Options); + } + + if (directAccessKeyId && directSecretAccessKey) { + accessKeyId = directAccessKeyId; + secretAccessKey = directSecretAccessKey; + + // Remove these properties from providerOptions + providerOptions.value.properties = providerOptions.value.properties.filter( + (prop) => + j.Property.check(prop) && + j.Identifier.check(prop.key) && + prop.key.name !== 'accessKeyId' && + prop.key.name !== 'secretAccessKey' + ); + } else if (j.Property.check(s3Options) && j.ObjectExpression.check(s3Options.value)) { + // Look inside s3Options + accessKeyId = getPropertyByKeyName(j, s3Options.value, 'accessKeyId'); + secretAccessKey = getPropertyByKeyName(j, s3Options.value, 'secretAccessKey'); + } + + if ( + accessKeyId && + secretAccessKey && + j.Property.check(s3Options) && + j.ObjectExpression.check(s3Options.value) + ) { + // Create the credentials object + const credentials = j.objectExpression([ + j.property('init', j.identifier('accessKeyId'), accessKeyId.value), + j.property('init', j.identifier('secretAccessKey'), secretAccessKey.value), + ]); + + // Remove the old properties from s3Options + s3Options.value.properties = s3Options.value.properties.filter( + (prop) => + j.Property.check(prop) && + j.Identifier.check(prop.key) && + prop.key.name !== 'accessKeyId' && + prop.key.name !== 'secretAccessKey' ); - if (configProperty && configProperty.value.type === 'ObjectExpression') { - const providerProperty = configProperty.value.properties.find( - (prop: Property) => - prop.key.type === 'Identifier' && - prop.key.name === 'provider' && - prop.value.type === 'Literal' && - prop.value.value === 'aws-s3' - ); - - if (providerProperty) { - const providerOptions = configProperty.value.properties.find( - (prop: Property) => - prop.key.type === 'Identifier' && prop.key.name === 'providerOptions' - ); - - if (providerOptions && providerOptions.value.type === 'ObjectExpression') { - let accessKeyId: Property | undefined; - let secretAccessKey: Property | undefined; - - // Check for accessKeyId and secretAccessKey directly under providerOptions - const directAccessKeyId = providerOptions.value.properties.find( - (prop: Property) => - prop.key.type === 'Identifier' && prop.key.name === 'accessKeyId' - ); - const directSecretAccessKey = providerOptions.value.properties.find( - (prop: Property) => - prop.key.type === 'Identifier' && prop.key.name === 'secretAccessKey' - ); - - let s3Options = providerOptions.value.properties.find( - (prop: Property) => prop.key.type === 'Identifier' && prop.key.name === 's3Options' - ); - - if (!s3Options) { - // Create s3Options if it doesn't exist - s3Options = j.property('init', j.identifier('s3Options'), j.objectExpression([])); - providerOptions.value.properties.push(s3Options); - } - - if (directAccessKeyId && directSecretAccessKey) { - accessKeyId = directAccessKeyId; - secretAccessKey = directSecretAccessKey; - - // Remove these properties from providerOptions - providerOptions.value.properties = providerOptions.value.properties.filter( - (prop: Property) => - prop.key.type === 'Identifier' && - prop.key.name !== 'accessKeyId' && - prop.key.name !== 'secretAccessKey' - ); - } else if (s3Options.value.type === 'ObjectExpression') { - // Look inside s3Options - accessKeyId = s3Options.value.properties.find( - (prop: Property) => - prop.key.type === 'Identifier' && prop.key.name === 'accessKeyId' - ); - secretAccessKey = s3Options.value.properties.find( - (prop: Property) => - prop.key.type === 'Identifier' && prop.key.name === 'secretAccessKey' - ); - } - - if (accessKeyId && secretAccessKey && s3Options.value.type === 'ObjectExpression') { - // Create the credentials object - const credentials = j.objectExpression([ - j.property('init', j.identifier('accessKeyId'), accessKeyId.value), - j.property('init', j.identifier('secretAccessKey'), secretAccessKey.value), - ]); - - // Remove the old properties from s3Options - s3Options.value.properties = s3Options.value.properties.filter( - (prop: Property) => - prop.key.type === 'Identifier' && - prop.key.name !== 'accessKeyId' && - prop.key.name !== 'secretAccessKey' - ); - - // Add the new credentials object to s3Options - s3Options.value.properties.push( - j.property('init', j.identifier('credentials'), credentials) - ); - } - } - } - } + // Add the new credentials object to s3Options + s3Options.value.properties.push( + j.property('init', j.identifier('credentials'), credentials) + ); } - } - }); + }); return root.toSource(); };