From 751b467b2d64bd18d538110fd1031c6f2626d30b Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Fri, 22 Apr 2022 08:51:01 -0700 Subject: [PATCH 1/2] Allow transforming the title --- src/__tests__/index.js | 33 +++++++++++++++++++++++++++++++++ src/index.js | 12 +++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/__tests__/index.js b/src/__tests__/index.js index 3b2d967..b67f7b0 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -143,4 +143,37 @@ tester({ babelOptions: { plugins: ["@babel/plugin-syntax-jsx"], } +}); + +tester({ + plugin, + tests: [ + { + title: "Default export object with title and ifTitleFound: transform", + code: outdent` + import React from 'react'; + import { Component } from './index'; + export default { + title: "existing" + }; + export const Default = () => ; + `, + output: outdent` + import React from 'react'; + import { Component } from './index'; + export default { + title: "bar" + }; + export const Default = () => ; + ` + } + ], + pluginOptions: { + title: 'bar', + toTitle: (state) => state.opts.title, + ifTitleFound: 'transform' + }, + babelOptions: { + plugins: ["@babel/plugin-syntax-jsx"], + } }); \ No newline at end of file diff --git a/src/index.js b/src/index.js index 7350dc3..1d60128 100644 --- a/src/index.js +++ b/src/index.js @@ -2,13 +2,19 @@ const TITLE_KEY = 'title'; const fixObjectDefaultExport = (path, t, title, ifTitleFound) => { if (path.node.declaration.properties) { - const titleProperty = path.node.declaration.properties.find(node => + const newTitleNode = t.objectProperty(t.identifier(TITLE_KEY), t.stringLiteral(title)) + const titlePropertyIndex = path.node.declaration.properties.findIndex(node => node.key && node.key.name === TITLE_KEY ); - if (titleProperty) { + if (titlePropertyIndex !== -1) { switch (ifTitleFound) { case 'skip': return; + case 'transform': + const newNode = t.cloneNode(path.node); + newNode.declaration.properties.splice(titlePropertyIndex, 1, newTitleNode); + path.replaceWith(newNode); + return; default: throw new Error( `Default export object has a '${TITLE_KEY}' property; the title should, however, be generated. Please remove '${TITLE_KEY}'.` @@ -17,7 +23,7 @@ const fixObjectDefaultExport = (path, t, title, ifTitleFound) => { } path.get('declaration').pushContainer( 'properties', - t.objectProperty(t.identifier(TITLE_KEY), t.stringLiteral(title)) + newTitleNode ); } else { throw new Error('Default export object does not have properties.'); From 4574275d5ebe423af1e8153adf9a700f5722a027 Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Fri, 22 Apr 2022 09:27:17 -0700 Subject: [PATCH 2/2] Pass title / titleIndex into state --- README.md | 1 + src/__tests__/index.js | 4 ++-- src/index.js | 22 +++++++++++++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7f13bff..326c39e 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ The plugin takes three options, `toTitle` (required), `ifTitleFound` (optional), - `ifTitleFound` is an optional string value that may either be set to: - `'skip'` - skips adding a title if it has already been manually specified in the code + - `'transform'` - replaces the existing title with the value from `toTitle` - `undefined` (or any other value) - raise an error if processing a file that already defines a title - `renameDefaultExportsTo` is an optional string value that controls scenario 3 as described above. It is `undefined` by default. diff --git a/src/__tests__/index.js b/src/__tests__/index.js index b67f7b0..5f0b7bc 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -162,7 +162,7 @@ tester({ import React from 'react'; import { Component } from './index'; export default { - title: "bar" + title: "existingbar" }; export const Default = () => ; ` @@ -170,7 +170,7 @@ tester({ ], pluginOptions: { title: 'bar', - toTitle: (state) => state.opts.title, + toTitle: (state) => state.title + state.opts.title, ifTitleFound: 'transform' }, babelOptions: { diff --git a/src/index.js b/src/index.js index 1d60128..b9de3b1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,8 @@ const TITLE_KEY = 'title'; -const fixObjectDefaultExport = (path, t, title, ifTitleFound) => { +const fixObjectDefaultExport = (path, t, title, ifTitleFound, titlePropertyIndex) => { if (path.node.declaration.properties) { const newTitleNode = t.objectProperty(t.identifier(TITLE_KEY), t.stringLiteral(title)) - const titlePropertyIndex = path.node.declaration.properties.findIndex(node => - node.key && node.key.name === TITLE_KEY - ); if (titlePropertyIndex !== -1) { switch (ifTitleFound) { case 'skip': @@ -67,6 +64,21 @@ const plugin = babel => { return; } state.defaultExportPath = path; + state.titleIndex = -1; + state.title = ''; + + const properties = path.node.declaration.properties; + if (properties) { + const titlePropertyIndex = properties.findIndex(node => + node.key && node.key.name === TITLE_KEY + ); + if (titlePropertyIndex !== -1) { + if (properties[titlePropertyIndex].value.type === 'StringLiteral') { + state.title = properties[titlePropertyIndex].value.value; + state.titleIndex = titlePropertyIndex; + } + } + } }, ExportNamedDeclaration: (path, state) => { if (state.handled) { @@ -99,7 +111,7 @@ const plugin = babel => { if (state.defaultExportPath) { if (state.defaultExportPath.node.declaration.type === 'ObjectExpression') { - fixObjectDefaultExport(state.defaultExportPath, t, title, state.opts.ifTitleFound); + fixObjectDefaultExport(state.defaultExportPath, t, title, state.opts.ifTitleFound, state.titleIndex); } else { if (renameDefaultExportsTo) { if (!state.namedDefaultExportPath) {