@trpc/upgrade 0.0.0-alpha.29 → 0.0.0-alpha.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.cjs ADDED
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env node
2
+ var args = require('@bomb.sh/args');
3
+ var p = require('@clack/prompts');
4
+ var ts = require('typescript');
5
+ var Path = require('path');
6
+ var CP = require('node:child_process');
7
+ var Util = require('node:util');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return n;
25
+ }
26
+
27
+ var p__namespace = /*#__PURE__*/_interopNamespace(p);
28
+ var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
29
+ var Path__namespace = /*#__PURE__*/_interopNamespace(Path);
30
+ var CP__namespace = /*#__PURE__*/_interopNamespace(CP);
31
+ var Util__namespace = /*#__PURE__*/_interopNamespace(Util);
32
+
33
+ var version = "0.0.0-alpha.29";
34
+
35
+ function getProgram(args) {
36
+ const configFile = ts__namespace.findConfigFile(process.cwd(), (filepath)=>ts__namespace.sys.fileExists(filepath));
37
+ if (!configFile) {
38
+ p__namespace.log.error('No tsconfig found');
39
+ process.exit(1);
40
+ }
41
+ if (args.verbose) {
42
+ p__namespace.log.info(`Using tsconfig: ${configFile}`);
43
+ }
44
+ const { config } = ts__namespace.readConfigFile(configFile, (filepath)=>ts__namespace.sys.readFile(filepath));
45
+ const parsedConfig = ts__namespace.parseJsonConfigFileContent(config, ts__namespace.sys, process.cwd());
46
+ const program = ts__namespace.createProgram({
47
+ options: parsedConfig.options,
48
+ rootNames: parsedConfig.fileNames,
49
+ configFileParsingDiagnostics: parsedConfig.errors
50
+ });
51
+ return program;
52
+ }
53
+ function findSourceAndImportName(program) {
54
+ const files = program.getSourceFiles().filter((sourceFile)=>{
55
+ if (sourceFile.isDeclarationFile) return false;
56
+ let found = false;
57
+ ts__namespace.forEachChild(sourceFile, (node)=>{
58
+ if (!found && ts__namespace.isImportDeclaration(node)) {
59
+ const { moduleSpecifier } = node;
60
+ if (ts__namespace.isStringLiteral(moduleSpecifier) && moduleSpecifier.text.includes('@trpc/react-query')) {
61
+ found = true;
62
+ }
63
+ }
64
+ });
65
+ return found;
66
+ });
67
+ let importName = 'trpc';
68
+ files.forEach((sourceFile)=>{
69
+ ts__namespace.forEachChild(sourceFile, (node)=>{
70
+ if (ts__namespace.isVariableStatement(node) && node.modifiers?.some((mod)=>mod.getText(sourceFile) === 'export')) {
71
+ node.declarationList.declarations.forEach((declaration)=>{
72
+ if (ts__namespace.isVariableDeclaration(declaration) && declaration.initializer && ts__namespace.isCallExpression(declaration.initializer) && ts__namespace.isIdentifier(declaration.initializer.expression) && declaration.initializer.expression.getText(sourceFile) === 'createTRPCReact') {
73
+ importName = declaration.name.getText(sourceFile);
74
+ }
75
+ });
76
+ }
77
+ });
78
+ });
79
+ return {
80
+ files: files.map((d)=>d.fileName),
81
+ importName
82
+ };
83
+ }
84
+ function findTRPCImportReferences(program) {
85
+ const { files: filesImportingTRPC, importName } = findSourceAndImportName(program);
86
+ const trpcReferenceSpecifiers = new Map();
87
+ program.getSourceFiles().forEach((sourceFile)=>{
88
+ if (sourceFile.isDeclarationFile) return;
89
+ ts__namespace.forEachChild(sourceFile, (node)=>{
90
+ if (ts__namespace.isImportDeclaration(node) && ts__namespace.isStringLiteral(node.moduleSpecifier)) {
91
+ const resolved = ts__namespace.resolveModuleName(node.moduleSpecifier.text, sourceFile.fileName, program.getCompilerOptions(), ts__namespace.sys);
92
+ if (resolved.resolvedModule && filesImportingTRPC.includes(resolved.resolvedModule.resolvedFileName)) {
93
+ trpcReferenceSpecifiers.set(resolved.resolvedModule.resolvedFileName, node.moduleSpecifier.text);
94
+ }
95
+ }
96
+ });
97
+ });
98
+ const counts = {};
99
+ let currentMax = 0;
100
+ const mostUsed = {
101
+ file: ''
102
+ };
103
+ [
104
+ ...trpcReferenceSpecifiers.values()
105
+ ].forEach((specifier)=>{
106
+ counts[specifier] = (counts[specifier] || 0) + 1;
107
+ if (counts[specifier] > currentMax) {
108
+ currentMax = counts[specifier];
109
+ mostUsed.file = specifier;
110
+ }
111
+ });
112
+ return {
113
+ importName,
114
+ mostUsed,
115
+ all: Object.fromEntries(trpcReferenceSpecifiers.entries())
116
+ };
117
+ }
118
+
119
+ const execa = Util__namespace.promisify(CP__namespace.exec);
120
+
121
+ async function assertCleanGitTree() {
122
+ const { stdout } = await execa('git status');
123
+ if (!stdout.includes('nothing to commit')) {
124
+ p__namespace.cancel('Git tree is not clean, please commit your changes and try again, or run with `--force`');
125
+ process.exit(1);
126
+ }
127
+ }
128
+ async function filterIgnored(files) {
129
+ const { stdout } = await execa('git check-ignore **/*');
130
+ const ignores = stdout.split('\n');
131
+ if (process.env.VERBOSE) {
132
+ p__namespace.log.info(`cwd: ${process.cwd()}`);
133
+ p__namespace.log.info(`All files in program: ${files.map((file)=>file.fileName).join(', ')}`);
134
+ p__namespace.log.info(`Ignored files: ${ignores.join(', ')}`);
135
+ }
136
+ // Ignore "common files"
137
+ const filteredSourcePaths = files.filter((source)=>source.fileName.startsWith(Path__namespace.resolve()) && // only look ahead of current directory
138
+ !source.fileName.includes('/trpc/packages/') && // relative paths when running codemod locally
139
+ !source.fileName.includes('/node_modules/') && // always ignore node_modules
140
+ !ignores.includes(source.fileName)).map((source)=>source.fileName);
141
+ if (process.env.VERBOSE) {
142
+ p__namespace.log.info(`Filtered files: ${filteredSourcePaths.join(', ')}`);
143
+ }
144
+ return filteredSourcePaths;
145
+ }
146
+
147
+ function getPackageManager() {
148
+ const userAgent = process.env.npm_config_user_agent;
149
+ if (userAgent?.startsWith('pnpm')) return 'pnpm';
150
+ if (userAgent?.startsWith('yarn')) return 'yarn';
151
+ if (userAgent?.startsWith('bun')) return 'bun';
152
+ return 'npm';
153
+ }
154
+ async function installPackage(packageName) {
155
+ const packageManager = getPackageManager();
156
+ const installCmd = packageManager === 'yarn' ? 'add' : 'install';
157
+ const { stdout, stderr } = await execa(`${packageManager} ${installCmd} ${packageName}`);
158
+ if (stderr) {
159
+ p__namespace.log.error(stderr);
160
+ }
161
+ p__namespace.log.info(stdout);
162
+ }
163
+ async function uninstallPackage(packageName) {
164
+ const packageManager = getPackageManager();
165
+ const uninstallCmd = packageManager === 'yarn' ? 'remove' : 'uninstall';
166
+ const { stdout, stderr } = await execa(`${packageManager} ${uninstallCmd} ${packageName}`);
167
+ if (stderr) {
168
+ p__namespace.log.error(stderr);
169
+ }
170
+ p__namespace.log.info(stdout);
171
+ }
172
+
173
+ void (async ()=>{
174
+ const args$1 = args.parse(process.argv.slice(2), {
175
+ default: {
176
+ force: false,
177
+ skipTanstackQuery: false,
178
+ verbose: false
179
+ },
180
+ alias: {
181
+ f: 'force',
182
+ h: 'help',
183
+ v: 'verbose',
184
+ q: 'skipTanstackQuery'
185
+ },
186
+ boolean: true
187
+ });
188
+ p.intro(`tRPC Upgrade CLI v${version}`);
189
+ if (args$1.help) {
190
+ p.log.info(`
191
+ Usage: upgrade [options]
192
+
193
+ Options:
194
+ -f, --force Skip git status check, use with caution
195
+ -q, --skipTanstackQuery Skip installing @trpc/tanstack-react-query package
196
+ -v, --verbose Enable verbose logging
197
+ -h, --help Show help
198
+ `.trim());
199
+ process.exit(0);
200
+ }
201
+ if (args$1.verbose) {
202
+ p.log.info(`Running upgrade with args: ${JSON.stringify(args$1, null, 2)}`);
203
+ }
204
+ if (!args$1.force) {
205
+ await assertCleanGitTree();
206
+ }
207
+ const transforms = await p.multiselect({
208
+ message: 'Select transforms to run',
209
+ options: [
210
+ {
211
+ value: require.resolve('@trpc/upgrade/transforms/hooksToOptions'),
212
+ label: 'Migrate Hooks to xxxOptions API'
213
+ },
214
+ {
215
+ value: require.resolve('@trpc/upgrade/transforms/provider'),
216
+ label: 'Migrate context provider setup'
217
+ }
218
+ ]
219
+ });
220
+ if (p.isCancel(transforms)) process.exit(0);
221
+ // Make sure provider transform runs first if it's selected
222
+ const sortedTransforms = transforms.sort((a)=>a.includes('provider') ? -1 : 1);
223
+ const program = getProgram(args$1);
224
+ const sourceFiles = program.getSourceFiles();
225
+ const possibleReferences = findTRPCImportReferences(program);
226
+ const trpcFile = possibleReferences.mostUsed.file;
227
+ const trpcImportName = possibleReferences.importName;
228
+ const commitedFiles = await filterIgnored(sourceFiles);
229
+ for (const transform of sortedTransforms){
230
+ p.log.info(`Running transform: ${transform}`);
231
+ const { run } = await import('jscodeshift/src/Runner.js');
232
+ await run(transform, commitedFiles, {
233
+ ...args$1,
234
+ trpcFile,
235
+ trpcImportName
236
+ });
237
+ p.log.info(`Transform ${transform} completed`);
238
+ }
239
+ if (!args$1.skipTanstackQuery) {
240
+ p.log.info('Installing @trpc/tanstack-react-query');
241
+ await installPackage('@trpc/tanstack-react-query');
242
+ p.log.success('@trpc/tanstack-react-query installed');
243
+ p.log.info('Uninstalling @trpc/react-query');
244
+ await uninstallPackage('@trpc/react-query');
245
+ p.log.success('@trpc/react-query uninstalled');
246
+ }
247
+ p.outro('Upgrade complete! 🎉');
248
+ })();
@@ -1,3 +1,5 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
1
3
  /**
2
4
  * Replaces the identifier for the root path key
3
5
  * of a member expression
@@ -259,4 +261,5 @@ function transform(file, api, options) {
259
261
  }
260
262
  const parser = 'tsx';
261
263
 
262
- export { transform as default, parser };
264
+ exports.default = transform;
265
+ exports.parser = parser;
@@ -1,3 +1,5 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
1
3
  function transform(file, api, options) {
2
4
  const { trpcImportName } = options;
3
5
  let routerName = undefined;
@@ -114,4 +116,5 @@ function transform(file, api, options) {
114
116
  }
115
117
  const parser = 'tsx';
116
118
 
117
- export { transform as default, parser };
119
+ exports.default = transform;
120
+ exports.parser = parser;
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@trpc/upgrade",
3
- "version": "0.0.0-alpha.29",
3
+ "version": "0.0.0-alpha.30",
4
4
  "description": "Upgrade scripts for tRPC",
5
5
  "author": "juliusmarminge",
6
6
  "license": "MIT",
7
- "type": "module",
8
- "bin": "./dist/bin.js",
7
+ "bin": "./dist/bin.cjs",
9
8
  "homepage": "https://trpc.io",
10
9
  "repository": {
11
10
  "type": "git",
@@ -14,10 +13,10 @@
14
13
  },
15
14
  "exports": {
16
15
  "./transforms/hooksToOptions": {
17
- "default": "./dist/transforms/hooksToOptions.js"
16
+ "default": "./dist/transforms/hooksToOptions.cjs"
18
17
  },
19
18
  "./transforms/provider": {
20
- "default": "./dist/transforms/provider.js"
19
+ "default": "./dist/transforms/provider.cjs"
21
20
  }
22
21
  },
23
22
  "files": [
package/src/bin/index.ts CHANGED
@@ -6,26 +6,27 @@ import { findTRPCImportReferences, getProgram } from '../lib/ast/scanners';
6
6
  import { assertCleanGitTree, filterIgnored } from '../lib/git';
7
7
  import { installPackage, uninstallPackage } from '../lib/pkgmgr';
8
8
 
9
- const args = parse(process.argv.slice(2), {
10
- default: {
11
- force: false,
12
- skipTanstackQuery: false,
13
- verbose: false,
14
- },
15
- alias: {
16
- f: 'force',
17
- h: 'help',
18
- v: 'verbose',
19
- q: 'skipTanstackQuery',
20
- },
21
- boolean: true,
22
- });
9
+ void (async () => {
10
+ const args = parse(process.argv.slice(2), {
11
+ default: {
12
+ force: false,
13
+ skipTanstackQuery: false,
14
+ verbose: false,
15
+ },
16
+ alias: {
17
+ f: 'force',
18
+ h: 'help',
19
+ v: 'verbose',
20
+ q: 'skipTanstackQuery',
21
+ },
22
+ boolean: true,
23
+ });
23
24
 
24
- intro(`tRPC Upgrade CLI v${version}`);
25
+ intro(`tRPC Upgrade CLI v${version}`);
25
26
 
26
- if (args.help) {
27
- log.info(
28
- `
27
+ if (args.help) {
28
+ log.info(
29
+ `
29
30
  Usage: upgrade [options]
30
31
 
31
32
  Options:
@@ -34,65 +35,66 @@ Options:
34
35
  -v, --verbose Enable verbose logging
35
36
  -h, --help Show help
36
37
  `.trim(),
37
- );
38
- process.exit(0);
39
- }
38
+ );
39
+ process.exit(0);
40
+ }
40
41
 
41
- if (args.verbose) {
42
- log.info(`Running upgrade with args: ${JSON.stringify(args, null, 2)}`);
43
- }
42
+ if (args.verbose) {
43
+ log.info(`Running upgrade with args: ${JSON.stringify(args, null, 2)}`);
44
+ }
44
45
 
45
- if (!args.force) {
46
- await assertCleanGitTree();
47
- }
46
+ if (!args.force) {
47
+ await assertCleanGitTree();
48
+ }
48
49
 
49
- const transforms = await multiselect({
50
- message: 'Select transforms to run',
51
- options: [
52
- {
53
- value: require.resolve('@trpc/upgrade/transforms/hooksToOptions'),
54
- label: 'Migrate Hooks to xxxOptions API',
55
- },
56
- {
57
- value: require.resolve('@trpc/upgrade/transforms/provider'),
58
- label: 'Migrate context provider setup',
59
- },
60
- ],
61
- });
62
- if (isCancel(transforms)) process.exit(0);
50
+ const transforms = await multiselect({
51
+ message: 'Select transforms to run',
52
+ options: [
53
+ {
54
+ value: require.resolve('@trpc/upgrade/transforms/hooksToOptions'),
55
+ label: 'Migrate Hooks to xxxOptions API',
56
+ },
57
+ {
58
+ value: require.resolve('@trpc/upgrade/transforms/provider'),
59
+ label: 'Migrate context provider setup',
60
+ },
61
+ ],
62
+ });
63
+ if (isCancel(transforms)) process.exit(0);
63
64
 
64
- // Make sure provider transform runs first if it's selected
65
- const sortedTransforms = transforms.sort((a) =>
66
- a.includes('provider') ? -1 : 1,
67
- );
65
+ // Make sure provider transform runs first if it's selected
66
+ const sortedTransforms = transforms.sort((a) =>
67
+ a.includes('provider') ? -1 : 1,
68
+ );
68
69
 
69
- const program = getProgram(args);
70
- const sourceFiles = program.getSourceFiles();
71
- const possibleReferences = findTRPCImportReferences(program);
72
- const trpcFile = possibleReferences.mostUsed.file;
73
- const trpcImportName = possibleReferences.importName;
70
+ const program = getProgram(args);
71
+ const sourceFiles = program.getSourceFiles();
72
+ const possibleReferences = findTRPCImportReferences(program);
73
+ const trpcFile = possibleReferences.mostUsed.file;
74
+ const trpcImportName = possibleReferences.importName;
74
75
 
75
- const commitedFiles = await filterIgnored(sourceFiles);
76
+ const commitedFiles = await filterIgnored(sourceFiles);
76
77
 
77
- for (const transform of sortedTransforms) {
78
- log.info(`Running transform: ${transform}`);
79
- const { run } = await import('jscodeshift/src/Runner.js');
80
- await run(transform, commitedFiles, {
81
- ...args,
82
- trpcFile,
83
- trpcImportName,
84
- });
85
- log.info(`Transform ${transform} completed`);
86
- }
78
+ for (const transform of sortedTransforms) {
79
+ log.info(`Running transform: ${transform}`);
80
+ const { run } = await import('jscodeshift/src/Runner.js');
81
+ await run(transform, commitedFiles, {
82
+ ...args,
83
+ trpcFile,
84
+ trpcImportName,
85
+ });
86
+ log.info(`Transform ${transform} completed`);
87
+ }
87
88
 
88
- if (!args.skipTanstackQuery) {
89
- log.info('Installing @trpc/tanstack-react-query');
90
- await installPackage('@trpc/tanstack-react-query');
91
- log.success('@trpc/tanstack-react-query installed');
89
+ if (!args.skipTanstackQuery) {
90
+ log.info('Installing @trpc/tanstack-react-query');
91
+ await installPackage('@trpc/tanstack-react-query');
92
+ log.success('@trpc/tanstack-react-query installed');
92
93
 
93
- log.info('Uninstalling @trpc/react-query');
94
- await uninstallPackage('@trpc/react-query');
95
- log.success('@trpc/react-query uninstalled');
96
- }
94
+ log.info('Uninstalling @trpc/react-query');
95
+ await uninstallPackage('@trpc/react-query');
96
+ log.success('@trpc/react-query uninstalled');
97
+ }
97
98
 
98
- outro('Upgrade complete! 🎉');
99
+ outro('Upgrade complete! 🎉');
100
+ })();
package/dist/bin.js DELETED
@@ -1,226 +0,0 @@
1
- #!/usr/bin/env node
2
- import { parse } from '@bomb.sh/args';
3
- import * as p from '@clack/prompts';
4
- import { intro, log, multiselect, isCancel, outro } from '@clack/prompts';
5
- import * as ts from 'typescript';
6
- import * as Path from 'path';
7
- import * as CP from 'node:child_process';
8
- import * as Util from 'node:util';
9
- import __node_cjsModule from 'node:module';
10
-
11
- var version = "0.0.0-alpha.28";
12
-
13
- function getProgram(args) {
14
- const configFile = ts.findConfigFile(process.cwd(), (filepath)=>ts.sys.fileExists(filepath));
15
- if (!configFile) {
16
- p.log.error('No tsconfig found');
17
- process.exit(1);
18
- }
19
- if (args.verbose) {
20
- p.log.info(`Using tsconfig: ${configFile}`);
21
- }
22
- const { config } = ts.readConfigFile(configFile, (filepath)=>ts.sys.readFile(filepath));
23
- const parsedConfig = ts.parseJsonConfigFileContent(config, ts.sys, process.cwd());
24
- const program = ts.createProgram({
25
- options: parsedConfig.options,
26
- rootNames: parsedConfig.fileNames,
27
- configFileParsingDiagnostics: parsedConfig.errors
28
- });
29
- return program;
30
- }
31
- function findSourceAndImportName(program) {
32
- const files = program.getSourceFiles().filter((sourceFile)=>{
33
- if (sourceFile.isDeclarationFile) return false;
34
- let found = false;
35
- ts.forEachChild(sourceFile, (node)=>{
36
- if (!found && ts.isImportDeclaration(node)) {
37
- const { moduleSpecifier } = node;
38
- if (ts.isStringLiteral(moduleSpecifier) && moduleSpecifier.text.includes('@trpc/react-query')) {
39
- found = true;
40
- }
41
- }
42
- });
43
- return found;
44
- });
45
- let importName = 'trpc';
46
- files.forEach((sourceFile)=>{
47
- ts.forEachChild(sourceFile, (node)=>{
48
- if (ts.isVariableStatement(node) && node.modifiers?.some((mod)=>mod.getText(sourceFile) === 'export')) {
49
- node.declarationList.declarations.forEach((declaration)=>{
50
- if (ts.isVariableDeclaration(declaration) && declaration.initializer && ts.isCallExpression(declaration.initializer) && ts.isIdentifier(declaration.initializer.expression) && declaration.initializer.expression.getText(sourceFile) === 'createTRPCReact') {
51
- importName = declaration.name.getText(sourceFile);
52
- }
53
- });
54
- }
55
- });
56
- });
57
- return {
58
- files: files.map((d)=>d.fileName),
59
- importName
60
- };
61
- }
62
- function findTRPCImportReferences(program) {
63
- const { files: filesImportingTRPC, importName } = findSourceAndImportName(program);
64
- const trpcReferenceSpecifiers = new Map();
65
- program.getSourceFiles().forEach((sourceFile)=>{
66
- if (sourceFile.isDeclarationFile) return;
67
- ts.forEachChild(sourceFile, (node)=>{
68
- if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
69
- const resolved = ts.resolveModuleName(node.moduleSpecifier.text, sourceFile.fileName, program.getCompilerOptions(), ts.sys);
70
- if (resolved.resolvedModule && filesImportingTRPC.includes(resolved.resolvedModule.resolvedFileName)) {
71
- trpcReferenceSpecifiers.set(resolved.resolvedModule.resolvedFileName, node.moduleSpecifier.text);
72
- }
73
- }
74
- });
75
- });
76
- const counts = {};
77
- let currentMax = 0;
78
- const mostUsed = {
79
- file: ''
80
- };
81
- [
82
- ...trpcReferenceSpecifiers.values()
83
- ].forEach((specifier)=>{
84
- counts[specifier] = (counts[specifier] || 0) + 1;
85
- if (counts[specifier] > currentMax) {
86
- currentMax = counts[specifier];
87
- mostUsed.file = specifier;
88
- }
89
- });
90
- return {
91
- importName,
92
- mostUsed,
93
- all: Object.fromEntries(trpcReferenceSpecifiers.entries())
94
- };
95
- }
96
-
97
- const execa = Util.promisify(CP.exec);
98
-
99
- async function assertCleanGitTree() {
100
- const { stdout } = await execa('git status');
101
- if (!stdout.includes('nothing to commit')) {
102
- p.cancel('Git tree is not clean, please commit your changes and try again, or run with `--force`');
103
- process.exit(1);
104
- }
105
- }
106
- async function filterIgnored(files) {
107
- const { stdout } = await execa('git check-ignore **/*');
108
- const ignores = stdout.split('\n');
109
- if (process.env.VERBOSE) {
110
- p.log.info(`cwd: ${process.cwd()}`);
111
- p.log.info(`All files in program: ${files.map((file)=>file.fileName).join(', ')}`);
112
- p.log.info(`Ignored files: ${ignores.join(', ')}`);
113
- }
114
- // Ignore "common files"
115
- const filteredSourcePaths = files.filter((source)=>source.fileName.startsWith(Path.resolve()) && // only look ahead of current directory
116
- !source.fileName.includes('/trpc/packages/') && // relative paths when running codemod locally
117
- !source.fileName.includes('/node_modules/') && // always ignore node_modules
118
- !ignores.includes(source.fileName)).map((source)=>source.fileName);
119
- if (process.env.VERBOSE) {
120
- p.log.info(`Filtered files: ${filteredSourcePaths.join(', ')}`);
121
- }
122
- return filteredSourcePaths;
123
- }
124
-
125
- function getPackageManager() {
126
- const userAgent = process.env.npm_config_user_agent;
127
- if (userAgent?.startsWith('pnpm')) return 'pnpm';
128
- if (userAgent?.startsWith('yarn')) return 'yarn';
129
- if (userAgent?.startsWith('bun')) return 'bun';
130
- return 'npm';
131
- }
132
- async function installPackage(packageName) {
133
- const packageManager = getPackageManager();
134
- const installCmd = packageManager === 'yarn' ? 'add' : 'install';
135
- const { stdout, stderr } = await execa(`${packageManager} ${installCmd} ${packageName}`);
136
- if (stderr) {
137
- p.log.error(stderr);
138
- }
139
- p.log.info(stdout);
140
- }
141
- async function uninstallPackage(packageName) {
142
- const packageManager = getPackageManager();
143
- const uninstallCmd = packageManager === 'yarn' ? 'remove' : 'uninstall';
144
- const { stdout, stderr } = await execa(`${packageManager} ${uninstallCmd} ${packageName}`);
145
- if (stderr) {
146
- p.log.error(stderr);
147
- }
148
- p.log.info(stdout);
149
- }
150
-
151
- const require = __node_cjsModule.createRequire(import.meta.url);
152
-
153
- const args = parse(process.argv.slice(2), {
154
- default: {
155
- force: false,
156
- skipTanstackQuery: false,
157
- verbose: false
158
- },
159
- alias: {
160
- f: 'force',
161
- h: 'help',
162
- v: 'verbose',
163
- q: 'skipTanstackQuery'
164
- },
165
- boolean: true
166
- });
167
- intro(`tRPC Upgrade CLI v${version}`);
168
- if (args.help) {
169
- log.info(`
170
- Usage: upgrade [options]
171
-
172
- Options:
173
- -f, --force Skip git status check, use with caution
174
- -q, --skipTanstackQuery Skip installing @trpc/tanstack-react-query package
175
- -v, --verbose Enable verbose logging
176
- -h, --help Show help
177
- `.trim());
178
- process.exit(0);
179
- }
180
- if (args.verbose) {
181
- log.info(`Running upgrade with args: ${JSON.stringify(args, null, 2)}`);
182
- }
183
- if (!args.force) {
184
- await assertCleanGitTree();
185
- }
186
- const transforms = await multiselect({
187
- message: 'Select transforms to run',
188
- options: [
189
- {
190
- value: require.resolve('@trpc/upgrade/transforms/hooksToOptions'),
191
- label: 'Migrate Hooks to xxxOptions API'
192
- },
193
- {
194
- value: require.resolve('@trpc/upgrade/transforms/provider'),
195
- label: 'Migrate context provider setup'
196
- }
197
- ]
198
- });
199
- if (isCancel(transforms)) process.exit(0);
200
- // Make sure provider transform runs first if it's selected
201
- const sortedTransforms = transforms.sort((a)=>a.includes('provider') ? -1 : 1);
202
- const program = getProgram(args);
203
- const sourceFiles = program.getSourceFiles();
204
- const possibleReferences = findTRPCImportReferences(program);
205
- const trpcFile = possibleReferences.mostUsed.file;
206
- const trpcImportName = possibleReferences.importName;
207
- const commitedFiles = await filterIgnored(sourceFiles);
208
- for (const transform of sortedTransforms){
209
- log.info(`Running transform: ${transform}`);
210
- const { run } = await import('jscodeshift/src/Runner.js');
211
- await run(transform, commitedFiles, {
212
- ...args,
213
- trpcFile,
214
- trpcImportName
215
- });
216
- log.info(`Transform ${transform} completed`);
217
- }
218
- if (!args.skipTanstackQuery) {
219
- log.info('Installing @trpc/tanstack-react-query');
220
- await installPackage('@trpc/tanstack-react-query');
221
- log.success('@trpc/tanstack-react-query installed');
222
- log.info('Uninstalling @trpc/react-query');
223
- await uninstallPackage('@trpc/react-query');
224
- log.success('@trpc/react-query uninstalled');
225
- }
226
- outro('Upgrade complete! 🎉');