├── .changeset ├── README.md ├── config.json └── format-changelogs.cjs ├── .editorconfig ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .npmrc ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── configs ├── eslint │ └── node │ │ ├── eslint.config.mjs │ │ ├── javascript │ │ └── index.mjs │ │ ├── package.json │ │ ├── prettier.config.mjs │ │ └── typescript │ │ └── index.mjs ├── prettier │ ├── node │ │ └── index.mjs │ ├── package.json │ └── prettier.config.mjs └── typescript │ ├── node20 │ └── index.json │ ├── package.json │ └── prettier.config.mjs ├── package.json ├── packages ├── .gitkeep ├── ast │ ├── javascript │ │ ├── .npmignore │ │ ├── .prettierignore │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── build.sh │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── prettier.config.mjs │ │ ├── src │ │ │ ├── ast │ │ │ │ └── javascript.ts │ │ │ └── index.ts │ │ ├── tests │ │ │ ├── ast │ │ │ │ ├── javascript │ │ │ │ │ ├── transform-base-case.test.ts │ │ │ │ │ ├── transform-file-is-empty.test.ts │ │ │ │ │ ├── traverse-base-case.test.ts │ │ │ │ │ └── traverse-file-is-empty.test.ts │ │ │ │ └── typescript │ │ │ │ │ ├── transform-base-case.test.ts │ │ │ │ │ ├── transform-file-is-empty.test.ts │ │ │ │ │ ├── traverse-base-case.test.ts │ │ │ │ │ └── traverse-file-is-empty.test.ts │ │ │ └── shared-test-setups │ │ │ │ ├── index.ts │ │ │ │ └── transforms │ │ │ │ ├── javascript.ts │ │ │ │ └── typescript.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ └── template │ │ ├── .npmignore │ │ ├── .prettierignore │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── build.sh │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── prettier.config.mjs │ │ ├── src │ │ ├── ast │ │ │ └── handlebars.ts │ │ └── index.ts │ │ ├── tests │ │ ├── ast │ │ │ └── handlebars │ │ │ │ ├── transform-base-case.test.ts │ │ │ │ ├── transform-file-is-empty.test.ts │ │ │ │ ├── traverse-base-case.test.ts │ │ │ │ └── traverse-file-is-empty.test.ts │ │ └── shared-test-setups │ │ │ ├── index.ts │ │ │ └── transforms │ │ │ └── handlebars.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json ├── blueprints │ ├── .npmignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── README.md │ ├── build.sh │ ├── eslint.config.mjs │ ├── package.json │ ├── prettier.config.mjs │ ├── src │ │ ├── blueprints │ │ │ ├── decide-version.ts │ │ │ ├── get-file-path.ts │ │ │ └── process-template.ts │ │ └── index.ts │ ├── tests │ │ └── blueprints │ │ │ ├── decide-version │ │ │ ├── base-case.test.ts │ │ │ ├── edge-case-package-is-already-installed.test.ts │ │ │ └── error-handling-latest-version-is-undefined.test.ts │ │ │ ├── get-file-path │ │ │ └── base-case.test.ts │ │ │ └── process-template │ │ │ ├── escape.test.ts │ │ │ ├── evaluate.test.ts │ │ │ └── interpolate.test.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── cli │ ├── .npmignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── README.md │ ├── bin │ │ └── cli.ts │ ├── build.sh │ ├── eslint.config.mjs │ ├── package.json │ ├── prettier.config.mjs │ ├── src │ │ ├── blueprints │ │ │ ├── .changeset │ │ │ │ ├── config.json │ │ │ │ └── format-changelogs.cjs │ │ │ ├── .github │ │ │ │ ├── ISSUE_TEMPLATE │ │ │ │ │ ├── ask-for-better-documentation.md │ │ │ │ │ ├── ask-for-new-feature-or-refactor.md │ │ │ │ │ ├── report-bug.md │ │ │ │ │ └── report-outdated-dependency.md │ │ │ │ └── workflows │ │ │ │ │ └── ci.yml │ │ │ ├── .prettierignore │ │ │ ├── CHANGELOG.md │ │ │ ├── CONTRIBUTING.md │ │ │ ├── LICENSE.md │ │ │ ├── README.md │ │ │ ├── __gitignore__ │ │ │ ├── __npmignore__ │ │ │ ├── bin │ │ │ │ └── __codemod-name__.__js__ │ │ │ ├── build.sh │ │ │ ├── eslint.config.mjs │ │ │ ├── package.json │ │ │ ├── prettier.config.mjs │ │ │ ├── src │ │ │ │ ├── blueprints │ │ │ │ │ └── .gitkeep │ │ │ │ ├── index.__js__ │ │ │ │ ├── steps │ │ │ │ │ ├── add-end-of-line.__js__ │ │ │ │ │ ├── create-options.__js__ │ │ │ │ │ └── index.__js__ │ │ │ │ ├── types │ │ │ │ │ └── index.ts │ │ │ │ └── utils │ │ │ │ │ ├── blueprints.__js__ │ │ │ │ │ └── blueprints │ │ │ │ │ └── blueprints-root.__js__ │ │ │ ├── tests │ │ │ │ ├── fixtures │ │ │ │ │ └── sample-project │ │ │ │ │ │ ├── index.__js__ │ │ │ │ │ │ ├── input │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ │ └── output │ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── helpers │ │ │ │ │ └── shared-test-setups │ │ │ │ │ │ └── sample-project.__js__ │ │ │ │ ├── index │ │ │ │ │ └── sample-project.test.__js__ │ │ │ │ ├── steps │ │ │ │ │ ├── add-end-of-line │ │ │ │ │ │ ├── base-case.test.__js__ │ │ │ │ │ │ ├── edge-case-file-ends-with-newline.test.__js__ │ │ │ │ │ │ └── edge-case-file-is-empty.test.__js__ │ │ │ │ │ └── create-options │ │ │ │ │ │ └── sample-project.test.__js__ │ │ │ │ └── utils │ │ │ │ │ └── blueprints │ │ │ │ │ └── blueprints-root.test.__js__ │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ └── update-test-fixtures.sh │ │ ├── index.ts │ │ ├── steps │ │ │ ├── create-files-from-blueprints.ts │ │ │ ├── create-options.ts │ │ │ ├── index.ts │ │ │ └── update-package-json.ts │ │ ├── types │ │ │ └── index.ts │ │ └── utils │ │ │ ├── blueprints.ts │ │ │ └── blueprints │ │ │ ├── blueprints-root.ts │ │ │ └── get-version.ts │ ├── tests │ │ ├── fixtures │ │ │ ├── javascript-with-addons │ │ │ │ ├── index.js │ │ │ │ ├── input │ │ │ │ │ └── .gitkeep │ │ │ │ └── output │ │ │ │ │ ├── .gitkeep │ │ │ │ │ └── ember-codemod-args-to-signature │ │ │ │ │ ├── .changeset │ │ │ │ │ ├── config.json │ │ │ │ │ └── format-changelogs.cjs │ │ │ │ │ ├── .github │ │ │ │ │ ├── ISSUE_TEMPLATE │ │ │ │ │ │ ├── ask-for-better-documentation.md │ │ │ │ │ │ ├── ask-for-new-feature-or-refactor.md │ │ │ │ │ │ ├── report-bug.md │ │ │ │ │ │ └── report-outdated-dependency.md │ │ │ │ │ └── workflows │ │ │ │ │ │ └── ci.yml │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .npmignore │ │ │ │ │ ├── .prettierignore │ │ │ │ │ ├── CHANGELOG.md │ │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ │ ├── LICENSE.md │ │ │ │ │ ├── README.md │ │ │ │ │ ├── bin │ │ │ │ │ └── ember-codemod-args-to-signature.js │ │ │ │ │ ├── eslint.config.mjs │ │ │ │ │ ├── package.json │ │ │ │ │ ├── prettier.config.mjs │ │ │ │ │ ├── src │ │ │ │ │ ├── blueprints │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ ├── index.js │ │ │ │ │ ├── steps │ │ │ │ │ │ ├── add-end-of-line.js │ │ │ │ │ │ ├── create-options.js │ │ │ │ │ │ └── index.js │ │ │ │ │ └── utils │ │ │ │ │ │ ├── blueprints.js │ │ │ │ │ │ └── blueprints │ │ │ │ │ │ └── blueprints-root.js │ │ │ │ │ ├── tests │ │ │ │ │ ├── fixtures │ │ │ │ │ │ └── sample-project │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── input │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ │ │ └── output │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ ├── helpers │ │ │ │ │ │ └── shared-test-setups │ │ │ │ │ │ │ └── sample-project.js │ │ │ │ │ ├── index │ │ │ │ │ │ └── sample-project.test.js │ │ │ │ │ ├── steps │ │ │ │ │ │ ├── add-end-of-line │ │ │ │ │ │ │ ├── base-case.test.js │ │ │ │ │ │ │ ├── edge-case-file-ends-with-newline.test.js │ │ │ │ │ │ │ └── edge-case-file-is-empty.test.js │ │ │ │ │ │ └── create-options │ │ │ │ │ │ │ └── sample-project.test.js │ │ │ │ │ └── utils │ │ │ │ │ │ └── blueprints │ │ │ │ │ │ └── blueprints-root.test.js │ │ │ │ │ └── update-test-fixtures.sh │ │ │ ├── javascript │ │ │ │ ├── index.js │ │ │ │ ├── input │ │ │ │ │ └── .gitkeep │ │ │ │ └── output │ │ │ │ │ ├── .gitkeep │ │ │ │ │ └── ember-codemod-pod-to-octane │ │ │ │ │ ├── .changeset │ │ │ │ │ ├── config.json │ │ │ │ │ └── format-changelogs.cjs │ │ │ │ │ ├── .github │ │ │ │ │ ├── ISSUE_TEMPLATE │ │ │ │ │ │ ├── ask-for-better-documentation.md │ │ │ │ │ │ ├── ask-for-new-feature-or-refactor.md │ │ │ │ │ │ ├── report-bug.md │ │ │ │ │ │ └── report-outdated-dependency.md │ │ │ │ │ └── workflows │ │ │ │ │ │ └── ci.yml │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .npmignore │ │ │ │ │ ├── .prettierignore │ │ │ │ │ ├── CHANGELOG.md │ │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ │ ├── LICENSE.md │ │ │ │ │ ├── README.md │ │ │ │ │ ├── bin │ │ │ │ │ └── ember-codemod-pod-to-octane.js │ │ │ │ │ ├── eslint.config.mjs │ │ │ │ │ ├── package.json │ │ │ │ │ ├── prettier.config.mjs │ │ │ │ │ ├── src │ │ │ │ │ ├── index.js │ │ │ │ │ └── steps │ │ │ │ │ │ ├── add-end-of-line.js │ │ │ │ │ │ ├── create-options.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── tests │ │ │ │ │ ├── fixtures │ │ │ │ │ │ └── sample-project │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── input │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ │ │ └── output │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ ├── helpers │ │ │ │ │ │ └── shared-test-setups │ │ │ │ │ │ │ └── sample-project.js │ │ │ │ │ ├── index │ │ │ │ │ │ └── sample-project.test.js │ │ │ │ │ └── steps │ │ │ │ │ │ ├── add-end-of-line │ │ │ │ │ │ ├── base-case.test.js │ │ │ │ │ │ ├── edge-case-file-ends-with-newline.test.js │ │ │ │ │ │ └── edge-case-file-is-empty.test.js │ │ │ │ │ │ └── create-options │ │ │ │ │ │ └── sample-project.test.js │ │ │ │ │ └── update-test-fixtures.sh │ │ │ ├── typescript-with-addons │ │ │ │ ├── index.js │ │ │ │ ├── input │ │ │ │ │ └── .gitkeep │ │ │ │ └── output │ │ │ │ │ ├── .gitkeep │ │ │ │ │ └── ember-codemod-args-to-signature │ │ │ │ │ ├── .changeset │ │ │ │ │ ├── config.json │ │ │ │ │ └── format-changelogs.cjs │ │ │ │ │ ├── .github │ │ │ │ │ ├── ISSUE_TEMPLATE │ │ │ │ │ │ ├── ask-for-better-documentation.md │ │ │ │ │ │ ├── ask-for-new-feature-or-refactor.md │ │ │ │ │ │ ├── report-bug.md │ │ │ │ │ │ └── report-outdated-dependency.md │ │ │ │ │ └── workflows │ │ │ │ │ │ └── ci.yml │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .npmignore │ │ │ │ │ ├── .prettierignore │ │ │ │ │ ├── CHANGELOG.md │ │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ │ ├── LICENSE.md │ │ │ │ │ ├── README.md │ │ │ │ │ ├── bin │ │ │ │ │ └── ember-codemod-args-to-signature.ts │ │ │ │ │ ├── build.sh │ │ │ │ │ ├── eslint.config.mjs │ │ │ │ │ ├── package.json │ │ │ │ │ ├── prettier.config.mjs │ │ │ │ │ ├── src │ │ │ │ │ ├── blueprints │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── steps │ │ │ │ │ │ ├── add-end-of-line.ts │ │ │ │ │ │ ├── create-options.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── types │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── utils │ │ │ │ │ │ ├── blueprints.ts │ │ │ │ │ │ └── blueprints │ │ │ │ │ │ └── blueprints-root.ts │ │ │ │ │ ├── tests │ │ │ │ │ ├── fixtures │ │ │ │ │ │ └── sample-project │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── input │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ │ │ └── output │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ ├── helpers │ │ │ │ │ │ └── shared-test-setups │ │ │ │ │ │ │ └── sample-project.ts │ │ │ │ │ ├── index │ │ │ │ │ │ └── sample-project.test.ts │ │ │ │ │ ├── steps │ │ │ │ │ │ ├── add-end-of-line │ │ │ │ │ │ │ ├── base-case.test.ts │ │ │ │ │ │ │ ├── edge-case-file-ends-with-newline.test.ts │ │ │ │ │ │ │ └── edge-case-file-is-empty.test.ts │ │ │ │ │ │ └── create-options │ │ │ │ │ │ │ └── sample-project.test.ts │ │ │ │ │ └── utils │ │ │ │ │ │ └── blueprints │ │ │ │ │ │ └── blueprints-root.test.ts │ │ │ │ │ ├── tsconfig.build.json │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── update-test-fixtures.sh │ │ │ └── typescript │ │ │ │ ├── index.js │ │ │ │ ├── input │ │ │ │ └── .gitkeep │ │ │ │ └── output │ │ │ │ ├── .gitkeep │ │ │ │ └── ember-codemod-pod-to-octane │ │ │ │ ├── .changeset │ │ │ │ ├── config.json │ │ │ │ └── format-changelogs.cjs │ │ │ │ ├── .github │ │ │ │ ├── ISSUE_TEMPLATE │ │ │ │ │ ├── ask-for-better-documentation.md │ │ │ │ │ ├── ask-for-new-feature-or-refactor.md │ │ │ │ │ ├── report-bug.md │ │ │ │ │ └── report-outdated-dependency.md │ │ │ │ └── workflows │ │ │ │ │ └── ci.yml │ │ │ │ ├── .gitignore │ │ │ │ ├── .npmignore │ │ │ │ ├── .prettierignore │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── LICENSE.md │ │ │ │ ├── README.md │ │ │ │ ├── bin │ │ │ │ └── ember-codemod-pod-to-octane.ts │ │ │ │ ├── build.sh │ │ │ │ ├── eslint.config.mjs │ │ │ │ ├── package.json │ │ │ │ ├── prettier.config.mjs │ │ │ │ ├── src │ │ │ │ ├── index.ts │ │ │ │ ├── steps │ │ │ │ │ ├── add-end-of-line.ts │ │ │ │ │ ├── create-options.ts │ │ │ │ │ └── index.ts │ │ │ │ └── types │ │ │ │ │ └── index.ts │ │ │ │ ├── tests │ │ │ │ ├── fixtures │ │ │ │ │ └── sample-project │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── input │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ │ └── output │ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── helpers │ │ │ │ │ └── shared-test-setups │ │ │ │ │ │ └── sample-project.ts │ │ │ │ ├── index │ │ │ │ │ └── sample-project.test.ts │ │ │ │ └── steps │ │ │ │ │ ├── add-end-of-line │ │ │ │ │ ├── base-case.test.ts │ │ │ │ │ ├── edge-case-file-ends-with-newline.test.ts │ │ │ │ │ └── edge-case-file-is-empty.test.ts │ │ │ │ │ └── create-options │ │ │ │ │ └── sample-project.test.ts │ │ │ │ ├── tsconfig.build.json │ │ │ │ ├── tsconfig.json │ │ │ │ └── update-test-fixtures.sh │ │ ├── helpers │ │ │ └── shared-test-setups │ │ │ │ ├── javascript-with-addons.ts │ │ │ │ ├── javascript.ts │ │ │ │ ├── typescript-with-addons.ts │ │ │ │ └── typescript.ts │ │ ├── index │ │ │ ├── javascript-with-addons.test.ts │ │ │ ├── javascript.test.ts │ │ │ ├── typescript-with-addons.test.ts │ │ │ └── typescript.test.ts │ │ ├── steps │ │ │ └── create-options │ │ │ │ ├── javascript-with-addons.test.ts │ │ │ │ ├── javascript.test.ts │ │ │ │ ├── typescript-with-addons.test.ts │ │ │ │ └── typescript.test.ts │ │ └── utils │ │ │ └── blueprints │ │ │ └── blueprints-root.test.ts │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── update-test-fixtures.sh ├── ember │ ├── .npmignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── README.md │ ├── build.sh │ ├── eslint.config.mjs │ ├── package.json │ ├── prettier.config.mjs │ ├── src │ │ ├── ember │ │ │ └── entity-name │ │ │ │ ├── camelize.ts │ │ │ │ ├── double-colonize.ts │ │ │ │ └── pascalize.ts │ │ └── index.ts │ ├── tests │ │ ├── .gitkeep │ │ └── ember │ │ │ └── entity-name │ │ │ ├── camelize │ │ │ ├── base-case.test.ts │ │ │ ├── nested.test.ts │ │ │ └── wrong-input.test.ts │ │ │ ├── double-colonize │ │ │ ├── base-case.test.ts │ │ │ ├── edge-case-empty-string.test.ts │ │ │ └── wrong-input.test.ts │ │ │ └── pascalize │ │ │ ├── base-case.test.ts │ │ │ ├── nested.test.ts │ │ │ └── wrong-input.test.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── files │ ├── .npmignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── README.md │ ├── build.sh │ ├── eslint.config.mjs │ ├── package.json │ ├── prettier.config.mjs │ ├── src │ │ ├── files │ │ │ ├── copy-files.ts │ │ │ ├── create-directory.ts │ │ │ ├── create-files.ts │ │ │ ├── find-files.ts │ │ │ ├── get-package-roots.ts │ │ │ ├── map-file-paths.ts │ │ │ ├── move-files.ts │ │ │ ├── parse-file-path.ts │ │ │ ├── remove-directory-if-empty.ts │ │ │ ├── remove-files.ts │ │ │ └── rename-path-by-directory.ts │ │ ├── index.ts │ │ └── types │ │ │ └── index.ts │ ├── tests │ │ ├── files │ │ │ ├── copy-files │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-filePathMap-is-empty.test.ts │ │ │ │ ├── edge-case-from-and-to-are-sibling-directories.test.ts │ │ │ │ └── edge-case-from-and-to-are-the-same.test.ts │ │ │ ├── create-directory │ │ │ │ ├── base-case.test.ts │ │ │ │ └── idempotency.test.ts │ │ │ ├── create-files │ │ │ │ ├── base-case.test.ts │ │ │ │ └── edge-case-fileMap-is-empty.test.ts │ │ │ ├── find-files │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-projectRoot-does-not-exist.test.ts │ │ │ │ ├── edge-case-specified-folder-is-empty.test.ts │ │ │ │ ├── error-handling-pattern-is-undefined.test.ts │ │ │ │ ├── error-handling-projectRoot-is-undefined.test.ts │ │ │ │ ├── ignore-list.test.ts │ │ │ │ └── multiple-patterns.test.ts │ │ │ ├── get-package-roots │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-file-name-is-incorrect.test.ts │ │ │ │ ├── edge-case-no-packages.test.ts │ │ │ │ └── monorepo.test.ts │ │ │ ├── map-file-paths │ │ │ │ ├── base-case.test.ts │ │ │ │ └── edge-case-no-match.test.ts │ │ │ ├── move-files │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-filePathMap-is-empty.test.ts │ │ │ │ ├── edge-case-from-and-to-are-sibling-directories.test.ts │ │ │ │ └── edge-case-from-and-to-are-the-same.test.ts │ │ │ ├── parse-file-path │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-css-d-ts.test.ts │ │ │ │ ├── edge-case-d-ts.test.ts │ │ │ │ ├── edge-case-no-directory.test.ts │ │ │ │ ├── edge-case-no-extension.test.ts │ │ │ │ └── edge-case-special-characters.test.ts │ │ │ ├── remove-directory-if-empty │ │ │ │ ├── base-case.test.ts │ │ │ │ └── edge-case-parent-directory-is-not-empty.test.ts │ │ │ ├── remove-files │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-file-does-not-exist.test.ts │ │ │ │ └── edge-case-filePaths-is-empty.test.ts │ │ │ └── rename-path-by-directory │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-from-is-empty.test.ts │ │ │ │ ├── edge-case-no-match.test.ts │ │ │ │ └── edge-case-to-is-empty.test.ts │ │ └── shared-test-setups │ │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── json │ ├── .npmignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── README.md │ ├── build.sh │ ├── eslint.config.mjs │ ├── package.json │ ├── prettier.config.mjs │ ├── src │ │ ├── index.ts │ │ ├── json │ │ │ ├── convert-to-map.ts │ │ │ ├── convert-to-object.ts │ │ │ ├── read-package-json.ts │ │ │ └── validate-package-json.ts │ │ └── types │ │ │ └── index.ts │ ├── tests │ │ ├── json │ │ │ ├── convert-to-map │ │ │ │ ├── base-case.test.ts │ │ │ │ └── edge-case-input-is-undefined.test.ts │ │ │ ├── convert-to-object │ │ │ │ ├── base-case.test.ts │ │ │ │ └── edge-case-input-is-undefined.test.ts │ │ │ ├── read-package-json │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-package-name-is-missing.test.ts │ │ │ │ ├── edge-case-package-name-is-not-valid.test.ts │ │ │ │ ├── edge-case-package-name-is-scoped.test.ts │ │ │ │ ├── edge-case-package-version-is-missing.test.ts │ │ │ │ ├── error-handling-package-json-is-an-empty-file.test.ts │ │ │ │ ├── error-handling-package-json-is-missing.test.ts │ │ │ │ └── error-handling-package-json-is-not-a-valid-json.test.ts │ │ │ └── validate-package-json │ │ │ │ ├── base-case.test.ts │ │ │ │ ├── edge-case-package-name-is-scoped.test.ts │ │ │ │ ├── package-name-is-missing.test.ts │ │ │ │ ├── package-name-is-not-valid.test.ts │ │ │ │ └── package-version-is-missing.test.ts │ │ └── shared-test-setups │ │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json └── tests │ ├── .npmignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── README.md │ ├── build.sh │ ├── eslint.config.mjs │ ├── package.json │ ├── prettier.config.mjs │ ├── src │ ├── index.ts │ ├── tests │ │ ├── assert-fixture.ts │ │ ├── convert-fixture-to-json.ts │ │ └── load-fixture.ts │ └── types │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── tutorials ├── create-blueprints ├── 00-introduction.md ├── 01-create-a-project.md ├── 02-create-static-files.md ├── 03-define-options.md ├── 04-create-dynamic-files.md └── 05-conclusion.md ├── main-tutorial ├── 00-introduction.md ├── 01-create-a-project.md ├── 02-understand-the-folder-structure.md ├── 03-sketch-out-the-solution.md ├── 04-step-1-update-acceptance-tests-part-1.md ├── 05-step-1-update-acceptance-tests-part-2.md ├── 06-step-2-update-integration-tests.md ├── 07-step-3-update-unit-tests.md ├── 08-refactor-code-part-1.md ├── 09-refactor-code-part-2.md └── 10-conclusion.md ├── update-css-files ├── 00-introduction.md ├── 01-use-existing-plugins.md ├── 02-write-custom-plugins.md └── 03-conclusion.md └── update-template-tags ├── 00-introduction.md ├── 01-a-simple-example.md ├── 02-create-utilities.md └── 03-conclusion.md /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "./format-changelogs.cjs", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.hbs] 16 | insert_final_newline = false 17 | 18 | [*.{diff,md}] 19 | trim_trailing_whitespace = false 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | dist/ 3 | dist-for-testing/ 4 | tmp/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # misc 10 | .DS_Store 11 | .env* 12 | .eslintcache 13 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # https://github.com/emberjs/rfcs/pull/907 2 | auto-install-peers=false 3 | resolve-peers-from-workspace-root=false 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /configs/eslint/node/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from './javascript/index.mjs'; 2 | -------------------------------------------------------------------------------- /configs/eslint/node/javascript/index.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/eslint-config-node/javascript'; 2 | -------------------------------------------------------------------------------- /configs/eslint/node/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /configs/eslint/node/typescript/index.mjs: -------------------------------------------------------------------------------- 1 | import baseConfiguration from '@ijlee2-frontend-configs/eslint-config-node/typescript'; 2 | 3 | export default [ 4 | { 5 | ignores: [ 6 | 'dist/', 7 | 'dist-for-testing/', 8 | 'node_modules/', 9 | 'src/blueprints/', 10 | 'tests/fixtures/', 11 | 'tmp/', 12 | '.*/', 13 | ], 14 | }, 15 | ...baseConfiguration, 16 | ]; 17 | -------------------------------------------------------------------------------- /configs/prettier/node/index.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /configs/prettier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@shared-configs/prettier", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "Configuration for prettier", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:ijlee2/codemod-utils.git" 9 | }, 10 | "author": "Isaac J. Lee", 11 | "type": "module", 12 | "exports": { 13 | "./node": "./node/index.mjs" 14 | }, 15 | "scripts": { 16 | "lint": "prettier \"**/*.mjs\" --cache --check", 17 | "lint:fix": "prettier \"**/*.mjs\" --cache --write" 18 | }, 19 | "dependencies": { 20 | "@ijlee2-frontend-configs/prettier": "^2.0.0" 21 | }, 22 | "devDependencies": { 23 | "prettier": "^3.5.3" 24 | }, 25 | "peerDependencies": { 26 | "prettier": "^3.5.3" 27 | }, 28 | "peerDependenciesMeta": { 29 | "prettier": { 30 | "optional": false 31 | } 32 | }, 33 | "engines": { 34 | "node": "20.* || >= 22" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /configs/prettier/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from './node/index.mjs'; 2 | -------------------------------------------------------------------------------- /configs/typescript/node20/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/node20/tsconfig", "@tsconfig/strictest/tsconfig"], 3 | "compilerOptions": { 4 | "module": "nodenext", 5 | "moduleResolution": "nodenext", 6 | "verbatimModuleSyntax": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /configs/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@shared-configs/typescript", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "Configuration for typescript", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:ijlee2/codemod-utils.git" 9 | }, 10 | "author": "Isaac J. Lee", 11 | "type": "module", 12 | "exports": { 13 | "./node20": "./node20/index.json" 14 | }, 15 | "scripts": { 16 | "lint": "prettier \"**/*.{json,mjs}\" --cache --check", 17 | "lint:fix": "prettier \"**/*.{json,mjs}\" --cache --write" 18 | }, 19 | "dependencies": { 20 | "@tsconfig/node20": "^20.1.5", 21 | "@tsconfig/strictest": "^2.0.5" 22 | }, 23 | "devDependencies": { 24 | "@shared-configs/prettier": "workspace:*", 25 | "prettier": "^3.5.3" 26 | }, 27 | "peerDependencies": { 28 | "typescript": "^5.8.3" 29 | }, 30 | "peerDependenciesMeta": { 31 | "typescript": { 32 | "optional": false 33 | } 34 | }, 35 | "engines": { 36 | "node": "20.* || >= 22" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /configs/typescript/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/.gitkeep -------------------------------------------------------------------------------- /packages/ast/javascript/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintcache 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | -------------------------------------------------------------------------------- /packages/ast/javascript/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | !.* 8 | .*/ 9 | 10 | # specific to this package 11 | README.md 12 | -------------------------------------------------------------------------------- /packages/ast/javascript/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/ast/javascript/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ENVIRONMENT=$1 4 | 5 | if [ $ENVIRONMENT = "--production" ] 6 | then 7 | # Clean slate 8 | rm -rf "dist" 9 | 10 | # Compile TypeScript 11 | tsc --project "tsconfig.build.json" 12 | 13 | echo "SUCCESS: Built dist.\n" 14 | 15 | elif [ $ENVIRONMENT = "--test" ] 16 | then 17 | # Clean slate 18 | rm -rf "dist-for-testing" 19 | 20 | # Compile TypeScript 21 | tsc --project "tsconfig.json" 22 | 23 | echo "SUCCESS: Built dist-for-testing.\n" 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /packages/ast/javascript/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/ast/javascript/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/ast/javascript/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ast/javascript.js'; 2 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/javascript/transform-base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { transformJavaScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | javascript > transform (base case)', function () { 6 | const oldFile = [ 7 | `import Component from '@glimmer/component';`, 8 | ``, 9 | `export default class NavigationMenuComponent extends Component {}`, 10 | ``, 11 | ].join('\n'); 12 | 13 | const newFile = transformJavaScript(oldFile); 14 | 15 | assert.strictEqual( 16 | newFile, 17 | [ 18 | `import Component from '@glimmer/component';`, 19 | ``, 20 | `export default class NavigationMenuComponent extends Component {`, 21 | ` styles = styles;`, 22 | `}`, 23 | ``, 24 | ].join('\n'), 25 | ); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/javascript/transform-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { transformJavaScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | javascript > transform (file is empty)', function () { 6 | const oldFile = ''; 7 | 8 | const newFile = transformJavaScript(oldFile); 9 | 10 | assert.strictEqual(newFile, ''); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/javascript/traverse-base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { traverseJavaScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | javascript > traverse (base case)', function () { 6 | const oldFile = [ 7 | `import Component from '@glimmer/component';`, 8 | ``, 9 | `export default class NavigationMenuComponent extends Component {}`, 10 | ``, 11 | ].join('\n'); 12 | 13 | const newFile = traverseJavaScript(oldFile); 14 | 15 | assert.strictEqual( 16 | newFile, 17 | [ 18 | `import Component from '@glimmer/component';`, 19 | ``, 20 | `export default class NavigationMenuComponent extends Component {}`, 21 | ``, 22 | ].join('\n'), 23 | ); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/javascript/traverse-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { traverseJavaScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | javascript > traverse (file is empty)', function () { 6 | const oldFile = ''; 7 | 8 | const newFile = traverseJavaScript(oldFile); 9 | 10 | assert.strictEqual(newFile, ''); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/typescript/transform-base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { transformTypeScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | typescript > transform (base case)', function () { 6 | const oldFile = [ 7 | `import Component from '@glimmer/component';`, 8 | ``, 9 | `interface NavigationMenuSignature {}`, 10 | ``, 11 | `export default class NavigationMenuComponent extends Component {}`, 12 | ``, 13 | ].join('\n'); 14 | 15 | const newFile = transformTypeScript(oldFile); 16 | 17 | assert.strictEqual( 18 | newFile, 19 | [ 20 | `import Component from '@glimmer/component';`, 21 | ``, 22 | `interface NavigationMenuSignature {}`, 23 | ``, 24 | `export default class NavigationMenuComponent extends Component {`, 25 | ` styles = styles;`, 26 | `}`, 27 | ``, 28 | ].join('\n'), 29 | ); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/typescript/transform-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { transformTypeScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | typescript > transform (file is empty)', function () { 6 | const oldFile = ''; 7 | 8 | const newFile = transformTypeScript(oldFile); 9 | 10 | assert.strictEqual(newFile, ''); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/typescript/traverse-base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { traverseTypeScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | typescript > traverse (base case)', function () { 6 | const oldFile = [ 7 | `import Component from '@glimmer/component';`, 8 | ``, 9 | `interface NavigationMenuSignature {}`, 10 | ``, 11 | `export default class NavigationMenuComponent extends Component {}`, 12 | ``, 13 | ].join('\n'); 14 | const newFile = traverseTypeScript(oldFile); 15 | 16 | assert.strictEqual( 17 | newFile, 18 | [ 19 | `import Component from '@glimmer/component';`, 20 | ``, 21 | `interface NavigationMenuSignature {}`, 22 | ``, 23 | `export default class NavigationMenuComponent extends Component {}`, 24 | ``, 25 | ].join('\n'), 26 | ); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/ast/typescript/traverse-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { traverseTypeScript } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | typescript > traverse (file is empty)', function () { 6 | const oldFile = ''; 7 | 8 | const newFile = traverseTypeScript(oldFile); 9 | 10 | assert.strictEqual(newFile, ''); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/shared-test-setups/index.ts: -------------------------------------------------------------------------------- 1 | export * from './transforms/javascript.js'; 2 | export * from './transforms/typescript.js'; 3 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/shared-test-setups/transforms/javascript.ts: -------------------------------------------------------------------------------- 1 | import { AST } from '../../../src/index.js'; 2 | 3 | export function transformJavaScript(file: string) { 4 | const traverse = AST.traverse(); 5 | 6 | const ast = traverse(file, { 7 | visitClassDeclaration(path) { 8 | const { body } = path.node.body; 9 | 10 | const nodesToAdd = [ 11 | AST.builders.classProperty( 12 | AST.builders.identifier('styles'), 13 | AST.builders.identifier('styles'), 14 | ), 15 | ]; 16 | 17 | body.unshift(...nodesToAdd); 18 | 19 | return false; 20 | }, 21 | }); 22 | 23 | return AST.print(ast); 24 | } 25 | 26 | export function traverseJavaScript(file: string) { 27 | const traverse = AST.traverse(); 28 | 29 | const ast = traverse(file); 30 | 31 | return AST.print(ast); 32 | } 33 | -------------------------------------------------------------------------------- /packages/ast/javascript/tests/shared-test-setups/transforms/typescript.ts: -------------------------------------------------------------------------------- 1 | import { AST } from '../../../src/index.js'; 2 | 3 | export function transformTypeScript(file: string) { 4 | const traverse = AST.traverse(true); 5 | 6 | const ast = traverse(file, { 7 | visitClassDeclaration(path) { 8 | const { body } = path.node.body; 9 | 10 | const nodesToAdd = [ 11 | AST.builders.classProperty( 12 | AST.builders.identifier('styles'), 13 | AST.builders.identifier('styles'), 14 | ), 15 | ]; 16 | 17 | body.unshift(...nodesToAdd); 18 | 19 | return false; 20 | }, 21 | }); 22 | 23 | return AST.print(ast); 24 | } 25 | 26 | export function traverseTypeScript(file: string) { 27 | const traverse = AST.traverse(true); 28 | 29 | const ast = traverse(file); 30 | 31 | return AST.print(ast); 32 | } 33 | -------------------------------------------------------------------------------- /packages/ast/javascript/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/ast/javascript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["src", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/ast/template/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintcache 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | -------------------------------------------------------------------------------- /packages/ast/template/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | !.* 8 | .*/ 9 | 10 | # specific to this package 11 | README.md 12 | -------------------------------------------------------------------------------- /packages/ast/template/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/ast/template/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ENVIRONMENT=$1 4 | 5 | if [ $ENVIRONMENT = "--production" ] 6 | then 7 | # Clean slate 8 | rm -rf "dist" 9 | 10 | # Compile TypeScript 11 | tsc --project "tsconfig.build.json" 12 | 13 | echo "SUCCESS: Built dist.\n" 14 | 15 | elif [ $ENVIRONMENT = "--test" ] 16 | then 17 | # Clean slate 18 | rm -rf "dist-for-testing" 19 | 20 | # Compile TypeScript 21 | tsc --project "tsconfig.json" 22 | 23 | echo "SUCCESS: Built dist-for-testing.\n" 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /packages/ast/template/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/ast/template/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/ast/template/src/ast/handlebars.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type AST as _AST, 3 | builders, 4 | type NodeVisitor, 5 | print, 6 | transform, 7 | } from 'ember-template-recast'; 8 | 9 | function _traverse() { 10 | return function ( 11 | file: string, 12 | visitMethods: NodeVisitor = {}, 13 | ): _AST.Template { 14 | const { ast } = transform({ 15 | plugin() { 16 | return visitMethods; 17 | }, 18 | template: file, 19 | }); 20 | 21 | return ast; 22 | }; 23 | } 24 | 25 | /** 26 | * Provides methods from `ember-template-recast` to help you parse 27 | * and transform `*.hbs` files. 28 | * 29 | * @example 30 | * 31 | * ```ts 32 | * import { AST } from '@codemod-utils/ast-template'; 33 | * 34 | * function transformCode(file: string): string { 35 | * const traverse = AST.traverse(); 36 | * 37 | * const ast = traverse(file, { 38 | * // Use AST.builders to transform the tree 39 | * }); 40 | * 41 | * return AST.print(ast); 42 | * } 43 | * ``` 44 | */ 45 | export const AST = { 46 | builders, 47 | print, 48 | traverse: _traverse, 49 | }; 50 | -------------------------------------------------------------------------------- /packages/ast/template/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ast/handlebars.js'; 2 | -------------------------------------------------------------------------------- /packages/ast/template/tests/ast/handlebars/transform-base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { transformHandlebars } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | handlebars > transform (base case)', function () { 6 | const oldFile = [ 7 | `{{! Some comment }}`, 8 | `
`, 9 | ` {{! Some content }}`, 10 | `
`, 11 | ``, 12 | ].join('\n'); 13 | 14 | const newFile = transformHandlebars(oldFile); 15 | 16 | assert.strictEqual( 17 | newFile, 18 | [ 19 | `{{! Some comment }}`, 20 | `
`, 21 | ` {{! Some content }}`, 22 | `
`, 23 | ``, 24 | ].join('\n'), 25 | ); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ast/template/tests/ast/handlebars/transform-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { transformHandlebars } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | handlebars > transform (file is empty)', function () { 6 | const oldFile = ''; 7 | 8 | const newFile = transformHandlebars(oldFile); 9 | 10 | assert.strictEqual(newFile, ''); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ast/template/tests/ast/handlebars/traverse-base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { traverseHandlebars } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | handlebars > traverse (base case)', function () { 6 | const oldFile = [ 7 | `{{! Some comment }}`, 8 | `
`, 9 | ` {{! Some content }}`, 10 | `
`, 11 | ``, 12 | ].join('\n'); 13 | 14 | const newFile = traverseHandlebars(oldFile); 15 | 16 | assert.strictEqual( 17 | newFile, 18 | [ 19 | `{{! Some comment }}`, 20 | `
`, 21 | ` {{! Some content }}`, 22 | `
`, 23 | ``, 24 | ].join('\n'), 25 | ); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ast/template/tests/ast/handlebars/traverse-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { traverseHandlebars } from '../../shared-test-setups/index.js'; 4 | 5 | test('utils | ast | handlebars > traverse (file is empty)', function () { 6 | const oldFile = ''; 7 | 8 | const newFile = traverseHandlebars(oldFile); 9 | 10 | assert.strictEqual(newFile, ''); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ast/template/tests/shared-test-setups/index.ts: -------------------------------------------------------------------------------- 1 | export * from './transforms/handlebars.js'; 2 | -------------------------------------------------------------------------------- /packages/ast/template/tests/shared-test-setups/transforms/handlebars.ts: -------------------------------------------------------------------------------- 1 | import { AST } from '../../../src/index.js'; 2 | 3 | export function transformHandlebars(file: string) { 4 | const traverse = AST.traverse(); 5 | 6 | const ast = traverse(file, { 7 | AttrNode(node) { 8 | if (node.name !== 'local-class') { 9 | return; 10 | } 11 | 12 | node.name = 'class'; 13 | 14 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 15 | // @ts-ignore: Property 'chars' does not exist on type 'TextNode | MustacheStatement | ConcatStatement'. 16 | const attributeValue = (node.value.chars as string).trim(); 17 | 18 | node.value = AST.builders.mustache( 19 | AST.builders.path(`this.styles.${attributeValue}`), 20 | ); 21 | }, 22 | }); 23 | 24 | return AST.print(ast); 25 | } 26 | 27 | export function traverseHandlebars(file: string) { 28 | const traverse = AST.traverse(); 29 | 30 | const ast = traverse(file); 31 | 32 | return AST.print(ast); 33 | } 34 | -------------------------------------------------------------------------------- /packages/ast/template/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/ast/template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["src", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/blueprints/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintrc.cjs 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | -------------------------------------------------------------------------------- /packages/blueprints/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | !.* 8 | .*/ 9 | 10 | # specific to this package 11 | README.md 12 | -------------------------------------------------------------------------------- /packages/blueprints/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/blueprints/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ENVIRONMENT=$1 4 | 5 | if [ $ENVIRONMENT = "--production" ] 6 | then 7 | # Clean slate 8 | rm -rf "dist" 9 | 10 | # Compile TypeScript 11 | tsc --project "tsconfig.build.json" 12 | 13 | echo "SUCCESS: Built dist.\n" 14 | 15 | elif [ $ENVIRONMENT = "--test" ] 16 | then 17 | # Clean slate 18 | rm -rf "dist-for-testing" 19 | 20 | # Compile TypeScript 21 | tsc --project "tsconfig.json" 22 | 23 | echo "SUCCESS: Built dist-for-testing.\n" 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /packages/blueprints/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/blueprints/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/blueprints/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './blueprints/decide-version.js'; 2 | export * from './blueprints/get-file-path.js'; 3 | export * from './blueprints/process-template.js'; 4 | -------------------------------------------------------------------------------- /packages/blueprints/tests/blueprints/decide-version/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { decideVersion } from '../../../src/index.js'; 4 | 5 | test('blueprints | decide-version > base case', function () { 6 | const latestVersions = new Map([ 7 | ['embroider-css-modules', '0.1.2'], 8 | ['webpack', '5.82.0'], 9 | ]); 10 | 11 | const version = decideVersion('embroider-css-modules', { 12 | dependencies: new Map([['webpack', '^5.79.0']]), 13 | latestVersions, 14 | }); 15 | 16 | assert.strictEqual(version, '^0.1.2'); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/blueprints/tests/blueprints/decide-version/edge-case-package-is-already-installed.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { decideVersion } from '../../../src/index.js'; 4 | 5 | test('blueprints | decide-version > edge case (package is already installed)', function () { 6 | const latestVersions = new Map([ 7 | ['embroider-css-modules', '0.1.2'], 8 | ['webpack', '5.82.0'], 9 | ]); 10 | 11 | const version = decideVersion('webpack', { 12 | dependencies: new Map([['webpack', '^5.79.0']]), 13 | latestVersions, 14 | }); 15 | 16 | assert.strictEqual(version, '^5.79.0'); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/blueprints/tests/blueprints/decide-version/error-handling-latest-version-is-undefined.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { decideVersion } from '../../../src/index.js'; 4 | 5 | test('blueprints | decide-version > error handling (latest version is undefined)', function () { 6 | const latestVersions = new Map([ 7 | ['embroider-css-modules', '0.1.2'], 8 | ['webpack', '5.82.0'], 9 | ]); 10 | 11 | assert.throws( 12 | () => { 13 | decideVersion('type-css-modules', { 14 | dependencies: new Map([['webpack', '^5.79.0']]), 15 | latestVersions, 16 | }); 17 | }, 18 | (error: Error) => { 19 | assert.strictEqual( 20 | error.message, 21 | 'ERROR: The latest version of `type-css-modules` is unknown.\n', 22 | ); 23 | 24 | return true; 25 | }, 26 | ); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/blueprints/tests/blueprints/get-file-path/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { getFilePath } from '../../../src/index.js'; 4 | 5 | test('blueprints | get-file-path > base case', function () { 6 | const fileURL = import.meta.url; 7 | const filePath = getFilePath(fileURL); 8 | 9 | assert.strictEqual(filePath.endsWith('tests/blueprints/get-file-path'), true); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/blueprints/tests/blueprints/process-template/escape.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { processTemplate } from '../../../src/index.js'; 4 | 5 | test('blueprints | process-template > escape', function () { 6 | const blueprintFile = '<%- context.htmlCode %>'; 7 | 8 | const file = processTemplate(blueprintFile, { 9 | context: { 10 | htmlCode: 'I 🧡 container queries!', 11 | }, 12 | }); 13 | 14 | const expectedValue = '<em>I 🧡 container queries!</em>'; 15 | 16 | assert.strictEqual(file, expectedValue); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/blueprints/tests/blueprints/process-template/interpolate.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { processTemplate } from '../../../src/index.js'; 4 | 5 | test('blueprints | process-template > interpolate', function () { 6 | const blueprintFile = [ 7 | `packages:`, 8 | ` - '<%= options.packages.addon.name %>'`, 9 | ` - '<%= options.packages.testApp.name %>'`, 10 | ].join('\n'); 11 | 12 | const file = processTemplate(blueprintFile, { 13 | options: { 14 | packages: { 15 | addon: { 16 | name: 'ember-container-query', 17 | }, 18 | testApp: { 19 | name: 'test-app', 20 | }, 21 | }, 22 | }, 23 | }); 24 | 25 | const expectedValue = [ 26 | `packages:`, 27 | ` - 'ember-container-query'`, 28 | ` - 'test-app'`, 29 | ].join('\n'); 30 | 31 | assert.strictEqual(file, expectedValue); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/blueprints/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/blueprints/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["src", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintcache 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | /update-test-fixtures.sh 21 | -------------------------------------------------------------------------------- /packages/cli/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | /src/blueprints/ 8 | /tests/fixtures/ 9 | !.* 10 | .*/ 11 | 12 | # specific to this package 13 | README.md 14 | -------------------------------------------------------------------------------- /packages/cli/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/cli/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | COMMAND="cli" 4 | ENVIRONMENT=$1 5 | 6 | if [ $ENVIRONMENT = "--production" ] 7 | then 8 | # Clean slate 9 | rm -rf "dist" 10 | 11 | # Compile TypeScript 12 | tsc --project "tsconfig.build.json" 13 | 14 | # Configure files 15 | chmod +x "dist/bin/$COMMAND.js" 16 | 17 | if [ -d "src/blueprints" ] 18 | then 19 | cp -r "src/blueprints" "dist/src/blueprints" 20 | fi 21 | 22 | echo "SUCCESS: Built dist.\n" 23 | 24 | elif [ $ENVIRONMENT = "--test" ] 25 | then 26 | # Clean slate 27 | rm -rf "dist-for-testing" 28 | 29 | # Compile TypeScript 30 | tsc --project "tsconfig.json" 31 | 32 | # Configure files 33 | if [ -d "src/blueprints" ] 34 | then 35 | cp -r "src/blueprints" "dist-for-testing/src/blueprints" 36 | fi 37 | 38 | echo "SUCCESS: Built dist-for-testing.\n" 39 | 40 | fi 41 | -------------------------------------------------------------------------------- /packages/cli/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/cli/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "./format-changelogs.cjs", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/.github/ISSUE_TEMPLATE/ask-for-better-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for better documentation 3 | about: Ask for better documentation 4 | title: '' 5 | labels: 'enhance: documentation' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve documentation. 11 | 12 | Here, documentation can mean a few different things, including README, code comments, and tests. Anything that will help everyone understand how to use `<%= options.codemod.name %>`! 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/.github/ISSUE_TEMPLATE/ask-for-new-feature-or-refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for new feature or refactor 3 | about: Ask for new feature or refactor 4 | title: '' 5 | labels: 'enhance: code' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve `<%= options.codemod.name %>`. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has made a request already. 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/.github/ISSUE_TEMPLATE/report-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report bug 3 | about: Report bug 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to make a bug report. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has reported this bug already. 13 | 14 | 15 | ## Describe the bug 🐞 16 | 17 | A clear and concise description of the bug. 18 | 19 | 20 | ## Expected behavior 🤔 21 | 22 | A clear and concise description of what you expected to see. 23 | 24 | 25 | ## Minimal reproduction 🔬 26 | 27 | Describe steps to reproduce the issue. 28 | 29 | 1. ... 30 | 1. ... 31 | 1. ... 32 | 33 | If possible, please share a repo with the minimum files to reproduce the issue. 34 | 35 | 36 | ## Additional context ➕ 37 | 38 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the problem here. 39 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | /src/blueprints/ 8 | /tests/fixtures/ 9 | !.* 10 | .*/ 11 | CONTRIBUTING.md 12 | README.md 13 | pnpm-lock.yaml 14 | 15 | # specific to this package 16 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/__gitignore__: -------------------------------------------------------------------------------- 1 | # compiled output 2 | dist/ 3 | dist-for-testing/ 4 | tmp/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # misc 10 | .DS_Store 11 | .env* 12 | .eslintcache 13 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/__npmignore__: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist-for-testing/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /node_modules/ 7 | 8 | # misc 9 | /.DS_Store 10 | /.env* 11 | /.eslintcache 12 | /.git/ 13 | /.github/ 14 | /.gitignore 15 | /.pnpm-debug.log 16 | /.prettierignore 17 | /build.sh 18 | /CONTRIBUTING.md 19 | /eslint.config.mjs 20 | /prettier.config.mjs 21 | /tests/ 22 | /update-test-fixtures.sh 23 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | COMMAND="<%= options.codemod.name %>" 4 | ENVIRONMENT=$1 5 | 6 | if [ $ENVIRONMENT = "--production" ] 7 | then 8 | # Clean slate 9 | rm -rf "dist" 10 | 11 | # Compile TypeScript 12 | tsc --project "tsconfig.build.json" 13 | 14 | # Configure files 15 | chmod +x "dist/bin/$COMMAND.js" 16 | 17 | if [ -d "src/blueprints" ] 18 | then 19 | cp -r "src/blueprints" "dist/src/blueprints" 20 | fi 21 | 22 | echo "SUCCESS: Built dist.\n" 23 | 24 | elif [ $ENVIRONMENT = "--test" ] 25 | then 26 | # Clean slate 27 | rm -rf "dist-for-testing" 28 | 29 | # Compile TypeScript 30 | tsc --project "tsconfig.json" 31 | 32 | # Configure files 33 | if [ -d "src/blueprints" ] 34 | then 35 | cp -r "src/blueprints" "dist-for-testing/src/blueprints" 36 | fi 37 | 38 | echo "SUCCESS: Built dist-for-testing.\n" 39 | 40 | fi 41 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | <% if (options.codemod.hasTypeScript) { %>import baseConfiguration from '@ijlee2-frontend-configs/eslint-config-node/typescript';<% } else { %>import baseConfiguration from '@ijlee2-frontend-configs/eslint-config-node/javascript';<% } %> 2 | 3 | export default [ 4 | { 5 | ignores: [ 6 | 'dist/', 7 | 'dist-for-testing/', 8 | 'node_modules/', 9 | 'src/blueprints/', 10 | 'tests/fixtures/', 11 | 'tmp/', 12 | '.*/', 13 | ], 14 | }, 15 | ...baseConfiguration, 16 | ]; 17 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/src/blueprints/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/src/blueprints/src/blueprints/.gitkeep -------------------------------------------------------------------------------- /packages/cli/src/blueprints/src/index.__js__: -------------------------------------------------------------------------------- 1 | <% if (options.codemod.hasTypeScript) { %>import { addEndOfLine, createOptions } from './steps/index.js'; 2 | import type { CodemodOptions } from './types/index.js'; 3 | 4 | export function runCodemod(codemodOptions: CodemodOptions): void { 5 | const options = createOptions(codemodOptions); 6 | 7 | // TODO: Replace with actual steps 8 | addEndOfLine(options); 9 | }<% } else { %>import { addEndOfLine, createOptions } from './steps/index.js'; 10 | 11 | export function runCodemod(codemodOptions) { 12 | const options = createOptions(codemodOptions); 13 | 14 | // TODO: Replace with actual steps 15 | addEndOfLine(options); 16 | }<% } %> 17 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/src/steps/create-options.__js__: -------------------------------------------------------------------------------- 1 | <% if (options.codemod.hasTypeScript) { %>import type { CodemodOptions, Options } from '../types/index.js'; 2 | 3 | export function createOptions(codemodOptions: CodemodOptions): Options { 4 | const { projectRoot } = codemodOptions; 5 | 6 | return { 7 | projectRoot, 8 | }; 9 | }<% } else { %>export function createOptions(codemodOptions) { 10 | const { projectRoot } = codemodOptions; 11 | 12 | return { 13 | projectRoot, 14 | }; 15 | }<% } %> 16 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/src/steps/index.__js__: -------------------------------------------------------------------------------- 1 | export * from './add-end-of-line.js'; 2 | export * from './create-options.js'; 3 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/src/types/index.ts: -------------------------------------------------------------------------------- 1 | type CodemodOptions = { 2 | projectRoot: string; 3 | }; 4 | 5 | type Options = { 6 | projectRoot: string; 7 | }; 8 | 9 | export type { CodemodOptions, Options }; 10 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/src/utils/blueprints.__js__: -------------------------------------------------------------------------------- 1 | export * from './blueprints/blueprints-root.js'; 2 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/src/utils/blueprints/blueprints-root.__js__: -------------------------------------------------------------------------------- 1 | import { join } from 'node:path'; 2 | 3 | import { getFilePath } from '@codemod-utils/blueprints'; 4 | 5 | const fileURL = import.meta.url; 6 | 7 | export const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints'); 8 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/fixtures/sample-project/index.__js__: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('sample-project/input'); 4 | const outputProject = convertFixtureToJson('sample-project/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/fixtures/sample-project/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/src/blueprints/tests/fixtures/sample-project/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/fixtures/sample-project/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/src/blueprints/tests/fixtures/sample-project/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/helpers/shared-test-setups/sample-project.__js__: -------------------------------------------------------------------------------- 1 | <% if (options.codemod.hasTypeScript) { %>import type { CodemodOptions, Options } from '../../../src/types/index.js'; 2 | 3 | const codemodOptions: CodemodOptions = { 4 | projectRoot: 'tmp/sample-project', 5 | }; 6 | 7 | const options: Options = { 8 | projectRoot: 'tmp/sample-project', 9 | }; 10 | 11 | export { codemodOptions, options };<% } else { %>const codemodOptions = { 12 | projectRoot: 'tmp/sample-project', 13 | }; 14 | 15 | const options = { 16 | projectRoot: 'tmp/sample-project', 17 | }; 18 | 19 | export { codemodOptions, options };<% } %> 20 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/index/sample-project.test.__js__: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { runCodemod } from '../../src/index.js'; 4 | import { 5 | inputProject, 6 | outputProject, 7 | } from '../fixtures/sample-project/index.js'; 8 | import { codemodOptions } from '../helpers/shared-test-setups/sample-project.js'; 9 | 10 | test('index > sample-project', function () { 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | runCodemod(codemodOptions); 14 | 15 | assertFixture(outputProject, codemodOptions); 16 | 17 | // Check idempotence 18 | runCodemod(codemodOptions); 19 | 20 | assertFixture(outputProject, codemodOptions); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/steps/add-end-of-line/base-case.test.__js__: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > base case', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/steps/add-end-of-line/edge-case-file-ends-with-newline.test.__js__: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file ends with newline)', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!\n', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/steps/add-end-of-line/edge-case-file-is-empty.test.__js__: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file is empty)', function () { 10 | const inputProject = { 11 | 'file.txt': '', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': '\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/steps/create-options/sample-project.test.__js__: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | create-options > sample-project', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tests/utils/blueprints/blueprints-root.test.__js__: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { blueprintsRoot } from '../../../src/utils/blueprints.js'; 4 | 5 | test('utils | blueprints | blueprints-root', function () { 6 | assert.strictEqual(blueprintsRoot.endsWith('src/blueprints'), true); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/node20/tsconfig", "@tsconfig/strictest/tsconfig"], 3 | "compilerOptions": { 4 | "declaration": false, 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext", 7 | "outDir": "dist", 8 | "verbatimModuleSyntax": true 9 | }, 10 | "include": ["bin", "src"], 11 | "exclude": ["src/blueprints"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/node20/tsconfig", "@tsconfig/strictest/tsconfig"], 3 | "compilerOptions": { 4 | "declaration": false, 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext", 7 | "outDir": "dist-for-testing", 8 | "verbatimModuleSyntax": true 9 | }, 10 | "include": ["bin", "src", "tests"], 11 | "exclude": ["src/blueprints", "tests/fixtures"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/src/blueprints/update-test-fixtures.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | #---------- 4 | # 5 | # A. Purpose 6 | # 7 | # Fix all test fixtures after updating the source code. 8 | # 9 | # B. Usage 10 | # 11 | # ./update-test-fixtures.sh 12 | # 13 | #--------- 14 | <% if (options.codemod.hasTypeScript) { %> 15 | # Compile TypeScript 16 | pnpm build 17 | <% } %> 18 | # Update fixtures 19 | rm -r "tests/fixtures/sample-project/output" 20 | cp -r "tests/fixtures/sample-project/input" "tests/fixtures/sample-project/output" 21 | 22 | ./dist/bin/<%= options.codemod.name %>.js \ 23 | --root "tests/fixtures/sample-project/output" 24 | -------------------------------------------------------------------------------- /packages/cli/src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createFilesFromBlueprints, 3 | createOptions, 4 | updatePackageJson, 5 | } from './steps/index.js'; 6 | import type { CodemodOptions } from './types/index.js'; 7 | 8 | export function createCodemod(codemodOptions: CodemodOptions): void { 9 | const options = createOptions(codemodOptions); 10 | 11 | createFilesFromBlueprints(options); 12 | updatePackageJson(options); 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli/src/steps/create-options.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../types/index.js'; 2 | 3 | export function createOptions(codemodOptions: CodemodOptions): Options { 4 | const { addons, hasTypeScript, name, projectRoot } = codemodOptions; 5 | 6 | return { 7 | codemod: { 8 | addons, 9 | hasTypeScript, 10 | name, 11 | }, 12 | projectRoot, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /packages/cli/src/steps/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-files-from-blueprints.js'; 2 | export * from './create-options.js'; 3 | export * from './update-package-json.js'; 4 | -------------------------------------------------------------------------------- /packages/cli/src/types/index.ts: -------------------------------------------------------------------------------- 1 | type Addon = 2 | | 'ast-javascript' 3 | | 'ast-template' 4 | | 'blueprints' 5 | | 'ember' 6 | | 'json'; 7 | 8 | type CodemodOptions = { 9 | addons: Set; 10 | hasTypeScript: boolean; 11 | name: string; 12 | projectRoot: string; 13 | }; 14 | 15 | type Options = { 16 | codemod: { 17 | addons: Set; 18 | hasTypeScript: boolean; 19 | name: string; 20 | }; 21 | projectRoot: string; 22 | }; 23 | 24 | export type { CodemodOptions, Options }; 25 | -------------------------------------------------------------------------------- /packages/cli/src/utils/blueprints.ts: -------------------------------------------------------------------------------- 1 | export * from './blueprints/blueprints-root.js'; 2 | export * from './blueprints/get-version.js'; 3 | -------------------------------------------------------------------------------- /packages/cli/src/utils/blueprints/blueprints-root.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'node:path'; 2 | 3 | import { getFilePath } from '@codemod-utils/blueprints'; 4 | 5 | const fileURL = import.meta.url; 6 | 7 | export const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints'); 8 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/index.js: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('javascript-with-addons/input'); 4 | const outputProject = convertFixtureToJson('javascript-with-addons/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript-with-addons/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript-with-addons/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "./format-changelogs.cjs", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/.github/ISSUE_TEMPLATE/ask-for-better-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for better documentation 3 | about: Ask for better documentation 4 | title: '' 5 | labels: 'enhance: documentation' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve documentation. 11 | 12 | Here, documentation can mean a few different things, including README, code comments, and tests. Anything that will help everyone understand how to use `ember-codemod-args-to-signature`! 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/.github/ISSUE_TEMPLATE/ask-for-new-feature-or-refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for new feature or refactor 3 | about: Ask for new feature or refactor 4 | title: '' 5 | labels: 'enhance: code' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve `ember-codemod-args-to-signature`. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has made a request already. 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/.github/ISSUE_TEMPLATE/report-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report bug 3 | about: Report bug 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to make a bug report. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has reported this bug already. 13 | 14 | 15 | ## Describe the bug 🐞 16 | 17 | A clear and concise description of the bug. 18 | 19 | 20 | ## Expected behavior 🤔 21 | 22 | A clear and concise description of what you expected to see. 23 | 24 | 25 | ## Minimal reproduction 🔬 26 | 27 | Describe steps to reproduce the issue. 28 | 29 | 1. ... 30 | 1. ... 31 | 1. ... 32 | 33 | If possible, please share a repo with the minimum files to reproduce the issue. 34 | 35 | 36 | ## Additional context ➕ 37 | 38 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the problem here. 39 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | dist/ 3 | dist-for-testing/ 4 | tmp/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # misc 10 | .DS_Store 11 | .env* 12 | .eslintcache 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist-for-testing/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /node_modules/ 7 | 8 | # misc 9 | /.DS_Store 10 | /.env* 11 | /.eslintcache 12 | /.git/ 13 | /.github/ 14 | /.gitignore 15 | /.pnpm-debug.log 16 | /.prettierignore 17 | /build.sh 18 | /CONTRIBUTING.md 19 | /eslint.config.mjs 20 | /prettier.config.mjs 21 | /tests/ 22 | /update-test-fixtures.sh 23 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | /src/blueprints/ 8 | /tests/fixtures/ 9 | !.* 10 | .*/ 11 | CONTRIBUTING.md 12 | README.md 13 | pnpm-lock.yaml 14 | 15 | # specific to this package 16 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/bin/ember-codemod-args-to-signature.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | import yargs from 'yargs'; 5 | import { hideBin } from 'yargs/helpers'; 6 | 7 | import { runCodemod } from '../src/index.js'; 8 | 9 | // Provide a title to the process in `ps` 10 | process.title = 'ember-codemod-args-to-signature'; 11 | 12 | // Set codemod options 13 | const argv = yargs(hideBin(process.argv)) 14 | .option('root', { 15 | describe: 'Where to run the codemod', 16 | type: 'string', 17 | }) 18 | .parseSync(); 19 | 20 | const codemodOptions = { 21 | projectRoot: argv['root'] ?? process.cwd(), 22 | }; 23 | 24 | runCodemod(codemodOptions); 25 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import baseConfiguration from '@ijlee2-frontend-configs/eslint-config-node/javascript'; 2 | 3 | export default [ 4 | { 5 | ignores: [ 6 | 'dist/', 7 | 'dist-for-testing/', 8 | 'node_modules/', 9 | 'src/blueprints/', 10 | 'tests/fixtures/', 11 | 'tmp/', 12 | '.*/', 13 | ], 14 | }, 15 | ...baseConfiguration, 16 | ]; 17 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/blueprints/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/blueprints/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/index.js: -------------------------------------------------------------------------------- 1 | import { addEndOfLine, createOptions } from './steps/index.js'; 2 | 3 | export function runCodemod(codemodOptions) { 4 | const options = createOptions(codemodOptions); 5 | 6 | // TODO: Replace with actual steps 7 | addEndOfLine(options); 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/steps/add-end-of-line.js: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'node:fs'; 2 | import { join } from 'node:path'; 3 | 4 | import { createFiles, findFiles } from '@codemod-utils/files'; 5 | 6 | export function addEndOfLine(options) { 7 | const { projectRoot } = options; 8 | 9 | const filePaths = findFiles('**/*.txt', { 10 | projectRoot, 11 | }); 12 | 13 | const fileMap = new Map( 14 | filePaths.map((filePath) => { 15 | const file = readFileSync(join(projectRoot, filePath), 'utf8'); 16 | 17 | const newFile = file.endsWith('\n') ? file : `${file}\n`; 18 | 19 | return [filePath, newFile]; 20 | }), 21 | ); 22 | 23 | createFiles(fileMap, options); 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/steps/create-options.js: -------------------------------------------------------------------------------- 1 | export function createOptions(codemodOptions) { 2 | const { projectRoot } = codemodOptions; 3 | 4 | return { 5 | projectRoot, 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/steps/index.js: -------------------------------------------------------------------------------- 1 | export * from './add-end-of-line.js'; 2 | export * from './create-options.js'; 3 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/utils/blueprints.js: -------------------------------------------------------------------------------- 1 | export * from './blueprints/blueprints-root.js'; 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/src/utils/blueprints/blueprints-root.js: -------------------------------------------------------------------------------- 1 | import { join } from 'node:path'; 2 | 3 | import { getFilePath } from '@codemod-utils/blueprints'; 4 | 5 | const fileURL = import.meta.url; 6 | 7 | export const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints'); 8 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/index.js: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('sample-project/input'); 4 | const outputProject = convertFixtureToJson('sample-project/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/helpers/shared-test-setups/sample-project.js: -------------------------------------------------------------------------------- 1 | const codemodOptions = { 2 | projectRoot: 'tmp/sample-project', 3 | }; 4 | 5 | const options = { 6 | projectRoot: 'tmp/sample-project', 7 | }; 8 | 9 | export { codemodOptions, options }; 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/index/sample-project.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { runCodemod } from '../../src/index.js'; 4 | import { 5 | inputProject, 6 | outputProject, 7 | } from '../fixtures/sample-project/index.js'; 8 | import { codemodOptions } from '../helpers/shared-test-setups/sample-project.js'; 9 | 10 | test('index > sample-project', function () { 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | runCodemod(codemodOptions); 14 | 15 | assertFixture(outputProject, codemodOptions); 16 | 17 | // Check idempotence 18 | runCodemod(codemodOptions); 19 | 20 | assertFixture(outputProject, codemodOptions); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/steps/add-end-of-line/base-case.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > base case', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/steps/add-end-of-line/edge-case-file-ends-with-newline.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file ends with newline)', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!\n', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/steps/add-end-of-line/edge-case-file-is-empty.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file is empty)', function () { 10 | const inputProject = { 11 | 'file.txt': '', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': '\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/steps/create-options/sample-project.test.js: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | create-options > sample-project', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/tests/utils/blueprints/blueprints-root.test.js: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { blueprintsRoot } from '../../../src/utils/blueprints.js'; 4 | 5 | test('utils | blueprints | blueprints-root', function () { 6 | assert.strictEqual(blueprintsRoot.endsWith('src/blueprints'), true); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript-with-addons/output/ember-codemod-args-to-signature/update-test-fixtures.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | #---------- 4 | # 5 | # A. Purpose 6 | # 7 | # Fix all test fixtures after updating the source code. 8 | # 9 | # B. Usage 10 | # 11 | # ./update-test-fixtures.sh 12 | # 13 | #--------- 14 | 15 | # Update fixtures 16 | rm -r "tests/fixtures/sample-project/output" 17 | cp -r "tests/fixtures/sample-project/input" "tests/fixtures/sample-project/output" 18 | 19 | ./dist/bin/ember-codemod-args-to-signature.js \ 20 | --root "tests/fixtures/sample-project/output" 21 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/index.js: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('javascript/input'); 4 | const outputProject = convertFixtureToJson('javascript/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "./format-changelogs.cjs", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/.github/ISSUE_TEMPLATE/ask-for-better-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for better documentation 3 | about: Ask for better documentation 4 | title: '' 5 | labels: 'enhance: documentation' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve documentation. 11 | 12 | Here, documentation can mean a few different things, including README, code comments, and tests. Anything that will help everyone understand how to use `ember-codemod-pod-to-octane`! 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/.github/ISSUE_TEMPLATE/ask-for-new-feature-or-refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for new feature or refactor 3 | about: Ask for new feature or refactor 4 | title: '' 5 | labels: 'enhance: code' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve `ember-codemod-pod-to-octane`. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has made a request already. 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/.github/ISSUE_TEMPLATE/report-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report bug 3 | about: Report bug 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to make a bug report. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has reported this bug already. 13 | 14 | 15 | ## Describe the bug 🐞 16 | 17 | A clear and concise description of the bug. 18 | 19 | 20 | ## Expected behavior 🤔 21 | 22 | A clear and concise description of what you expected to see. 23 | 24 | 25 | ## Minimal reproduction 🔬 26 | 27 | Describe steps to reproduce the issue. 28 | 29 | 1. ... 30 | 1. ... 31 | 1. ... 32 | 33 | If possible, please share a repo with the minimum files to reproduce the issue. 34 | 35 | 36 | ## Additional context ➕ 37 | 38 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the problem here. 39 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | dist/ 3 | dist-for-testing/ 4 | tmp/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # misc 10 | .DS_Store 11 | .env* 12 | .eslintcache 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist-for-testing/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /node_modules/ 7 | 8 | # misc 9 | /.DS_Store 10 | /.env* 11 | /.eslintcache 12 | /.git/ 13 | /.github/ 14 | /.gitignore 15 | /.pnpm-debug.log 16 | /.prettierignore 17 | /build.sh 18 | /CONTRIBUTING.md 19 | /eslint.config.mjs 20 | /prettier.config.mjs 21 | /tests/ 22 | /update-test-fixtures.sh 23 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | /src/blueprints/ 8 | /tests/fixtures/ 9 | !.* 10 | .*/ 11 | CONTRIBUTING.md 12 | README.md 13 | pnpm-lock.yaml 14 | 15 | # specific to this package 16 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/bin/ember-codemod-pod-to-octane.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | import yargs from 'yargs'; 5 | import { hideBin } from 'yargs/helpers'; 6 | 7 | import { runCodemod } from '../src/index.js'; 8 | 9 | // Provide a title to the process in `ps` 10 | process.title = 'ember-codemod-pod-to-octane'; 11 | 12 | // Set codemod options 13 | const argv = yargs(hideBin(process.argv)) 14 | .option('root', { 15 | describe: 'Where to run the codemod', 16 | type: 'string', 17 | }) 18 | .parseSync(); 19 | 20 | const codemodOptions = { 21 | projectRoot: argv['root'] ?? process.cwd(), 22 | }; 23 | 24 | runCodemod(codemodOptions); 25 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import baseConfiguration from '@ijlee2-frontend-configs/eslint-config-node/javascript'; 2 | 3 | export default [ 4 | { 5 | ignores: [ 6 | 'dist/', 7 | 'dist-for-testing/', 8 | 'node_modules/', 9 | 'src/blueprints/', 10 | 'tests/fixtures/', 11 | 'tmp/', 12 | '.*/', 13 | ], 14 | }, 15 | ...baseConfiguration, 16 | ]; 17 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/src/index.js: -------------------------------------------------------------------------------- 1 | import { addEndOfLine, createOptions } from './steps/index.js'; 2 | 3 | export function runCodemod(codemodOptions) { 4 | const options = createOptions(codemodOptions); 5 | 6 | // TODO: Replace with actual steps 7 | addEndOfLine(options); 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/src/steps/add-end-of-line.js: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'node:fs'; 2 | import { join } from 'node:path'; 3 | 4 | import { createFiles, findFiles } from '@codemod-utils/files'; 5 | 6 | export function addEndOfLine(options) { 7 | const { projectRoot } = options; 8 | 9 | const filePaths = findFiles('**/*.txt', { 10 | projectRoot, 11 | }); 12 | 13 | const fileMap = new Map( 14 | filePaths.map((filePath) => { 15 | const file = readFileSync(join(projectRoot, filePath), 'utf8'); 16 | 17 | const newFile = file.endsWith('\n') ? file : `${file}\n`; 18 | 19 | return [filePath, newFile]; 20 | }), 21 | ); 22 | 23 | createFiles(fileMap, options); 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/src/steps/create-options.js: -------------------------------------------------------------------------------- 1 | export function createOptions(codemodOptions) { 2 | const { projectRoot } = codemodOptions; 3 | 4 | return { 5 | projectRoot, 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/src/steps/index.js: -------------------------------------------------------------------------------- 1 | export * from './add-end-of-line.js'; 2 | export * from './create-options.js'; 3 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/index.js: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('sample-project/input'); 4 | const outputProject = convertFixtureToJson('sample-project/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/helpers/shared-test-setups/sample-project.js: -------------------------------------------------------------------------------- 1 | const codemodOptions = { 2 | projectRoot: 'tmp/sample-project', 3 | }; 4 | 5 | const options = { 6 | projectRoot: 'tmp/sample-project', 7 | }; 8 | 9 | export { codemodOptions, options }; 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/index/sample-project.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { runCodemod } from '../../src/index.js'; 4 | import { 5 | inputProject, 6 | outputProject, 7 | } from '../fixtures/sample-project/index.js'; 8 | import { codemodOptions } from '../helpers/shared-test-setups/sample-project.js'; 9 | 10 | test('index > sample-project', function () { 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | runCodemod(codemodOptions); 14 | 15 | assertFixture(outputProject, codemodOptions); 16 | 17 | // Check idempotence 18 | runCodemod(codemodOptions); 19 | 20 | assertFixture(outputProject, codemodOptions); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/steps/add-end-of-line/base-case.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > base case', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/steps/add-end-of-line/edge-case-file-ends-with-newline.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file ends with newline)', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!\n', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/steps/add-end-of-line/edge-case-file-is-empty.test.js: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file is empty)', function () { 10 | const inputProject = { 11 | 'file.txt': '', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': '\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/tests/steps/create-options/sample-project.test.js: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | create-options > sample-project', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/javascript/output/ember-codemod-pod-to-octane/update-test-fixtures.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | #---------- 4 | # 5 | # A. Purpose 6 | # 7 | # Fix all test fixtures after updating the source code. 8 | # 9 | # B. Usage 10 | # 11 | # ./update-test-fixtures.sh 12 | # 13 | #--------- 14 | 15 | # Update fixtures 16 | rm -r "tests/fixtures/sample-project/output" 17 | cp -r "tests/fixtures/sample-project/input" "tests/fixtures/sample-project/output" 18 | 19 | ./dist/bin/ember-codemod-pod-to-octane.js \ 20 | --root "tests/fixtures/sample-project/output" 21 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/index.js: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('typescript-with-addons/input'); 4 | const outputProject = convertFixtureToJson('typescript-with-addons/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript-with-addons/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript-with-addons/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "./format-changelogs.cjs", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/.github/ISSUE_TEMPLATE/ask-for-better-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for better documentation 3 | about: Ask for better documentation 4 | title: '' 5 | labels: 'enhance: documentation' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve documentation. 11 | 12 | Here, documentation can mean a few different things, including README, code comments, and tests. Anything that will help everyone understand how to use `ember-codemod-args-to-signature`! 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/.github/ISSUE_TEMPLATE/ask-for-new-feature-or-refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for new feature or refactor 3 | about: Ask for new feature or refactor 4 | title: '' 5 | labels: 'enhance: code' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve `ember-codemod-args-to-signature`. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has made a request already. 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/.github/ISSUE_TEMPLATE/report-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report bug 3 | about: Report bug 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to make a bug report. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has reported this bug already. 13 | 14 | 15 | ## Describe the bug 🐞 16 | 17 | A clear and concise description of the bug. 18 | 19 | 20 | ## Expected behavior 🤔 21 | 22 | A clear and concise description of what you expected to see. 23 | 24 | 25 | ## Minimal reproduction 🔬 26 | 27 | Describe steps to reproduce the issue. 28 | 29 | 1. ... 30 | 1. ... 31 | 1. ... 32 | 33 | If possible, please share a repo with the minimum files to reproduce the issue. 34 | 35 | 36 | ## Additional context ➕ 37 | 38 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the problem here. 39 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | dist/ 3 | dist-for-testing/ 4 | tmp/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # misc 10 | .DS_Store 11 | .env* 12 | .eslintcache 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist-for-testing/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /node_modules/ 7 | 8 | # misc 9 | /.DS_Store 10 | /.env* 11 | /.eslintcache 12 | /.git/ 13 | /.github/ 14 | /.gitignore 15 | /.pnpm-debug.log 16 | /.prettierignore 17 | /build.sh 18 | /CONTRIBUTING.md 19 | /eslint.config.mjs 20 | /prettier.config.mjs 21 | /tests/ 22 | /update-test-fixtures.sh 23 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | /src/blueprints/ 8 | /tests/fixtures/ 9 | !.* 10 | .*/ 11 | CONTRIBUTING.md 12 | README.md 13 | pnpm-lock.yaml 14 | 15 | # specific to this package 16 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/bin/ember-codemod-args-to-signature.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | import yargs from 'yargs'; 5 | import { hideBin } from 'yargs/helpers'; 6 | 7 | import { runCodemod } from '../src/index.js'; 8 | import type { CodemodOptions } from '../src/types/index.js'; 9 | 10 | // Provide a title to the process in `ps` 11 | process.title = 'ember-codemod-args-to-signature'; 12 | 13 | // Set codemod options 14 | const argv = yargs(hideBin(process.argv)) 15 | .option('root', { 16 | describe: 'Where to run the codemod', 17 | type: 'string', 18 | }) 19 | .parseSync(); 20 | 21 | const codemodOptions: CodemodOptions = { 22 | projectRoot: argv['root'] ?? process.cwd(), 23 | }; 24 | 25 | runCodemod(codemodOptions); 26 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | COMMAND="ember-codemod-args-to-signature" 4 | ENVIRONMENT=$1 5 | 6 | if [ $ENVIRONMENT = "--production" ] 7 | then 8 | # Clean slate 9 | rm -rf "dist" 10 | 11 | # Compile TypeScript 12 | tsc --project "tsconfig.build.json" 13 | 14 | # Configure files 15 | chmod +x "dist/bin/$COMMAND.js" 16 | 17 | if [ -d "src/blueprints" ] 18 | then 19 | cp -r "src/blueprints" "dist/src/blueprints" 20 | fi 21 | 22 | echo "SUCCESS: Built dist.\n" 23 | 24 | elif [ $ENVIRONMENT = "--test" ] 25 | then 26 | # Clean slate 27 | rm -rf "dist-for-testing" 28 | 29 | # Compile TypeScript 30 | tsc --project "tsconfig.json" 31 | 32 | # Configure files 33 | if [ -d "src/blueprints" ] 34 | then 35 | cp -r "src/blueprints" "dist-for-testing/src/blueprints" 36 | fi 37 | 38 | echo "SUCCESS: Built dist-for-testing.\n" 39 | 40 | fi 41 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import baseConfiguration from '@ijlee2-frontend-configs/eslint-config-node/typescript'; 2 | 3 | export default [ 4 | { 5 | ignores: [ 6 | 'dist/', 7 | 'dist-for-testing/', 8 | 'node_modules/', 9 | 'src/blueprints/', 10 | 'tests/fixtures/', 11 | 'tmp/', 12 | '.*/', 13 | ], 14 | }, 15 | ...baseConfiguration, 16 | ]; 17 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/blueprints/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/blueprints/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/index.ts: -------------------------------------------------------------------------------- 1 | import { addEndOfLine, createOptions } from './steps/index.js'; 2 | import type { CodemodOptions } from './types/index.js'; 3 | 4 | export function runCodemod(codemodOptions: CodemodOptions): void { 5 | const options = createOptions(codemodOptions); 6 | 7 | // TODO: Replace with actual steps 8 | addEndOfLine(options); 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/steps/add-end-of-line.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'node:fs'; 2 | import { join } from 'node:path'; 3 | 4 | import { createFiles, findFiles } from '@codemod-utils/files'; 5 | 6 | import type { Options } from '../types/index.js'; 7 | 8 | export function addEndOfLine(options: Options): void { 9 | const { projectRoot } = options; 10 | 11 | const filePaths = findFiles('**/*.txt', { 12 | projectRoot, 13 | }); 14 | 15 | const fileMap = new Map( 16 | filePaths.map((filePath) => { 17 | const file = readFileSync(join(projectRoot, filePath), 'utf8'); 18 | 19 | const newFile = file.endsWith('\n') ? file : `${file}\n`; 20 | 21 | return [filePath, newFile]; 22 | }), 23 | ); 24 | 25 | createFiles(fileMap, options); 26 | } 27 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/steps/create-options.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../types/index.js'; 2 | 3 | export function createOptions(codemodOptions: CodemodOptions): Options { 4 | const { projectRoot } = codemodOptions; 5 | 6 | return { 7 | projectRoot, 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/steps/index.ts: -------------------------------------------------------------------------------- 1 | export * from './add-end-of-line.js'; 2 | export * from './create-options.js'; 3 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/types/index.ts: -------------------------------------------------------------------------------- 1 | type CodemodOptions = { 2 | projectRoot: string; 3 | }; 4 | 5 | type Options = { 6 | projectRoot: string; 7 | }; 8 | 9 | export type { CodemodOptions, Options }; 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/utils/blueprints.ts: -------------------------------------------------------------------------------- 1 | export * from './blueprints/blueprints-root.js'; 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/src/utils/blueprints/blueprints-root.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'node:path'; 2 | 3 | import { getFilePath } from '@codemod-utils/blueprints'; 4 | 5 | const fileURL = import.meta.url; 6 | 7 | export const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints'); 8 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/index.ts: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('sample-project/input'); 4 | const outputProject = convertFixtureToJson('sample-project/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/fixtures/sample-project/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/helpers/shared-test-setups/sample-project.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../../../src/types/index.js'; 2 | 3 | const codemodOptions: CodemodOptions = { 4 | projectRoot: 'tmp/sample-project', 5 | }; 6 | 7 | const options: Options = { 8 | projectRoot: 'tmp/sample-project', 9 | }; 10 | 11 | export { codemodOptions, options }; 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/index/sample-project.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { runCodemod } from '../../src/index.js'; 4 | import { 5 | inputProject, 6 | outputProject, 7 | } from '../fixtures/sample-project/index.js'; 8 | import { codemodOptions } from '../helpers/shared-test-setups/sample-project.js'; 9 | 10 | test('index > sample-project', function () { 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | runCodemod(codemodOptions); 14 | 15 | assertFixture(outputProject, codemodOptions); 16 | 17 | // Check idempotence 18 | runCodemod(codemodOptions); 19 | 20 | assertFixture(outputProject, codemodOptions); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/steps/add-end-of-line/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > base case', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/steps/add-end-of-line/edge-case-file-ends-with-newline.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file ends with newline)', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!\n', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/steps/add-end-of-line/edge-case-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file is empty)', function () { 10 | const inputProject = { 11 | 'file.txt': '', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': '\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/steps/create-options/sample-project.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | create-options > sample-project', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tests/utils/blueprints/blueprints-root.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { blueprintsRoot } from '../../../src/utils/blueprints.js'; 4 | 5 | test('utils | blueprints | blueprints-root', function () { 6 | assert.strictEqual(blueprintsRoot.endsWith('src/blueprints'), true); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/node20/tsconfig", "@tsconfig/strictest/tsconfig"], 3 | "compilerOptions": { 4 | "declaration": false, 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext", 7 | "outDir": "dist", 8 | "verbatimModuleSyntax": true 9 | }, 10 | "include": ["bin", "src"], 11 | "exclude": ["src/blueprints"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/node20/tsconfig", "@tsconfig/strictest/tsconfig"], 3 | "compilerOptions": { 4 | "declaration": false, 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext", 7 | "outDir": "dist-for-testing", 8 | "verbatimModuleSyntax": true 9 | }, 10 | "include": ["bin", "src", "tests"], 11 | "exclude": ["src/blueprints", "tests/fixtures"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript-with-addons/output/ember-codemod-args-to-signature/update-test-fixtures.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | #---------- 4 | # 5 | # A. Purpose 6 | # 7 | # Fix all test fixtures after updating the source code. 8 | # 9 | # B. Usage 10 | # 11 | # ./update-test-fixtures.sh 12 | # 13 | #--------- 14 | 15 | # Compile TypeScript 16 | pnpm build 17 | 18 | # Update fixtures 19 | rm -r "tests/fixtures/sample-project/output" 20 | cp -r "tests/fixtures/sample-project/input" "tests/fixtures/sample-project/output" 21 | 22 | ./dist/bin/ember-codemod-args-to-signature.js \ 23 | --root "tests/fixtures/sample-project/output" 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/index.js: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('typescript/input'); 4 | const outputProject = convertFixtureToJson('typescript/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "./format-changelogs.cjs", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/.github/ISSUE_TEMPLATE/ask-for-better-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for better documentation 3 | about: Ask for better documentation 4 | title: '' 5 | labels: 'enhance: documentation' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve documentation. 11 | 12 | Here, documentation can mean a few different things, including README, code comments, and tests. Anything that will help everyone understand how to use `ember-codemod-pod-to-octane`! 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/.github/ISSUE_TEMPLATE/ask-for-new-feature-or-refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask for new feature or refactor 3 | about: Ask for new feature or refactor 4 | title: '' 5 | labels: 'enhance: code' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to suggest how we can improve `ember-codemod-pod-to-octane`. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has made a request already. 13 | 14 | 15 | ## I would like to see... 🙋‍♀️🙋‍♂️ 16 | 17 | A clear, concise description of what you want to happen. 18 | 19 | 20 | ## Why and how 💬 21 | 22 | A clear, concise description of why you want something to happen and how we might be able to solve the problem. 23 | 24 | 25 | ## Additional context ➕ 26 | 27 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the request here. 28 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/.github/ISSUE_TEMPLATE/report-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report bug 3 | about: Report bug 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | Hello! Thanks for taking time to make a bug report. 11 | 12 | Before you make a new issue, please search for similar issues. It's possible that someone has reported this bug already. 13 | 14 | 15 | ## Describe the bug 🐞 16 | 17 | A clear and concise description of the bug. 18 | 19 | 20 | ## Expected behavior 🤔 21 | 22 | A clear and concise description of what you expected to see. 23 | 24 | 25 | ## Minimal reproduction 🔬 26 | 27 | Describe steps to reproduce the issue. 28 | 29 | 1. ... 30 | 1. ... 31 | 1. ... 32 | 33 | If possible, please share a repo with the minimum files to reproduce the issue. 34 | 35 | 36 | ## Additional context ➕ 37 | 38 | If needed, you can provide more context (e.g. reference materials, screenshots, GIFs) for the problem here. 39 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | dist/ 3 | dist-for-testing/ 4 | tmp/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # misc 10 | .DS_Store 11 | .env* 12 | .eslintcache 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist-for-testing/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /node_modules/ 7 | 8 | # misc 9 | /.DS_Store 10 | /.env* 11 | /.eslintcache 12 | /.git/ 13 | /.github/ 14 | /.gitignore 15 | /.pnpm-debug.log 16 | /.prettierignore 17 | /build.sh 18 | /CONTRIBUTING.md 19 | /eslint.config.mjs 20 | /prettier.config.mjs 21 | /tests/ 22 | /update-test-fixtures.sh 23 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | /src/blueprints/ 8 | /tests/fixtures/ 9 | !.* 10 | .*/ 11 | CONTRIBUTING.md 12 | README.md 13 | pnpm-lock.yaml 14 | 15 | # specific to this package 16 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/bin/ember-codemod-pod-to-octane.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | import yargs from 'yargs'; 5 | import { hideBin } from 'yargs/helpers'; 6 | 7 | import { runCodemod } from '../src/index.js'; 8 | import type { CodemodOptions } from '../src/types/index.js'; 9 | 10 | // Provide a title to the process in `ps` 11 | process.title = 'ember-codemod-pod-to-octane'; 12 | 13 | // Set codemod options 14 | const argv = yargs(hideBin(process.argv)) 15 | .option('root', { 16 | describe: 'Where to run the codemod', 17 | type: 'string', 18 | }) 19 | .parseSync(); 20 | 21 | const codemodOptions: CodemodOptions = { 22 | projectRoot: argv['root'] ?? process.cwd(), 23 | }; 24 | 25 | runCodemod(codemodOptions); 26 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | COMMAND="ember-codemod-pod-to-octane" 4 | ENVIRONMENT=$1 5 | 6 | if [ $ENVIRONMENT = "--production" ] 7 | then 8 | # Clean slate 9 | rm -rf "dist" 10 | 11 | # Compile TypeScript 12 | tsc --project "tsconfig.build.json" 13 | 14 | # Configure files 15 | chmod +x "dist/bin/$COMMAND.js" 16 | 17 | if [ -d "src/blueprints" ] 18 | then 19 | cp -r "src/blueprints" "dist/src/blueprints" 20 | fi 21 | 22 | echo "SUCCESS: Built dist.\n" 23 | 24 | elif [ $ENVIRONMENT = "--test" ] 25 | then 26 | # Clean slate 27 | rm -rf "dist-for-testing" 28 | 29 | # Compile TypeScript 30 | tsc --project "tsconfig.json" 31 | 32 | # Configure files 33 | if [ -d "src/blueprints" ] 34 | then 35 | cp -r "src/blueprints" "dist-for-testing/src/blueprints" 36 | fi 37 | 38 | echo "SUCCESS: Built dist-for-testing.\n" 39 | 40 | fi 41 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import baseConfiguration from '@ijlee2-frontend-configs/eslint-config-node/typescript'; 2 | 3 | export default [ 4 | { 5 | ignores: [ 6 | 'dist/', 7 | 'dist-for-testing/', 8 | 'node_modules/', 9 | 'src/blueprints/', 10 | 'tests/fixtures/', 11 | 'tmp/', 12 | '.*/', 13 | ], 14 | }, 15 | ...baseConfiguration, 16 | ]; 17 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@ijlee2-frontend-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/src/index.ts: -------------------------------------------------------------------------------- 1 | import { addEndOfLine, createOptions } from './steps/index.js'; 2 | import type { CodemodOptions } from './types/index.js'; 3 | 4 | export function runCodemod(codemodOptions: CodemodOptions): void { 5 | const options = createOptions(codemodOptions); 6 | 7 | // TODO: Replace with actual steps 8 | addEndOfLine(options); 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/src/steps/add-end-of-line.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'node:fs'; 2 | import { join } from 'node:path'; 3 | 4 | import { createFiles, findFiles } from '@codemod-utils/files'; 5 | 6 | import type { Options } from '../types/index.js'; 7 | 8 | export function addEndOfLine(options: Options): void { 9 | const { projectRoot } = options; 10 | 11 | const filePaths = findFiles('**/*.txt', { 12 | projectRoot, 13 | }); 14 | 15 | const fileMap = new Map( 16 | filePaths.map((filePath) => { 17 | const file = readFileSync(join(projectRoot, filePath), 'utf8'); 18 | 19 | const newFile = file.endsWith('\n') ? file : `${file}\n`; 20 | 21 | return [filePath, newFile]; 22 | }), 23 | ); 24 | 25 | createFiles(fileMap, options); 26 | } 27 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/src/steps/create-options.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../types/index.js'; 2 | 3 | export function createOptions(codemodOptions: CodemodOptions): Options { 4 | const { projectRoot } = codemodOptions; 5 | 6 | return { 7 | projectRoot, 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/src/steps/index.ts: -------------------------------------------------------------------------------- 1 | export * from './add-end-of-line.js'; 2 | export * from './create-options.js'; 3 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/src/types/index.ts: -------------------------------------------------------------------------------- 1 | type CodemodOptions = { 2 | projectRoot: string; 3 | }; 4 | 5 | type Options = { 6 | projectRoot: string; 7 | }; 8 | 9 | export type { CodemodOptions, Options }; 10 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/index.ts: -------------------------------------------------------------------------------- 1 | import { convertFixtureToJson } from '@codemod-utils/tests'; 2 | 3 | const inputProject = convertFixtureToJson('sample-project/input'); 4 | const outputProject = convertFixtureToJson('sample-project/output'); 5 | 6 | export { inputProject, outputProject }; 7 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/input/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/input/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/fixtures/sample-project/output/.gitkeep -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/helpers/shared-test-setups/sample-project.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../../../src/types/index.js'; 2 | 3 | const codemodOptions: CodemodOptions = { 4 | projectRoot: 'tmp/sample-project', 5 | }; 6 | 7 | const options: Options = { 8 | projectRoot: 'tmp/sample-project', 9 | }; 10 | 11 | export { codemodOptions, options }; 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/index/sample-project.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { runCodemod } from '../../src/index.js'; 4 | import { 5 | inputProject, 6 | outputProject, 7 | } from '../fixtures/sample-project/index.js'; 8 | import { codemodOptions } from '../helpers/shared-test-setups/sample-project.js'; 9 | 10 | test('index > sample-project', function () { 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | runCodemod(codemodOptions); 14 | 15 | assertFixture(outputProject, codemodOptions); 16 | 17 | // Check idempotence 18 | runCodemod(codemodOptions); 19 | 20 | assertFixture(outputProject, codemodOptions); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/steps/add-end-of-line/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > base case', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/steps/add-end-of-line/edge-case-file-ends-with-newline.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file ends with newline)', function () { 10 | const inputProject = { 11 | 'file.txt': 'Hello world!\n', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': 'Hello world!\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/steps/add-end-of-line/edge-case-file-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { addEndOfLine } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | add-end-of-line > edge case (file is empty)', function () { 10 | const inputProject = { 11 | 'file.txt': '', 12 | }; 13 | 14 | const outputProject = { 15 | 'file.txt': '\n', 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | addEndOfLine(options); 21 | 22 | assertFixture(outputProject, codemodOptions); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tests/steps/create-options/sample-project.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/sample-project.js'; 8 | 9 | test('steps | create-options > sample-project', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/node20/tsconfig", "@tsconfig/strictest/tsconfig"], 3 | "compilerOptions": { 4 | "declaration": false, 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext", 7 | "outDir": "dist", 8 | "verbatimModuleSyntax": true 9 | }, 10 | "include": ["bin", "src"], 11 | "exclude": ["src/blueprints"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@tsconfig/node20/tsconfig", "@tsconfig/strictest/tsconfig"], 3 | "compilerOptions": { 4 | "declaration": false, 5 | "module": "nodenext", 6 | "moduleResolution": "nodenext", 7 | "outDir": "dist-for-testing", 8 | "verbatimModuleSyntax": true 9 | }, 10 | "include": ["bin", "src", "tests"], 11 | "exclude": ["src/blueprints", "tests/fixtures"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/tests/fixtures/typescript/output/ember-codemod-pod-to-octane/update-test-fixtures.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | #---------- 4 | # 5 | # A. Purpose 6 | # 7 | # Fix all test fixtures after updating the source code. 8 | # 9 | # B. Usage 10 | # 11 | # ./update-test-fixtures.sh 12 | # 13 | #--------- 14 | 15 | # Compile TypeScript 16 | pnpm build 17 | 18 | # Update fixtures 19 | rm -r "tests/fixtures/sample-project/output" 20 | cp -r "tests/fixtures/sample-project/input" "tests/fixtures/sample-project/output" 21 | 22 | ./dist/bin/ember-codemod-pod-to-octane.js \ 23 | --root "tests/fixtures/sample-project/output" 24 | -------------------------------------------------------------------------------- /packages/cli/tests/helpers/shared-test-setups/javascript-with-addons.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../../../src/types/index.js'; 2 | 3 | const codemodOptions: CodemodOptions = { 4 | addons: new Set([ 5 | 'ast-javascript', 6 | 'ast-template', 7 | 'blueprints', 8 | 'ember', 9 | 'json', 10 | ]), 11 | hasTypeScript: false, 12 | name: 'ember-codemod-args-to-signature', 13 | projectRoot: 'tmp/javascript-with-addons', 14 | }; 15 | 16 | const options: Options = { 17 | codemod: { 18 | addons: new Set([ 19 | 'ast-javascript', 20 | 'ast-template', 21 | 'blueprints', 22 | 'ember', 23 | 'json', 24 | ]), 25 | hasTypeScript: false, 26 | name: 'ember-codemod-args-to-signature', 27 | }, 28 | projectRoot: 'tmp/javascript-with-addons', 29 | }; 30 | 31 | export { codemodOptions, options }; 32 | -------------------------------------------------------------------------------- /packages/cli/tests/helpers/shared-test-setups/javascript.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../../../src/types/index.js'; 2 | 3 | const codemodOptions: CodemodOptions = { 4 | addons: new Set(), 5 | hasTypeScript: false, 6 | name: 'ember-codemod-pod-to-octane', 7 | projectRoot: 'tmp/javascript', 8 | }; 9 | 10 | const options: Options = { 11 | codemod: { 12 | addons: new Set(), 13 | hasTypeScript: false, 14 | name: 'ember-codemod-pod-to-octane', 15 | }, 16 | projectRoot: 'tmp/javascript', 17 | }; 18 | 19 | export { codemodOptions, options }; 20 | -------------------------------------------------------------------------------- /packages/cli/tests/helpers/shared-test-setups/typescript-with-addons.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../../../src/types/index.js'; 2 | 3 | const codemodOptions: CodemodOptions = { 4 | addons: new Set([ 5 | 'ast-javascript', 6 | 'ast-template', 7 | 'blueprints', 8 | 'ember', 9 | 'json', 10 | ]), 11 | hasTypeScript: true, 12 | name: 'ember-codemod-args-to-signature', 13 | projectRoot: 'tmp/typescript-with-addons', 14 | }; 15 | 16 | const options: Options = { 17 | codemod: { 18 | addons: new Set([ 19 | 'ast-javascript', 20 | 'ast-template', 21 | 'blueprints', 22 | 'ember', 23 | 'json', 24 | ]), 25 | hasTypeScript: true, 26 | name: 'ember-codemod-args-to-signature', 27 | }, 28 | projectRoot: 'tmp/typescript-with-addons', 29 | }; 30 | 31 | export { codemodOptions, options }; 32 | -------------------------------------------------------------------------------- /packages/cli/tests/helpers/shared-test-setups/typescript.ts: -------------------------------------------------------------------------------- 1 | import type { CodemodOptions, Options } from '../../../src/types/index.js'; 2 | 3 | const codemodOptions: CodemodOptions = { 4 | addons: new Set(), 5 | hasTypeScript: true, 6 | name: 'ember-codemod-pod-to-octane', 7 | projectRoot: 'tmp/typescript', 8 | }; 9 | 10 | const options: Options = { 11 | codemod: { 12 | addons: new Set(), 13 | hasTypeScript: true, 14 | name: 'ember-codemod-pod-to-octane', 15 | }, 16 | projectRoot: 'tmp/typescript', 17 | }; 18 | 19 | export { codemodOptions, options }; 20 | -------------------------------------------------------------------------------- /packages/cli/tests/index/javascript-with-addons.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { createCodemod } from '../../src/index.js'; 4 | import { 5 | inputProject, 6 | outputProject, 7 | } from '../fixtures/javascript-with-addons/index.js'; 8 | import { codemodOptions } from '../helpers/shared-test-setups/javascript-with-addons.js'; 9 | 10 | test('migration | index > javascript with addons', function () { 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | createCodemod(codemodOptions); 14 | 15 | assertFixture(outputProject, codemodOptions); 16 | 17 | // Check idempotence 18 | createCodemod(codemodOptions); 19 | 20 | assertFixture(outputProject, codemodOptions); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/tests/index/javascript.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { createCodemod } from '../../src/index.js'; 4 | import { inputProject, outputProject } from '../fixtures/javascript/index.js'; 5 | import { codemodOptions } from '../helpers/shared-test-setups/javascript.js'; 6 | 7 | test('migration | index > javascript', function () { 8 | loadFixture(inputProject, codemodOptions); 9 | 10 | createCodemod(codemodOptions); 11 | 12 | assertFixture(outputProject, codemodOptions); 13 | 14 | // Check idempotence 15 | createCodemod(codemodOptions); 16 | 17 | assertFixture(outputProject, codemodOptions); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/cli/tests/index/typescript-with-addons.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { createCodemod } from '../../src/index.js'; 4 | import { 5 | inputProject, 6 | outputProject, 7 | } from '../fixtures/typescript-with-addons/index.js'; 8 | import { codemodOptions } from '../helpers/shared-test-setups/typescript-with-addons.js'; 9 | 10 | test('migration | index > typescript with addons', function () { 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | createCodemod(codemodOptions); 14 | 15 | assertFixture(outputProject, codemodOptions); 16 | 17 | // Check idempotence 18 | createCodemod(codemodOptions); 19 | 20 | assertFixture(outputProject, codemodOptions); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/tests/index/typescript.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { createCodemod } from '../../src/index.js'; 4 | import { inputProject, outputProject } from '../fixtures/typescript/index.js'; 5 | import { codemodOptions } from '../helpers/shared-test-setups/typescript.js'; 6 | 7 | test('migration | index > typescript', function () { 8 | loadFixture(inputProject, codemodOptions); 9 | 10 | createCodemod(codemodOptions); 11 | 12 | assertFixture(outputProject, codemodOptions); 13 | 14 | // Check idempotence 15 | createCodemod(codemodOptions); 16 | 17 | assertFixture(outputProject, codemodOptions); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/cli/tests/steps/create-options/javascript-with-addons.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/javascript-with-addons.js'; 8 | 9 | test('migration | steps | create-options > javascript-with-addons', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/steps/create-options/javascript.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/javascript.js'; 8 | 9 | test('migration | steps | create-options > javascript', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/steps/create-options/typescript-with-addons.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/typescript-with-addons.js'; 8 | 9 | test('migration | steps | create-options > typescript-with-addons', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/steps/create-options/typescript.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { createOptions } from '../../../src/steps/index.js'; 4 | import { 5 | codemodOptions, 6 | options, 7 | } from '../../helpers/shared-test-setups/typescript.js'; 8 | 9 | test('migration | steps | create-options > typescript', function () { 10 | assert.deepStrictEqual(createOptions(codemodOptions), options); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli/tests/utils/blueprints/blueprints-root.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { blueprintsRoot } from '../../../src/utils/blueprints.js'; 4 | 5 | test('utils | blueprints | blueprints-root', function () { 6 | assert.strictEqual(blueprintsRoot.endsWith('src/blueprints'), true); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": false, 5 | "outDir": "dist" 6 | }, 7 | "include": ["bin", "src"], 8 | "exclude": ["src/blueprints"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": false, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["bin", "src", "tests"], 8 | "exclude": ["src/blueprints", "tests/fixtures"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/ember/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintcache 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | -------------------------------------------------------------------------------- /packages/ember/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | !.* 8 | .*/ 9 | 10 | # specific to this package 11 | README.md 12 | -------------------------------------------------------------------------------- /packages/ember/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/ember/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ENVIRONMENT=$1 4 | 5 | if [ $ENVIRONMENT = "--production" ] 6 | then 7 | # Clean slate 8 | rm -rf "dist" 9 | 10 | # Compile TypeScript 11 | tsc --project "tsconfig.build.json" 12 | 13 | echo "SUCCESS: Built dist.\n" 14 | 15 | elif [ $ENVIRONMENT = "--test" ] 16 | then 17 | # Clean slate 18 | rm -rf "dist-for-testing" 19 | 20 | # Compile TypeScript 21 | tsc --project "tsconfig.json" 22 | 23 | echo "SUCCESS: Built dist-for-testing.\n" 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /packages/ember/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/ember/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/ember/src/ember/entity-name/camelize.ts: -------------------------------------------------------------------------------- 1 | import { pascalize } from './pascalize.js'; 2 | 3 | /** 4 | * Converts an entity name to camel case. Used for naming the 5 | * function that is associated with the entity. 6 | * 7 | * @param entityName 8 | * 9 | * The name of an entity (made up of lowercase letters, hyphen, 10 | * and forward slash). 11 | * 12 | * @return 13 | * 14 | * The name in camel case. 15 | * 16 | * @example 17 | * 18 | * ```ts 19 | * const newValue = camelize('ui/form/generate-error-message'); 20 | * 21 | * // 'uiFormGenerateErrorMessage' 22 | * ``` 23 | */ 24 | export function camelize(entityName: string): string { 25 | const pascalizedName = pascalize(entityName); 26 | 27 | return pascalizedName.charAt(0).toLowerCase() + pascalizedName.substring(1); 28 | } 29 | -------------------------------------------------------------------------------- /packages/ember/src/ember/entity-name/double-colonize.ts: -------------------------------------------------------------------------------- 1 | function pascalize(value: string): string { 2 | return value 3 | .split('-') 4 | .map((token) => { 5 | return token.charAt(0).toUpperCase() + token.substring(1).toLowerCase(); 6 | }) 7 | .join(''); 8 | } 9 | 10 | /** 11 | * Converts an entity name to double colon (`::`) case. Used for 12 | * writing the angle bracket syntax or the signature for a component. 13 | * 14 | * @param entityName 15 | * 16 | * The name of an entity (made up of lowercase letters, hyphen, 17 | * and forward slash). 18 | * 19 | * @return 20 | * 21 | * The name in double colon case. 22 | * 23 | * @example 24 | * 25 | * ```ts 26 | * const newValue = doubleColonize('ui/form/input'); 27 | * 28 | * // 'Ui::Form::Input' 29 | * ``` 30 | */ 31 | export function doubleColonize(entityName: string): string { 32 | return entityName.split('/').map(pascalize).join('::'); 33 | } 34 | -------------------------------------------------------------------------------- /packages/ember/src/ember/entity-name/pascalize.ts: -------------------------------------------------------------------------------- 1 | import { doubleColonize } from './double-colonize.js'; 2 | 3 | /** 4 | * Converts an entity name to Pascal case. Used for naming the 5 | * class that is associated with the entity. 6 | * 7 | * @param entityName 8 | * 9 | * The name of an entity (made up of lowercase letters, hyphen, 10 | * and forward slash). 11 | * 12 | * @return 13 | * 14 | * The name in Pascal case. 15 | * 16 | * @example 17 | * 18 | * ```ts 19 | * const newValue = pascalize('ui/form/input'); 20 | * 21 | * // 'UiFormInput' 22 | * ``` 23 | */ 24 | export function pascalize(entityName: string): string { 25 | const doubleColonizedName = doubleColonize(entityName); 26 | 27 | return doubleColonizedName.replaceAll('::', ''); 28 | } 29 | -------------------------------------------------------------------------------- /packages/ember/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ember/entity-name/camelize.js'; 2 | export * from './ember/entity-name/double-colonize.js'; 3 | export * from './ember/entity-name/pascalize.js'; 4 | -------------------------------------------------------------------------------- /packages/ember/tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ijlee2/codemod-utils/e5e9e4cb776a217323aee9f5e02e4394814662c3/packages/ember/tests/.gitkeep -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/camelize/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { camelize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | camelize > base case', function () { 6 | assert.strictEqual(camelize('hello'), 'hello'); 7 | 8 | assert.strictEqual(camelize('hello-world'), 'helloWorld'); 9 | 10 | assert.strictEqual(camelize('hello-world-123'), 'helloWorld123'); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/camelize/nested.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { camelize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | camelize > nested', function () { 6 | assert.strictEqual(camelize('ui/form'), 'uiForm'); 7 | 8 | assert.strictEqual(camelize('ui/form/input'), 'uiFormInput'); 9 | 10 | assert.strictEqual(camelize('ui/form/submit-button'), 'uiFormSubmitButton'); 11 | 12 | assert.strictEqual( 13 | camelize('widgets/widget-3/tour-schedule/responsive-image'), 14 | 'widgetsWidget3TourScheduleResponsiveImage', 15 | ); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/camelize/wrong-input.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { camelize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | camelize > wrong input', function () { 6 | assert.strictEqual(camelize(''), ''); 7 | 8 | assert.strictEqual(camelize('-'), ''); 9 | 10 | assert.strictEqual(camelize('/'), ''); 11 | 12 | assert.strictEqual(camelize('ui/'), 'ui'); 13 | 14 | assert.strictEqual(camelize('/ui'), 'ui'); 15 | 16 | assert.strictEqual(camelize('ui.form.input'), 'ui.form.input'); 17 | 18 | assert.strictEqual(camelize('ui_form_input'), 'ui_form_input'); 19 | 20 | assert.strictEqual(camelize('ui form input'), 'ui form input'); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/double-colonize/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { doubleColonize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | double-colonize > base case', function () { 6 | assert.strictEqual(doubleColonize('hello'), 'Hello'); 7 | 8 | assert.strictEqual(doubleColonize('hello-world'), 'HelloWorld'); 9 | 10 | assert.strictEqual(doubleColonize('hello-world-123'), 'HelloWorld123'); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/double-colonize/edge-case-empty-string.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { doubleColonize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | double-colonize > nested', function () { 6 | assert.strictEqual(doubleColonize('ui/form'), 'Ui::Form'); 7 | assert.strictEqual(doubleColonize('ui/form/input'), 'Ui::Form::Input'); 8 | assert.strictEqual( 9 | doubleColonize('ui/form/submit-button'), 10 | 'Ui::Form::SubmitButton', 11 | ); 12 | assert.strictEqual( 13 | doubleColonize('widgets/widget-3/tour-schedule/responsive-image'), 14 | 'Widgets::Widget3::TourSchedule::ResponsiveImage', 15 | ); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/double-colonize/wrong-input.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { doubleColonize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | double-colonize > wrong input', function () { 6 | assert.strictEqual(doubleColonize(''), ''); 7 | 8 | assert.strictEqual(doubleColonize('-'), ''); 9 | 10 | assert.strictEqual(doubleColonize('/'), '::'); 11 | 12 | assert.strictEqual(doubleColonize('ui/'), 'Ui::'); 13 | 14 | assert.strictEqual(doubleColonize('/ui'), '::Ui'); 15 | 16 | assert.strictEqual(doubleColonize('ui.form.input'), 'Ui.form.input'); 17 | 18 | assert.strictEqual(doubleColonize('ui_form_input'), 'Ui_form_input'); 19 | 20 | assert.strictEqual(doubleColonize('ui form input'), 'Ui form input'); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/pascalize/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { pascalize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | pascalize > base case', function () { 6 | assert.strictEqual(pascalize('hello'), 'Hello'); 7 | 8 | assert.strictEqual(pascalize('hello-world'), 'HelloWorld'); 9 | 10 | assert.strictEqual(pascalize('hello-world-123'), 'HelloWorld123'); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/pascalize/nested.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { pascalize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | pascalize > nested', function () { 6 | assert.strictEqual(pascalize('ui/form'), 'UiForm'); 7 | 8 | assert.strictEqual(pascalize('ui/form/input'), 'UiFormInput'); 9 | 10 | assert.strictEqual(pascalize('ui/form/submit-button'), 'UiFormSubmitButton'); 11 | 12 | assert.strictEqual( 13 | pascalize('widgets/widget-3/tour-schedule/responsive-image'), 14 | 'WidgetsWidget3TourScheduleResponsiveImage', 15 | ); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/ember/tests/ember/entity-name/pascalize/wrong-input.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { pascalize } from '../../../../src/index.js'; 4 | 5 | test('utils | ember | entity-name | pascalize > wrong input', function () { 6 | assert.strictEqual(pascalize(''), ''); 7 | 8 | assert.strictEqual(pascalize('-'), ''); 9 | 10 | assert.strictEqual(pascalize('/'), ''); 11 | 12 | assert.strictEqual(pascalize('ui/'), 'Ui'); 13 | 14 | assert.strictEqual(pascalize('/ui'), 'Ui'); 15 | 16 | assert.strictEqual(pascalize('ui.form.input'), 'Ui.form.input'); 17 | 18 | assert.strictEqual(pascalize('ui_form_input'), 'Ui_form_input'); 19 | 20 | assert.strictEqual(pascalize('ui form input'), 'Ui form input'); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/ember/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/ember/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["src", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/files/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintcache 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | -------------------------------------------------------------------------------- /packages/files/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | !.* 8 | .*/ 9 | 10 | # specific to this package 11 | README.md 12 | -------------------------------------------------------------------------------- /packages/files/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/files/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ENVIRONMENT=$1 4 | 5 | if [ $ENVIRONMENT = "--production" ] 6 | then 7 | # Clean slate 8 | rm -rf "dist" 9 | 10 | # Compile TypeScript 11 | tsc --project "tsconfig.build.json" 12 | 13 | echo "SUCCESS: Built dist.\n" 14 | 15 | elif [ $ENVIRONMENT = "--test" ] 16 | then 17 | # Clean slate 18 | rm -rf "dist-for-testing" 19 | 20 | # Compile TypeScript 21 | tsc --project "tsconfig.json" 22 | 23 | echo "SUCCESS: Built dist-for-testing.\n" 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /packages/files/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/files/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/files/src/files/create-directory.ts: -------------------------------------------------------------------------------- 1 | import { existsSync, mkdirSync } from 'node:fs'; 2 | import { dirname } from 'node:path'; 3 | 4 | import type { FilePath } from '../types/index.js'; 5 | 6 | /** 7 | * Creates the directories specified in the file path, if they don't 8 | * exist yet. 9 | * 10 | * ⚠️ Likely, you won't need this method but `createFiles()` instead. 11 | * 12 | * @param filePath 13 | * 14 | * A file path. 15 | * 16 | * @example 17 | * 18 | * Create the folder `ember-container-query` if it doesn't exist. 19 | * 20 | * ```ts 21 | * const newFilePath = 'ember-container-query/LICENSE.md'; 22 | * const destination = join(projectRoot, newFilePath); 23 | * 24 | * createDirectory(destination); 25 | * ``` 26 | */ 27 | export function createDirectory(filePath: FilePath): void { 28 | const directory = dirname(filePath); 29 | 30 | if (existsSync(directory)) { 31 | return; 32 | } 33 | 34 | mkdirSync(directory, { recursive: true }); 35 | } 36 | -------------------------------------------------------------------------------- /packages/files/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './files/copy-files.js'; 2 | export * from './files/create-directory.js'; 3 | export * from './files/create-files.js'; 4 | export * from './files/find-files.js'; 5 | export * from './files/get-package-roots.js'; 6 | export * from './files/map-file-paths.js'; 7 | export * from './files/move-files.js'; 8 | export * from './files/parse-file-path.js'; 9 | export * from './files/remove-directory-if-empty.js'; 10 | export * from './files/remove-files.js'; 11 | export * from './files/rename-path-by-directory.js'; 12 | export * from './types/index.js'; 13 | -------------------------------------------------------------------------------- /packages/files/src/types/index.ts: -------------------------------------------------------------------------------- 1 | type FileContent = string; 2 | 3 | type FileMap = Map; 4 | 5 | type FilePath = string; 6 | 7 | type FilePathMap = Map; 8 | 9 | type Options = Record; 10 | 11 | type ParsedPath = { 12 | base: string; 13 | dir: string; 14 | ext: string; 15 | name: string; 16 | }; 17 | 18 | export type { 19 | FileContent, 20 | FileMap, 21 | FilePath, 22 | FilePathMap, 23 | Options, 24 | ParsedPath, 25 | }; 26 | -------------------------------------------------------------------------------- /packages/files/tests/files/copy-files/edge-case-filePathMap-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { copyFiles, type FilePath } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | copy-files > edge case (filePathMap is empty)', function () { 7 | const inputProject = { 8 | '.editorconfig': 'some code for .editorconfig', 9 | '.eslintrc.js': 'some code for .eslintrc.js', 10 | 'package.json': 'some code for package.json', 11 | }; 12 | 13 | const outputProject = { 14 | '.editorconfig': 'some code for .editorconfig', 15 | '.eslintrc.js': 'some code for .eslintrc.js', 16 | 'package.json': 'some code for package.json', 17 | }; 18 | 19 | loadFixture(inputProject, codemodOptions); 20 | 21 | const filePathMap = new Map(); 22 | 23 | copyFiles(filePathMap, { 24 | projectRoot: options.projectRoot, 25 | }); 26 | 27 | assertFixture(outputProject, codemodOptions); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/files/tests/files/copy-files/edge-case-from-and-to-are-sibling-directories.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { copyFiles } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | copy-files > edge case (from and to are sibling directories)', function () { 7 | const inputProject = { 8 | app: { 9 | assets: {}, 10 | styles: { 11 | 'app.css': 'some code for app.css', 12 | }, 13 | }, 14 | }; 15 | 16 | const outputProject = { 17 | app: { 18 | assets: { 19 | 'app.css': 'some code for app.css', 20 | }, 21 | styles: { 22 | 'app.css': 'some code for app.css', 23 | }, 24 | }, 25 | }; 26 | 27 | loadFixture(inputProject, codemodOptions); 28 | 29 | const filePathMap = new Map([['app/styles/app.css', 'app/assets/app.css']]); 30 | 31 | copyFiles(filePathMap, { 32 | projectRoot: options.projectRoot, 33 | }); 34 | 35 | assertFixture(outputProject, codemodOptions); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/files/tests/files/copy-files/edge-case-from-and-to-are-the-same.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { copyFiles } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | copy-files > edge case (from and to are the same)', function () { 7 | const inputProject = { 8 | '.editorconfig': 'some code for .editorconfig', 9 | '.eslintrc.js': 'some code for .eslintrc.js', 10 | 'package.json': 'some code for package.json', 11 | }; 12 | 13 | const outputProject = { 14 | '.editorconfig': 'some code for .editorconfig', 15 | '.eslintrc.js': 'some code for .eslintrc.js', 16 | 'package.json': 'some code for package.json', 17 | }; 18 | 19 | loadFixture(inputProject, codemodOptions); 20 | 21 | const filePathMap = new Map([ 22 | ['.eslintrc.js', '.eslintrc.js'], 23 | ['package.json', 'package.json'], 24 | ]); 25 | 26 | copyFiles(filePathMap, { 27 | projectRoot: options.projectRoot, 28 | }); 29 | 30 | assertFixture(outputProject, codemodOptions); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/files/tests/files/create-directory/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { createDirectory } from '../../../src/index.js'; 4 | import { codemodOptions } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | create-directory > base case', function () { 7 | const inputProject = {}; 8 | 9 | const outputProject = { 10 | addon: { 11 | components: {}, 12 | }, 13 | }; 14 | 15 | loadFixture(inputProject, codemodOptions); 16 | 17 | const filePath = `${codemodOptions.projectRoot}/addon/components/ember-container-query.ts`; 18 | 19 | createDirectory(filePath); 20 | 21 | assertFixture(outputProject, codemodOptions); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/files/tests/files/create-directory/idempotency.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { createDirectory } from '../../../src/index.js'; 4 | import { codemodOptions } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | create-directory > idempotency', function () { 7 | const inputProject = { 8 | addon: { 9 | components: {}, 10 | }, 11 | }; 12 | 13 | const outputProject = { 14 | addon: { 15 | components: {}, 16 | }, 17 | }; 18 | 19 | loadFixture(inputProject, codemodOptions); 20 | 21 | const filePath = `${codemodOptions.projectRoot}/addon/components/ember-container-query.ts`; 22 | 23 | createDirectory(filePath); 24 | 25 | assertFixture(outputProject, codemodOptions); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/files/tests/files/create-files/edge-case-fileMap-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { 4 | createFiles, 5 | type FileContent, 6 | type FilePath, 7 | } from '../../../src/index.js'; 8 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 9 | 10 | test('files | create-files > edge case (fileMap is empty)', function () { 11 | const inputProject = {}; 12 | 13 | const outputProject = {}; 14 | 15 | loadFixture(inputProject, codemodOptions); 16 | 17 | const fileMap = new Map(); 18 | 19 | createFiles(fileMap, options); 20 | 21 | assertFixture(outputProject, codemodOptions); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/files/tests/files/find-files/edge-case-specified-folder-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { findFiles } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | find-files > edge case (specified folder does not exist)', function () { 7 | const inputProject = { 8 | tests: {}, 9 | }; 10 | 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | const filePaths = findFiles('tests/dummy/**/*.{js,ts}', { 14 | projectRoot: options.projectRoot, 15 | }); 16 | 17 | assert.deepStrictEqual(filePaths, []); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/files/tests/files/get-package-roots/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { getPackageRoots } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | get-package-roots > base case', function () { 7 | const inputProject = { 8 | 'package.json': '', 9 | }; 10 | 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | const packageRoots = getPackageRoots({ 14 | projectRoot: options.projectRoot, 15 | }); 16 | 17 | assert.deepStrictEqual(packageRoots, ['tmp/test-project']); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/files/tests/files/get-package-roots/edge-case-file-name-is-incorrect.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { getPackageRoots } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | get-package-roots > edge case (file name is incorrect)', function () { 7 | const inputProject = { 8 | packagejson: '', 9 | 'package.json5': '', 10 | 'somepackage.json': '', 11 | }; 12 | 13 | loadFixture(inputProject, codemodOptions); 14 | 15 | const packageRoots = getPackageRoots({ 16 | projectRoot: options.projectRoot, 17 | }); 18 | 19 | assert.deepStrictEqual(packageRoots, []); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/files/tests/files/get-package-roots/edge-case-no-packages.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { getPackageRoots } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | get-package-roots > edge case (no packages)', function () { 7 | const inputProject = {}; 8 | 9 | loadFixture(inputProject, codemodOptions); 10 | 11 | const packageRoots = getPackageRoots({ 12 | projectRoot: options.projectRoot, 13 | }); 14 | 15 | assert.deepStrictEqual(packageRoots, []); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/files/tests/files/map-file-paths/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { mapFilePaths } from '../../../src/index.js'; 4 | 5 | test('files | map-file-paths > base case', function () { 6 | const filePaths = ['addon/components/container-query.hbs', 'addon/.gitkeep']; 7 | 8 | const filePathMap = mapFilePaths(filePaths, { 9 | from: 'addon', 10 | to: 'ember-container-query/src', 11 | }); 12 | 13 | assert.deepStrictEqual( 14 | filePathMap, 15 | new Map([ 16 | [ 17 | 'addon/components/container-query.hbs', 18 | 'ember-container-query/src/components/container-query.hbs', 19 | ], 20 | ['addon/.gitkeep', 'ember-container-query/src/.gitkeep'], 21 | ]), 22 | ); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/files/tests/files/map-file-paths/edge-case-no-match.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { mapFilePaths } from '../../../src/index.js'; 4 | 5 | test('files | map-file-paths > edge case (no match)', function () { 6 | const filePaths = ['.addon/index.js', 'addon', 'addon.js', 'app/index.js']; 7 | 8 | const filePathMap = mapFilePaths(filePaths, { 9 | from: 'addon', 10 | to: 'ember-container-query/src', 11 | }); 12 | 13 | assert.deepStrictEqual( 14 | filePathMap, 15 | new Map([ 16 | ['.addon/index.js', '.addon/index.js'], 17 | ['addon', 'addon'], 18 | ['addon.js', 'addon.js'], 19 | ['app/index.js', 'app/index.js'], 20 | ]), 21 | ); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/files/tests/files/move-files/edge-case-from-and-to-are-sibling-directories.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { moveFiles } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | move-files > edge case (from and to are sibling directories)', function () { 7 | const inputProject = { 8 | app: { 9 | assets: {}, 10 | styles: { 11 | 'app.css': 'some code for app.css', 12 | }, 13 | }, 14 | }; 15 | 16 | const outputProject = { 17 | app: { 18 | assets: { 19 | 'app.css': 'some code for app.css', 20 | }, 21 | }, 22 | }; 23 | 24 | loadFixture(inputProject, codemodOptions); 25 | 26 | const filePathMap = new Map([['app/styles/app.css', 'app/assets/app.css']]); 27 | 28 | moveFiles(filePathMap, { 29 | projectRoot: options.projectRoot, 30 | }); 31 | 32 | assertFixture(outputProject, codemodOptions); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/files/tests/files/parse-file-path/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { parseFilePath } from '../../../src/index.js'; 4 | 5 | test('files | parse-file-path > base case', function () { 6 | const filePath = 'src/components/navigation-menu.hbs'; 7 | 8 | const parsedPath = parseFilePath(filePath); 9 | 10 | assert.deepEqual(parsedPath, { 11 | base: 'navigation-menu.hbs', 12 | dir: 'src/components', 13 | ext: '.hbs', 14 | name: 'navigation-menu', 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/files/tests/files/parse-file-path/edge-case-css-d-ts.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { parseFilePath } from '../../../src/index.js'; 4 | 5 | test('files | parse-file-path > edge case (.css.d.ts)', function () { 6 | const filePath = 'src/components/navigation-menu.css.d.ts'; 7 | 8 | const parsedPath = parseFilePath(filePath); 9 | 10 | assert.deepEqual(parsedPath, { 11 | base: 'navigation-menu.css.d.ts', 12 | dir: 'src/components', 13 | ext: '.css.d.ts', 14 | name: 'navigation-menu', 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/files/tests/files/parse-file-path/edge-case-d-ts.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { parseFilePath } from '../../../src/index.js'; 4 | 5 | test('files | parse-file-path > edge case (.d.ts)', function () { 6 | const filePath = 'src/components/navigation-menu.d.ts'; 7 | 8 | const parsedPath = parseFilePath(filePath); 9 | 10 | assert.deepEqual(parsedPath, { 11 | base: 'navigation-menu.d.ts', 12 | dir: 'src/components', 13 | ext: '.d.ts', 14 | name: 'navigation-menu', 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/files/tests/files/parse-file-path/edge-case-no-directory.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { parseFilePath } from '../../../src/index.js'; 4 | 5 | test('files | parse-file-path > edge case (no directory)', function () { 6 | const filePath = 'README.md'; 7 | 8 | const parsedPath = parseFilePath(filePath); 9 | 10 | assert.deepEqual(parsedPath, { 11 | base: 'README.md', 12 | dir: '', 13 | ext: '.md', 14 | name: 'README', 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/files/tests/files/parse-file-path/edge-case-no-extension.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { parseFilePath } from '../../../src/index.js'; 4 | 5 | test('files | parse-file-path > edge case (no extension)', function () { 6 | const filePath = '.gitignore'; 7 | 8 | const parsedPath = parseFilePath(filePath); 9 | 10 | assert.deepEqual(parsedPath, { 11 | base: '.gitignore', 12 | dir: '', 13 | ext: '', 14 | name: '.gitignore', 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/files/tests/files/parse-file-path/edge-case-special-characters.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { parseFilePath } from '../../../src/index.js'; 4 | 5 | test('files | parse-file-path > edge case (special characters)', function () { 6 | const filePath = 'photos/image (1).png'; 7 | 8 | const parsedPath = parseFilePath(filePath); 9 | 10 | assert.deepEqual(parsedPath, { 11 | base: 'image (1).png', 12 | dir: 'photos', 13 | ext: '.png', 14 | name: 'image (1)', 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/files/tests/files/remove-directory-if-empty/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { removeDirectoryIfEmpty } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | remove-directory-if-empty > base case', function () { 7 | const inputProject = { 8 | addon: { 9 | components: {}, 10 | }, 11 | }; 12 | 13 | const outputProject = {}; 14 | 15 | loadFixture(inputProject, codemodOptions); 16 | 17 | removeDirectoryIfEmpty('addon/components/container-query.ts', options); 18 | 19 | assertFixture(outputProject, codemodOptions); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/files/tests/files/remove-directory-if-empty/edge-case-parent-directory-is-not-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { removeDirectoryIfEmpty } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | remove-directory-if-empty > edge case (parent directory is not empty)', function () { 7 | const inputProject = { 8 | addon: { 9 | components: {}, 10 | '.gitkeep': '', 11 | }, 12 | }; 13 | 14 | const outputProject = { 15 | addon: { 16 | '.gitkeep': '', 17 | }, 18 | }; 19 | 20 | loadFixture(inputProject, codemodOptions); 21 | 22 | removeDirectoryIfEmpty('addon/components/container-query.ts', options); 23 | 24 | assertFixture(outputProject, codemodOptions); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/files/tests/files/remove-files/edge-case-file-does-not-exist.test.ts: -------------------------------------------------------------------------------- 1 | import { assertFixture, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { removeFiles } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('files | remove-files > edge case (file does not exist)', function () { 7 | const inputProject = { 8 | addon: { 9 | components: { 10 | 'container-query.css': 'some code for container-query.css', 11 | 'container-query.ts': 'some code for container-query.ts', 12 | }, 13 | }, 14 | }; 15 | 16 | const outputProject = { 17 | addon: { 18 | components: { 19 | 'container-query.css': 'some code for container-query.css', 20 | }, 21 | }, 22 | }; 23 | 24 | loadFixture(inputProject, codemodOptions); 25 | 26 | const filePaths = [ 27 | 'addon/components/container-query.hbs', 28 | 'addon/components/container-query.ts', 29 | ]; 30 | 31 | removeFiles(filePaths, options); 32 | 33 | assertFixture(outputProject, codemodOptions); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/files/tests/files/rename-path-by-directory/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { renamePathByDirectory } from '../../../src/index.js'; 4 | 5 | test('files | rename-path-by-directory > base case', function () { 6 | const oldFilePath = 'addon/components/container-query.hbs'; 7 | 8 | const newFilePath = renamePathByDirectory(oldFilePath, { 9 | from: 'addon', 10 | to: 'ember-container-query/src', 11 | }); 12 | 13 | assert.strictEqual( 14 | newFilePath, 15 | 'ember-container-query/src/components/container-query.hbs', 16 | ); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/files/tests/files/rename-path-by-directory/edge-case-from-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { renamePathByDirectory } from '../../../src/index.js'; 4 | 5 | test('files | rename-path-by-directory > edge case (from is empty)', function () { 6 | const oldFilePath = 'addon/components/container-query.hbs'; 7 | 8 | const newFilePath = renamePathByDirectory(oldFilePath, { 9 | from: '', 10 | to: 'ember-container-query/src', 11 | }); 12 | 13 | assert.strictEqual( 14 | newFilePath, 15 | 'ember-container-query/src/addon/components/container-query.hbs', 16 | ); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/files/tests/files/rename-path-by-directory/edge-case-no-match.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { renamePathByDirectory } from '../../../src/index.js'; 4 | 5 | test('files | rename-path-by-directory > edge case (no match)', function () { 6 | const oldFilePath = 'addon'; 7 | 8 | const newFilePath = renamePathByDirectory(oldFilePath, { 9 | from: 'addon', 10 | to: 'ember-container-query/src', 11 | }); 12 | 13 | assert.strictEqual(newFilePath, 'addon'); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/files/tests/files/rename-path-by-directory/edge-case-to-is-empty.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { renamePathByDirectory } from '../../../src/index.js'; 4 | 5 | test('files | rename-path-by-directory > edge case (to is empty)', function () { 6 | const oldFilePath = 'addon/components/container-query.hbs'; 7 | 8 | const newFilePath = renamePathByDirectory(oldFilePath, { 9 | from: 'addon', 10 | to: '', 11 | }); 12 | 13 | assert.strictEqual(newFilePath, 'components/container-query.hbs'); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/files/tests/shared-test-setups/index.ts: -------------------------------------------------------------------------------- 1 | const codemodOptions = { 2 | projectRoot: 'tmp/test-project', 3 | }; 4 | 5 | const options = { 6 | projectRoot: 'tmp/test-project', 7 | }; 8 | 9 | export { codemodOptions, options }; 10 | -------------------------------------------------------------------------------- /packages/files/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/files/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["src", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/json/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintcache 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | -------------------------------------------------------------------------------- /packages/json/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | !.* 8 | .*/ 9 | 10 | # specific to this package 11 | README.md 12 | -------------------------------------------------------------------------------- /packages/json/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/json/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ENVIRONMENT=$1 4 | 5 | if [ $ENVIRONMENT = "--production" ] 6 | then 7 | # Clean slate 8 | rm -rf "dist" 9 | 10 | # Compile TypeScript 11 | tsc --project "tsconfig.build.json" 12 | 13 | echo "SUCCESS: Built dist.\n" 14 | 15 | elif [ $ENVIRONMENT = "--test" ] 16 | then 17 | # Clean slate 18 | rm -rf "dist-for-testing" 19 | 20 | # Compile TypeScript 21 | tsc --project "tsconfig.json" 22 | 23 | echo "SUCCESS: Built dist-for-testing.\n" 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /packages/json/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/json/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/json/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './json/convert-to-map.js'; 2 | export * from './json/convert-to-object.js'; 3 | export * from './json/read-package-json.js'; 4 | export * from './json/validate-package-json.js'; 5 | export * from './types/index.js'; 6 | -------------------------------------------------------------------------------- /packages/json/src/types/index.ts: -------------------------------------------------------------------------------- 1 | import type { PackageJson, TsConfigJson } from 'type-fest'; 2 | 3 | type Options = { 4 | [key: string]: unknown; 5 | projectRoot: string; 6 | }; 7 | 8 | type ValidatedPackageJson = PackageJson & 9 | Required>; 10 | 11 | export type { Options, PackageJson, TsConfigJson, ValidatedPackageJson }; 12 | -------------------------------------------------------------------------------- /packages/json/tests/json/convert-to-map/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { convertToMap } from '../../../src/index.js'; 4 | 5 | test('json | convert-to-map > base case', function () { 6 | const devDependencies = { 7 | 'ember-cli-babel': '^7.26.11', 8 | 'ember-cli-htmlbars': '^6.1.1', 9 | 'ember-cli-typescript': '^5.2.1', 10 | 'ember-element-helper': '^0.6.1', 11 | 'ember-modifier': '^3.2.7', 12 | 'ember-resize-observer-service': '^1.1.0', 13 | 'ember-test-selectors': '^6.0.0', 14 | }; 15 | 16 | const expectedValue = new Map([ 17 | ['ember-cli-babel', '^7.26.11'], 18 | ['ember-cli-htmlbars', '^6.1.1'], 19 | ['ember-cli-typescript', '^5.2.1'], 20 | ['ember-element-helper', '^0.6.1'], 21 | ['ember-modifier', '^3.2.7'], 22 | ['ember-resize-observer-service', '^1.1.0'], 23 | ['ember-test-selectors', '^6.0.0'], 24 | ]); 25 | 26 | assert.deepStrictEqual(convertToMap(devDependencies), expectedValue); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/json/tests/json/convert-to-map/edge-case-input-is-undefined.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { convertToMap } from '../../../src/index.js'; 4 | 5 | test('json | convert-to-map > edge case (input is undefined)', function () { 6 | const devDependencies = undefined; 7 | 8 | const expectedValue = new Map(); 9 | 10 | assert.deepStrictEqual(convertToMap(devDependencies), expectedValue); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/json/tests/json/convert-to-object/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { convertToObject } from '../../../src/index.js'; 4 | 5 | test('json | convert-to-object > base case', function () { 6 | const devDependencies = new Map([ 7 | ['ember-cli-htmlbars', '^6.1.1'], 8 | ['ember-test-selectors', '^6.0.0'], 9 | ['ember-resize-observer-service', '^1.1.0'], 10 | ['ember-cli-typescript', '^5.2.1'], 11 | ['ember-modifier', '^3.2.7'], 12 | ['ember-element-helper', '^0.6.1'], 13 | ['ember-cli-babel', '^7.26.11'], 14 | ]); 15 | 16 | const expectedValue = { 17 | 'ember-cli-babel': '^7.26.11', 18 | 'ember-cli-htmlbars': '^6.1.1', 19 | 'ember-cli-typescript': '^5.2.1', 20 | 'ember-element-helper': '^0.6.1', 21 | 'ember-modifier': '^3.2.7', 22 | 'ember-resize-observer-service': '^1.1.0', 23 | 'ember-test-selectors': '^6.0.0', 24 | }; 25 | 26 | assert.deepStrictEqual(convertToObject(devDependencies), expectedValue); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/json/tests/json/convert-to-object/edge-case-input-is-undefined.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { convertToObject } from '../../../src/index.js'; 4 | 5 | test('json | convert-to-object > edge case (input is undefined)', function () { 6 | const devDependencies = undefined; 7 | 8 | const expectedValue = {}; 9 | 10 | assert.deepStrictEqual(convertToObject(devDependencies), expectedValue); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/json/tests/json/read-package-json/edge-case-package-name-is-missing.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { readPackageJson } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('json | read-package-json > edge case (package name is missing)', function () { 7 | const inputProject = { 8 | 'package.json': JSON.stringify( 9 | { 10 | version: '0.0.0', 11 | private: true, 12 | }, 13 | null, 14 | 2, 15 | ), 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | const packageJson = readPackageJson({ 21 | projectRoot: options.projectRoot, 22 | }); 23 | 24 | assert.deepStrictEqual(packageJson, { 25 | version: '0.0.0', 26 | private: true, 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/json/tests/json/read-package-json/edge-case-package-name-is-not-valid.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { readPackageJson } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('json | read-package-json > edge case (package name is not valid)', function () { 7 | const inputProject = { 8 | 'package.json': JSON.stringify( 9 | { 10 | name: '@ijlee2/', 11 | version: '0.0.0', 12 | }, 13 | null, 14 | 2, 15 | ), 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | const packageJson = readPackageJson({ 21 | projectRoot: options.projectRoot, 22 | }); 23 | 24 | assert.deepStrictEqual(packageJson, { 25 | name: '@ijlee2/', 26 | version: '0.0.0', 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/json/tests/json/read-package-json/edge-case-package-version-is-missing.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { readPackageJson } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('json | read-package-json > edge case (package version is missing)', function () { 7 | const inputProject = { 8 | 'package.json': JSON.stringify( 9 | { 10 | name: 'workspace-root', 11 | private: true, 12 | }, 13 | null, 14 | 2, 15 | ), 16 | }; 17 | 18 | loadFixture(inputProject, codemodOptions); 19 | 20 | const packageJson = readPackageJson({ 21 | projectRoot: options.projectRoot, 22 | }); 23 | 24 | assert.deepStrictEqual(packageJson, { 25 | name: 'workspace-root', 26 | private: true, 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/json/tests/json/read-package-json/error-handling-package-json-is-an-empty-file.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { readPackageJson } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('json | read-package-json > error handling (package.json is an empty file)', function () { 7 | const inputProject = { 8 | 'package.json': '', 9 | }; 10 | 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | assert.throws( 14 | () => { 15 | readPackageJson({ 16 | projectRoot: options.projectRoot, 17 | }); 18 | }, 19 | (error: Error) => { 20 | assert.strictEqual( 21 | error.message, 22 | 'ERROR: package.json is not valid. (Unexpected end of JSON input)\n', 23 | ); 24 | 25 | return true; 26 | }, 27 | ); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/json/tests/json/read-package-json/error-handling-package-json-is-missing.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { readPackageJson } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('json | read-package-json > error handling (package.json is missing)', function () { 7 | const inputProject = {}; 8 | 9 | loadFixture(inputProject, codemodOptions); 10 | 11 | assert.throws( 12 | () => { 13 | readPackageJson({ 14 | projectRoot: options.projectRoot, 15 | }); 16 | }, 17 | (error: Error) => { 18 | assert.strictEqual(error.message, 'ERROR: package.json is missing.\n'); 19 | 20 | return true; 21 | }, 22 | ); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/json/tests/json/read-package-json/error-handling-package-json-is-not-a-valid-json.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, loadFixture, test } from '@codemod-utils/tests'; 2 | 3 | import { readPackageJson } from '../../../src/index.js'; 4 | import { codemodOptions, options } from '../../shared-test-setups/index.js'; 5 | 6 | test('json | read-package-json > error handling (package.json is not a valid JSON)', function () { 7 | const inputProject = { 8 | 'package.json': '{\n "name": }', 9 | }; 10 | 11 | loadFixture(inputProject, codemodOptions); 12 | 13 | assert.throws( 14 | () => { 15 | readPackageJson({ 16 | projectRoot: options.projectRoot, 17 | }); 18 | }, 19 | (error: Error) => { 20 | assert.strictEqual( 21 | error.message, 22 | [ 23 | `ERROR: package.json is not valid. (Unexpected token '}', "{\n`, 24 | ' "name": }" is not valid JSON)\n', 25 | ].join(''), 26 | ); 27 | 28 | return true; 29 | }, 30 | ); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/json/tests/json/validate-package-json/base-case.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { validatePackageJson } from '../../../src/index.js'; 4 | 5 | test('json | validate-package-json > base case', function () { 6 | const packageJson = { 7 | name: 'ember-container-query', 8 | version: '3.2.0', 9 | }; 10 | 11 | validatePackageJson(packageJson); 12 | 13 | assert.ok(true); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/json/tests/json/validate-package-json/edge-case-package-name-is-scoped.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { validatePackageJson } from '../../../src/index.js'; 4 | 5 | test('json | validate-package-json > edge case (package name is scoped)', function () { 6 | const packageJson = { 7 | name: '@ijlee2/ember-container-query', 8 | version: '3.2.0', 9 | }; 10 | 11 | validatePackageJson(packageJson); 12 | 13 | assert.ok(true); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/json/tests/json/validate-package-json/package-name-is-missing.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { validatePackageJson } from '../../../src/index.js'; 4 | 5 | test('json | validate-package-json > package name is missing', function () { 6 | const packageJson = { 7 | version: '0.0.0', 8 | private: true, 9 | }; 10 | 11 | assert.throws( 12 | () => { 13 | validatePackageJson(packageJson); 14 | }, 15 | (error: Error) => { 16 | assert.strictEqual( 17 | error.message, 18 | 'ERROR: package.json is not valid. (Package name is missing.)\n', 19 | ); 20 | 21 | return true; 22 | }, 23 | ); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/json/tests/json/validate-package-json/package-name-is-not-valid.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { validatePackageJson } from '../../../src/index.js'; 4 | 5 | test('json | validate-package-json > package name is not valid', function () { 6 | const packageJson = { 7 | name: '@ijlee2/', 8 | version: '0.0.0', 9 | }; 10 | 11 | assert.throws( 12 | () => { 13 | validatePackageJson(packageJson); 14 | }, 15 | (error: Error) => { 16 | assert.strictEqual( 17 | error.message, 18 | 'ERROR: package.json is not valid. (Package name is missing.)\n', 19 | ); 20 | 21 | return true; 22 | }, 23 | ); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/json/tests/json/validate-package-json/package-version-is-missing.test.ts: -------------------------------------------------------------------------------- 1 | import { assert, test } from '@codemod-utils/tests'; 2 | 3 | import { validatePackageJson } from '../../../src/index.js'; 4 | 5 | test('json | validate-package-json > package version is missing', function () { 6 | const packageJson = { 7 | name: 'workspace-root', 8 | private: true, 9 | }; 10 | 11 | assert.throws( 12 | () => { 13 | validatePackageJson(packageJson); 14 | }, 15 | (error: Error) => { 16 | assert.strictEqual( 17 | error.message, 18 | 'ERROR: package.json is not valid. (Package version is missing.)\n', 19 | ); 20 | 21 | return true; 22 | }, 23 | ); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/json/tests/shared-test-setups/index.ts: -------------------------------------------------------------------------------- 1 | const codemodOptions = { 2 | projectRoot: 'tmp/test-project', 3 | }; 4 | 5 | const options = { 6 | projectRoot: 'tmp/test-project', 7 | }; 8 | 9 | export { codemodOptions, options }; 10 | -------------------------------------------------------------------------------- /packages/json/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/json/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["src", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/tests/.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /tmp/ 3 | 4 | # dependencies 5 | /node_modules/ 6 | 7 | # misc 8 | /.DS_Store 9 | /.env* 10 | /.eslintcache 11 | /.git/ 12 | /.github/ 13 | /.gitignore 14 | /.pnpm-debug.log 15 | /.prettierignore 16 | /build.sh 17 | /eslint.config.mjs 18 | /prettier.config.mjs 19 | /tests/ 20 | -------------------------------------------------------------------------------- /packages/tests/.prettierignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /dist-for-testing/ 4 | /tmp/ 5 | 6 | # misc 7 | !.* 8 | .*/ 9 | 10 | # specific to this package 11 | README.md 12 | -------------------------------------------------------------------------------- /packages/tests/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Isaac J. Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/tests/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ENVIRONMENT=$1 4 | 5 | if [ $ENVIRONMENT = "--production" ] 6 | then 7 | # Clean slate 8 | rm -rf "dist" 9 | 10 | # Compile TypeScript 11 | tsc --project "tsconfig.build.json" 12 | 13 | echo "SUCCESS: Built dist.\n" 14 | 15 | elif [ $ENVIRONMENT = "--test" ] 16 | then 17 | # Clean slate 18 | rm -rf "dist-for-testing" 19 | 20 | # Compile TypeScript 21 | tsc --project "tsconfig.json" 22 | 23 | echo "SUCCESS: Built dist-for-testing.\n" 24 | 25 | fi 26 | -------------------------------------------------------------------------------- /packages/tests/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/eslint-config-node/typescript'; 2 | -------------------------------------------------------------------------------- /packages/tests/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export { default } from '@shared-configs/prettier/node'; 2 | -------------------------------------------------------------------------------- /packages/tests/src/index.ts: -------------------------------------------------------------------------------- 1 | import { strict as assert } from 'node:assert'; 2 | 3 | import { test } from '@sondr3/minitest'; 4 | 5 | export { assert, test }; 6 | 7 | export * from './tests/assert-fixture.js'; 8 | export * from './tests/convert-fixture-to-json.js'; 9 | export * from './tests/load-fixture.js'; 10 | export * from './types/index.js'; 11 | -------------------------------------------------------------------------------- /packages/tests/src/types/index.ts: -------------------------------------------------------------------------------- 1 | import type { DirJSON } from 'fixturify'; 2 | 3 | type Options = { 4 | [key: string]: unknown; 5 | projectRoot: string; 6 | }; 7 | 8 | export type { DirJSON, Options }; 9 | -------------------------------------------------------------------------------- /packages/tests/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist" 6 | }, 7 | "include": ["src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@shared-configs/typescript/node20", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "outDir": "dist-for-testing" 6 | }, 7 | "include": ["src", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - configs/** 3 | - packages/ast/javascript 4 | - packages/ast/template 5 | - packages/blueprints 6 | - packages/cli 7 | - packages/ember 8 | - packages/files 9 | - packages/json 10 | - packages/tests 11 | -------------------------------------------------------------------------------- /tutorials/create-blueprints/05-conclusion.md: -------------------------------------------------------------------------------- 1 | # Conclusion 2 | 3 | You have learned how blueprints help you create or update files in a project. The blueprint files can be static (the content is always the same) or dynamic (the content differs, depending on the circumstances). 4 | 5 | You might also understand better why `codemodOptions` and `options` exist, as well as which related files to update, should you decide to provide users more codemod options. 6 | 7 | For brevity, our `blueprints-v2-addon` created only 1 file in the addon and the test app. To familiarize yourself with delimiters (in particular, with evaluate and interpolate), I encourage you to extend the project and add more blueprint files. You can also explore how to write integration tests for the `create-files-from-blueprints` step. 8 | -------------------------------------------------------------------------------- /tutorials/main-tutorial/10-conclusion.md: -------------------------------------------------------------------------------- 1 | # Conclusion 2 | 3 | First, give yourself a hearty pat for making it through. Writing a codemod is an advanced technique, and you likely encountered and had to quickly understand several new concepts. 4 | 5 | To summarize what you learned: 6 | 7 | - `@codemod-utils` provides a set of tools and conventions to help you write codemods. 8 | - Break the problem into small steps. There may be a sequence of steps that makes it easier to solve the problem. 9 | - Before implementing the first step, create fixture project(s) for acceptance tests. You can then run `./update-test-fixtures.sh` to see the effect of your code change. 10 | - Take the simplest approach to implement steps quickly. Prefer duplication over premature abstraction. 11 | - After implementing all steps, refactor code. Write integration and unit tests to improve documentation. 12 | -------------------------------------------------------------------------------- /tutorials/update-css-files/00-introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | > [!IMPORTANT] 4 | > Please complete the [main tutorial](../main-tutorial/00-introduction.md) first. 5 | 6 | > [!NOTE] 7 | > This tutorial shows how to use [`postcss`](https://github.com/postcss/postcss) and its plugins to update `*.css` files. 8 | 9 | Currently, `@codemod-utils` doesn't provide a utility package to handle CSS. This is because (1) a few different libraries can be used, each with pros and cons, and (2) most codemods for Ember projects concern updating `*.{hbs,js,ts}` files (more recently, `*.{gjs,gts}`). 10 | 11 | Nonetheless, you can write a codemod to update many CSS files. This tutorial will show how to integrate PostCSS with `@codemod-utils/files`. Our target project is assumed to be an Ember app with CSS modules. 12 | 13 | 14 | ## Table of contents 15 | 16 | 1. [Use existing plugins](./01-use-existing-plugins.md) 17 | 1. [Write custom plugins](./02-write-custom-plugins.md) 18 | 1. [Conclusion](./03-conclusion.md) 19 | -------------------------------------------------------------------------------- /tutorials/update-css-files/03-conclusion.md: -------------------------------------------------------------------------------- 1 | # Conclusion 2 | 3 | You can write a codemod to update CSS files, even when `@codemod-utils` doesn't provide a utility package for CSS yet. 4 | 5 | As a concrete example, this tutorial showed how to use PostCSS along with `@codemod-utils/files`. Moreover, it highlighted the benefits of using existing plugins and having the option to write custom ones. 6 | 7 | Depending on your use case, you may look into other libraries like [`css-tree`](https://github.com/csstree/csstree) (this is used by [`type-css-modules`](https://github.com/ijlee2/embroider-css-modules/tree/2.0.16/packages/type-css-modules)). 8 | -------------------------------------------------------------------------------- /tutorials/update-template-tags/03-conclusion.md: -------------------------------------------------------------------------------- 1 | # Conclusion 2 | 3 | When utilities form the foundation of a codemod, we can experiment with new libraries and write code that stands the test of time. 4 | 5 | In this tutorial, we combined `content-tag` with `@codemod-utils/ast-template` so that we can update templates in `*.{gjs,gts}` files—a feature that neither `content-tag` nor `@codemod-utils` provides just yet. 6 | 7 | As exercise, see if you can update classes in `*.{gjs,gts}` (maybe for just 1 specific case) by combining `content-tag` with `@codemod-utils/ast-javascript`. 8 | 9 | ```ts 10 | /* src/utils/ast/template-tag.ts */ 11 | import { Preprocessor } from 'content-tag'; 12 | 13 | export function extractClass(file: string): string { 14 | const preprocessor = new Preprocessor(); 15 | 16 | // Compiles `