@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.
Files changed (46) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/package.json +2 -2
  3. package/dist/src/apple/cocoapod.js +2 -0
  4. package/dist/src/apple/cocoapod.js.map +1 -1
  5. package/dist/src/nextjs/nextjs-wizard.js +76 -21
  6. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  7. package/dist/src/nextjs/templates.d.ts +2 -0
  8. package/dist/src/nextjs/templates.js +15 -2
  9. package/dist/src/nextjs/templates.js.map +1 -1
  10. package/dist/src/react-native/metro.d.ts +13 -0
  11. package/dist/src/react-native/metro.js +398 -0
  12. package/dist/src/react-native/metro.js.map +1 -0
  13. package/dist/src/react-native/react-native-wizard.d.ts +2 -0
  14. package/dist/src/react-native/react-native-wizard.js +139 -38
  15. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  16. package/dist/src/react-native/uninstall.js +4 -0
  17. package/dist/src/react-native/uninstall.js.map +1 -1
  18. package/dist/src/react-native/xcode.d.ts +7 -3
  19. package/dist/src/react-native/xcode.js +43 -11
  20. package/dist/src/react-native/xcode.js.map +1 -1
  21. package/dist/src/remix/remix-wizard.js +80 -37
  22. package/dist/src/remix/remix-wizard.js.map +1 -1
  23. package/dist/src/remix/sdk-setup.d.ts +1 -0
  24. package/dist/src/remix/sdk-setup.js +21 -1
  25. package/dist/src/remix/sdk-setup.js.map +1 -1
  26. package/dist/src/utils/ast-utils.d.ts +14 -0
  27. package/dist/src/utils/ast-utils.js +49 -1
  28. package/dist/src/utils/ast-utils.js.map +1 -1
  29. package/dist/test/react-native/metro.test.d.ts +1 -0
  30. package/dist/test/react-native/metro.test.js +125 -0
  31. package/dist/test/react-native/metro.test.js.map +1 -0
  32. package/dist/test/react-native/xcode.test.js +40 -2
  33. package/dist/test/react-native/xcode.test.js.map +1 -1
  34. package/package.json +2 -2
  35. package/src/apple/cocoapod.ts +2 -0
  36. package/src/nextjs/nextjs-wizard.ts +99 -19
  37. package/src/nextjs/templates.ts +77 -0
  38. package/src/react-native/metro.ts +409 -0
  39. package/src/react-native/react-native-wizard.ts +103 -7
  40. package/src/react-native/uninstall.ts +3 -0
  41. package/src/react-native/xcode.ts +70 -12
  42. package/src/remix/remix-wizard.ts +51 -15
  43. package/src/remix/sdk-setup.ts +31 -0
  44. package/src/utils/ast-utils.ts +52 -0
  45. package/test/react-native/metro.test.ts +283 -0
  46. 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('addSentryToBundleShellScript', function () {
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.addSentryToBundleShellScript)(input)).toBe(expectedOutput);
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.16.5",
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.3.5",
30
+ "axios": "1.6.0",
31
31
  "chalk": "^2.4.1",
32
32
  "glob": "^7.1.3",
33
33
  "inquirer": "^6.2.0",
@@ -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.bold(path.join(...pagesLocation, '_error.jsx'))}.`,
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.bold(
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.bold(
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.bold(
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.bold(jsConfig)}.`);
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.bold(tsConfig)}.`);
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.bold(
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.bold('next.config.js')} with Sentry configuration.`,
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.bold(
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.bold(
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.bold(
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.bold(
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.bold(nextConfigMjs)}`,
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.bold(
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.bold(
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.bold(
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.bold(
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.bold(
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.bold(
690
+ `Created ${chalk.cyan(
611
691
  path.join(...pagesLocation, 'api', 'sentry-example-api.js'),
612
692
  )}.`,
613
693
  );