@sentry/wizard 3.24.1 → 3.25.1
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 +8 -0
- package/dist/package.json +1 -1
- package/dist/src/react-native/expo-env-file.d.ts +2 -0
- package/dist/src/react-native/expo-env-file.js +127 -0
- package/dist/src/react-native/expo-env-file.js.map +1 -0
- package/dist/src/react-native/expo-metro.d.ts +7 -0
- package/dist/src/react-native/expo-metro.js +236 -0
- package/dist/src/react-native/expo-metro.js.map +1 -0
- package/dist/src/react-native/expo.d.ts +16 -0
- package/dist/src/react-native/expo.js +195 -0
- package/dist/src/react-native/expo.js.map +1 -0
- package/dist/src/react-native/git.d.ts +1 -0
- package/dist/src/react-native/git.js +85 -0
- package/dist/src/react-native/git.js.map +1 -0
- package/dist/src/react-native/javascript.d.ts +3 -0
- package/dist/src/react-native/javascript.js +119 -1
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/metro.d.ts +3 -0
- package/dist/src/react-native/metro.js +17 -15
- package/dist/src/react-native/metro.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.d.ts +12 -0
- package/dist/src/react-native/react-native-wizard.js +91 -78
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-native/xcode.js +14 -3
- package/dist/src/react-native/xcode.js.map +1 -1
- package/dist/src/remix/codemods/handle-error.js +35 -33
- package/dist/src/remix/codemods/handle-error.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/utils/clack-utils.d.ts +2 -1
- package/dist/src/utils/clack-utils.js +2 -2
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/test/react-native/expo-metro.test.d.ts +1 -0
- package/dist/test/react-native/expo-metro.test.js +26 -0
- package/dist/test/react-native/expo-metro.test.js.map +1 -0
- package/dist/test/react-native/expo.test.d.ts +1 -0
- package/dist/test/react-native/expo.test.js +57 -0
- package/dist/test/react-native/expo.test.js.map +1 -0
- package/dist/test/react-native/xcode.test.js +5 -0
- package/dist/test/react-native/xcode.test.js.map +1 -1
- package/package.json +1 -1
- package/src/react-native/expo-env-file.ts +55 -0
- package/src/react-native/expo-metro.ts +212 -0
- package/src/react-native/expo.ts +175 -0
- package/src/react-native/git.ts +25 -0
- package/src/react-native/javascript.ts +68 -1
- package/src/react-native/metro.ts +3 -3
- package/src/react-native/react-native-wizard.ts +72 -76
- package/src/react-native/xcode.ts +21 -5
- package/src/remix/codemods/handle-error.ts +57 -37
- package/src/remix/templates.ts +3 -3
- package/src/utils/clack-utils.ts +4 -4
- package/test/react-native/expo-metro.test.ts +81 -0
- package/test/react-native/expo.test.ts +86 -0
- package/test/react-native/xcode.test.ts +90 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.25.1
|
|
4
|
+
|
|
5
|
+
- fix(remix): Change `handleError` in server entry (#621)
|
|
6
|
+
|
|
7
|
+
## 3.25.0
|
|
8
|
+
|
|
9
|
+
- feat(react-native): Add support for Expo projects (#505)
|
|
10
|
+
|
|
3
11
|
## 3.24.1
|
|
4
12
|
|
|
5
13
|
- fix(nextjs): Add trailing comma to `sentryUrl` option in `withSentryConfig` template (#601)
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.25.1",
|
|
4
4
|
"homepage": "https://github.com/getsentry/sentry-wizard",
|
|
5
5
|
"repository": "https://github.com/getsentry/sentry-wizard",
|
|
6
6
|
"description": "Sentry wizard helping you to configure your project",
|
|
@@ -0,0 +1,127 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
|
+
function step(op) {
|
|
39
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
40
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
41
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
42
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
43
|
+
switch (op[0]) {
|
|
44
|
+
case 0: case 1: t = op; break;
|
|
45
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
46
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
47
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
48
|
+
default:
|
|
49
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
50
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
51
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
52
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
53
|
+
if (t[2]) _.ops.pop();
|
|
54
|
+
_.trys.pop(); continue;
|
|
55
|
+
}
|
|
56
|
+
op = body.call(thisArg, _);
|
|
57
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
58
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
62
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
63
|
+
};
|
|
64
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
+
exports.addExpoEnvLocal = void 0;
|
|
66
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
67
|
+
var clack = __importStar(require("@clack/prompts"));
|
|
68
|
+
var chalk_1 = __importDefault(require("chalk"));
|
|
69
|
+
var fs_1 = __importDefault(require("fs"));
|
|
70
|
+
var Sentry = __importStar(require("@sentry/node"));
|
|
71
|
+
var git_1 = require("./git");
|
|
72
|
+
var EXPO_ENV_LOCAL_FILE = '.env.local';
|
|
73
|
+
function addExpoEnvLocal(options) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
75
|
+
var newContent, added, error_1, error_2;
|
|
76
|
+
return __generator(this, function (_a) {
|
|
77
|
+
switch (_a.label) {
|
|
78
|
+
case 0:
|
|
79
|
+
newContent = "#DO NOT COMMIT THIS\nSENTRY_AUTH_TOKEN=".concat(options.authToken, "\n");
|
|
80
|
+
return [4 /*yield*/, (0, git_1.addToGitignore)(EXPO_ENV_LOCAL_FILE)];
|
|
81
|
+
case 1:
|
|
82
|
+
added = _a.sent();
|
|
83
|
+
if (added) {
|
|
84
|
+
clack.log.success("Added ".concat(chalk_1.default.cyan(EXPO_ENV_LOCAL_FILE), " to .gitignore."));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
clack.log.error("Could not add ".concat(chalk_1.default.cyan(EXPO_ENV_LOCAL_FILE), " to .gitignore, please add it to not commit your auth key."));
|
|
88
|
+
}
|
|
89
|
+
if (!!fs_1.default.existsSync(EXPO_ENV_LOCAL_FILE)) return [3 /*break*/, 5];
|
|
90
|
+
_a.label = 2;
|
|
91
|
+
case 2:
|
|
92
|
+
_a.trys.push([2, 4, , 5]);
|
|
93
|
+
return [4 /*yield*/, fs_1.default.promises.writeFile(EXPO_ENV_LOCAL_FILE, newContent)];
|
|
94
|
+
case 3:
|
|
95
|
+
_a.sent();
|
|
96
|
+
Sentry.setTag('expo-env-local', 'written');
|
|
97
|
+
clack.log.success("Written ".concat(chalk_1.default.cyan(EXPO_ENV_LOCAL_FILE), "."));
|
|
98
|
+
return [2 /*return*/, true];
|
|
99
|
+
case 4:
|
|
100
|
+
error_1 = _a.sent();
|
|
101
|
+
Sentry.setTag('expo-env-local', 'write-error');
|
|
102
|
+
clack.log.error("Unable to write ".concat(chalk_1.default.cyan(EXPO_ENV_LOCAL_FILE), "."));
|
|
103
|
+
return [2 /*return*/, false];
|
|
104
|
+
case 5:
|
|
105
|
+
Sentry.setTag('expo-env-local', 'exists');
|
|
106
|
+
clack.log.info("Updating existing ".concat(chalk_1.default.cyan(EXPO_ENV_LOCAL_FILE), "."));
|
|
107
|
+
_a.label = 6;
|
|
108
|
+
case 6:
|
|
109
|
+
_a.trys.push([6, 8, , 9]);
|
|
110
|
+
return [4 /*yield*/, fs_1.default.promises.appendFile(EXPO_ENV_LOCAL_FILE, newContent)];
|
|
111
|
+
case 7:
|
|
112
|
+
_a.sent();
|
|
113
|
+
Sentry.setTag('expo-env-local', 'updated');
|
|
114
|
+
clack.log.success("Updated ".concat(chalk_1.default.cyan(EXPO_ENV_LOCAL_FILE), "."));
|
|
115
|
+
return [2 /*return*/, true];
|
|
116
|
+
case 8:
|
|
117
|
+
error_2 = _a.sent();
|
|
118
|
+
Sentry.setTag('expo-env-local', 'update-error');
|
|
119
|
+
clack.log.error("Unable to update ".concat(chalk_1.default.cyan(EXPO_ENV_LOCAL_FILE), "."));
|
|
120
|
+
return [2 /*return*/, false];
|
|
121
|
+
case 9: return [2 /*return*/];
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
exports.addExpoEnvLocal = addExpoEnvLocal;
|
|
127
|
+
//# sourceMappingURL=expo-env-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expo-env-file.js","sourceRoot":"","sources":["../../../src/react-native/expo-env-file.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yEAAyE;AACzE,oDAAwC;AACxC,gDAA0B;AAC1B,0CAAoB;AACpB,mDAAuC;AAEvC,6BAAuC;AAEvC,IAAM,mBAAmB,GAAG,YAAY,CAAC;AAEzC,SAAsB,eAAe,CACnC,OAAgC;;;;;;oBAE1B,UAAU,GAAG,iDAA0C,OAAO,CAAC,SAAS,OAAI,CAAC;oBAErE,qBAAM,IAAA,oBAAc,EAAC,mBAAmB,CAAC,EAAA;;oBAAjD,KAAK,GAAG,SAAyC;oBACvD,IAAI,KAAK,EAAE;wBACT,KAAK,CAAC,GAAG,CAAC,OAAO,CACf,gBAAS,eAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,oBAAiB,CAC1D,CAAC;qBACH;yBAAM;wBACL,KAAK,CAAC,GAAG,CAAC,KAAK,CACb,wBAAiB,eAAK,CAAC,IAAI,CACzB,mBAAmB,CACpB,+DAA4D,CAC9D,CAAC;qBACH;yBAEG,CAAC,YAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAnC,wBAAmC;;;;oBAEnC,qBAAM,YAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAA;;oBAA5D,SAA4D,CAAC;oBAC7D,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;oBAC3C,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAW,eAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAG,CAAC,CAAC;oBACjE,sBAAO,IAAI,EAAC;;;oBAEZ,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;oBAC/C,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,0BAAmB,eAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAG,CAAC,CAAC;oBACvE,sBAAO,KAAK,EAAC;;oBAIjB,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;oBAC1C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,4BAAqB,eAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAG,CAAC,CAAC;;;;oBAGtE,qBAAM,YAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAA;;oBAA7D,SAA6D,CAAC;oBAC9D,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;oBAC3C,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAW,eAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAG,CAAC,CAAC;oBACjE,sBAAO,IAAI,EAAC;;;oBAEZ,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;oBAChD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,2BAAoB,eAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAG,CAAC,CAAC;oBACxE,sBAAO,KAAK,EAAC;;;;;CAEhB;AA5CD,0CA4CC","sourcesContent":["// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport * as Sentry from '@sentry/node';\nimport { RNCliSetupConfigContent } from './react-native-wizard';\nimport { addToGitignore } from './git';\n\nconst EXPO_ENV_LOCAL_FILE = '.env.local';\n\nexport async function addExpoEnvLocal(\n options: RNCliSetupConfigContent,\n): Promise<boolean> {\n const newContent = `#DO NOT COMMIT THIS\\nSENTRY_AUTH_TOKEN=${options.authToken}\\n`;\n\n const added = await addToGitignore(EXPO_ENV_LOCAL_FILE);\n if (added) {\n clack.log.success(\n `Added ${chalk.cyan(EXPO_ENV_LOCAL_FILE)} to .gitignore.`,\n );\n } else {\n clack.log.error(\n `Could not add ${chalk.cyan(\n EXPO_ENV_LOCAL_FILE,\n )} to .gitignore, please add it to not commit your auth key.`,\n );\n }\n\n if (!fs.existsSync(EXPO_ENV_LOCAL_FILE)) {\n try {\n await fs.promises.writeFile(EXPO_ENV_LOCAL_FILE, newContent);\n Sentry.setTag('expo-env-local', 'written');\n clack.log.success(`Written ${chalk.cyan(EXPO_ENV_LOCAL_FILE)}.`);\n return true;\n } catch (error) {\n Sentry.setTag('expo-env-local', 'write-error');\n clack.log.error(`Unable to write ${chalk.cyan(EXPO_ENV_LOCAL_FILE)}.`);\n return false;\n }\n }\n\n Sentry.setTag('expo-env-local', 'exists');\n clack.log.info(`Updating existing ${chalk.cyan(EXPO_ENV_LOCAL_FILE)}.`);\n\n try {\n await fs.promises.appendFile(EXPO_ENV_LOCAL_FILE, newContent);\n Sentry.setTag('expo-env-local', 'updated');\n clack.log.success(`Updated ${chalk.cyan(EXPO_ENV_LOCAL_FILE)}.`);\n return true;\n } catch (error) {\n Sentry.setTag('expo-env-local', 'update-error');\n clack.log.error(`Unable to update ${chalk.cyan(EXPO_ENV_LOCAL_FILE)}.`);\n return false;\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ProxifiedModule } from 'magicast';
|
|
2
|
+
import * as recast from 'recast';
|
|
3
|
+
import x = recast.types;
|
|
4
|
+
import t = x.namedTypes;
|
|
5
|
+
export declare function addSentryToExpoMetroConfig(): Promise<void>;
|
|
6
|
+
export declare function patchMetroInMemory(mod: ProxifiedModule): boolean;
|
|
7
|
+
export declare function addSentryExpoConfigRequire(program: t.Program): void;
|
|
@@ -0,0 +1,236 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
|
+
function step(op) {
|
|
39
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
40
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
41
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
42
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
43
|
+
switch (op[0]) {
|
|
44
|
+
case 0: case 1: t = op; break;
|
|
45
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
46
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
47
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
48
|
+
default:
|
|
49
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
50
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
51
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
52
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
53
|
+
if (t[2]) _.ops.pop();
|
|
54
|
+
_.trys.pop(); continue;
|
|
55
|
+
}
|
|
56
|
+
op = body.call(thisArg, _);
|
|
57
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
58
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
62
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
63
|
+
};
|
|
64
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
+
exports.addSentryExpoConfigRequire = exports.patchMetroInMemory = exports.addSentryToExpoMetroConfig = void 0;
|
|
66
|
+
var fs = __importStar(require("fs"));
|
|
67
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
68
|
+
var clack = __importStar(require("@clack/prompts"));
|
|
69
|
+
var chalk_1 = __importDefault(require("chalk"));
|
|
70
|
+
var Sentry = __importStar(require("@sentry/node"));
|
|
71
|
+
var ast_utils_1 = require("../utils/ast-utils");
|
|
72
|
+
var clack_utils_1 = require("../utils/clack-utils");
|
|
73
|
+
var metro_1 = require("./metro");
|
|
74
|
+
var recast = __importStar(require("recast"));
|
|
75
|
+
var b = recast.types.builders;
|
|
76
|
+
function addSentryToExpoMetroConfig() {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
78
|
+
var success, mod, didPatch, saved;
|
|
79
|
+
return __generator(this, function (_a) {
|
|
80
|
+
switch (_a.label) {
|
|
81
|
+
case 0:
|
|
82
|
+
if (!!fs.existsSync(metro_1.metroConfigPath)) return [3 /*break*/, 4];
|
|
83
|
+
return [4 /*yield*/, createSentryExpoMetroConfig()];
|
|
84
|
+
case 1:
|
|
85
|
+
success = _a.sent();
|
|
86
|
+
if (!!success) return [3 /*break*/, 3];
|
|
87
|
+
Sentry.setTag('expo-metro-config', 'create-new-error');
|
|
88
|
+
return [4 /*yield*/, showInstructions()];
|
|
89
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
90
|
+
case 3:
|
|
91
|
+
Sentry.setTag('expo-metro-config', 'created-new');
|
|
92
|
+
return [2 /*return*/, undefined];
|
|
93
|
+
case 4: return [4 /*yield*/, (0, metro_1.parseMetroConfig)()];
|
|
94
|
+
case 5:
|
|
95
|
+
mod = _a.sent();
|
|
96
|
+
didPatch = false;
|
|
97
|
+
try {
|
|
98
|
+
didPatch = patchMetroInMemory(mod);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
// noop
|
|
102
|
+
}
|
|
103
|
+
if (!!didPatch) return [3 /*break*/, 7];
|
|
104
|
+
Sentry.setTag('expo-metro-config', 'patch-error');
|
|
105
|
+
clack.log.error("Could not patch ".concat(chalk_1.default.cyan(metro_1.metroConfigPath), " with Sentry configuration."));
|
|
106
|
+
return [4 /*yield*/, showInstructions()];
|
|
107
|
+
case 6: return [2 /*return*/, _a.sent()];
|
|
108
|
+
case 7: return [4 /*yield*/, (0, metro_1.writeMetroConfig)(mod)];
|
|
109
|
+
case 8:
|
|
110
|
+
saved = _a.sent();
|
|
111
|
+
if (!saved) return [3 /*break*/, 9];
|
|
112
|
+
Sentry.setTag('expo-metro-config', 'patch-saved');
|
|
113
|
+
clack.log.success(chalk_1.default.green("".concat(chalk_1.default.cyan(metro_1.metroConfigPath), " changes saved.")));
|
|
114
|
+
return [3 /*break*/, 11];
|
|
115
|
+
case 9:
|
|
116
|
+
Sentry.setTag('expo-metro-config', 'patch-save-error');
|
|
117
|
+
clack.log.warn("Could not save changes to ".concat(chalk_1.default.cyan(metro_1.metroConfigPath), ", please follow the manual steps."));
|
|
118
|
+
return [4 /*yield*/, showInstructions()];
|
|
119
|
+
case 10: return [2 /*return*/, _a.sent()];
|
|
120
|
+
case 11: return [2 /*return*/];
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
exports.addSentryToExpoMetroConfig = addSentryToExpoMetroConfig;
|
|
126
|
+
function patchMetroInMemory(mod) {
|
|
127
|
+
var ast = mod.$ast;
|
|
128
|
+
if ((0, ast_utils_1.hasSentryContent)(ast)) {
|
|
129
|
+
clack.log.warn("The ".concat(chalk_1.default.cyan(metro_1.metroConfigPath), " file already has Sentry configuration."));
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
var didReplaceDefaultConfigCall = false;
|
|
133
|
+
recast.visit(ast, {
|
|
134
|
+
visitVariableDeclaration: function (path) {
|
|
135
|
+
var node = path.node;
|
|
136
|
+
if (
|
|
137
|
+
// path is require("expo/metro-config")
|
|
138
|
+
// and only getDefaultConfig is being destructured
|
|
139
|
+
// then remove the entire declaration
|
|
140
|
+
node.declarations.length > 0 &&
|
|
141
|
+
node.declarations[0].type === 'VariableDeclarator' &&
|
|
142
|
+
node.declarations[0].init &&
|
|
143
|
+
node.declarations[0].init.type === 'CallExpression' &&
|
|
144
|
+
node.declarations[0].init.callee &&
|
|
145
|
+
node.declarations[0].init.callee.type === 'Identifier' &&
|
|
146
|
+
node.declarations[0].init.callee.name === 'require' &&
|
|
147
|
+
node.declarations[0].init.arguments[0].type === 'StringLiteral' &&
|
|
148
|
+
node.declarations[0].init.arguments[0].value === 'expo/metro-config' &&
|
|
149
|
+
node.declarations[0].id.type === 'ObjectPattern' &&
|
|
150
|
+
node.declarations[0].id.properties.length === 1 &&
|
|
151
|
+
node.declarations[0].id.properties[0].type === 'ObjectProperty' &&
|
|
152
|
+
node.declarations[0].id.properties[0].key.type === 'Identifier' &&
|
|
153
|
+
node.declarations[0].id.properties[0].key.name === 'getDefaultConfig') {
|
|
154
|
+
path.prune();
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
this.traverse(path);
|
|
158
|
+
},
|
|
159
|
+
visitCallExpression: function (path) {
|
|
160
|
+
var node = path.node;
|
|
161
|
+
if (
|
|
162
|
+
// path is getDefaultConfig
|
|
163
|
+
// then rename it to getSentryExpoConfig
|
|
164
|
+
node.callee.type === 'Identifier' &&
|
|
165
|
+
node.callee.name === 'getDefaultConfig') {
|
|
166
|
+
node.callee.name = 'getSentryExpoConfig';
|
|
167
|
+
didReplaceDefaultConfigCall = true;
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
this.traverse(path);
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
if (!didReplaceDefaultConfigCall) {
|
|
174
|
+
clack.log.warn("Could not find `getDefaultConfig` in ".concat(chalk_1.default.cyan(metro_1.metroConfigPath), "."));
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
addSentryExpoConfigRequire(ast);
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
exports.patchMetroInMemory = patchMetroInMemory;
|
|
181
|
+
function addSentryExpoConfigRequire(program) {
|
|
182
|
+
var lastRequireIndex = (0, ast_utils_1.getLastRequireIndex)(program);
|
|
183
|
+
var sentryExpoConfigRequire = createSentryExpoConfigRequire();
|
|
184
|
+
program.body.splice(lastRequireIndex + 1, 0, sentryExpoConfigRequire);
|
|
185
|
+
}
|
|
186
|
+
exports.addSentryExpoConfigRequire = addSentryExpoConfigRequire;
|
|
187
|
+
/**
|
|
188
|
+
* Creates const { getSentryExpoConfig } = require("@sentry/react-native/metro");
|
|
189
|
+
*/
|
|
190
|
+
function createSentryExpoConfigRequire() {
|
|
191
|
+
return b.variableDeclaration('const', [
|
|
192
|
+
b.variableDeclarator(b.objectPattern([
|
|
193
|
+
b.objectProperty.from({
|
|
194
|
+
key: b.identifier('getSentryExpoConfig'),
|
|
195
|
+
value: b.identifier('getSentryExpoConfig'),
|
|
196
|
+
shorthand: true,
|
|
197
|
+
}),
|
|
198
|
+
]), b.callExpression(b.identifier('require'), [
|
|
199
|
+
b.literal('@sentry/react-native/metro'),
|
|
200
|
+
])),
|
|
201
|
+
]);
|
|
202
|
+
}
|
|
203
|
+
function createSentryExpoMetroConfig() {
|
|
204
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
205
|
+
var snippet, e_1;
|
|
206
|
+
return __generator(this, function (_a) {
|
|
207
|
+
switch (_a.label) {
|
|
208
|
+
case 0:
|
|
209
|
+
snippet = "const { getSentryExpoConfig } = require(\"@sentry/react-native/metro\");\n\nconst config = getSentryExpoConfig(__dirname);\n\nmodule.exports = config;\n";
|
|
210
|
+
_a.label = 1;
|
|
211
|
+
case 1:
|
|
212
|
+
_a.trys.push([1, 3, , 4]);
|
|
213
|
+
return [4 /*yield*/, fs.promises.writeFile(metro_1.metroConfigPath, snippet)];
|
|
214
|
+
case 2:
|
|
215
|
+
_a.sent();
|
|
216
|
+
return [3 /*break*/, 4];
|
|
217
|
+
case 3:
|
|
218
|
+
e_1 = _a.sent();
|
|
219
|
+
clack.log.error("Could not create ".concat(chalk_1.default.cyan(metro_1.metroConfigPath), " with Sentry configuration."));
|
|
220
|
+
return [2 /*return*/, false];
|
|
221
|
+
case 4:
|
|
222
|
+
clack.log.success("Created ".concat(chalk_1.default.cyan(metro_1.metroConfigPath), " with Sentry configuration."));
|
|
223
|
+
return [2 /*return*/, true];
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
function showInstructions() {
|
|
229
|
+
return (0, clack_utils_1.showCopyPasteInstructions)(metro_1.metroConfigPath, getMetroWithSentryExpoConfigSnippet(true));
|
|
230
|
+
}
|
|
231
|
+
function getMetroWithSentryExpoConfigSnippet(colors) {
|
|
232
|
+
return (0, clack_utils_1.makeCodeSnippet)(colors, function (unchanged, plus, minus) {
|
|
233
|
+
return unchanged("".concat(minus("// const { getDefaultConfig } = require(\"expo/metro-config\");"), "\n").concat(plus("const { getSentryExpoConfig } = require(\"@sentry/react-native/metro\");"), "\n\n").concat(minus("// const config = getDefaultConfig(__dirname);"), "\n").concat(plus("const config = getSentryExpoConfig(__dirname);"), "\n\nmodule.exports = config;"));
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=expo-metro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expo-metro.js","sourceRoot":"","sources":["../../../src/react-native/expo-metro.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\n// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n// @ts-ignore - magicast is ESM and TS complains about that. It works though\nimport { ProxifiedModule } from 'magicast';\nimport chalk from 'chalk';\nimport * as Sentry from '@sentry/node';\n\nimport { getLastRequireIndex, hasSentryContent } from '../utils/ast-utils';\nimport {\n makeCodeSnippet,\n showCopyPasteInstructions,\n} from '../utils/clack-utils';\n\nimport { metroConfigPath, parseMetroConfig, writeMetroConfig } from './metro';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nconst b = recast.types.builders;\n\nexport async function addSentryToExpoMetroConfig() {\n if (!fs.existsSync(metroConfigPath)) {\n const success = await createSentryExpoMetroConfig();\n if (!success) {\n Sentry.setTag('expo-metro-config', 'create-new-error');\n return await showInstructions();\n }\n Sentry.setTag('expo-metro-config', 'created-new');\n return undefined;\n }\n\n const mod = await parseMetroConfig();\n\n let didPatch = false;\n try {\n didPatch = patchMetroInMemory(mod);\n } catch (e) {\n // noop\n }\n if (!didPatch) {\n Sentry.setTag('expo-metro-config', 'patch-error');\n clack.log.error(\n `Could not patch ${chalk.cyan(\n metroConfigPath,\n )} with Sentry configuration.`,\n );\n return await showInstructions();\n }\n\n const saved = await writeMetroConfig(mod);\n if (saved) {\n Sentry.setTag('expo-metro-config', 'patch-saved');\n clack.log.success(\n chalk.green(`${chalk.cyan(metroConfigPath)} changes saved.`),\n );\n } else {\n Sentry.setTag('expo-metro-config', 'patch-save-error');\n clack.log.warn(\n `Could not save changes to ${chalk.cyan(\n metroConfigPath,\n )}, please follow the manual steps.`,\n );\n return await showInstructions();\n }\n}\n\nexport function patchMetroInMemory(mod: ProxifiedModule): boolean {\n const ast = mod.$ast as t.Program;\n\n if (hasSentryContent(ast)) {\n clack.log.warn(\n `The ${chalk.cyan(\n metroConfigPath,\n )} file already has Sentry configuration.`,\n );\n return false;\n }\n\n let didReplaceDefaultConfigCall = false;\n\n recast.visit(ast, {\n visitVariableDeclaration(path) {\n const { node } = path;\n\n if (\n // path is require(\"expo/metro-config\")\n // and only getDefaultConfig is being destructured\n // then remove the entire declaration\n node.declarations.length > 0 &&\n node.declarations[0].type === 'VariableDeclarator' &&\n node.declarations[0].init &&\n node.declarations[0].init.type === 'CallExpression' &&\n node.declarations[0].init.callee &&\n node.declarations[0].init.callee.type === 'Identifier' &&\n node.declarations[0].init.callee.name === 'require' &&\n node.declarations[0].init.arguments[0].type === 'StringLiteral' &&\n node.declarations[0].init.arguments[0].value === 'expo/metro-config' &&\n node.declarations[0].id.type === 'ObjectPattern' &&\n node.declarations[0].id.properties.length === 1 &&\n node.declarations[0].id.properties[0].type === 'ObjectProperty' &&\n node.declarations[0].id.properties[0].key.type === 'Identifier' &&\n node.declarations[0].id.properties[0].key.name === 'getDefaultConfig'\n ) {\n path.prune();\n return false;\n }\n\n this.traverse(path);\n },\n\n visitCallExpression(path) {\n const { node } = path;\n if (\n // path is getDefaultConfig\n // then rename it to getSentryExpoConfig\n node.callee.type === 'Identifier' &&\n node.callee.name === 'getDefaultConfig'\n ) {\n node.callee.name = 'getSentryExpoConfig';\n didReplaceDefaultConfigCall = true;\n return false;\n }\n\n this.traverse(path);\n },\n });\n\n if (!didReplaceDefaultConfigCall) {\n clack.log.warn(\n `Could not find \\`getDefaultConfig\\` in ${chalk.cyan(metroConfigPath)}.`,\n );\n return false;\n }\n\n addSentryExpoConfigRequire(ast);\n\n return true;\n}\n\nexport function addSentryExpoConfigRequire(program: t.Program) {\n const lastRequireIndex = getLastRequireIndex(program);\n const sentryExpoConfigRequire = createSentryExpoConfigRequire();\n program.body.splice(lastRequireIndex + 1, 0, sentryExpoConfigRequire);\n}\n\n/**\n * Creates const { getSentryExpoConfig } = require(\"@sentry/react-native/metro\");\n */\nfunction createSentryExpoConfigRequire() {\n return b.variableDeclaration('const', [\n b.variableDeclarator(\n b.objectPattern([\n b.objectProperty.from({\n key: b.identifier('getSentryExpoConfig'),\n value: b.identifier('getSentryExpoConfig'),\n shorthand: true,\n }),\n ]),\n b.callExpression(b.identifier('require'), [\n b.literal('@sentry/react-native/metro'),\n ]),\n ),\n ]);\n}\n\nasync function createSentryExpoMetroConfig(): Promise<boolean> {\n const snippet = `const { getSentryExpoConfig } = require(\"@sentry/react-native/metro\");\n\nconst config = getSentryExpoConfig(__dirname);\n\nmodule.exports = config;\n`;\n try {\n await fs.promises.writeFile(metroConfigPath, snippet);\n } catch (e) {\n clack.log.error(\n `Could not create ${chalk.cyan(\n metroConfigPath,\n )} with Sentry configuration.`,\n );\n return false;\n }\n clack.log.success(\n `Created ${chalk.cyan(metroConfigPath)} with Sentry configuration.`,\n );\n return true;\n}\n\nfunction showInstructions() {\n return showCopyPasteInstructions(\n metroConfigPath,\n getMetroWithSentryExpoConfigSnippet(true),\n );\n}\n\nfunction getMetroWithSentryExpoConfigSnippet(colors: boolean): string {\n return makeCodeSnippet(colors, (unchanged, plus, minus) =>\n unchanged(`${minus(\n `// const { getDefaultConfig } = require(\"expo/metro-config\");`,\n )}\n${plus(\n `const { getSentryExpoConfig } = require(\"@sentry/react-native/metro\");`,\n)}\n\n${minus(`// const config = getDefaultConfig(__dirname);`)}\n${plus(`const config = getSentryExpoConfig(__dirname);`)}\n\nmodule.exports = config;`),\n );\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RNCliSetupConfigContent } from './react-native-wizard';
|
|
2
|
+
export declare const SENTRY_EXPO_PLUGIN_NAME = "@sentry/react-native/expo";
|
|
3
|
+
export declare const DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = "sentry-expo";
|
|
4
|
+
export declare const SENTRY_PLUGIN_FUNCTION_NAME = "withSentry";
|
|
5
|
+
export interface AppConfigJson {
|
|
6
|
+
expo?: {
|
|
7
|
+
plugins?: Array<[string, undefined | Record<string, unknown>]>;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function printSentryExpoMigrationOutro(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Finds app.json in the project root and add Sentry Expo `withSentry` plugin.
|
|
13
|
+
*/
|
|
14
|
+
export declare function patchExpoAppConfig(options: RNCliSetupConfigContent): Promise<void>;
|
|
15
|
+
export declare function addWithSentryToAppConfigJson(appConfigContent: string, options: RNCliSetupConfigContent): string | null;
|
|
16
|
+
export declare function getSentryAppConfigJsonCodeSnippet({ url, project, org, }: Omit<RNCliSetupConfigContent, 'authToken'>): string;
|
|
@@ -0,0 +1,195 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
|
+
function step(op) {
|
|
39
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
40
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
41
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
42
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
43
|
+
switch (op[0]) {
|
|
44
|
+
case 0: case 1: t = op; break;
|
|
45
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
46
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
47
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
48
|
+
default:
|
|
49
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
50
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
51
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
52
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
53
|
+
if (t[2]) _.ops.pop();
|
|
54
|
+
_.trys.pop(); continue;
|
|
55
|
+
}
|
|
56
|
+
op = body.call(thisArg, _);
|
|
57
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
58
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
62
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
63
|
+
};
|
|
64
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
+
exports.getSentryAppConfigJsonCodeSnippet = exports.addWithSentryToAppConfigJson = exports.patchExpoAppConfig = exports.printSentryExpoMigrationOutro = exports.SENTRY_PLUGIN_FUNCTION_NAME = exports.DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = exports.SENTRY_EXPO_PLUGIN_NAME = void 0;
|
|
66
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
67
|
+
var clack = __importStar(require("@clack/prompts"));
|
|
68
|
+
var chalk_1 = __importDefault(require("chalk"));
|
|
69
|
+
var fs = __importStar(require("fs"));
|
|
70
|
+
var os_1 = require("os");
|
|
71
|
+
var utils_1 = require("@sentry/utils");
|
|
72
|
+
var Sentry = __importStar(require("@sentry/node"));
|
|
73
|
+
var clack_utils_1 = require("../utils/clack-utils");
|
|
74
|
+
var telemetry_1 = require("../telemetry");
|
|
75
|
+
exports.SENTRY_EXPO_PLUGIN_NAME = '@sentry/react-native/expo';
|
|
76
|
+
exports.DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = 'sentry-expo';
|
|
77
|
+
exports.SENTRY_PLUGIN_FUNCTION_NAME = 'withSentry';
|
|
78
|
+
var APP_CONFIG_JSON = "app.json";
|
|
79
|
+
function printSentryExpoMigrationOutro() {
|
|
80
|
+
clack.outro("Deprecated ".concat(chalk_1.default.cyan('sentry-expo'), " package installed in your dependencies. Please follow the migration guide at ").concat(chalk_1.default.cyan('https://docs.sentry.io/platforms/react-native/migration/sentry-expo/')));
|
|
81
|
+
}
|
|
82
|
+
exports.printSentryExpoMigrationOutro = printSentryExpoMigrationOutro;
|
|
83
|
+
/**
|
|
84
|
+
* Finds app.json in the project root and add Sentry Expo `withSentry` plugin.
|
|
85
|
+
*/
|
|
86
|
+
function patchExpoAppConfig(options) {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
88
|
+
function showInstructions() {
|
|
89
|
+
return (0, clack_utils_1.showCopyPasteInstructions)(APP_CONFIG_JSON, getSentryAppConfigJsonCodeSnippet(options), 'This ensures auto upload of source maps during native app build.');
|
|
90
|
+
}
|
|
91
|
+
var appConfigJsonExists, patched;
|
|
92
|
+
return __generator(this, function (_a) {
|
|
93
|
+
switch (_a.label) {
|
|
94
|
+
case 0:
|
|
95
|
+
appConfigJsonExists = fs.existsSync(APP_CONFIG_JSON);
|
|
96
|
+
Sentry.setTag('app-config-file-status', appConfigJsonExists ? 'found' : 'not-found');
|
|
97
|
+
if (!!appConfigJsonExists) return [3 /*break*/, 2];
|
|
98
|
+
return [4 /*yield*/, showInstructions()];
|
|
99
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
100
|
+
case 2: return [4 /*yield*/, patchAppConfigJson(APP_CONFIG_JSON, options)];
|
|
101
|
+
case 3:
|
|
102
|
+
patched = _a.sent();
|
|
103
|
+
if (!!patched) return [3 /*break*/, 5];
|
|
104
|
+
return [4 /*yield*/, showInstructions()];
|
|
105
|
+
case 4: return [2 /*return*/, _a.sent()];
|
|
106
|
+
case 5: return [2 /*return*/];
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
exports.patchExpoAppConfig = patchExpoAppConfig;
|
|
112
|
+
function patchAppConfigJson(path, options) {
|
|
113
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
114
|
+
var appConfigContent, patchedContent, error_1;
|
|
115
|
+
return __generator(this, function (_a) {
|
|
116
|
+
switch (_a.label) {
|
|
117
|
+
case 0: return [4 /*yield*/, fs.promises.readFile(path, { encoding: 'utf-8' })];
|
|
118
|
+
case 1:
|
|
119
|
+
appConfigContent = (_a.sent()).toString();
|
|
120
|
+
patchedContent = (0, telemetry_1.traceStep)('app-config-json-patch', function () {
|
|
121
|
+
return addWithSentryToAppConfigJson(appConfigContent, options);
|
|
122
|
+
});
|
|
123
|
+
if (patchedContent === null) {
|
|
124
|
+
return [2 /*return*/, false];
|
|
125
|
+
}
|
|
126
|
+
_a.label = 2;
|
|
127
|
+
case 2:
|
|
128
|
+
_a.trys.push([2, 4, , 5]);
|
|
129
|
+
return [4 /*yield*/, fs.promises.writeFile(path, patchedContent)];
|
|
130
|
+
case 3:
|
|
131
|
+
_a.sent();
|
|
132
|
+
return [3 /*break*/, 5];
|
|
133
|
+
case 4:
|
|
134
|
+
error_1 = _a.sent();
|
|
135
|
+
Sentry.setTag('app-config-file-status', 'json-write-error');
|
|
136
|
+
clack.log.error("Unable to write ".concat(chalk_1.default.cyan('app.config.json'), "."));
|
|
137
|
+
return [2 /*return*/, false];
|
|
138
|
+
case 5:
|
|
139
|
+
Sentry.setTag('app-config-file-status', 'json-write-success');
|
|
140
|
+
clack.log.success("Added Sentry Expo plugin to ".concat(chalk_1.default.cyan('app.config.json'), "."));
|
|
141
|
+
return [2 /*return*/, true];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function addWithSentryToAppConfigJson(appConfigContent, options) {
|
|
147
|
+
var _a, _b;
|
|
148
|
+
try {
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
150
|
+
var parsedAppConfig = JSON.parse(appConfigContent);
|
|
151
|
+
var includesWithSentry = appConfigContent.includes(exports.SENTRY_EXPO_PLUGIN_NAME) ||
|
|
152
|
+
appConfigContent.includes(exports.DEPRECATED_SENTRY_EXPO_PLUGIN_NAME);
|
|
153
|
+
if (includesWithSentry) {
|
|
154
|
+
Sentry.setTag('app-config-file-status', 'already-patched');
|
|
155
|
+
clack.log.warn("Your ".concat(chalk_1.default.cyan('app.config.json'), " already includes the Sentry Expo plugin."));
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
if (parsedAppConfig.expo !== undefined &&
|
|
159
|
+
!(0, utils_1.isPlainObject)(parsedAppConfig.expo)) {
|
|
160
|
+
Sentry.setTag('app-config-file-status', 'invalid-json');
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
if (parsedAppConfig.expo &&
|
|
164
|
+
parsedAppConfig.expo.plugins !== undefined &&
|
|
165
|
+
!Array.isArray(parsedAppConfig.expo.plugins)) {
|
|
166
|
+
Sentry.setTag('app-config-file-status', 'invalid-json');
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
parsedAppConfig.expo = (_a = parsedAppConfig.expo) !== null && _a !== void 0 ? _a : {};
|
|
170
|
+
parsedAppConfig.expo.plugins = (_b = parsedAppConfig.expo.plugins) !== null && _b !== void 0 ? _b : [];
|
|
171
|
+
parsedAppConfig.expo.plugins.push([
|
|
172
|
+
exports.SENTRY_EXPO_PLUGIN_NAME,
|
|
173
|
+
{
|
|
174
|
+
url: options.url,
|
|
175
|
+
project: options.project,
|
|
176
|
+
organization: options.org,
|
|
177
|
+
},
|
|
178
|
+
]);
|
|
179
|
+
return JSON.stringify(parsedAppConfig, null, 2) + os_1.EOL;
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
Sentry.setTag('app-config-file-status', 'invalid-json');
|
|
183
|
+
clack.log.error("Unable to parse your ".concat(chalk_1.default.cyan('app.config.json'), ". Make sure it has a valid format!"));
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.addWithSentryToAppConfigJson = addWithSentryToAppConfigJson;
|
|
188
|
+
function getSentryAppConfigJsonCodeSnippet(_a) {
|
|
189
|
+
var url = _a.url, project = _a.project, org = _a.org;
|
|
190
|
+
return (0, clack_utils_1.makeCodeSnippet)(true, function (unchanged, plus, _minus) {
|
|
191
|
+
return unchanged("{\n \"name\": \"my app\",\n \"plugins\": [\n ".concat(plus("[\n \"@sentry/react-native/expo\",\n {\n \"url\": \"".concat(url, "\",\n \"project\": \"").concat(project, "\",\n \"organization\": \"").concat(org, "\"\n }\n ]")), "\n ],\n}"));
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
exports.getSentryAppConfigJsonCodeSnippet = getSentryAppConfigJsonCodeSnippet;
|
|
195
|
+
//# sourceMappingURL=expo.js.map
|