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

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.js ADDED
@@ -0,0 +1,227 @@
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.30";
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
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
211
+ const { run } = require('jscodeshift/src/Runner.js');
212
+ await run(transform, commitedFiles, {
213
+ ...args,
214
+ trpcFile,
215
+ trpcImportName
216
+ });
217
+ log.info(`Transform ${transform} completed`);
218
+ }
219
+ if (!args.skipTanstackQuery) {
220
+ log.info('Installing @trpc/tanstack-react-query');
221
+ await installPackage('@trpc/tanstack-react-query');
222
+ log.success('@trpc/tanstack-react-query installed');
223
+ log.info('Uninstalling @trpc/react-query');
224
+ await uninstallPackage('@trpc/react-query');
225
+ log.success('@trpc/react-query uninstalled');
226
+ }
227
+ outro('Upgrade complete! 🎉');
@@ -1,5 +1,3 @@
1
- Object.defineProperty(exports, '__esModule', { value: true });
2
-
3
1
  /**
4
2
  * Replaces the identifier for the root path key
5
3
  * of a member expression
@@ -261,5 +259,4 @@ function transform(file, api, options) {
261
259
  }
262
260
  const parser = 'tsx';
263
261
 
264
- exports.default = transform;
265
- exports.parser = parser;
262
+ export { transform as default, parser };
@@ -1,5 +1,3 @@
1
- Object.defineProperty(exports, '__esModule', { value: true });
2
-
3
1
  function transform(file, api, options) {
4
2
  const { trpcImportName } = options;
5
3
  let routerName = undefined;
@@ -116,5 +114,4 @@ function transform(file, api, options) {
116
114
  }
117
115
  const parser = 'tsx';
118
116
 
119
- exports.default = transform;
120
- exports.parser = parser;
117
+ export { transform as default, parser };
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@trpc/upgrade",
3
- "version": "0.0.0-alpha.30",
3
+ "version": "0.0.0-alpha.31",
4
4
  "description": "Upgrade scripts for tRPC",
5
5
  "author": "juliusmarminge",
6
6
  "license": "MIT",
7
- "bin": "./dist/bin.cjs",
7
+ "type": "module",
8
+ "bin": "./dist/bin.js",
8
9
  "homepage": "https://trpc.io",
9
10
  "repository": {
10
11
  "type": "git",
@@ -13,10 +14,10 @@
13
14
  },
14
15
  "exports": {
15
16
  "./transforms/hooksToOptions": {
16
- "default": "./dist/transforms/hooksToOptions.cjs"
17
+ "default": "./dist/transforms/hooksToOptions.js"
17
18
  },
18
19
  "./transforms/provider": {
19
- "default": "./dist/transforms/provider.cjs"
20
+ "default": "./dist/transforms/provider.js"
20
21
  }
21
22
  },
22
23
  "files": [
package/src/bin/index.ts CHANGED
@@ -6,27 +6,26 @@ 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
- 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
- });
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
+ });
24
23
 
25
- intro(`tRPC Upgrade CLI v${version}`);
24
+ intro(`tRPC Upgrade CLI v${version}`);
26
25
 
27
- if (args.help) {
28
- log.info(
29
- `
26
+ if (args.help) {
27
+ log.info(
28
+ `
30
29
  Usage: upgrade [options]
31
30
 
32
31
  Options:
@@ -35,66 +34,66 @@ Options:
35
34
  -v, --verbose Enable verbose logging
36
35
  -h, --help Show help
37
36
  `.trim(),
38
- );
39
- process.exit(0);
40
- }
37
+ );
38
+ process.exit(0);
39
+ }
41
40
 
42
- if (args.verbose) {
43
- log.info(`Running upgrade with args: ${JSON.stringify(args, null, 2)}`);
44
- }
41
+ if (args.verbose) {
42
+ log.info(`Running upgrade with args: ${JSON.stringify(args, null, 2)}`);
43
+ }
45
44
 
46
- if (!args.force) {
47
- await assertCleanGitTree();
48
- }
45
+ if (!args.force) {
46
+ await assertCleanGitTree();
47
+ }
49
48
 
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);
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);
64
63
 
65
- // Make sure provider transform runs first if it's selected
66
- const sortedTransforms = transforms.sort((a) =>
67
- a.includes('provider') ? -1 : 1,
68
- );
64
+ // Make sure provider transform runs first if it's selected
65
+ const sortedTransforms = transforms.sort((a) =>
66
+ a.includes('provider') ? -1 : 1,
67
+ );
69
68
 
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;
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;
75
74
 
76
- const commitedFiles = await filterIgnored(sourceFiles);
75
+ const commitedFiles = await filterIgnored(sourceFiles);
77
76
 
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
- }
77
+ for (const transform of sortedTransforms) {
78
+ log.info(`Running transform: ${transform}`);
79
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
80
+ const { run } = require('jscodeshift/src/Runner.js');
81
+ await run(transform, commitedFiles, {
82
+ ...args,
83
+ trpcFile,
84
+ trpcImportName,
85
+ });
86
+ log.info(`Transform ${transform} completed`);
87
+ }
88
88
 
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');
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');
93
93
 
94
- log.info('Uninstalling @trpc/react-query');
95
- await uninstallPackage('@trpc/react-query');
96
- log.success('@trpc/react-query uninstalled');
97
- }
94
+ log.info('Uninstalling @trpc/react-query');
95
+ await uninstallPackage('@trpc/react-query');
96
+ log.success('@trpc/react-query uninstalled');
97
+ }
98
98
 
99
- outro('Upgrade complete! 🎉');
100
- })();
99
+ outro('Upgrade complete! 🎉');
package/dist/bin.cjs DELETED
@@ -1,248 +0,0 @@
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
- })();