@sentry/wizard 3.16.5 → 3.18.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 +13 -0
- package/dist/package.json +2 -2
- package/dist/src/apple/cocoapod.js +2 -0
- package/dist/src/apple/cocoapod.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +76 -21
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.d.ts +2 -0
- package/dist/src/nextjs/templates.js +15 -2
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/react-native/metro.d.ts +13 -0
- package/dist/src/react-native/metro.js +398 -0
- package/dist/src/react-native/metro.js.map +1 -0
- package/dist/src/react-native/react-native-wizard.d.ts +2 -0
- package/dist/src/react-native/react-native-wizard.js +139 -38
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-native/uninstall.js +4 -0
- package/dist/src/react-native/uninstall.js.map +1 -1
- package/dist/src/react-native/xcode.d.ts +7 -3
- package/dist/src/react-native/xcode.js +43 -11
- package/dist/src/react-native/xcode.js.map +1 -1
- package/dist/src/remix/remix-wizard.js +80 -37
- 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 +21 -1
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +14 -0
- package/dist/src/utils/ast-utils.js +49 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/test/react-native/metro.test.d.ts +1 -0
- package/dist/test/react-native/metro.test.js +125 -0
- package/dist/test/react-native/metro.test.js.map +1 -0
- package/dist/test/react-native/xcode.test.js +40 -2
- package/dist/test/react-native/xcode.test.js.map +1 -1
- package/package.json +2 -2
- package/src/apple/cocoapod.ts +2 -0
- package/src/nextjs/nextjs-wizard.ts +99 -19
- package/src/nextjs/templates.ts +77 -0
- package/src/react-native/metro.ts +409 -0
- package/src/react-native/react-native-wizard.ts +103 -7
- package/src/react-native/uninstall.ts +3 -0
- package/src/react-native/xcode.ts +70 -12
- package/src/remix/remix-wizard.ts +51 -15
- package/src/remix/sdk-setup.ts +31 -0
- package/src/utils/ast-utils.ts +52 -0
- package/test/react-native/metro.test.ts +283 -0
- package/test/react-native/xcode.test.ts +76 -3
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// @ts-ignore - magicast is ESM and TS complains about that. It works though
|
|
4
|
+
var magicast_1 = require("magicast");
|
|
5
|
+
var metro_1 = require("../../src/react-native/metro");
|
|
6
|
+
describe('patch metro config - sentry serializer', function () {
|
|
7
|
+
describe('addSentrySerializerToMetroConfig', function () {
|
|
8
|
+
it('add to empty config', function () {
|
|
9
|
+
var mod = (0, magicast_1.parseModule)("module.exports = {\n other: 'config'\n }");
|
|
10
|
+
var configObject = getModuleExportsObject(mod);
|
|
11
|
+
var result = (0, metro_1.addSentrySerializerToMetroConfig)(configObject);
|
|
12
|
+
expect(result).toBe(true);
|
|
13
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("module.exports = {\n other: 'config',\n\n serializer: {\n customSerializer: createSentryMetroSerializer()\n }\n}");
|
|
14
|
+
});
|
|
15
|
+
it('add to existing serializer config', function () {
|
|
16
|
+
var mod = (0, magicast_1.parseModule)("module.exports = {\n other: 'config',\n serializer: {\n other: 'config'\n }\n}");
|
|
17
|
+
var configObject = getModuleExportsObject(mod);
|
|
18
|
+
var result = (0, metro_1.addSentrySerializerToMetroConfig)(configObject);
|
|
19
|
+
expect(result).toBe(true);
|
|
20
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: createSentryMetroSerializer()\n }\n}");
|
|
21
|
+
});
|
|
22
|
+
it('not add to existing customSerializer config', function () {
|
|
23
|
+
var mod = (0, magicast_1.parseModule)("module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}");
|
|
24
|
+
var configObject = getModuleExportsObject(mod);
|
|
25
|
+
var result = (0, metro_1.addSentrySerializerToMetroConfig)(configObject);
|
|
26
|
+
expect(result).toBe(false);
|
|
27
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}");
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe('addSentrySerializerImportToMetroConfig', function () {
|
|
31
|
+
it('add import', function () {
|
|
32
|
+
var mod = (0, magicast_1.parseModule)("const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nmodule.exports = {\n other: 'config'\n}");
|
|
33
|
+
var result = (0, metro_1.addSentrySerializerRequireToMetroConfig)(mod.$ast);
|
|
34
|
+
expect(result).toBe(true);
|
|
35
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code)
|
|
36
|
+
.toBe("const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nconst {\n createSentryMetroSerializer\n} = require(\"@sentry/react-native/dist/js/tools/sentryMetroSerializer\");\n\nmodule.exports = {\n other: 'config'\n}");
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('getMetroConfigObject', function () {
|
|
40
|
+
it('get config object from variable called config', function () {
|
|
41
|
+
var mod = (0, magicast_1.parseModule)("var config = { some: 'config' };");
|
|
42
|
+
var configObject = (0, metro_1.getMetroConfigObject)(mod.$ast);
|
|
43
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0]).key
|
|
44
|
+
.name).toBe('some');
|
|
45
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0])
|
|
46
|
+
.value.value).toBe('config');
|
|
47
|
+
});
|
|
48
|
+
it('get config object from const called config', function () {
|
|
49
|
+
var mod = (0, magicast_1.parseModule)("const config = { some: 'config' };");
|
|
50
|
+
var configObject = (0, metro_1.getMetroConfigObject)(mod.$ast);
|
|
51
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0]).key
|
|
52
|
+
.name).toBe('some');
|
|
53
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0])
|
|
54
|
+
.value.value).toBe('config');
|
|
55
|
+
});
|
|
56
|
+
it('get config oject from let called config', function () {
|
|
57
|
+
var mod = (0, magicast_1.parseModule)("let config = { some: 'config' };");
|
|
58
|
+
var configObject = (0, metro_1.getMetroConfigObject)(mod.$ast);
|
|
59
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0]).key
|
|
60
|
+
.name).toBe('some');
|
|
61
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0])
|
|
62
|
+
.value.value).toBe('config');
|
|
63
|
+
});
|
|
64
|
+
it('get config object from module.exports', function () {
|
|
65
|
+
var mod = (0, magicast_1.parseModule)("module.exports = { some: 'config' };");
|
|
66
|
+
var configObject = (0, metro_1.getMetroConfigObject)(mod.$ast);
|
|
67
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0]).key
|
|
68
|
+
.name).toBe('some');
|
|
69
|
+
expect((configObject === null || configObject === void 0 ? void 0 : configObject.properties[0])
|
|
70
|
+
.value.value).toBe('config');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe('remove @sentry require', function () {
|
|
74
|
+
it('nothing to remove', function () {
|
|
75
|
+
var mod = (0, magicast_1.parseModule)("let config = { some: 'config' };");
|
|
76
|
+
var result = (0, metro_1.removeSentryRequire)(mod.$ast);
|
|
77
|
+
expect(result).toBe(false);
|
|
78
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("let config = { some: 'config' };");
|
|
79
|
+
});
|
|
80
|
+
it('remove metro serializer import', function () {
|
|
81
|
+
var mod = (0, magicast_1.parseModule)("const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nlet config = { some: 'config' };");
|
|
82
|
+
var result = (0, metro_1.removeSentryRequire)(mod.$ast);
|
|
83
|
+
expect(result).toBe(true);
|
|
84
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("let config = { some: 'config' };");
|
|
85
|
+
});
|
|
86
|
+
it('remove all sentry imports', function () {
|
|
87
|
+
var mod = (0, magicast_1.parseModule)("const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nvar Sentry = require('@sentry/react-native');\nlet SentryIntegrations = require('@sentry/integrations');\n\nlet config = { some: 'config' };");
|
|
88
|
+
var result = (0, metro_1.removeSentryRequire)(mod.$ast);
|
|
89
|
+
expect(result).toBe(true);
|
|
90
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("let config = { some: 'config' };");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('remove sentryMetroSerializer', function () {
|
|
94
|
+
it('no custom serializer to remove', function () {
|
|
95
|
+
var mod = (0, magicast_1.parseModule)("let config = { some: 'config' };");
|
|
96
|
+
var result = (0, metro_1.removeSentrySerializerFromMetroConfig)(mod.$ast);
|
|
97
|
+
expect(result).toBe(false);
|
|
98
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("let config = { some: 'config' };");
|
|
99
|
+
});
|
|
100
|
+
it('no Sentry custom serializer to remove', function () {
|
|
101
|
+
var mod = (0, magicast_1.parseModule)("let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};");
|
|
102
|
+
var result = (0, metro_1.removeSentrySerializerFromMetroConfig)(mod.$ast);
|
|
103
|
+
expect(result).toBe(false);
|
|
104
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};");
|
|
105
|
+
});
|
|
106
|
+
it('Sentry serializer to remove', function () {
|
|
107
|
+
var mod = (0, magicast_1.parseModule)("let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(),\n other: 'config',\n },\n other: 'config',\n};");
|
|
108
|
+
var result = (0, metro_1.removeSentrySerializerFromMetroConfig)(mod.$ast);
|
|
109
|
+
expect(result).toBe(true);
|
|
110
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("let config = {\n serializer: {\n other: 'config'\n },\n other: 'config',\n};");
|
|
111
|
+
});
|
|
112
|
+
it('Sentry serializer to remove with wrapped serializer', function () {
|
|
113
|
+
var mod = (0, magicast_1.parseModule)("let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(wrappedSerializer()),\n other: 'config',\n },\n other: 'config',\n};");
|
|
114
|
+
var result = (0, metro_1.removeSentrySerializerFromMetroConfig)(mod.$ast);
|
|
115
|
+
expect(result).toBe(true);
|
|
116
|
+
expect((0, magicast_1.generateCode)(mod.$ast).code).toBe("let config = {\n serializer: {\n customSerializer: wrappedSerializer(),\n other: 'config',\n },\n other: 'config',\n};");
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
function getModuleExportsObject(mod, index) {
|
|
121
|
+
if (index === void 0) { index = 0; }
|
|
122
|
+
return mod.$ast.body[index]
|
|
123
|
+
.expression.right;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=metro.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metro.test.js","sourceRoot":"","sources":["../../../test/react-native/metro.test.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-ignore - magicast is ESM and TS complains about that. It works though\nimport { generateCode, type ProxifiedModule, parseModule } from 'magicast';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nimport {\n addSentrySerializerRequireToMetroConfig,\n addSentrySerializerToMetroConfig,\n getMetroConfigObject,\n removeSentryRequire,\n removeSentrySerializerFromMetroConfig,\n} from '../../src/react-native/metro';\n\ndescribe('patch metro config - sentry serializer', () => {\n describe('addSentrySerializerToMetroConfig', () => {\n it('add to empty config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config'\n }`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n\n serializer: {\n customSerializer: createSentryMetroSerializer()\n }\n}`);\n });\n\n it('add to existing serializer config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config'\n }\n}`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: createSentryMetroSerializer()\n }\n}`);\n });\n\n it('not add to existing customSerializer config', () => {\n const mod = parseModule(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}`);\n const configObject = getModuleExportsObject(mod);\n const result = addSentrySerializerToMetroConfig(configObject);\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`module.exports = {\n other: 'config',\n serializer: {\n other: 'config',\n customSerializer: 'existing-serializer'\n }\n}`);\n });\n });\n\n describe('addSentrySerializerImportToMetroConfig', () => {\n it('add import', () => {\n const mod =\n parseModule(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nmodule.exports = {\n other: 'config'\n}`);\n const result = addSentrySerializerRequireToMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code)\n .toBe(`const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\n\nconst {\n createSentryMetroSerializer\n} = require(\"@sentry/react-native/dist/js/tools/sentryMetroSerializer\");\n\nmodule.exports = {\n other: 'config'\n}`);\n });\n });\n\n describe('getMetroConfigObject', () => {\n it('get config object from variable called config', () => {\n const mod = parseModule(`var config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config object from const called config', () => {\n const mod = parseModule(`const config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config oject from let called config', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n\n it('get config object from module.exports', () => {\n const mod = parseModule(`module.exports = { some: 'config' };`);\n const configObject = getMetroConfigObject(mod.$ast as t.Program);\n expect(\n ((configObject?.properties[0] as t.ObjectProperty).key as t.Identifier)\n .name,\n ).toBe('some');\n expect(\n (\n (configObject?.properties[0] as t.ObjectProperty)\n .value as t.StringLiteral\n ).value,\n ).toBe('config');\n });\n });\n\n describe('remove @sentry require', () => {\n it('nothing to remove', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('remove metro serializer import', () => {\n const mod = parseModule(`const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nlet config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('remove all sentry imports', () => {\n const mod = parseModule(`const {\n createSentryMetroSerializer,\n} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\nvar Sentry = require('@sentry/react-native');\nlet SentryIntegrations = require('@sentry/integrations');\n\nlet config = { some: 'config' };`);\n const result = removeSentryRequire(mod.$ast as t.Program);\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n });\n\n describe('remove sentryMetroSerializer', () => {\n it('no custom serializer to remove', () => {\n const mod = parseModule(`let config = { some: 'config' };`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(\n `let config = { some: 'config' };`,\n );\n });\n\n it('no Sentry custom serializer to remove', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n customSerializer: 'existing-serializer',\n other: 'config',\n },\n other: 'config',\n};`);\n });\n\n it('Sentry serializer to remove', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(),\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n other: 'config'\n },\n other: 'config',\n};`);\n });\n\n it('Sentry serializer to remove with wrapped serializer', () => {\n const mod = parseModule(`let config = {\n serializer: {\n customSerializer: createSentryMetroSerializer(wrappedSerializer()),\n other: 'config',\n },\n other: 'config',\n};`);\n const result = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(`let config = {\n serializer: {\n customSerializer: wrappedSerializer(),\n other: 'config',\n },\n other: 'config',\n};`);\n });\n });\n});\n\nfunction getModuleExportsObject(\n mod: ProxifiedModule,\n index = 0,\n): t.ObjectExpression {\n return (\n ((mod.$ast as t.Program).body[index] as t.ExpressionStatement)\n .expression as t.AssignmentExpression\n ).right as t.ObjectExpression;\n}\n"]}
|
|
@@ -3,14 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
/* eslint-disable no-useless-escape */
|
|
4
4
|
var xcode_1 = require("../../src/react-native/xcode");
|
|
5
5
|
describe('react-native xcode', function () {
|
|
6
|
-
describe('
|
|
6
|
+
describe('addSentryWithCliToBundleShellScript', function () {
|
|
7
7
|
it('adds sentry cli to rn bundle build phase', function () {
|
|
8
8
|
var input = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"";
|
|
9
9
|
// actual shell script looks like this:
|
|
10
10
|
// /bin/sh -c "$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\""
|
|
11
11
|
// but during parsing xcode library removes the quotes
|
|
12
12
|
var expectedOutput = "export SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\"\"\n/bin/sh -c \"$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh\"\n";
|
|
13
|
-
expect((0, xcode_1.
|
|
13
|
+
expect((0, xcode_1.addSentryWithCliToBundleShellScript)(input)).toBe(expectedOutput);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe('addSentryBundledScriptsToBundleShellScript', function () {
|
|
17
|
+
it('adds sentry cli to rn bundle build phase', function () {
|
|
18
|
+
var input = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"";
|
|
19
|
+
// actual shell script looks like this:
|
|
20
|
+
// /bin/sh -c "$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\""
|
|
21
|
+
// but during parsing xcode library removes the quotes
|
|
22
|
+
var expectedOutput = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\\\"\"";
|
|
23
|
+
expect((0, xcode_1.addSentryWithBundledScriptsToBundleShellScript)(input)).toBe(expectedOutput);
|
|
14
24
|
});
|
|
15
25
|
});
|
|
16
26
|
describe('removeSentryFromBundleShellScript', function () {
|
|
@@ -19,6 +29,11 @@ describe('react-native xcode', function () {
|
|
|
19
29
|
var expectedOutput = "export EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\"\"\n\n";
|
|
20
30
|
expect((0, xcode_1.removeSentryFromBundleShellScript)(input)).toBe(expectedOutput);
|
|
21
31
|
});
|
|
32
|
+
it('removes sentry bundled scripts from rn bundle build phase', function () {
|
|
33
|
+
var input = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\"\"";
|
|
34
|
+
var expectedOutput = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\"\"";
|
|
35
|
+
expect((0, xcode_1.removeSentryFromBundleShellScript)(input)).toBe(expectedOutput);
|
|
36
|
+
});
|
|
22
37
|
});
|
|
23
38
|
describe('findBundlePhase', function () {
|
|
24
39
|
it('returns build phase with react native xcode shell script', function () {
|
|
@@ -67,6 +82,12 @@ describe('react-native xcode', function () {
|
|
|
67
82
|
};
|
|
68
83
|
expect((0, xcode_1.doesBundlePhaseIncludeSentry)(input)).toBeTruthy();
|
|
69
84
|
});
|
|
85
|
+
it('returns true for script containing sentry bundled script', function () {
|
|
86
|
+
var input = {
|
|
87
|
+
shellScript: "set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\"\\\"\n",
|
|
88
|
+
};
|
|
89
|
+
expect((0, xcode_1.doesBundlePhaseIncludeSentry)(input)).toBeTruthy();
|
|
90
|
+
});
|
|
70
91
|
it('returns false', function () {
|
|
71
92
|
var input = {
|
|
72
93
|
// note sentry-cli can be part of the script but doesn't call react native xcode script
|
|
@@ -127,6 +148,23 @@ describe('react-native xcode', function () {
|
|
|
127
148
|
];
|
|
128
149
|
expect((0, xcode_1.findDebugFilesUploadPhase)(input)).toEqual(expected);
|
|
129
150
|
});
|
|
151
|
+
it('returns debug files build phase using bundled scripts', function () {
|
|
152
|
+
var input = {
|
|
153
|
+
1: {
|
|
154
|
+
shellScript: 'foo',
|
|
155
|
+
},
|
|
156
|
+
2: {
|
|
157
|
+
shellScript: "/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh",
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
var expected = [
|
|
161
|
+
'2',
|
|
162
|
+
{
|
|
163
|
+
shellScript: "/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh",
|
|
164
|
+
},
|
|
165
|
+
];
|
|
166
|
+
expect((0, xcode_1.findDebugFilesUploadPhase)(input)).toEqual(expected);
|
|
167
|
+
});
|
|
130
168
|
it('returns undefined if build phase not present', function () {
|
|
131
169
|
var input = {
|
|
132
170
|
1: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcode.test.js","sourceRoot":"","sources":["../../../test/react-native/xcode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-useless-escape */\nimport {\n addSentryToBundleShellScript,\n doesBundlePhaseIncludeSentry,\n findBundlePhase,\n findDebugFilesUploadPhase,\n removeSentryFromBundleShellScript,\n} from '../../src/react-native/xcode';\n\ndescribe('react-native xcode', () => {\n describe('addSentryToBundleShellScript', () => {\n it('adds sentry cli to rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `export SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\\\"\"\n/bin/sh -c \"$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh\"\n`;\n\n expect(addSentryToBundleShellScript(input)).toBe(expectedOutput);\n });\n });\n\n describe('removeSentryFromBundleShellScript', () => {\n it('removes sentry cli from rn bundle build phase', () => {\n const input = `export SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\"\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh\"\n`;\n const expectedOutput = `export EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`;\n\n expect(removeSentryFromBundleShellScript(input)).toBe(expectedOutput);\n });\n });\n\n describe('findBundlePhase', () => {\n it('returns build phase with react native xcode shell script', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n const expected = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n };\n\n expect(findBundlePhase(inputMap)).toEqual(expected);\n });\n\n it('returns undefined if bundle phase not present', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n // note different path to the script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/unknown/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n expect(findBundlePhase(inputMap)).toBeUndefined();\n });\n });\n\n describe('doesBundlePhaseIncludeSentry', () => {\n it('returns true for script containing sentry cli calling react native xcode command', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$SENTRY_CLI $REACT_NATIVE_XCODE\\\"\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns false', () => {\n const input = {\n // note sentry-cli can be part of the script but doesn't call react native xcode script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\nsentry-cli --version\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeFalsy();\n });\n });\n\n describe('findDebugFilesUploadPhase', () => {\n it('returns debug files build phase using debug files command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase with sentry-cli absolute path', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using dsym command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns undefined if build phase not present', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n // sentry-cli present but with different command\n shellScript: 'sentry-cli sourcempas upload',\n },\n };\n\n expect(findDebugFilesUploadPhase(input)).toBeUndefined();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"xcode.test.js","sourceRoot":"","sources":["../../../test/react-native/xcode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-useless-escape */\nimport {\n addSentryWithBundledScriptsToBundleShellScript,\n addSentryWithCliToBundleShellScript,\n doesBundlePhaseIncludeSentry,\n findBundlePhase,\n findDebugFilesUploadPhase,\n removeSentryFromBundleShellScript,\n} from '../../src/react-native/xcode';\n\ndescribe('react-native xcode', () => {\n describe('addSentryWithCliToBundleShellScript', () => {\n it('adds sentry cli to rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `export SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\\\"\"\n/bin/sh -c \"$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh\"\n`;\n\n expect(addSentryWithCliToBundleShellScript(input)).toBe(expectedOutput);\n });\n });\n\n describe('addSentryBundledScriptsToBundleShellScript', () => {\n it('adds sentry cli to rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\\\\\"\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n });\n\n describe('removeSentryFromBundleShellScript', () => {\n it('removes sentry cli from rn bundle build phase', () => {\n const input = `export SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\"\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT ../node_modules/@sentry/react-native/scripts/collect-modules.sh\"\n`;\n const expectedOutput = `export EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nset -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`;\n\n expect(removeSentryFromBundleShellScript(input)).toBe(expectedOutput);\n });\n\n it('removes sentry bundled scripts from rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\\\"\"`;\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"`;\n\n expect(removeSentryFromBundleShellScript(input)).toBe(expectedOutput);\n });\n });\n\n describe('findBundlePhase', () => {\n it('returns build phase with react native xcode shell script', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n const expected = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n };\n\n expect(findBundlePhase(inputMap)).toEqual(expected);\n });\n\n it('returns undefined if bundle phase not present', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n // note different path to the script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/unknown/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n expect(findBundlePhase(inputMap)).toBeUndefined();\n });\n });\n\n describe('doesBundlePhaseIncludeSentry', () => {\n it('returns true for script containing sentry cli calling react native xcode command', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$SENTRY_CLI $REACT_NATIVE_XCODE\\\"\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns true for script containing sentry bundled script', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\"\\\\\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns false', () => {\n const input = {\n // note sentry-cli can be part of the script but doesn't call react native xcode script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\nsentry-cli --version\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeFalsy();\n });\n });\n\n describe('findDebugFilesUploadPhase', () => {\n it('returns debug files build phase using debug files command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase with sentry-cli absolute path', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using dsym command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using bundled scripts', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns undefined if build phase not present', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n // sentry-cli present but with different command\n shellScript: 'sentry-cli sourcempas upload',\n },\n };\n\n expect(findDebugFilesUploadPhase(input)).toBeUndefined();\n });\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.0",
|
|
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",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@clack/prompts": "0.7.0",
|
|
28
28
|
"@sentry/cli": "^1.72.0",
|
|
29
29
|
"@sentry/node": "^7.69.0",
|
|
30
|
-
"axios": "1.
|
|
30
|
+
"axios": "1.6.0",
|
|
31
31
|
"chalk": "^2.4.1",
|
|
32
32
|
"glob": "^7.1.3",
|
|
33
33
|
"inquirer": "^6.2.0",
|
package/src/apple/cocoapod.ts
CHANGED
|
@@ -56,8 +56,10 @@ export async function podInstall(dir = '.') {
|
|
|
56
56
|
await bash.execute(`cd ${dir} && pod repo update`);
|
|
57
57
|
await bash.execute(`cd ${dir} && pod install --silent`);
|
|
58
58
|
installSpinner.stop('Pods installed.');
|
|
59
|
+
Sentry.setTag('pods-installed', true);
|
|
59
60
|
} catch (e) {
|
|
60
61
|
installSpinner.stop('Failed to install pods.');
|
|
62
|
+
Sentry.setTag('pods-installed', false);
|
|
61
63
|
clack.log.error(
|
|
62
64
|
`${chalk.red(
|
|
63
65
|
'Encountered the following error during pods installation:',
|
|
@@ -24,12 +24,14 @@ import {
|
|
|
24
24
|
import { SentryProjectData, WizardOptions } from '../utils/types';
|
|
25
25
|
import {
|
|
26
26
|
getFullUnderscoreErrorCopyPasteSnippet,
|
|
27
|
+
getGlobalErrorCopyPasteSnippet,
|
|
27
28
|
getNextjsConfigCjsAppendix,
|
|
28
29
|
getNextjsConfigCjsTemplate,
|
|
29
30
|
getNextjsConfigEsmCopyPasteSnippet,
|
|
30
31
|
getNextjsSentryBuildOptionsTemplate,
|
|
31
32
|
getNextjsWebpackPluginOptionsTemplate,
|
|
32
33
|
getSentryConfigContents,
|
|
34
|
+
getSentryDefaultGlobalErrorPage,
|
|
33
35
|
getSentryDefaultUnderscoreErrorPage,
|
|
34
36
|
getSentryExampleApiRoute,
|
|
35
37
|
getSentryExampleAppDirApiRoute,
|
|
@@ -124,7 +126,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
124
126
|
);
|
|
125
127
|
|
|
126
128
|
clack.log.success(
|
|
127
|
-
`Created ${chalk.
|
|
129
|
+
`Created ${chalk.cyan(path.join(...pagesLocation, '_error.jsx'))}.`,
|
|
128
130
|
);
|
|
129
131
|
} else if (
|
|
130
132
|
fs
|
|
@@ -147,7 +149,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
147
149
|
|
|
148
150
|
const shouldContinue = await abortIfCancelled(
|
|
149
151
|
clack.confirm({
|
|
150
|
-
message: `Did you modify your ${chalk.
|
|
152
|
+
message: `Did you modify your ${chalk.cyan(
|
|
151
153
|
path.join(...pagesLocation, underscoreErrorPageFile),
|
|
152
154
|
)} file as described above?`,
|
|
153
155
|
active: 'Yes',
|
|
@@ -160,7 +162,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
160
162
|
}
|
|
161
163
|
} else {
|
|
162
164
|
clack.log.info(
|
|
163
|
-
`It seems like you already have a custom error page.\n\nPlease add the following code to your custom error page\nat ${chalk.
|
|
165
|
+
`It seems like you already have a custom error page.\n\nPlease add the following code to your custom error page\nat ${chalk.cyan(
|
|
164
166
|
path.join(...pagesLocation, underscoreErrorPageFile),
|
|
165
167
|
)}:`,
|
|
166
168
|
);
|
|
@@ -175,7 +177,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
175
177
|
|
|
176
178
|
const shouldContinue = await abortIfCancelled(
|
|
177
179
|
clack.confirm({
|
|
178
|
-
message: `Did add the code to your ${chalk.
|
|
180
|
+
message: `Did add the code to your ${chalk.cyan(
|
|
179
181
|
path.join(...pagesLocation, underscoreErrorPageFile),
|
|
180
182
|
)} file as described above?`,
|
|
181
183
|
active: 'Yes',
|
|
@@ -189,6 +191,84 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
189
191
|
}
|
|
190
192
|
});
|
|
191
193
|
|
|
194
|
+
await traceStep('create-global-error-page', async () => {
|
|
195
|
+
const maybeAppDirPath = path.join(process.cwd(), 'pages');
|
|
196
|
+
const maybeSrcAppDirPath = path.join(process.cwd(), 'src', 'pages');
|
|
197
|
+
|
|
198
|
+
const appDirLocation =
|
|
199
|
+
fs.existsSync(maybeAppDirPath) &&
|
|
200
|
+
fs.lstatSync(maybeAppDirPath).isDirectory()
|
|
201
|
+
? ['app']
|
|
202
|
+
: fs.existsSync(maybeSrcAppDirPath) &&
|
|
203
|
+
fs.lstatSync(maybeSrcAppDirPath).isDirectory()
|
|
204
|
+
? ['src', 'app']
|
|
205
|
+
: undefined;
|
|
206
|
+
|
|
207
|
+
if (!appDirLocation) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const globalErrorPageFile = fs.existsSync(
|
|
212
|
+
path.join(process.cwd(), ...appDirLocation, 'global-error.tsx'),
|
|
213
|
+
)
|
|
214
|
+
? 'global-error.tsx'
|
|
215
|
+
: fs.existsSync(
|
|
216
|
+
path.join(process.cwd(), ...appDirLocation, 'global-error.ts'),
|
|
217
|
+
)
|
|
218
|
+
? 'global-error.ts'
|
|
219
|
+
: fs.existsSync(
|
|
220
|
+
path.join(process.cwd(), ...appDirLocation, 'global-error.jsx'),
|
|
221
|
+
)
|
|
222
|
+
? 'global-error.jsx'
|
|
223
|
+
: fs.existsSync(
|
|
224
|
+
path.join(process.cwd(), ...appDirLocation, 'global-error.js'),
|
|
225
|
+
)
|
|
226
|
+
? 'global-error.js'
|
|
227
|
+
: undefined;
|
|
228
|
+
|
|
229
|
+
if (!globalErrorPageFile) {
|
|
230
|
+
await fs.promises.writeFile(
|
|
231
|
+
path.join(process.cwd(), ...appDirLocation, 'global-error.jsx'),
|
|
232
|
+
getSentryDefaultGlobalErrorPage(),
|
|
233
|
+
{ encoding: 'utf8', flag: 'w' },
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
clack.log.success(
|
|
237
|
+
`Created ${chalk.cyan(
|
|
238
|
+
path.join(...appDirLocation, 'global-error.jsx'),
|
|
239
|
+
)}.`,
|
|
240
|
+
);
|
|
241
|
+
} else {
|
|
242
|
+
clack.log.info(
|
|
243
|
+
`It seems like you already have a custom error page for your app directory.\n\nPlease add the following code to your custom error page\nat ${chalk.cyan(
|
|
244
|
+
path.join(...appDirLocation, globalErrorPageFile),
|
|
245
|
+
)}:`,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
// eslint-disable-next-line no-console
|
|
249
|
+
console.log(
|
|
250
|
+
getGlobalErrorCopyPasteSnippet(
|
|
251
|
+
globalErrorPageFile === 'global-error.ts' ||
|
|
252
|
+
globalErrorPageFile === 'global-error.tsx',
|
|
253
|
+
),
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
const shouldContinue = await abortIfCancelled(
|
|
257
|
+
clack.confirm({
|
|
258
|
+
message: `Did add the code to your ${chalk.cyan(
|
|
259
|
+
path.join(...appDirLocation, globalErrorPageFile),
|
|
260
|
+
)} file as described above?`,
|
|
261
|
+
active: 'Yes',
|
|
262
|
+
inactive: 'No, get me out of here',
|
|
263
|
+
}),
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
if (!shouldContinue) {
|
|
267
|
+
await abort();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
|
|
192
272
|
await traceStep('create-example-page', async () =>
|
|
193
273
|
createExamplePage(selfHosted, selectedProject, sentryUrl),
|
|
194
274
|
);
|
|
@@ -265,11 +345,11 @@ async function createOrMergeNextJsFiles(
|
|
|
265
345
|
if (overwriteExistingConfigs) {
|
|
266
346
|
if (jsConfigExists) {
|
|
267
347
|
fs.unlinkSync(path.join(process.cwd(), jsConfig));
|
|
268
|
-
clack.log.warn(`Removed existing ${chalk.
|
|
348
|
+
clack.log.warn(`Removed existing ${chalk.cyan(jsConfig)}.`);
|
|
269
349
|
}
|
|
270
350
|
if (tsConfigExists) {
|
|
271
351
|
fs.unlinkSync(path.join(process.cwd(), tsConfig));
|
|
272
|
-
clack.log.warn(`Removed existing ${chalk.
|
|
352
|
+
clack.log.warn(`Removed existing ${chalk.cyan(tsConfig)}.`);
|
|
273
353
|
}
|
|
274
354
|
}
|
|
275
355
|
}
|
|
@@ -284,7 +364,7 @@ async function createOrMergeNextJsFiles(
|
|
|
284
364
|
{ encoding: 'utf8', flag: 'w' },
|
|
285
365
|
);
|
|
286
366
|
clack.log.success(
|
|
287
|
-
`Created fresh ${chalk.
|
|
367
|
+
`Created fresh ${chalk.cyan(
|
|
288
368
|
typeScriptDetected ? tsConfig : jsConfig,
|
|
289
369
|
)}.`,
|
|
290
370
|
);
|
|
@@ -325,7 +405,7 @@ async function createOrMergeNextJsFiles(
|
|
|
325
405
|
);
|
|
326
406
|
|
|
327
407
|
clack.log.success(
|
|
328
|
-
`Created ${chalk.
|
|
408
|
+
`Created ${chalk.cyan('next.config.js')} with Sentry configuration.`,
|
|
329
409
|
);
|
|
330
410
|
}
|
|
331
411
|
|
|
@@ -346,7 +426,7 @@ async function createOrMergeNextJsFiles(
|
|
|
346
426
|
if (probablyIncludesSdk) {
|
|
347
427
|
const injectAnyhow = await abortIfCancelled(
|
|
348
428
|
clack.confirm({
|
|
349
|
-
message: `${chalk.
|
|
429
|
+
message: `${chalk.cyan(
|
|
350
430
|
nextConfigJs,
|
|
351
431
|
)} already contains Sentry SDK configuration. Should the wizard modify it anyways?`,
|
|
352
432
|
}),
|
|
@@ -366,7 +446,7 @@ async function createOrMergeNextJsFiles(
|
|
|
366
446
|
);
|
|
367
447
|
|
|
368
448
|
clack.log.success(
|
|
369
|
-
`Added Sentry configuration to ${chalk.
|
|
449
|
+
`Added Sentry configuration to ${chalk.cyan(
|
|
370
450
|
nextConfigJs,
|
|
371
451
|
)}. ${chalk.dim('(you probably want to clean this up a bit!)')}`,
|
|
372
452
|
);
|
|
@@ -390,7 +470,7 @@ async function createOrMergeNextJsFiles(
|
|
|
390
470
|
if (probablyIncludesSdk) {
|
|
391
471
|
const injectAnyhow = await abortIfCancelled(
|
|
392
472
|
clack.confirm({
|
|
393
|
-
message: `${chalk.
|
|
473
|
+
message: `${chalk.cyan(
|
|
394
474
|
nextConfigMjs,
|
|
395
475
|
)} already contains Sentry SDK configuration. Should the wizard modify it anyways?`,
|
|
396
476
|
}),
|
|
@@ -426,7 +506,7 @@ async function createOrMergeNextJsFiles(
|
|
|
426
506
|
},
|
|
427
507
|
);
|
|
428
508
|
clack.log.success(
|
|
429
|
-
`Added Sentry configuration to ${chalk.
|
|
509
|
+
`Added Sentry configuration to ${chalk.cyan(
|
|
430
510
|
nextConfigMjs,
|
|
431
511
|
)}. ${chalk.dim('(you probably want to clean this up a bit!)')}`,
|
|
432
512
|
);
|
|
@@ -437,11 +517,11 @@ async function createOrMergeNextJsFiles(
|
|
|
437
517
|
Sentry.setTag('next-config-mod-result', 'fail');
|
|
438
518
|
clack.log.warn(
|
|
439
519
|
chalk.yellow(
|
|
440
|
-
`Something went wrong writing to ${chalk.
|
|
520
|
+
`Something went wrong writing to ${chalk.cyan(nextConfigMjs)}`,
|
|
441
521
|
),
|
|
442
522
|
);
|
|
443
523
|
clack.log.info(
|
|
444
|
-
`Please put the following code snippet into ${chalk.
|
|
524
|
+
`Please put the following code snippet into ${chalk.cyan(
|
|
445
525
|
nextConfigMjs,
|
|
446
526
|
)}: ${chalk.dim('You probably have to clean it up a bit.')}\n`,
|
|
447
527
|
);
|
|
@@ -456,7 +536,7 @@ async function createOrMergeNextJsFiles(
|
|
|
456
536
|
|
|
457
537
|
const shouldContinue = await abortIfCancelled(
|
|
458
538
|
clack.confirm({
|
|
459
|
-
message: `Are you done putting the snippet above into ${chalk.
|
|
539
|
+
message: `Are you done putting the snippet above into ${chalk.cyan(
|
|
460
540
|
nextConfigMjs,
|
|
461
541
|
)}?`,
|
|
462
542
|
active: 'Yes',
|
|
@@ -541,7 +621,7 @@ async function createExamplePage(
|
|
|
541
621
|
);
|
|
542
622
|
|
|
543
623
|
clack.log.success(
|
|
544
|
-
`Created ${chalk.
|
|
624
|
+
`Created ${chalk.cyan(
|
|
545
625
|
path.join(...appLocation, 'sentry-example-page', 'page.jsx'),
|
|
546
626
|
)}.`,
|
|
547
627
|
);
|
|
@@ -566,7 +646,7 @@ async function createExamplePage(
|
|
|
566
646
|
);
|
|
567
647
|
|
|
568
648
|
clack.log.success(
|
|
569
|
-
`Created ${chalk.
|
|
649
|
+
`Created ${chalk.cyan(
|
|
570
650
|
path.join(...appLocation, 'api', 'sentry-example-api', 'route.js'),
|
|
571
651
|
)}.`,
|
|
572
652
|
);
|
|
@@ -586,7 +666,7 @@ async function createExamplePage(
|
|
|
586
666
|
);
|
|
587
667
|
|
|
588
668
|
clack.log.success(
|
|
589
|
-
`Created ${chalk.
|
|
669
|
+
`Created ${chalk.cyan(
|
|
590
670
|
path.join(...pagesLocation, 'sentry-example-page.js'),
|
|
591
671
|
)}.`,
|
|
592
672
|
);
|
|
@@ -607,7 +687,7 @@ async function createExamplePage(
|
|
|
607
687
|
);
|
|
608
688
|
|
|
609
689
|
clack.log.success(
|
|
610
|
-
`Created ${chalk.
|
|
690
|
+
`Created ${chalk.cyan(
|
|
611
691
|
path.join(...pagesLocation, 'api', 'sentry-example-api.js'),
|
|
612
692
|
)}.`,
|
|
613
693
|
);
|