Skip to content

Commit 301443b

Browse files
Merge pull request #218 from hypermod-io/fix-local-config-search
Fix local config search
2 parents 7510eec + 401823f commit 301443b

File tree

9 files changed

+86
-22
lines changed

9 files changed

+86
-22
lines changed

.changeset/fair-flowers-sing.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hypermod/cli': patch
3+
---
4+
5+
Patches selection of transform via local config prompt

.changeset/spotty-parrots-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hypermod/fetcher': minor
3+
---
4+
5+
Adds typescript support for config requires. Now a config can be in TS/TSX etc.

.changeset/stupid-mice-lay.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@hypermod/validator': patch
3+
'@hypermod/fetcher': patch
4+
'@hypermod/types': patch
5+
'@hypermod/cli': patch
6+
---
7+
8+
Renames type `CodeshiftConfig` to `Config` (with backwards compatible alias)

packages/cli/src/main.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { PluginManager, PluginManagerOptions } from 'live-plugin-manager';
88
import { installPackage } from '@antfu/install-pkg';
99

1010
import * as core from '@hypermod/core';
11-
import { CodeshiftConfig } from '@hypermod/types';
11+
import { Config } from '@hypermod/types';
1212
import { fetchConfigAtPath, fetchConfigs } from '@hypermod/fetcher';
1313

