@sentry/wizard 3.14.1 → 3.16.0
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/CHANGELOG.md +19 -4
- package/dist/lib/Steps/ChooseIntegration.js +1 -1
- package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
- package/dist/lib/Steps/Integrations/ReactNative.d.ts +7 -32
- package/dist/lib/Steps/Integrations/ReactNative.js +17 -485
- package/dist/lib/Steps/Integrations/ReactNative.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/android/android-wizard.js +13 -18
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +11 -4
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/cocoapod.d.ts +1 -0
- package/dist/src/apple/cocoapod.js +36 -13
- package/dist/src/apple/cocoapod.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +1 -1
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/react-native/glob.d.ts +3 -0
- package/dist/src/react-native/glob.js +18 -0
- package/dist/src/react-native/glob.js.map +1 -0
- package/dist/src/react-native/gradle.d.ts +4 -0
- package/dist/src/react-native/gradle.js +49 -0
- package/dist/src/react-native/gradle.js.map +1 -0
- package/dist/src/react-native/javascript.d.ts +8 -0
- package/dist/src/react-native/javascript.js +25 -0
- package/dist/src/react-native/javascript.js.map +1 -0
- package/dist/src/react-native/options.d.ts +4 -0
- package/dist/src/react-native/options.js +3 -0
- package/dist/src/react-native/options.js.map +1 -0
- package/dist/src/react-native/react-native-wizard.d.ts +9 -0
- package/dist/src/react-native/react-native-wizard.js +356 -0
- package/dist/src/react-native/react-native-wizard.js.map +1 -0
- package/dist/src/react-native/uninstall.d.ts +2 -0
- package/dist/src/react-native/uninstall.js +130 -0
- package/dist/src/react-native/uninstall.js.map +1 -0
- package/dist/src/react-native/xcode.d.ts +18 -0
- package/dist/src/react-native/xcode.js +170 -0
- package/dist/src/react-native/xcode.js.map +1 -0
- package/dist/src/remix/codemods/handle-error.js +28 -0
- package/dist/src/remix/codemods/handle-error.js.map +1 -1
- package/dist/src/remix/codemods/root-common.d.ts +2 -0
- package/dist/src/remix/codemods/root-common.js +70 -0
- package/dist/src/remix/codemods/root-common.js.map +1 -0
- package/dist/src/remix/codemods/root-v1.js +5 -36
- package/dist/src/remix/codemods/root-v1.js.map +1 -1
- package/dist/src/remix/codemods/root-v2.js +53 -4
- package/dist/src/remix/codemods/root-v2.js.map +1 -1
- package/dist/src/remix/remix-wizard.js +8 -5
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/remix/sdk-setup.d.ts +1 -0
- package/dist/src/remix/sdk-setup.js +10 -6
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/remix/templates.d.ts +1 -1
- package/dist/src/remix/templates.js +1 -1
- package/dist/src/remix/templates.js.map +1 -1
- package/dist/src/remix/utils.d.ts +2 -0
- package/dist/src/remix/utils.js +6 -1
- package/dist/src/remix/utils.js.map +1 -1
- package/dist/src/sourcemaps/tools/nextjs.js +3 -3
- package/dist/src/sourcemaps/tools/nextjs.js.map +1 -1
- package/dist/src/sourcemaps/tools/sentry-cli.js +1 -1
- package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/clack-utils.d.ts +19 -3
- package/dist/src/utils/clack-utils.js +141 -39
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/src/utils/semver.d.ts +5 -0
- package/dist/src/utils/semver.js +27 -0
- package/dist/src/utils/semver.js.map +1 -0
- package/dist/src/utils/sentrycli-utils.js +4 -1
- package/dist/src/utils/sentrycli-utils.js.map +1 -1
- package/dist/src/utils/types.d.ts +3 -0
- package/dist/src/utils/types.js.map +1 -1
- package/dist/test/react-native/gradle.test.js +57 -0
- package/dist/test/react-native/gradle.test.js.map +1 -0
- package/dist/test/react-native/javascript.test.js +47 -0
- package/dist/test/react-native/javascript.test.js.map +1 -0
- package/dist/test/react-native/xcode.test.d.ts +1 -0
- package/dist/test/react-native/xcode.test.js +144 -0
- package/dist/test/react-native/xcode.test.js.map +1 -0
- package/lib/Steps/ChooseIntegration.ts +1 -1
- package/lib/Steps/Integrations/ReactNative.ts +17 -573
- package/package.json +1 -1
- package/src/android/android-wizard.ts +3 -18
- package/src/apple/apple-wizard.ts +12 -3
- package/src/apple/cocoapod.ts +20 -9
- package/src/nextjs/nextjs-wizard.ts +1 -1
- package/src/react-native/glob.ts +13 -0
- package/src/react-native/gradle.ts +26 -0
- package/src/react-native/javascript.ts +33 -0
- package/src/react-native/options.ts +5 -0
- package/src/react-native/react-native-wizard.ts +369 -0
- package/src/react-native/uninstall.ts +107 -0
- package/src/react-native/xcode.ts +228 -0
- package/src/remix/codemods/handle-error.ts +30 -0
- package/src/remix/codemods/root-common.ts +63 -0
- package/src/remix/codemods/root-v1.ts +3 -53
- package/src/remix/codemods/root-v2.ts +71 -2
- package/src/remix/remix-wizard.ts +9 -6
- package/src/remix/sdk-setup.ts +14 -6
- package/src/remix/templates.ts +2 -6
- package/src/remix/utils.ts +5 -0
- package/src/sourcemaps/tools/nextjs.ts +6 -6
- package/src/sourcemaps/tools/sentry-cli.ts +1 -1
- package/src/sveltekit/sveltekit-wizard.ts +1 -1
- package/src/utils/clack-utils.ts +229 -74
- package/src/utils/semver.ts +33 -0
- package/src/utils/sentrycli-utils.ts +3 -1
- package/src/utils/types.ts +3 -0
- package/test/react-native/gradle.test.ts +310 -0
- package/test/react-native/javascript.test.ts +131 -0
- package/test/react-native/xcode.test.ts +238 -0
- package/dist/lib/Steps/Integrations/__tests__/ReactNative.js +0 -198
- package/dist/lib/Steps/Integrations/__tests__/ReactNative.js.map +0 -1
- package/dist/lib/__tests__/Setup.js +0 -57
- package/dist/lib/__tests__/Setup.js.map +0 -1
- package/lib/Steps/Integrations/__tests__/ReactNative.ts +0 -136
- package/lib/__tests__/Setup.ts +0 -42
- /package/dist/{lib/Steps/Integrations/__tests__/ReactNative.d.ts → test/react-native/gradle.test.d.ts} +0 -0
- /package/dist/{lib/__tests__/Setup.d.ts → test/react-native/javascript.test.d.ts} +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type BuildPhase = {
|
|
2
|
+
shellScript: string;
|
|
3
|
+
};
|
|
4
|
+
type BuildPhaseMap = Record<string, BuildPhase>;
|
|
5
|
+
export declare function getValidExistingBuildPhases(xcodeProject: any): BuildPhaseMap;
|
|
6
|
+
export declare function patchBundlePhase(bundlePhase: BuildPhase | undefined): void;
|
|
7
|
+
export declare function unPatchBundlePhase(bundlePhase: BuildPhase | undefined): void;
|
|
8
|
+
export declare function removeSentryFromBundleShellScript(script: string): string;
|
|
9
|
+
export declare function findBundlePhase(buildPhases: BuildPhaseMap): BuildPhase | undefined;
|
|
10
|
+
export declare function doesBundlePhaseIncludeSentry(buildPhase: BuildPhase): boolean;
|
|
11
|
+
export declare function addSentryToBundleShellScript(script: string): string;
|
|
12
|
+
export declare function addDebugFilesUploadPhase(xcodeProject: any, { debugFilesUploadPhaseExists }: {
|
|
13
|
+
debugFilesUploadPhaseExists: boolean;
|
|
14
|
+
}): void;
|
|
15
|
+
export declare function unPatchDebugFilesUploadPhase(xcodeProject: any): void;
|
|
16
|
+
export declare function findDebugFilesUploadPhase(buildPhasesMap: Record<string, BuildPhase>): [key: string, buildPhase: BuildPhase] | undefined;
|
|
17
|
+
export declare function writeXcodeProject(xcodeProjectPath: string, xcodeProject: any): void;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.writeXcodeProject = exports.findDebugFilesUploadPhase = exports.unPatchDebugFilesUploadPhase = exports.addDebugFilesUploadPhase = exports.addSentryToBundleShellScript = exports.doesBundlePhaseIncludeSentry = exports.findBundlePhase = exports.removeSentryFromBundleShellScript = exports.unPatchBundlePhase = exports.patchBundlePhase = exports.getValidExistingBuildPhases = void 0;
|
|
30
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
31
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
32
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
33
|
+
var fs = __importStar(require("fs"));
|
|
34
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
35
|
+
var prompts_1 = __importDefault(require("@clack/prompts"));
|
|
36
|
+
var chalk_1 = __importDefault(require("chalk"));
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
function getValidExistingBuildPhases(xcodeProject) {
|
|
39
|
+
var map = {};
|
|
40
|
+
var raw = xcodeProject.hash.project.objects.PBXShellScriptBuildPhase || {};
|
|
41
|
+
for (var key in raw) {
|
|
42
|
+
var val = raw[key];
|
|
43
|
+
val.isa && (map[key] = val);
|
|
44
|
+
}
|
|
45
|
+
return map;
|
|
46
|
+
}
|
|
47
|
+
exports.getValidExistingBuildPhases = getValidExistingBuildPhases;
|
|
48
|
+
function patchBundlePhase(bundlePhase) {
|
|
49
|
+
if (!bundlePhase) {
|
|
50
|
+
prompts_1.default.log.warn("Could not find ".concat(chalk_1.default.cyan('Bundle React Native code and images'), " build phase."));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
var bundlePhaseIncludesSentry = doesBundlePhaseIncludeSentry(bundlePhase);
|
|
54
|
+
if (bundlePhaseIncludesSentry) {
|
|
55
|
+
prompts_1.default.log.warn("Build phase ".concat(chalk_1.default.cyan('Bundle React Native code and images'), " already includes Sentry."));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
var script = JSON.parse(bundlePhase.shellScript);
|
|
59
|
+
bundlePhase.shellScript = JSON.stringify(addSentryToBundleShellScript(script));
|
|
60
|
+
prompts_1.default.log.success("Patched Build phase ".concat(chalk_1.default.cyan('Bundle React Native code and images'), "."));
|
|
61
|
+
}
|
|
62
|
+
exports.patchBundlePhase = patchBundlePhase;
|
|
63
|
+
function unPatchBundlePhase(bundlePhase) {
|
|
64
|
+
if (!bundlePhase) {
|
|
65
|
+
prompts_1.default.log.warn("Could not find ".concat(chalk_1.default.cyan('Bundle React Native code and images'), " build phase."));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (!bundlePhase.shellScript.match(/sentry-cli\s+react-native\s+xcode/i)) {
|
|
69
|
+
prompts_1.default.log.success("Build phase ".concat(chalk_1.default.cyan('Bundle React Native code and images'), " does not include Sentry."));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
bundlePhase.shellScript = JSON.stringify(removeSentryFromBundleShellScript(JSON.parse(bundlePhase.shellScript)));
|
|
73
|
+
prompts_1.default.log.success("Build phase ".concat(chalk_1.default.cyan('Bundle React Native code and images'), " unpatched successfully."));
|
|
74
|
+
}
|
|
75
|
+
exports.unPatchBundlePhase = unPatchBundlePhase;
|
|
76
|
+
function removeSentryFromBundleShellScript(script) {
|
|
77
|
+
return (script
|
|
78
|
+
// remove sentry properties export
|
|
79
|
+
.replace(/^export SENTRY_PROPERTIES=sentry.properties\r?\n/m, '')
|
|
80
|
+
.replace(/^\/bin\/sh .*?..\/node_modules\/@sentry\/react-native\/scripts\/collect-modules.sh"?\r?\n/m, '')
|
|
81
|
+
// unwrap react-native-xcode.sh command. In case someone replaced it
|
|
82
|
+
// entirely with the sentry-cli command we need to put the original
|
|
83
|
+
// version back in.
|
|
84
|
+
.replace(/\.\.\/node_modules\/@sentry\/cli\/bin\/sentry-cli\s+react-native\s+xcode\s+\$REACT_NATIVE_XCODE/i, '$REACT_NATIVE_XCODE'));
|
|
85
|
+
}
|
|
86
|
+
exports.removeSentryFromBundleShellScript = removeSentryFromBundleShellScript;
|
|
87
|
+
function findBundlePhase(buildPhases) {
|
|
88
|
+
return Object.values(buildPhases).find(function (buildPhase) {
|
|
89
|
+
return buildPhase.shellScript.match(/\/scripts\/react-native-xcode\.sh/i);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
exports.findBundlePhase = findBundlePhase;
|
|
93
|
+
function doesBundlePhaseIncludeSentry(buildPhase) {
|
|
94
|
+
return !!buildPhase.shellScript.match(/sentry-cli\s+react-native\s+xcode/i);
|
|
95
|
+
}
|
|
96
|
+
exports.doesBundlePhaseIncludeSentry = doesBundlePhaseIncludeSentry;
|
|
97
|
+
function addSentryToBundleShellScript(script) {
|
|
98
|
+
return ('export SENTRY_PROPERTIES=sentry.properties\n' +
|
|
99
|
+
'export EXTRA_PACKAGER_ARGS="--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map"\n' +
|
|
100
|
+
script.replace('$REACT_NATIVE_XCODE', function () {
|
|
101
|
+
// eslint-disable-next-line no-useless-escape
|
|
102
|
+
return '\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\"';
|
|
103
|
+
}) +
|
|
104
|
+
'\n/bin/sh -c "$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh"\n');
|
|
105
|
+
}
|
|
106
|
+
exports.addSentryToBundleShellScript = addSentryToBundleShellScript;
|
|
107
|
+
function addDebugFilesUploadPhase(
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
+
xcodeProject, _a) {
|
|
110
|
+
var debugFilesUploadPhaseExists = _a.debugFilesUploadPhaseExists;
|
|
111
|
+
if (debugFilesUploadPhaseExists) {
|
|
112
|
+
prompts_1.default.log.warn("Build phase ".concat(chalk_1.default.cyan('Upload Debug Symbols to Sentry'), " already exists."));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
xcodeProject.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Upload Debug Symbols to Sentry', null, {
|
|
116
|
+
shellPath: '/bin/sh',
|
|
117
|
+
shellScript: "\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nif [ -f \"$WITH_ENVIRONMENT\" ]; then\n . \"$WITH_ENVIRONMENT\"\nfi\nexport SENTRY_PROPERTIES=sentry.properties\n[ \"$SENTRY_INCLUDE_NATIVE_SOURCES\" = \"true\" ] && INCLUDE_SOURCES_FLAG=\"--include-sources\" || INCLUDE_SOURCES_FLAG=\"\"\n../node_modules/@sentry/cli/bin/sentry-cli debug-files upload \"$INCLUDE_SOURCES_FLAG\" \"$DWARF_DSYM_FOLDER_PATH\"\n",
|
|
118
|
+
});
|
|
119
|
+
prompts_1.default.log.success("Added Build phase ".concat(chalk_1.default.cyan('Upload Debug Symbols to Sentry'), "."));
|
|
120
|
+
}
|
|
121
|
+
exports.addDebugFilesUploadPhase = addDebugFilesUploadPhase;
|
|
122
|
+
function unPatchDebugFilesUploadPhase(
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
124
|
+
xcodeProject) {
|
|
125
|
+
var buildPhasesMap = xcodeProject.hash.project.objects.PBXShellScriptBuildPhase || {};
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
127
|
+
var debugFilesUploadPhaseResult = findDebugFilesUploadPhase(buildPhasesMap);
|
|
128
|
+
if (!debugFilesUploadPhaseResult) {
|
|
129
|
+
prompts_1.default.log.success("Build phase ".concat(chalk_1.default.cyan('Upload Debug Symbols to Sentry'), " not found."));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
var debugFilesUploadPhaseKey = debugFilesUploadPhaseResult[0];
|
|
133
|
+
var firstTarget = xcodeProject.getFirstTarget().uuid;
|
|
134
|
+
var nativeTargets = xcodeProject.hash.project.objects.PBXNativeTarget;
|
|
135
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
136
|
+
delete buildPhasesMap[debugFilesUploadPhaseKey];
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
138
|
+
delete buildPhasesMap["".concat(debugFilesUploadPhaseKey, "_comment")];
|
|
139
|
+
var phases = nativeTargets[firstTarget].buildPhases;
|
|
140
|
+
if (phases) {
|
|
141
|
+
for (var i = 0; i < phases.length; i++) {
|
|
142
|
+
if (phases[i].value === debugFilesUploadPhaseKey) {
|
|
143
|
+
phases.splice(i, 1);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
prompts_1.default.log.success("Build phase ".concat(chalk_1.default.cyan('Upload Debug Symbols to Sentry'), " removed successfully."));
|
|
149
|
+
}
|
|
150
|
+
exports.unPatchDebugFilesUploadPhase = unPatchDebugFilesUploadPhase;
|
|
151
|
+
function findDebugFilesUploadPhase(buildPhasesMap) {
|
|
152
|
+
return Object.entries(buildPhasesMap).find(function (_a) {
|
|
153
|
+
var _ = _a[0], buildPhase = _a[1];
|
|
154
|
+
return typeof buildPhase !== 'string' &&
|
|
155
|
+
!!buildPhase.shellScript.match(/sentry-cli\s+(upload-dsym|debug-files upload)\b/);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
exports.findDebugFilesUploadPhase = findDebugFilesUploadPhase;
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
160
|
+
function writeXcodeProject(xcodeProjectPath, xcodeProject) {
|
|
161
|
+
var newContent = xcodeProject.writeSync();
|
|
162
|
+
var currentContent = fs.readFileSync(xcodeProjectPath, 'utf-8');
|
|
163
|
+
if (newContent === currentContent) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
fs.writeFileSync(xcodeProjectPath, newContent, 'utf-8');
|
|
167
|
+
prompts_1.default.log.success(chalk_1.default.green("Xcode project ".concat(chalk_1.default.cyan(xcodeProjectPath), " changes saved.")));
|
|
168
|
+
}
|
|
169
|
+
exports.writeXcodeProject = writeXcodeProject;
|
|
170
|
+
//# sourceMappingURL=xcode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xcode.js","sourceRoot":"","sources":["../../../src/react-native/xcode.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport * as fs from 'fs';\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\ntype BuildPhase = { shellScript: string };\ntype BuildPhaseMap = Record<string, BuildPhase>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getValidExistingBuildPhases(xcodeProject: any): BuildPhaseMap {\n const map: BuildPhaseMap = {};\n const raw = xcodeProject.hash.project.objects.PBXShellScriptBuildPhase || {};\n for (const key in raw) {\n const val = raw[key];\n val.isa && (map[key] = val);\n }\n\n return map;\n}\n\nexport function patchBundlePhase(bundlePhase: BuildPhase | undefined) {\n if (!bundlePhase) {\n clack.log.warn(\n `Could not find ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n return;\n }\n\n const bundlePhaseIncludesSentry = doesBundlePhaseIncludeSentry(bundlePhase);\n if (bundlePhaseIncludesSentry) {\n clack.log.warn(\n `Build phase ${chalk.cyan(\n 'Bundle React Native code and images',\n )} already includes Sentry.`,\n );\n return;\n }\n\n const script: string = JSON.parse(bundlePhase.shellScript);\n bundlePhase.shellScript = JSON.stringify(\n addSentryToBundleShellScript(script),\n );\n clack.log.success(\n `Patched Build phase ${chalk.cyan('Bundle React Native code and images')}.`,\n );\n}\n\nexport function unPatchBundlePhase(bundlePhase: BuildPhase | undefined) {\n if (!bundlePhase) {\n clack.log.warn(\n `Could not find ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n return;\n }\n\n if (!bundlePhase.shellScript.match(/sentry-cli\\s+react-native\\s+xcode/i)) {\n clack.log.success(\n `Build phase ${chalk.cyan(\n 'Bundle React Native code and images',\n )} does not include Sentry.`,\n );\n return;\n }\n\n bundlePhase.shellScript = JSON.stringify(\n removeSentryFromBundleShellScript(\n <string>JSON.parse(bundlePhase.shellScript),\n ),\n );\n clack.log.success(\n `Build phase ${chalk.cyan(\n 'Bundle React Native code and images',\n )} unpatched successfully.`,\n );\n}\n\nexport function removeSentryFromBundleShellScript(script: string): string {\n return (\n script\n // remove sentry properties export\n .replace(/^export SENTRY_PROPERTIES=sentry.properties\\r?\\n/m, '')\n .replace(\n /^\\/bin\\/sh .*?..\\/node_modules\\/@sentry\\/react-native\\/scripts\\/collect-modules.sh\"?\\r?\\n/m,\n '',\n )\n // unwrap react-native-xcode.sh command. In case someone replaced it\n // entirely with the sentry-cli command we need to put the original\n // version back in.\n .replace(\n /\\.\\.\\/node_modules\\/@sentry\\/cli\\/bin\\/sentry-cli\\s+react-native\\s+xcode\\s+\\$REACT_NATIVE_XCODE/i,\n '$REACT_NATIVE_XCODE',\n )\n );\n}\n\nexport function findBundlePhase(buildPhases: BuildPhaseMap) {\n return Object.values(buildPhases).find((buildPhase) =>\n buildPhase.shellScript.match(/\\/scripts\\/react-native-xcode\\.sh/i),\n );\n}\n\nexport function doesBundlePhaseIncludeSentry(buildPhase: BuildPhase) {\n return !!buildPhase.shellScript.match(/sentry-cli\\s+react-native\\s+xcode/i);\n}\n\nexport function addSentryToBundleShellScript(script: string): string {\n return (\n 'export SENTRY_PROPERTIES=sentry.properties\\n' +\n 'export EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\\n' +\n script.replace(\n '$REACT_NATIVE_XCODE',\n () =>\n // eslint-disable-next-line no-useless-escape\n '\\\\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\\\"',\n ) +\n '\\n/bin/sh -c \"$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh\"\\n'\n );\n}\n\nexport function addDebugFilesUploadPhase(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n xcodeProject: any,\n { debugFilesUploadPhaseExists }: { debugFilesUploadPhaseExists: boolean },\n) {\n if (debugFilesUploadPhaseExists) {\n clack.log.warn(\n `Build phase ${chalk.cyan(\n 'Upload Debug Symbols to Sentry',\n )} already exists.`,\n );\n return;\n }\n\n xcodeProject.addBuildPhase(\n [],\n 'PBXShellScriptBuildPhase',\n 'Upload Debug Symbols to Sentry',\n null,\n {\n shellPath: '/bin/sh',\n shellScript: `\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nif [ -f \"$WITH_ENVIRONMENT\" ]; then\n . \"$WITH_ENVIRONMENT\"\nfi\nexport SENTRY_PROPERTIES=sentry.properties\n[ \"$SENTRY_INCLUDE_NATIVE_SOURCES\" = \"true\" ] && INCLUDE_SOURCES_FLAG=\"--include-sources\" || INCLUDE_SOURCES_FLAG=\"\"\n../node_modules/@sentry/cli/bin/sentry-cli debug-files upload \"$INCLUDE_SOURCES_FLAG\" \"$DWARF_DSYM_FOLDER_PATH\"\n`,\n },\n );\n clack.log.success(\n `Added Build phase ${chalk.cyan('Upload Debug Symbols to Sentry')}.`,\n );\n}\n\nexport function unPatchDebugFilesUploadPhase(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n xcodeProject: any,\n) {\n const buildPhasesMap =\n xcodeProject.hash.project.objects.PBXShellScriptBuildPhase || {};\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const debugFilesUploadPhaseResult = findDebugFilesUploadPhase(buildPhasesMap);\n if (!debugFilesUploadPhaseResult) {\n clack.log.success(\n `Build phase ${chalk.cyan('Upload Debug Symbols to Sentry')} not found.`,\n );\n return;\n }\n\n const [debugFilesUploadPhaseKey] = debugFilesUploadPhaseResult;\n const firstTarget: string = xcodeProject.getFirstTarget().uuid;\n const nativeTargets = xcodeProject.hash.project.objects.PBXNativeTarget;\n\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete buildPhasesMap[debugFilesUploadPhaseKey];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete buildPhasesMap[`${debugFilesUploadPhaseKey}_comment`];\n const phases = nativeTargets[firstTarget].buildPhases;\n if (phases) {\n for (let i = 0; i < phases.length; i++) {\n if (phases[i].value === debugFilesUploadPhaseKey) {\n phases.splice(i, 1);\n break;\n }\n }\n }\n clack.log.success(\n `Build phase ${chalk.cyan(\n 'Upload Debug Symbols to Sentry',\n )} removed successfully.`,\n );\n}\n\nexport function findDebugFilesUploadPhase(\n buildPhasesMap: Record<string, BuildPhase>,\n): [key: string, buildPhase: BuildPhase] | undefined {\n return Object.entries(buildPhasesMap).find(\n ([_, buildPhase]) =>\n typeof buildPhase !== 'string' &&\n !!buildPhase.shellScript.match(\n /sentry-cli\\s+(upload-dsym|debug-files upload)\\b/,\n ),\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function writeXcodeProject(xcodeProjectPath: string, xcodeProject: any) {\n const newContent = xcodeProject.writeSync();\n const currentContent = fs.readFileSync(xcodeProjectPath, 'utf-8');\n if (newContent === currentContent) {\n return;\n }\n\n fs.writeFileSync(xcodeProjectPath, newContent, 'utf-8');\n clack.log.success(\n chalk.green(`Xcode project ${chalk.cyan(xcodeProjectPath)} changes saved.`),\n );\n}\n"]}
|
|
@@ -37,6 +37,7 @@ var chalk_1 = __importDefault(require("chalk"));
|
|
|
37
37
|
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
|
|
38
38
|
var magicast_1 = require("magicast");
|
|
39
39
|
function instrumentHandleError(originalEntryServerMod, serverEntryFilename) {
|
|
40
|
+
var _a, _b;
|
|
40
41
|
var originalEntryServerModAST = originalEntryServerMod.$ast;
|
|
41
42
|
var handleErrorFunction = originalEntryServerModAST.body.find(function (node) {
|
|
42
43
|
var _a, _b;
|
|
@@ -58,11 +59,38 @@ function instrumentHandleError(originalEntryServerMod, serverEntryFilename) {
|
|
|
58
59
|
return false;
|
|
59
60
|
}
|
|
60
61
|
else {
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
63
|
+
var implementation = recast.parse(templates_1.HANDLE_ERROR_TEMPLATE_V2).program
|
|
64
|
+
.body[0];
|
|
61
65
|
// @ts-expect-error - string works here because the AST is proxified by magicast
|
|
62
66
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
63
67
|
handleErrorFunction.declaration.body.body.unshift(
|
|
64
68
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
65
69
|
recast.parse(templates_1.HANDLE_ERROR_TEMPLATE_V2).program.body[0].body.body[0]);
|
|
70
|
+
// First parameter is the error
|
|
71
|
+
//
|
|
72
|
+
// @ts-expect-error - string works here because the AST is proxified by magicast
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
74
|
+
handleErrorFunction.declaration.params[0] = implementation.params[0];
|
|
75
|
+
// Second parameter is the request inside an object
|
|
76
|
+
// Merging the object properties to make sure it includes request
|
|
77
|
+
//
|
|
78
|
+
// @ts-expect-error - string works here because the AST is proxified by magicast
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
80
|
+
if ((_b = (_a = handleErrorFunction.declaration.params) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.properties) {
|
|
81
|
+
// @ts-expect-error - string works here because the AST is proxified by magicast
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
83
|
+
handleErrorFunction.declaration.params[1].properties.push(
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
85
|
+
implementation.params[1].properties[0]);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Create second parameter if it doesn't exist
|
|
89
|
+
//
|
|
90
|
+
// @ts-expect-error - string works here because the AST is proxified by magicast
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
92
|
+
handleErrorFunction.declaration.params[1] = implementation.params[1];
|
|
93
|
+
}
|
|
66
94
|
}
|
|
67
95
|
return true;
|
|
68
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-error.js","sourceRoot":"","sources":["../../../../src/remix/codemods/handle-error.ts"],"names":[],"mappings":";AAAA,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAM5D,6CAAiC;AAEjC,0CAAwD;AACxD,kCAAuE;AAEvE,+EAA+E;AAC/E,2DAAmC;AACnC,gDAA0B;AAE1B,kFAAkF;AAClF,qCAAwC;AAExC,SAAgB,qBAAqB,CACnC,sBAA4C,EAC5C,mBAA2B
|
|
1
|
+
{"version":3,"file":"handle-error.js","sourceRoot":"","sources":["../../../../src/remix/codemods/handle-error.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport type { ProxifiedModule } from 'magicast';\nimport type { Program } from '@babel/types';\n\nimport * as recast from 'recast';\n\nimport { HANDLE_ERROR_TEMPLATE_V2 } from '../templates';\nimport { getInitCallInsertionIndex, hasSentryContent } from '../utils';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode } from 'magicast';\n\nexport function instrumentHandleError(\n originalEntryServerMod: ProxifiedModule<any>,\n serverEntryFilename: string,\n): boolean {\n const originalEntryServerModAST = originalEntryServerMod.$ast as Program;\n\n const handleErrorFunction = originalEntryServerModAST.body.find(\n (node) =>\n node.type === 'ExportNamedDeclaration' &&\n node.declaration?.type === 'FunctionDeclaration' &&\n node.declaration.id?.name === 'handleError',\n );\n\n if (!handleErrorFunction) {\n clack.log.warn(\n `Could not find function ${chalk.cyan('handleError')} in ${chalk.cyan(\n serverEntryFilename,\n )}. Creating one for you.`,\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const implementation = recast.parse(HANDLE_ERROR_TEMPLATE_V2).program\n .body[0];\n\n originalEntryServerModAST.body.splice(\n getInitCallInsertionIndex(originalEntryServerModAST),\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n recast.types.builders.exportNamedDeclaration(implementation),\n );\n } else if (\n hasSentryContent(\n generateCode(handleErrorFunction).code,\n originalEntryServerMod.$code,\n )\n ) {\n return false;\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const implementation = recast.parse(HANDLE_ERROR_TEMPLATE_V2).program\n .body[0];\n\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n handleErrorFunction.declaration.body.body.unshift(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n recast.parse(HANDLE_ERROR_TEMPLATE_V2).program.body[0].body.body[0],\n );\n\n // First parameter is the error\n //\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n handleErrorFunction.declaration.params[0] = implementation.params[0];\n\n // Second parameter is the request inside an object\n // Merging the object properties to make sure it includes request\n //\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (handleErrorFunction.declaration.params?.[1]?.properties) {\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n handleErrorFunction.declaration.params[1].properties.push(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n implementation.params[1].properties[0],\n );\n } else {\n // Create second parameter if it doesn't exist\n //\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n handleErrorFunction.declaration.params[1] = implementation.params[1];\n }\n }\n\n return true;\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
29
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
|
+
};
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.wrapAppWithSentry = void 0;
|
|
33
|
+
var recast = __importStar(require("recast"));
|
|
34
|
+
// @ts-expect-error - clack is ESM and TS complains about that. It works though
|
|
35
|
+
var prompts_1 = __importDefault(require("@clack/prompts"));
|
|
36
|
+
var chalk_1 = __importDefault(require("chalk"));
|
|
37
|
+
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
|
|
38
|
+
var magicast_1 = require("magicast");
|
|
39
|
+
function wrapAppWithSentry(rootRouteAst, rootFileName) {
|
|
40
|
+
rootRouteAst.imports.$add({
|
|
41
|
+
from: '@sentry/remix',
|
|
42
|
+
imported: 'withSentry',
|
|
43
|
+
local: 'withSentry',
|
|
44
|
+
});
|
|
45
|
+
recast.visit(rootRouteAst.$ast, {
|
|
46
|
+
visitExportDefaultDeclaration: function (path) {
|
|
47
|
+
if (path.value.declaration.type === 'FunctionDeclaration') {
|
|
48
|
+
// Move the function declaration just before the default export
|
|
49
|
+
path.insertBefore(path.value.declaration);
|
|
50
|
+
// Get the name of the function to be wrapped
|
|
51
|
+
var functionName = path.value.declaration.id.name;
|
|
52
|
+
// Create the wrapped function call
|
|
53
|
+
var functionCall = recast.types.builders.callExpression(recast.types.builders.identifier('withSentry'), [recast.types.builders.identifier(functionName)]);
|
|
54
|
+
// Replace the default export with the wrapped function call
|
|
55
|
+
path.value.declaration = functionCall;
|
|
56
|
+
}
|
|
57
|
+
else if (path.value.declaration.type === 'Identifier') {
|
|
58
|
+
var rootRouteExport = rootRouteAst.exports.default;
|
|
59
|
+
var expressionToWrap = (0, magicast_1.generateCode)(rootRouteExport.$ast).code;
|
|
60
|
+
rootRouteAst.exports.default = magicast_1.builders.raw("withSentry(".concat(expressionToWrap, ")"));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
prompts_1.default.log.warn(chalk_1.default.yellow("Couldn't instrument ".concat(chalk_1.default.bold(rootFileName), " automatically. Wrap your default export with: ").concat(chalk_1.default.dim('withSentry()'), "\n")));
|
|
64
|
+
}
|
|
65
|
+
this.traverse(path);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
exports.wrapAppWithSentry = wrapAppWithSentry;
|
|
70
|
+
//# sourceMappingURL=root-common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root-common.js","sourceRoot":"","sources":["../../../../src/remix/codemods/root-common.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+DAA+D;AAC/D,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE1D,6CAAiC;AACjC,+EAA+E;AAC/E,2DAAmC;AACnC,gDAA0B;AAE1B,kFAAkF;AAClF,qCAAmE;AAEnE,SAAgB,iBAAiB,CAC/B,YAA6B,EAC7B,YAAoB;IAEpB,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;QACxB,IAAI,EAAE,eAAe;QACrB,QAAQ,EAAE,YAAY;QACtB,KAAK,EAAE,YAAY;KACpB,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE;QAC9B,6BAA6B,YAAC,IAAI;YAChC,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,qBAAqB,EAAE;gBACzD,+DAA+D;gBAC/D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAE1C,6CAA6C;gBAC7C,IAAM,YAAY,GAAW,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,IAAc,CAAC;gBAEtE,mCAAmC;gBACnC,IAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CACvD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,EAC9C,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CACjD,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,YAAY,CAAC;aACvC;iBAAM,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,YAAY,EAAE;gBACvD,IAAM,eAAe,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC;gBAErD,IAAM,gBAAgB,GAAG,IAAA,uBAAY,EAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;gBAEjE,YAAY,CAAC,OAAO,CAAC,OAAO,GAAG,mBAAQ,CAAC,GAAG,CACzC,qBAAc,gBAAgB,MAAG,CAClC,CAAC;aACH;iBAAM;gBACL,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,eAAK,CAAC,MAAM,CACV,8BAAuB,eAAK,CAAC,IAAI,CAC/B,YAAY,CACb,4DAAkD,eAAK,CAAC,GAAG,CAC1D,cAAc,CACf,OAAI,CACN,CACF,CAAC;aACH;YAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAlDD,8CAkDC","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\nimport * as recast from 'recast';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { builders, ProxifiedModule, generateCode } from 'magicast';\n\nexport function wrapAppWithSentry(\n rootRouteAst: ProxifiedModule,\n rootFileName: string,\n) {\n rootRouteAst.imports.$add({\n from: '@sentry/remix',\n imported: 'withSentry',\n local: 'withSentry',\n });\n\n recast.visit(rootRouteAst.$ast, {\n visitExportDefaultDeclaration(path) {\n if (path.value.declaration.type === 'FunctionDeclaration') {\n // Move the function declaration just before the default export\n path.insertBefore(path.value.declaration);\n\n // Get the name of the function to be wrapped\n const functionName: string = path.value.declaration.id.name as string;\n\n // Create the wrapped function call\n const functionCall = recast.types.builders.callExpression(\n recast.types.builders.identifier('withSentry'),\n [recast.types.builders.identifier(functionName)],\n );\n\n // Replace the default export with the wrapped function call\n path.value.declaration = functionCall;\n } else if (path.value.declaration.type === 'Identifier') {\n const rootRouteExport = rootRouteAst.exports.default;\n\n const expressionToWrap = generateCode(rootRouteExport.$ast).code;\n\n rootRouteAst.exports.default = builders.raw(\n `withSentry(${expressionToWrap})`,\n );\n } else {\n clack.log.warn(\n chalk.yellow(\n `Couldn't instrument ${chalk.bold(\n rootFileName,\n )} automatically. Wrap your default export with: ${chalk.dim(\n 'withSentry()',\n )}\\n`,\n ),\n );\n }\n\n this.traverse(path);\n },\n });\n}\n"]}
|
|
@@ -64,56 +64,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
64
64
|
};
|
|
65
65
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
66
66
|
exports.instrumentRootRouteV1 = void 0;
|
|
67
|
-
var recast = __importStar(require("recast"));
|
|
68
67
|
var path = __importStar(require("path"));
|
|
69
68
|
// @ts-expect-error - clack is ESM and TS complains about that. It works though
|
|
70
69
|
var prompts_1 = __importDefault(require("@clack/prompts"));
|
|
71
70
|
var chalk_1 = __importDefault(require("chalk"));
|
|
72
71
|
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
|
|
73
72
|
var magicast_1 = require("magicast");
|
|
73
|
+
var root_common_1 = require("./root-common");
|
|
74
74
|
function instrumentRootRouteV1(rootFileName) {
|
|
75
75
|
return __awaiter(this, void 0, void 0, function () {
|
|
76
|
-
var
|
|
76
|
+
var rootRouteAst, e_1;
|
|
77
77
|
return __generator(this, function (_a) {
|
|
78
78
|
switch (_a.label) {
|
|
79
79
|
case 0:
|
|
80
80
|
_a.trys.push([0, 3, , 4]);
|
|
81
81
|
return [4 /*yield*/, (0, magicast_1.loadFile)(path.join(process.cwd(), 'app', rootFileName))];
|
|
82
82
|
case 1:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
imported: 'withSentry',
|
|
87
|
-
local: 'withSentry',
|
|
88
|
-
});
|
|
89
|
-
recast.visit(rootRouteAst_1.$ast, {
|
|
90
|
-
visitExportDefaultDeclaration: function (path) {
|
|
91
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
92
|
-
if (path.value.declaration.type === 'FunctionDeclaration') {
|
|
93
|
-
// Move the function declaration just before the default export
|
|
94
|
-
path.insertBefore(path.value.declaration);
|
|
95
|
-
// Get the name of the function to be wrapped
|
|
96
|
-
var functionName = path.value.declaration.id.name;
|
|
97
|
-
// Create the wrapped function call
|
|
98
|
-
var functionCall = recast.types.builders.callExpression(recast.types.builders.identifier('withSentry'), [recast.types.builders.identifier(functionName)]);
|
|
99
|
-
// Replace the default export with the wrapped function call
|
|
100
|
-
path.value.declaration = functionCall;
|
|
101
|
-
}
|
|
102
|
-
else if (path.value.declaration.type === 'Identifier') {
|
|
103
|
-
var rootRouteExport = rootRouteAst_1.exports.default;
|
|
104
|
-
var expressionToWrap = (0, magicast_1.generateCode)(
|
|
105
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
106
|
-
rootRouteExport.$ast).code;
|
|
107
|
-
rootRouteAst_1.exports.default = magicast_1.builders.raw("withSentry(".concat(expressionToWrap, ")"));
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
prompts_1.default.log.warn(chalk_1.default.yellow("Couldn't instrument ".concat(chalk_1.default.bold(rootFileName), " automatically. Wrap your default export with: ").concat(chalk_1.default.dim('withSentry()'), "\n")));
|
|
111
|
-
}
|
|
112
|
-
this.traverse(path);
|
|
113
|
-
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
114
|
-
},
|
|
115
|
-
});
|
|
116
|
-
return [4 /*yield*/, (0, magicast_1.writeFile)(rootRouteAst_1.$ast, path.join(process.cwd(), 'app', rootFileName))];
|
|
83
|
+
rootRouteAst = _a.sent();
|
|
84
|
+
(0, root_common_1.wrapAppWithSentry)(rootRouteAst, rootFileName);
|
|
85
|
+
return [4 /*yield*/, (0, magicast_1.writeFile)(rootRouteAst.$ast, path.join(process.cwd(), 'app', rootFileName))];
|
|
117
86
|
case 2:
|
|
118
87
|
_a.sent();
|
|
119
88
|
return [3 /*break*/, 4];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-v1.js","sourceRoot":"","sources":["../../../../src/remix/codemods/root-v1.ts"],"names":[],"mappings":";AAAA,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5D,
|
|
1
|
+
{"version":3,"file":"root-v1.js","sourceRoot":"","sources":["../../../../src/remix/codemods/root-v1.ts"],"names":[],"mappings":";AAAA,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5D,yCAA6B;AAE7B,+EAA+E;AAC/E,2DAAmC;AACnC,gDAA0B;AAE1B,kFAAkF;AAClF,qCAA+C;AAC/C,6CAAkD;AAElD,SAAsB,qBAAqB,CACzC,YAAoB;;;;;;;oBAGG,qBAAM,IAAA,mBAAQ,EACjC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,CAC9C,EAAA;;oBAFK,YAAY,GAAG,SAEpB;oBAED,IAAA,+BAAiB,EAAC,YAAY,EAAE,YAAY,CAAC,CAAC;oBAE9C,qBAAM,IAAA,oBAAS,EACb,YAAY,CAAC,IAAI,EACjB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,CAC9C,EAAA;;oBAHD,SAGC,CAAC;;;;oBAEF,sCAAsC;oBACtC,OAAO,CAAC,KAAK,CAAC,GAAC,CAAC,CAAC;oBACjB,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,eAAK,CAAC,MAAM,CACV,0CAAmC,eAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAE,CAC9D,CACF,CAAC;oBACF,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,qDAA8C,eAAK,CAAC,IAAI,CACtD,YAAY,CACb,eAAK,eAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC,OAAI,CAC/D,CAAC;;;;;;CAEL;AA5BD,sDA4BC","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\nimport * as path from 'path';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { loadFile, writeFile } from 'magicast';\nimport { wrapAppWithSentry } from './root-common';\n\nexport async function instrumentRootRouteV1(\n rootFileName: string,\n): Promise<void> {\n try {\n const rootRouteAst = await loadFile(\n path.join(process.cwd(), 'app', rootFileName),\n );\n\n wrapAppWithSentry(rootRouteAst, rootFileName);\n\n await writeFile(\n rootRouteAst.$ast,\n path.join(process.cwd(), 'app', rootFileName),\n );\n } catch (e: unknown) {\n // eslint-disable-next-line no-console\n console.error(e);\n clack.log.warn(\n chalk.yellow(\n `Something went wrong writing to ${chalk.bold(rootFileName)}`,\n ),\n );\n clack.log.info(\n `Please put the following code snippet into ${chalk.bold(\n rootFileName,\n )}: ${chalk.dim('You probably have to clean it up a bit.')}\\n`,\n );\n }\n}\n"]}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
6
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
7
|
if (k2 === undefined) k2 = k;
|
|
5
8
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -66,6 +69,8 @@ var path = __importStar(require("path"));
|
|
|
66
69
|
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
|
|
67
70
|
var magicast_1 = require("magicast");
|
|
68
71
|
var templates_1 = require("../templates");
|
|
72
|
+
var utils_1 = require("../utils");
|
|
73
|
+
var root_common_1 = require("./root-common");
|
|
69
74
|
function instrumentRootRouteV2(rootFileName) {
|
|
70
75
|
return __awaiter(this, void 0, void 0, function () {
|
|
71
76
|
var rootRouteAst, exportsAst, namedExports, foundErrorBoundary;
|
|
@@ -112,12 +117,56 @@ function instrumentRootRouteV2(rootFileName) {
|
|
|
112
117
|
});
|
|
113
118
|
recast.visit(rootRouteAst.$ast, {
|
|
114
119
|
visitExportDefaultDeclaration: function (path) {
|
|
115
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
116
120
|
var implementation = recast.parse(templates_1.ERROR_BOUNDARY_TEMPLATE_V2).program
|
|
117
121
|
.body[0];
|
|
118
|
-
path.insertBefore(
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
path.insertBefore(recast.types.builders.exportDeclaration(false, implementation));
|
|
123
|
+
this.traverse(path);
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
// If there is already a ErrorBoundary export, and it doesn't have Sentry content
|
|
127
|
+
}
|
|
128
|
+
else if (!(0, utils_1.hasSentryContent)(rootFileName, rootRouteAst.$code)) {
|
|
129
|
+
rootRouteAst.imports.$add({
|
|
130
|
+
from: '@sentry/remix',
|
|
131
|
+
imported: 'captureRemixErrorBoundaryError',
|
|
132
|
+
local: 'captureRemixErrorBoundaryError',
|
|
133
|
+
});
|
|
134
|
+
(0, root_common_1.wrapAppWithSentry)(rootRouteAst, rootFileName);
|
|
135
|
+
recast.visit(rootRouteAst.$ast, {
|
|
136
|
+
visitExportNamedDeclaration: function (path) {
|
|
137
|
+
var _a, _b;
|
|
138
|
+
// Find ErrorBoundary export
|
|
139
|
+
if (((_b = (_a = path.value.declaration) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.name) === 'ErrorBoundary') {
|
|
140
|
+
var errorBoundaryExport = path.value.declaration;
|
|
141
|
+
var errorIdentifier_1;
|
|
142
|
+
// check if useRouteError is called
|
|
143
|
+
recast.visit(errorBoundaryExport, {
|
|
144
|
+
visitVariableDeclaration: function (path) {
|
|
145
|
+
var variableDeclaration = path.value.declarations[0];
|
|
146
|
+
var initializer = variableDeclaration.init;
|
|
147
|
+
if (initializer.type === 'CallExpression' &&
|
|
148
|
+
initializer.callee.name === 'useRouteError') {
|
|
149
|
+
errorIdentifier_1 = variableDeclaration.id.name;
|
|
150
|
+
}
|
|
151
|
+
this.traverse(path);
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
// We don't have an errorIdentifier, which means useRouteError is not called / imported
|
|
155
|
+
// We need to add it and capture the error
|
|
156
|
+
if (!errorIdentifier_1) {
|
|
157
|
+
rootRouteAst.imports.$add({
|
|
158
|
+
from: '@remix-run/react',
|
|
159
|
+
imported: 'useRouteError',
|
|
160
|
+
local: 'useRouteError',
|
|
161
|
+
});
|
|
162
|
+
var useRouteErrorCall = recast.parse("const error = useRouteError();").program.body[0];
|
|
163
|
+
// Insert at the top of ErrorBoundary body
|
|
164
|
+
errorBoundaryExport.body.body.splice(0, 0, useRouteErrorCall);
|
|
165
|
+
}
|
|
166
|
+
var captureErrorCall = recast.parse("captureRemixErrorBoundaryError(error);").program.body[0];
|
|
167
|
+
// Insert just before the the fallback page is returned
|
|
168
|
+
errorBoundaryExport.body.body.splice(errorBoundaryExport.body.body.length - 1, 0, captureErrorCall);
|
|
169
|
+
}
|
|
121
170
|
this.traverse(path);
|
|
122
171
|
},
|
|
123
172
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-v2.js","sourceRoot":"","sources":["../../../../src/remix/codemods/root-v2.ts"],"names":[],"mappings":";AAAA,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"root-v2.js","sourceRoot":"","sources":["../../../../src/remix/codemods/root-v2.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\nimport * as recast from 'recast';\nimport * as path from 'path';\n\nimport type { ExportNamedDeclaration, Program } from '@babel/types';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { loadFile, writeFile } from 'magicast';\n\nimport { ERROR_BOUNDARY_TEMPLATE_V2 } from '../templates';\nimport { hasSentryContent } from '../utils';\nimport { wrapAppWithSentry } from './root-common';\n\nexport async function instrumentRootRouteV2(\n rootFileName: string,\n): Promise<void> {\n const rootRouteAst = await loadFile(\n path.join(process.cwd(), 'app', rootFileName),\n );\n\n const exportsAst = rootRouteAst.exports.$ast as Program;\n\n const namedExports = exportsAst.body.filter(\n (node) => node.type === 'ExportNamedDeclaration',\n ) as ExportNamedDeclaration[];\n\n let foundErrorBoundary = false;\n\n namedExports.forEach((namedExport) => {\n const declaration = namedExport.declaration;\n\n if (!declaration) {\n return;\n }\n\n if (declaration.type === 'FunctionDeclaration') {\n if (declaration.id?.name === 'ErrorBoundary') {\n foundErrorBoundary = true;\n }\n } else if (declaration.type === 'VariableDeclaration') {\n const declarations = declaration.declarations;\n\n declarations.forEach((declaration) => {\n // @ts-expect-error - id should always have a name in this case\n if (declaration.id?.name === 'ErrorBoundary') {\n foundErrorBoundary = true;\n }\n });\n }\n });\n\n if (!foundErrorBoundary) {\n rootRouteAst.imports.$add({\n from: '@sentry/remix',\n imported: 'captureRemixErrorBoundaryError',\n local: 'captureRemixErrorBoundaryError',\n });\n\n rootRouteAst.imports.$add({\n from: '@remix-run/react',\n imported: 'useRouteError',\n local: 'useRouteError',\n });\n\n recast.visit(rootRouteAst.$ast, {\n visitExportDefaultDeclaration(path) {\n const implementation = recast.parse(ERROR_BOUNDARY_TEMPLATE_V2).program\n .body[0];\n\n path.insertBefore(\n recast.types.builders.exportDeclaration(false, implementation),\n );\n\n this.traverse(path);\n },\n });\n // If there is already a ErrorBoundary export, and it doesn't have Sentry content\n } else if (!hasSentryContent(rootFileName, rootRouteAst.$code)) {\n rootRouteAst.imports.$add({\n from: '@sentry/remix',\n imported: 'captureRemixErrorBoundaryError',\n local: 'captureRemixErrorBoundaryError',\n });\n\n wrapAppWithSentry(rootRouteAst, rootFileName);\n\n recast.visit(rootRouteAst.$ast, {\n visitExportNamedDeclaration(path) {\n // Find ErrorBoundary export\n if (path.value.declaration?.id?.name === 'ErrorBoundary') {\n const errorBoundaryExport = path.value.declaration;\n\n let errorIdentifier;\n\n // check if useRouteError is called\n recast.visit(errorBoundaryExport, {\n visitVariableDeclaration(path) {\n const variableDeclaration = path.value.declarations[0];\n const initializer = variableDeclaration.init;\n\n if (\n initializer.type === 'CallExpression' &&\n initializer.callee.name === 'useRouteError'\n ) {\n errorIdentifier = variableDeclaration.id.name;\n }\n\n this.traverse(path);\n },\n });\n\n // We don't have an errorIdentifier, which means useRouteError is not called / imported\n // We need to add it and capture the error\n if (!errorIdentifier) {\n rootRouteAst.imports.$add({\n from: '@remix-run/react',\n imported: 'useRouteError',\n local: 'useRouteError',\n });\n\n const useRouteErrorCall = recast.parse(\n `const error = useRouteError();`,\n ).program.body[0];\n\n // Insert at the top of ErrorBoundary body\n errorBoundaryExport.body.body.splice(0, 0, useRouteErrorCall);\n }\n\n const captureErrorCall = recast.parse(\n `captureRemixErrorBoundaryError(error);`,\n ).program.body[0];\n\n // Insert just before the the fallback page is returned\n errorBoundaryExport.body.body.splice(\n errorBoundaryExport.body.body.length - 1,\n 0,\n captureErrorCall,\n );\n }\n this.traverse(path);\n },\n });\n }\n\n await writeFile(\n rootRouteAst.$ast,\n path.join(process.cwd(), 'app', rootFileName),\n );\n}\n"]}
|