1414
import { InvalidUserInputError } from './errors';
@@ -78,7 +78,7 @@ export default async function main(
7878

7979
if (rootPackageJson && rootPackageJson.workspaces) {
8080
const configs = await (rootPackageJson.workspaces as string[]).reduce<
81-
Promise<{ filePath: string; config: CodeshiftConfig }[]>
81+
Promise<{ filePath: string; config: Config }[]>
8282
>(async (accum, filePath) => {
8383
const configs = await fetchConfigs(filePath);
8484
if (!configs.length) return accum;
@@ -164,9 +164,11 @@ export default async function main(
164164
if (config.transforms && config.transforms[answers.codemod]) {
165165
Object.entries(config.transforms)
166166
.filter(([key]) => semver.satisfies(key, `>=${answers.codemod}`))
167-
.forEach(([, path]) => transforms.push(path));
167+
.forEach(([, codemod]) =>
168+
transforms.push(`${configFilePath}@${codemod}`),
169+
);
168170
} else if (config.presets && config.presets[answers.codemod]) {
169-
transforms.push(config.presets[answers.codemod]);
171+
transforms.push(`${configFilePath}#${answers.codemod}`);
170172
}
171173
}
172174
}

packages/cli/src/prompt.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import inquirer from 'inquirer';
22

3-
import { CodeshiftConfig } from '@hypermod/types';
3+
import { Config } from '@hypermod/types';
44

5-
export const getConfigPrompt = (config: CodeshiftConfig) => {
5+
export const getConfigPrompt = (config: Config) => {
66
const transforms = Object.keys(config.transforms || {});
77
const presets = Object.keys(config.presets || {});
88

@@ -22,7 +22,7 @@ export const getConfigPrompt = (config: CodeshiftConfig) => {
2222
};
2323

2424
export const getMultiConfigPrompt = (
25-
configs: { filePath: string; config: CodeshiftConfig }[],
25+
configs: { filePath: string; config: Config }[],
2626
) => {
2727
const choices = configs.reduce<any[]>((accum, { filePath, config }) => {
2828
function mapToConfig(codemods: Record<string, string> = {}) {

packages/fetcher/package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@
77
"license": "MIT",
88
"repository": "https://github.com/hypermod-io/hypermod-community/tree/main/packages/fetcher",
99
"dependencies": {
10+
"@babel/core": "^7.13.16",
11+
"@babel/parser": "^7.13.16",
12+
"@babel/plugin-proposal-class-properties": "^7.13.0",
13+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8",
14+
"@babel/plugin-proposal-optional-chaining": "^7.13.12",
15+
"@babel/plugin-transform-modules-commonjs": "^7.13.8",
16+
"@babel/preset-flow": "^7.13.13",
17+
"@babel/preset-typescript": "^7.13.16",
18+
"@babel/register": "^7.13.16",
1019
"@hypermod/types": "*",
20+
"babel-core": "^7.0.0-bridge.0",
1121
"chalk": "^4.1.0",
1222
"fs-extra": "^9.1.0",
1323
"globby": "^11.1.0",

packages/fetcher/src/index.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,50 @@
1+
/* eslint-disable @typescript-eslint/no-var-requires */
12
import fs from 'fs';
23
import path from 'path';
34
import globby from 'globby';
45
import { PluginManager } from 'live-plugin-manager';
56

6-
import { CodeshiftConfig } from '@hypermod/types';
7+
import { Config } from '@hypermod/types';
8+
9+
// This configuration allows us to require TypeScript config files directly
10+
const { DEFAULT_EXTENSIONS } = require('@babel/core');
11+
const presets = [];
12+
13+
let presetEnv;
14+
try {
15+
presetEnv = require('@babel/preset-env');
16+
presets.push([presetEnv.default, { targets: { node: true } }]);
17+
} catch (_) {}
18+
19+
require('@babel/register')({
20+
configFile: false,
21+
babelrc: false,
22+
presets: [...presets, require('@babel/preset-typescript').default],
23+
plugins: [
24+
require('@babel/plugin-transform-class-properties').default,
25+
require('@babel/plugin-transform-nullish-coalescing-operator').default,
26+
require('@babel/plugin-transform-optional-chaining').default,
27+
require('@babel/plugin-transform-modules-commonjs').default,
28+
require('@babel/plugin-transform-private-methods').default,
29+
],
30+
extensions: [...DEFAULT_EXTENSIONS, '.ts', '.tsx'],
31+
// By default, babel register only compiles things inside the current working directory.
32+
// https://github.com/babel/babel/blob/2a4f16236656178e84b05b8915aab9261c55782c/packages/babel-register/src/node.js#L140-L157
33+
ignore: [
34+
// Ignore parser related files
35+
/@babel\/parser/,
36+
/\/flow-parser\//,
37+
/\/recast\//,
38+
/\/ast-types\//,
39+
],
40+
});
741

842
export interface ConfigMeta {
943
filePath: string;
10-
config: CodeshiftConfig;
44+
config: Config;
1145
}
1246

13-
function resolveConfigExport(pkg: any): CodeshiftConfig {
47+
function resolveConfigExport(pkg: any): Config {
1448
return pkg.default ? pkg.default : pkg;
1549
}
1650

@@ -62,9 +96,7 @@ export async function fetchConfigs(filePath: string): Promise<ConfigMeta[]> {
6296
return configs;
6397
}
6498

65-
export async function fetchConfigAtPath(
66-
filePath: string,
67-
): Promise<CodeshiftConfig> {
99+
export async function fetchConfigAtPath(filePath: string): Promise<Config> {
68100
const resolvedFilePath = path.resolve(filePath);
69101
const exists = fs.existsSync(resolvedFilePath);
70102

packages/types/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
export interface CodeshiftConfig {
1+
export interface Config {
22
targets?: string[];
33
maintainers?: string[];
44
description?: string;
55
transforms?: Record<string, string>;
66
presets?: Record<string, string>;
77
}
8+
9+
export type CodeshiftConfig = Config;

packages/validator/src/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import semver from 'semver';
22

3-
import { CodeshiftConfig } from '@hypermod/types';
3+
import { Config } from '@hypermod/types';
44
import { fetchConfig } from '@hypermod/fetcher';
55

6-
function hasValidTransforms(config: CodeshiftConfig) {
6+
function hasValidTransforms(config: Config) {
77
if (!config.transforms) return true;
88

99
return Object.entries(config.transforms).every(([key]) => semver.valid(key));
1010
}
1111

12-
function hasValidPresets(config: CodeshiftConfig): boolean {
12+
function hasValidPresets(config: Config): boolean {
1313
if (!config.presets) return true;
1414

1515
return Object.entries(config.presets).every(([key]) =>
1616
key.match(/^[0-9a-zA-Z\-]+$/),
1717
);
1818
}
1919

20-
function getInvalidProperties(config: CodeshiftConfig) {
20+
function getInvalidProperties(config: Config) {
2121
const validProperties = [
2222
'maintainers',
2323
'description',
@@ -33,7 +33,7 @@ export function isValidPackageName(dir: string): boolean {
3333
return !!dir.match(/^(@[a-z0-9-~][a-z0-9-._~]*__)?[a-z0-9-~][a-z0-9-._~]*$/);
3434
}
3535

36-
export function isValidConfig(config: CodeshiftConfig) {
36+
export function isValidConfig(config: Config) {
3737
return hasValidTransforms(config) && hasValidPresets(config);
3838
}
3939

@@ -44,10 +44,10 @@ export async function isValidConfigAtPath(filePath: string) {
4444
throw new Error(`Unable to locate config file at path: ${filePath}`);
4545
}
4646

47-
const invalidProperites = getInvalidProperties(configMeta.config);
48-
if (invalidProperites.length) {
47+
const invalidProperties = getInvalidProperties(configMeta.config);
48+
if (invalidProperties.length) {
4949
throw new Error(
50-
`Invalid transform ids found: ${invalidProperites.join(', ')}`,
50+
`Invalid transform ids found: ${invalidProperties.join(', ')}`,
5151
);
5252
}
5353

0 commit comments

Comments
 (0)