@sentry/wizard 6.1.2 → 6.2.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 +20 -0
- package/dist/e2e-tests/tests/flutter.test.js +16 -2
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +3 -2
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/lib/Steps/Integrations/Electron.js +4 -0
- package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +10 -0
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/code-tools.d.ts +1 -1
- package/dist/src/apple/code-tools.js +3 -3
- package/dist/src/apple/code-tools.js.map +1 -1
- package/dist/src/apple/inject-code-snippet.d.ts +2 -1
- package/dist/src/apple/inject-code-snippet.js +2 -2
- package/dist/src/apple/inject-code-snippet.js.map +1 -1
- package/dist/src/apple/templates.d.ts +2 -2
- package/dist/src/apple/templates.js +22 -6
- package/dist/src/apple/templates.js.map +1 -1
- package/dist/src/flutter/code-tools.d.ts +1 -0
- package/dist/src/flutter/code-tools.js +6 -0
- package/dist/src/flutter/code-tools.js.map +1 -1
- package/dist/src/flutter/templates.d.ts +1 -0
- package/dist/src/flutter/templates.js +5 -0
- package/dist/src/flutter/templates.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +11 -7
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nextjs/utils.d.ts +8 -0
- package/dist/src/nextjs/utils.js +36 -1
- package/dist/src/nextjs/utils.js.map +1 -1
- package/dist/src/react-native/expo-metro.d.ts +2 -2
- package/dist/src/react-native/expo-metro.js +32 -27
- package/dist/src/react-native/expo-metro.js.map +1 -1
- package/dist/src/react-native/metro.d.ts +4 -4
- package/dist/src/react-native/metro.js +39 -17
- package/dist/src/react-native/metro.js.map +1 -1
- package/dist/src/remix/codemods/root.d.ts +1 -0
- package/dist/src/remix/codemods/root.js +30 -2
- package/dist/src/remix/codemods/root.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +62 -14
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/apple/templates.test.js +68 -2
- package/dist/test/apple/templates.test.js.map +1 -1
- package/dist/test/flutter/code-tools.test.js +1 -0
- package/dist/test/flutter/code-tools.test.js.map +1 -1
- package/dist/test/flutter/templates.test.js +28 -1
- package/dist/test/flutter/templates.test.js.map +1 -1
- package/dist/test/nextjs/wizard-double-wrap-prevention.test.d.ts +1 -0
- package/dist/test/nextjs/wizard-double-wrap-prevention.test.js +266 -0
- package/dist/test/nextjs/wizard-double-wrap-prevention.test.js.map +1 -0
- package/dist/test/react-native/expo-metro.test.js +3 -3
- package/dist/test/react-native/expo-metro.test.js.map +1 -1
- package/dist/test/react-native/metro.test.js +73 -15
- package/dist/test/react-native/metro.test.js.map +1 -1
- package/dist/test/remix/root.test.js +226 -0
- package/dist/test/remix/root.test.js.map +1 -1
- package/package.json +1 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/apple/templates.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport {\n getFastlaneSnippet,\n getObjcSnippet,\n getRunScriptTemplate,\n getSwiftSnippet,\n scriptInputPath,\n} from '../../src/apple/templates';\n\ndescribe('templates', () => {\n describe('getRunScriptTemplate', () => {\n const variations: {\n uploadSource: boolean;\n includeHomebrewPath: boolean;\n expectedScript: string;\n }[] = [\n {\n uploadSource: true,\n includeHomebrewPath: true,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload --include-sources \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n {\n uploadSource: true,\n includeHomebrewPath: false,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload --include-sources \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n {\n uploadSource: false,\n includeHomebrewPath: true,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n {\n uploadSource: false,\n includeHomebrewPath: false,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n ];\n\n for (const variation of variations) {\n describe(`uploadSource: ${variation.uploadSource.toString()} and includeHomebrewPath: ${variation.includeHomebrewPath.toString()}`, () => {\n it('should return the correct script', () => {\n // -- ct --\n const script = getRunScriptTemplate(\n 'test-org',\n 'test-project',\n variation.uploadSource,\n variation.includeHomebrewPath,\n );\n\n // -- Assert --\n expect(script).toBe(variation.expectedScript);\n });\n });\n }\n });\n\n describe('scriptInputPath', () => {\n it('should return the correct path', () => {\n expect(scriptInputPath).toBe(\n '\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}\"',\n );\n });\n });\n\n describe('getSwiftSnippet', () => {\n it('should return the correct snippet', () => {\n // -- Arrange --\n const snippet = getSwiftSnippet('test-dsn');\n\n // -- Assert --\n expect(snippet).toBe(\n ` SentrySDK.start { options in\n options.dsn = \"test-dsn\"\n options.debug = true // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = true\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = {\n $0.sessionSampleRate = 1.0 // We recommend adjusting this value in production.\n $0.lifecycle = .trace\n }\n\n // Uncomment the following lines to add more data to your events\n // options.attachScreenshot = true // This adds a screenshot to the error events\n // options.attachViewHierarchy = true // This adds the view hierarchy to the error events\n }\n // Remove the next line after confirming that your Sentry integration is working.\n SentrySDK.capture(message: \"This app uses Sentry! :)\")\n`,\n );\n });\n });\n\n describe('getObjcSnippet', () => {\n it('should return the correct snippet', () => {\n // -- Arrange --\n const snippet = getObjcSnippet('test-dsn');\n\n // -- Assert --\n expect(snippet).toBe(\n ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {\n options.dsn = @\"test-dsn\";\n options.debug = YES; // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = YES;\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = @1.0;\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = ^(SentryProfileOptions *profiling) {\n profiling.sessionSampleRate = 1.0; // We recommend adjusting this value in production.\n profiling.lifecycle = SentryProfilingLifecycleTrace;\n };\n\n //Uncomment the following lines to add more data to your events\n //options.attachScreenshot = YES; //This will add a screenshot to the error events\n //options.attachViewHierarchy = YES; //This will add the view hierarchy to the error events\n }];\n //Remove the next line after confirming that your Sentry integration is working.\n [SentrySDK captureMessage:@\"This app uses Sentry!\"];\n`,\n );\n });\n });\n\n describe('getFastlaneSnippet', () => {\n it('should return the correct snippet', () => {\n // -- Arrange --\n const snippet = getFastlaneSnippet('test-org', 'test-project');\n\n // -- Assert --\n expect(snippet).toBe(\n ` sentry_cli(\n org_slug: 'test-org',\n project_slug: 'test-project',\n include_sources: true\n )`,\n );\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/apple/templates.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport {\n getFastlaneSnippet,\n getObjcSnippet,\n getRunScriptTemplate,\n getSwiftSnippet,\n scriptInputPath,\n} from '../../src/apple/templates';\n\ndescribe('templates', () => {\n describe('getRunScriptTemplate', () => {\n const variations: {\n uploadSource: boolean;\n includeHomebrewPath: boolean;\n expectedScript: string;\n }[] = [\n {\n uploadSource: true,\n includeHomebrewPath: true,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload --include-sources \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n {\n uploadSource: true,\n includeHomebrewPath: false,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload --include-sources \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n {\n uploadSource: false,\n includeHomebrewPath: true,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n {\n uploadSource: false,\n includeHomebrewPath: false,\n expectedScript: `# This script is responsible for uploading debug symbols and source context for Sentry.\nif which sentry-cli >/dev/null; then\n export SENTRY_ORG=test-org\n export SENTRY_PROJECT=test-project\n ERROR=$(sentry-cli debug-files upload \"$DWARF_DSYM_FOLDER_PATH\" 2>&1 >/dev/null)\n if [ ! $? -eq 0 ]; then\n echo \"warning: sentry-cli - $ERROR\"\n fi\nelse\n echo \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\n`,\n },\n ];\n\n for (const variation of variations) {\n describe(`uploadSource: ${variation.uploadSource.toString()} and includeHomebrewPath: ${variation.includeHomebrewPath.toString()}`, () => {\n it('should return the correct script', () => {\n // -- ct --\n const script = getRunScriptTemplate(\n 'test-org',\n 'test-project',\n variation.uploadSource,\n variation.includeHomebrewPath,\n );\n\n // -- Assert --\n expect(script).toBe(variation.expectedScript);\n });\n });\n }\n });\n\n describe('scriptInputPath', () => {\n it('should return the correct path', () => {\n expect(scriptInputPath).toBe(\n '\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}\"',\n );\n });\n });\n\n describe('getSwiftSnippet', () => {\n it('should return the correct snippet', () => {\n // -- Arrange --\n const snippet = getSwiftSnippet('test-dsn', false);\n\n // -- Assert --\n expect(snippet).toBe(\n ` SentrySDK.start { options in\n options.dsn = \"test-dsn\"\n options.debug = true // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = true\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = {\n $0.sessionSampleRate = 1.0 // We recommend adjusting this value in production.\n $0.lifecycle = .trace\n }\n\n // Uncomment the following lines to add more data to your events\n // options.attachScreenshot = true // This adds a screenshot to the error events\n // options.attachViewHierarchy = true // This adds the view hierarchy to the error events\n }\n // Remove the next line after confirming that your Sentry integration is working.\n SentrySDK.capture(message: \"This app uses Sentry! :)\")\n`,\n );\n });\n\n it('should return the correct snippet with logs enabled', () => {\n // -- Arrange --\n const snippet = getSwiftSnippet('test-dsn', true);\n\n // -- Assert --\n expect(snippet).toBe(\n ` SentrySDK.start { options in\n options.dsn = \"test-dsn\"\n options.debug = true // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = true\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = {\n $0.sessionSampleRate = 1.0 // We recommend adjusting this value in production.\n $0.lifecycle = .trace\n }\n\n // Uncomment the following lines to add more data to your events\n // options.attachScreenshot = true // This adds a screenshot to the error events\n // options.attachViewHierarchy = true // This adds the view hierarchy to the error events\n \n // Enable experimental logging features\n options.experimental.enableLogs = true\n }\n // Remove the next line after confirming that your Sentry integration is working.\n SentrySDK.capture(message: \"This app uses Sentry! :)\")\n`,\n );\n });\n });\n\n describe('getObjcSnippet', () => {\n it('should return the correct snippet', () => {\n // -- Arrange --\n const snippet = getObjcSnippet('test-dsn', false);\n\n // -- Assert --\n expect(snippet).toBe(\n ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {\n options.dsn = @\"test-dsn\";\n options.debug = YES; // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = YES;\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = @1.0;\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = ^(SentryProfileOptions *profiling) {\n profiling.sessionSampleRate = 1.0; // We recommend adjusting this value in production.\n profiling.lifecycle = SentryProfilingLifecycleTrace;\n };\n\n //Uncomment the following lines to add more data to your events\n //options.attachScreenshot = YES; //This will add a screenshot to the error events\n //options.attachViewHierarchy = YES; //This will add the view hierarchy to the error events\n }];\n //Remove the next line after confirming that your Sentry integration is working.\n [SentrySDK captureMessage:@\"This app uses Sentry!\"];\n`,\n );\n });\n\n it('should return the correct snippet with logs enabled', () => {\n // -- Arrange --\n const snippet = getObjcSnippet('test-dsn', true);\n\n // -- Assert --\n expect(snippet).toBe(\n ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {\n options.dsn = @\"test-dsn\";\n options.debug = YES; // Enabled debug when first installing is always helpful\n\n // Adds IP for users.\n // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/\n options.sendDefaultPii = YES;\n\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = @1.0;\n\n // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more.\n options.configureProfiling = ^(SentryProfileOptions *profiling) {\n profiling.sessionSampleRate = 1.0; // We recommend adjusting this value in production.\n profiling.lifecycle = SentryProfilingLifecycleTrace;\n };\n\n //Uncomment the following lines to add more data to your events\n //options.attachScreenshot = YES; //This will add a screenshot to the error events\n //options.attachViewHierarchy = YES; //This will add the view hierarchy to the error events\n \n // Enable experimental logging features\n options.experimental.enableLogs = YES;\n }];\n //Remove the next line after confirming that your Sentry integration is working.\n [SentrySDK captureMessage:@\"This app uses Sentry!\"];\n`,\n );\n });\n });\n\n describe('getFastlaneSnippet', () => {\n it('should return the correct snippet', () => {\n // -- Arrange --\n const snippet = getFastlaneSnippet('test-org', 'test-project');\n\n // -- Assert --\n expect(snippet).toBe(\n ` sentry_cli(\n org_slug: 'test-org',\n project_slug: 'test-project',\n include_sources: true\n )`,\n );\n });\n });\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-tools.test.js","sourceRoot":"","sources":["../../../test/flutter/code-tools.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,6DAKsC;AACtC,2DAA0D;AAE1D,IAAA,iBAAQ,EAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;CAejB,CAAC;IAEA,MAAM,YAAY,GAAG;;;;;CAKtB,CAAC;IAEA,MAAM,WAAW,GAAG;;;;;CAKrB,CAAC;IAEA,MAAM,mBAAmB,GAAG;QAC1B,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"code-tools.test.js","sourceRoot":"","sources":["../../../test/flutter/code-tools.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport {\n patchMainContent,\n getDependenciesLocation,\n getDevDependenciesLocation,\n getLastImportLineLocation,\n} from '../../src/flutter/code-tools';\nimport { initSnippet } from '../../src/flutter/templates';\n\ndescribe('code-tools', () => {\n const pubspec = `name: flutter_example\ndescription: An example flutter app.\nversion: 1.0.0\npublish_to: 'none' # Remove this line if you wish to publish to pub.dev\n\nenvironment:\n sdk: '>=2.17.0 <4.0.0'\n flutter: '>=3.0.0'\n\ndependencies:\n flutter:\n sdk: flutter\n\ndev_dependencies:\n flutter_lints: ^2.0.0\n`;\n\n const simpleRunApp = `import 'package:flutter/widgets.dart';\n\nvoid main() {\n runApp(const MyApp());\n}\n`;\n\n const asyncRunApp = `import 'package:flutter/widgets.dart';\n\nvoid main() {\n runApp(const MyApp());\n}\n`;\n\n const selectedFeaturesMap = {\n tracing: true,\n profiling: true,\n replay: true,\n logs: true,\n };\n\n const simpleRunAppPatched = `import 'package:flutter/widgets.dart';\nimport 'package:sentry_flutter/sentry_flutter.dart';\n\nFuture<void> main() async {\n ${initSnippet('dsn', selectedFeaturesMap, 'const MyApp()')}\n}\n`;\n\n const paramRunApp = `import 'package:flutter/widgets.dart';\n\nFuture<void> main() async {\n await someFunction();\n runApp(MyApp(param: SomeParam()));\n await anotherFunction();\n}\n`;\n\n const paramRunAppPatched = `import 'package:flutter/widgets.dart';\nimport 'package:sentry_flutter/sentry_flutter.dart';\n\nFuture<void> main() async {\n await someFunction();\n ${initSnippet('dsn', selectedFeaturesMap, 'MyApp(param: SomeParam())')}\n await anotherFunction();\n}\n`;\n\n const multilineRunApp = `import 'package:flutter/widgets.dart';\n\nvoid main() {\n runApp(\n MyApp(\n param: Param(),\n multi: Another(1),\n line: await bites(the: \"dust\"),\n ),\n );\n anotherFunction();\n}\n`;\n\n const multilineRunAppPatched = `import 'package:flutter/widgets.dart';\nimport 'package:sentry_flutter/sentry_flutter.dart';\n\nFuture<void> main() async {\n ${initSnippet(\n 'dsn',\n selectedFeaturesMap,\n `\n MyApp(\n param: Param(),\n multi: Another(1),\n line: await bites(the: \"dust\"),\n ),\n `,\n )}\n anotherFunction();\n}\n`;\n\n describe('patchMainContent', () => {\n it('wraps simple runApp', () => {\n expect(patchMainContent('dsn', simpleRunApp, selectedFeaturesMap)).toBe(\n simpleRunAppPatched,\n );\n });\n\n it('wraps async runApp', () => {\n expect(patchMainContent('dsn', asyncRunApp, selectedFeaturesMap)).toBe(\n simpleRunAppPatched,\n );\n });\n\n it('wraps runApp with parameterized app', () => {\n expect(patchMainContent('dsn', paramRunApp, selectedFeaturesMap)).toBe(\n paramRunAppPatched,\n );\n });\n\n it('wraps multiline runApp', () => {\n expect(\n patchMainContent('dsn', multilineRunApp, selectedFeaturesMap),\n ).toBe(multilineRunAppPatched);\n });\n });\n\n describe('pubspec', () => {\n it('returns proper line index for dependencies', () => {\n expect(getDependenciesLocation(pubspec)).toBe(\n pubspec.indexOf(' flutter:\\n'),\n );\n });\n\n it('returns proper line index for dev-dependencies', () => {\n expect(getDevDependenciesLocation(pubspec)).toBe(\n pubspec.indexOf(' flutter_lints: ^2.0.0\\n'),\n );\n });\n });\n\n describe('getLastImportLineLocation', () => {\n it('returns proper line index', () => {\n const code =\n `import 'foo:bar';\\n` + `//<insert-location>\\n` + `class X {}`;\n expect(getLastImportLineLocation(code)).toBe(\n code.indexOf('//<insert-location>'),\n );\n });\n\n it('returns proper line index when alias import is used', () => {\n const code =\n `import 'package:my_library/utils.dart' as utils;\\n` +\n `//<insert-location>\\n` +\n `class X {}`;\n expect(getLastImportLineLocation(code)).toBe(\n code.indexOf('//<insert-location>'),\n );\n });\n\n it('returns proper line index when specific parts import is used', () => {\n const code =\n `import 'dart:math' show pi, sin;\\n` +\n `//<insert-location>\\n` +\n `class X {}`;\n expect(getLastImportLineLocation(code)).toBe(\n code.indexOf('//<insert-location>'),\n );\n });\n\n it('returns proper line index when hide import is used', () => {\n const code =\n `import 'dart:math' hide Random;\\n` +\n `//<insert-location>\\n` +\n `class X {}`;\n expect(getLastImportLineLocation(code)).toBe(\n code.indexOf('//<insert-location>'),\n );\n });\n\n it('returns proper line index when deferred import is used', () => {\n const code =\n `import 'package:my_library/large_library.dart' deferred as largeLibrary;\\n` +\n `//<insert-location>\\n` +\n `class X {}`;\n expect(getLastImportLineLocation(code)).toBe(\n code.indexOf('//<insert-location>'),\n );\n });\n\n it('returns proper line index when multiple imports (with newlines) are present', () => {\n const code =\n `import 'foo:bar';\\n` +\n `import 'package:my_library/utils.dart' as utils;\\n` +\n `import 'dart:math' show pi, sin;\\n` +\n `import 'dart:math' hide Random;\\n` +\n `\\n` +\n `import 'package:my_library/large_library.dart' deferred as largeLibrary;\\n` +\n `//<insert-location>\\n` +\n `class X {}`;\n expect(getLastImportLineLocation(code)).toBe(\n code.indexOf('//<insert-location>'),\n );\n });\n });\n});\n"]}
|
|
@@ -28,6 +28,7 @@ const templates_1 = require("../../src/flutter/templates");
|
|
|
28
28
|
tracing: true,
|
|
29
29
|
profiling: true,
|
|
30
30
|
replay: true,
|
|
31
|
+
logs: true,
|
|
31
32
|
}, 'const MyApp()');
|
|
32
33
|
(0, vitest_1.expect)(template).toMatchInlineSnapshot(`
|
|
33
34
|
"await SentryFlutter.init(
|
|
@@ -36,6 +37,7 @@ const templates_1 = require("../../src/flutter/templates");
|
|
|
36
37
|
// Adds request headers and IP for users, for more info visit:
|
|
37
38
|
// https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/
|
|
38
39
|
options.sendDefaultPii = true;
|
|
40
|
+
options.enableLogs = true;
|
|
39
41
|
// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
|
|
40
42
|
// We recommend adjusting this value in production.
|
|
41
43
|
options.tracesSampleRate = 1.0;
|
|
@@ -57,6 +59,7 @@ const templates_1 = require("../../src/flutter/templates");
|
|
|
57
59
|
tracing: true,
|
|
58
60
|
profiling: false,
|
|
59
61
|
replay: false,
|
|
62
|
+
logs: true,
|
|
60
63
|
}, 'const MyApp()');
|
|
61
64
|
(0, vitest_1.expect)(template).toMatchInlineSnapshot(`
|
|
62
65
|
"await SentryFlutter.init(
|
|
@@ -65,6 +68,7 @@ const templates_1 = require("../../src/flutter/templates");
|
|
|
65
68
|
// Adds request headers and IP for users, for more info visit:
|
|
66
69
|
// https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/
|
|
67
70
|
options.sendDefaultPii = true;
|
|
71
|
+
options.enableLogs = true;
|
|
68
72
|
// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
|
|
69
73
|
// We recommend adjusting this value in production.
|
|
70
74
|
options.tracesSampleRate = 1.0;
|
|
@@ -75,11 +79,12 @@ const templates_1 = require("../../src/flutter/templates");
|
|
|
75
79
|
await Sentry.captureException(StateError('This is a sample exception.'));"
|
|
76
80
|
`);
|
|
77
81
|
});
|
|
78
|
-
(0, vitest_1.it)('generates Sentry config with tracing, profiling
|
|
82
|
+
(0, vitest_1.it)('generates Sentry config with tracing, profiling, replay and logs disabled', () => {
|
|
79
83
|
const template = (0, templates_1.initSnippet)('my-dsn', {
|
|
80
84
|
tracing: false,
|
|
81
85
|
profiling: false,
|
|
82
86
|
replay: false,
|
|
87
|
+
logs: false,
|
|
83
88
|
}, 'const MyApp()');
|
|
84
89
|
(0, vitest_1.expect)(template).toMatchInlineSnapshot(`
|
|
85
90
|
"await SentryFlutter.init(
|
|
@@ -95,6 +100,28 @@ const templates_1 = require("../../src/flutter/templates");
|
|
|
95
100
|
await Sentry.captureException(StateError('This is a sample exception.'));"
|
|
96
101
|
`);
|
|
97
102
|
});
|
|
103
|
+
(0, vitest_1.it)('generates Sentry config with only structured logs enabled', () => {
|
|
104
|
+
const template = (0, templates_1.initSnippet)('my-dsn', {
|
|
105
|
+
tracing: false,
|
|
106
|
+
profiling: false,
|
|
107
|
+
replay: false,
|
|
108
|
+
logs: true,
|
|
109
|
+
}, 'const MyApp()');
|
|
110
|
+
(0, vitest_1.expect)(template).toMatchInlineSnapshot(`
|
|
111
|
+
"await SentryFlutter.init(
|
|
112
|
+
(options) {
|
|
113
|
+
options.dsn = 'my-dsn';
|
|
114
|
+
// Adds request headers and IP for users, for more info visit:
|
|
115
|
+
// https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/
|
|
116
|
+
options.sendDefaultPii = true;
|
|
117
|
+
options.enableLogs = true;
|
|
118
|
+
},
|
|
119
|
+
appRunner: () => runApp(SentryWidget(child: const MyApp())),
|
|
120
|
+
);
|
|
121
|
+
// TODO: Remove this line after sending the first sample event to sentry.
|
|
122
|
+
await Sentry.captureException(StateError('This is a sample exception.'));"
|
|
123
|
+
`);
|
|
124
|
+
});
|
|
98
125
|
});
|
|
99
126
|
});
|
|
100
127
|
//# sourceMappingURL=templates.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/flutter/templates.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,2DAIqC;AAErC,IAAA,iBAAQ,EAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAA,iBAAQ,EAAC,SAAS,EAAE,GAAG,EAAE;QACvB,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,QAAQ,GAAG,IAAA,0BAAc,EAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;YAClE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;aAOhC,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,QAAQ,GAAG,IAAA,4BAAgB,EAAC,eAAe,CAAC,CAAC;YACnD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,4BAA4B,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAA,iBAAQ,EAAC,MAAM,EAAE,GAAG,EAAE;QACpB,IAAA,WAAE,EAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,QAAQ,GAAG,IAAA,uBAAW,EAC1B,QAAQ,EACR;gBACE,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/flutter/templates.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,2DAIqC;AAErC,IAAA,iBAAQ,EAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAA,iBAAQ,EAAC,SAAS,EAAE,GAAG,EAAE;QACvB,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,QAAQ,GAAG,IAAA,0BAAc,EAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;YAClE,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;aAOhC,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,QAAQ,GAAG,IAAA,4BAAgB,EAAC,eAAe,CAAC,CAAC;YACnD,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,4BAA4B,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,IAAA,iBAAQ,EAAC,MAAM,EAAE,GAAG,EAAE;QACpB,IAAA,WAAE,EAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,QAAQ,GAAG,IAAA,uBAAW,EAC1B,QAAQ,EACR;gBACE,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,IAAI;aACX,EACD,eAAe,CAChB,CAAC;YACF,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;OAsBtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,QAAQ,GAAG,IAAA,uBAAW,EAC1B,QAAQ,EACR;gBACE,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI;aACX,EACD,eAAe,CAChB,CAAC;YACF,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;OAgBtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,2EAA2E,EAAE,GAAG,EAAE;YACnF,MAAM,QAAQ,GAAG,IAAA,uBAAW,EAC1B,QAAQ,EACR;gBACE,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,KAAK;aACZ,EACD,eAAe,CAChB,CAAC;YACF,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;OAYtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,2DAA2D,EAAE,GAAG,EAAE;YACnE,MAAM,QAAQ,GAAG,IAAA,uBAAW,EAC1B,QAAQ,EACR;gBACE,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI;aACX,EACD,eAAe,CAChB,CAAC;YACF,IAAA,eAAM,EAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;OAatC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport {\n pubspecOptions,\n sentryProperties,\n initSnippet,\n} from '../../src/flutter/templates';\n\ndescribe('Flutter code templates', () => {\n describe('pubspec', () => {\n it('generates pubspec with project and org', () => {\n const template = pubspecOptions('fixture-project', 'fixture-org');\n expect(template).toMatchInlineSnapshot(`\n \"sentry:\n upload_debug_symbols: true\n upload_source_maps: true\n project: fixture-project\n org: fixture-org\n \"\n `);\n });\n });\n describe('sentry.properties', () => {\n it('generates sentry.properties with token', () => {\n const template = sentryProperties('fixture-token');\n expect(template).toMatchInlineSnapshot(`\"auth_token=fixture-token\"`);\n });\n });\n describe('init', () => {\n it('generates Sentry config with all features enabled', () => {\n const template = initSnippet(\n 'my-dsn',\n {\n tracing: true,\n profiling: true,\n replay: true,\n logs: true,\n },\n 'const MyApp()',\n );\n expect(template).toMatchInlineSnapshot(`\n \"await SentryFlutter.init(\n (options) {\n options.dsn = 'my-dsn';\n // Adds request headers and IP for users, for more info visit:\n // https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/\n options.sendDefaultPii = true;\n options.enableLogs = true;\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0;\n // The sampling rate for profiling is relative to tracesSampleRate\n // Setting to 1.0 will profile 100% of sampled transactions:\n options.profilesSampleRate = 1.0;\n // Configure Session Replay\n options.replay.sessionSampleRate = 0.1;\n options.replay.onErrorSampleRate = 1.0;\n },\n appRunner: () => runApp(SentryWidget(child: const MyApp())),\n );\n // TODO: Remove this line after sending the first sample event to sentry.\n await Sentry.captureException(StateError('This is a sample exception.'));\"\n `);\n });\n\n it('generates Sentry config with profiling & replay disabled', () => {\n const template = initSnippet(\n 'my-dsn',\n {\n tracing: true,\n profiling: false,\n replay: false,\n logs: true,\n },\n 'const MyApp()',\n );\n expect(template).toMatchInlineSnapshot(`\n \"await SentryFlutter.init(\n (options) {\n options.dsn = 'my-dsn';\n // Adds request headers and IP for users, for more info visit:\n // https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/\n options.sendDefaultPii = true;\n options.enableLogs = true;\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0;\n },\n appRunner: () => runApp(SentryWidget(child: const MyApp())),\n );\n // TODO: Remove this line after sending the first sample event to sentry.\n await Sentry.captureException(StateError('This is a sample exception.'));\"\n `);\n });\n\n it('generates Sentry config with tracing, profiling, replay and logs disabled', () => {\n const template = initSnippet(\n 'my-dsn',\n {\n tracing: false,\n profiling: false,\n replay: false,\n logs: false,\n },\n 'const MyApp()',\n );\n expect(template).toMatchInlineSnapshot(`\n \"await SentryFlutter.init(\n (options) {\n options.dsn = 'my-dsn';\n // Adds request headers and IP for users, for more info visit:\n // https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/\n options.sendDefaultPii = true;\n },\n appRunner: () => runApp(SentryWidget(child: const MyApp())),\n );\n // TODO: Remove this line after sending the first sample event to sentry.\n await Sentry.captureException(StateError('This is a sample exception.'));\"\n `);\n });\n\n it('generates Sentry config with only structured logs enabled', () => {\n const template = initSnippet(\n 'my-dsn',\n {\n tracing: false,\n profiling: false,\n replay: false,\n logs: true,\n },\n 'const MyApp()',\n );\n expect(template).toMatchInlineSnapshot(`\n \"await SentryFlutter.init(\n (options) {\n options.dsn = 'my-dsn';\n // Adds request headers and IP for users, for more info visit:\n // https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/\n options.sendDefaultPii = true;\n options.enableLogs = true;\n },\n appRunner: () => runApp(SentryWidget(child: const MyApp())),\n );\n // TODO: Remove this line after sending the first sample event to sentry.\n await Sentry.captureException(StateError('This is a sample exception.'));\"\n `);\n });\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
|
|
5
|
+
const magicast_1 = require("magicast");
|
|
6
|
+
const templates_1 = require("../../src/nextjs/templates");
|
|
7
|
+
const utils_1 = require("../../src/nextjs/utils");
|
|
8
|
+
(0, vitest_1.describe)('Next.js wizard double wrap prevention', () => {
|
|
9
|
+
const mockWithSentryConfigOptionsTemplate = (0, templates_1.getWithSentryConfigOptionsTemplate)({
|
|
10
|
+
orgSlug: 'test-org',
|
|
11
|
+
projectSlug: 'test-project',
|
|
12
|
+
selfHosted: false,
|
|
13
|
+
sentryUrl: 'https://sentry.io',
|
|
14
|
+
tunnelRoute: false,
|
|
15
|
+
});
|
|
16
|
+
(0, vitest_1.describe)('unwrapSentryConfigAst utility function', () => {
|
|
17
|
+
(0, vitest_1.describe)('AST-based expression unwrapping', () => {
|
|
18
|
+
(0, vitest_1.it)('keeps code without withSentryConfig', () => {
|
|
19
|
+
const mod = (0, magicast_1.parseModule)('export default nextConfig');
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
21
|
+
const originalAST = mod.exports.default.$ast;
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
23
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(originalAST);
|
|
24
|
+
(0, vitest_1.expect)(resultAST).toBe(originalAST);
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
26
|
+
const { code: exportDefaultCode } = (0, magicast_1.generateCode)({ $ast: resultAST });
|
|
27
|
+
(0, vitest_1.expect)(exportDefaultCode).toMatchInlineSnapshot(`"nextConfig"`);
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.it)('should handle plain object literal exports', () => {
|
|
30
|
+
const mod = (0, magicast_1.parseModule)(`export default { nextConfig: { randomValue: true } }`);
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
32
|
+
const originalAST = mod.exports.default.$ast;
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
34
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(originalAST);
|
|
35
|
+
(0, vitest_1.expect)(resultAST).toBe(originalAST);
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
37
|
+
(0, vitest_1.expect)(resultAST.type).toBe('ObjectExpression');
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
39
|
+
(0, vitest_1.expect)(resultAST.properties).toHaveLength(1);
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.it)('should unwrap withSentryConfig with options', () => {
|
|
42
|
+
const mod = (0, magicast_1.parseModule)('export default withSentryConfig(nextConfig, { org: "test" })');
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
44
|
+
const wrappedAst = mod.exports.default.$ast;
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
46
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(wrappedAst);
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
48
|
+
const { code: exportDefaultCode } = (0, magicast_1.generateCode)({ $ast: resultAST });
|
|
49
|
+
(0, vitest_1.expect)(exportDefaultCode).toMatchInlineSnapshot(`"nextConfig"`);
|
|
50
|
+
});
|
|
51
|
+
(0, vitest_1.it)('should unwrap withSentryConfig without options', () => {
|
|
52
|
+
const mod = (0, magicast_1.parseModule)('export default withSentryConfig(nextConfig)');
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
54
|
+
const wrappedAst = mod.exports.default.$ast;
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
56
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(wrappedAst);
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
58
|
+
const { code: exportDefaultCode } = (0, magicast_1.generateCode)({ $ast: resultAST });
|
|
59
|
+
(0, vitest_1.expect)(exportDefaultCode).toMatchInlineSnapshot(`"nextConfig"`);
|
|
60
|
+
});
|
|
61
|
+
(0, vitest_1.it)('should handle nested withSentryConfig calls', () => {
|
|
62
|
+
const mod = (0, magicast_1.parseModule)('export default withSentryConfig(withSentryConfig(nextConfig, { org: "inner" }), { org: "outer" })');
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
64
|
+
const wrappedAst = mod.exports.default.$ast;
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
66
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(wrappedAst);
|
|
67
|
+
// Should unwrap one level and return the inner withSentryConfig call
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
69
|
+
(0, vitest_1.expect)(resultAST.type).toBe('CallExpression');
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
71
|
+
(0, vitest_1.expect)(resultAST.callee.name).toBe('withSentryConfig');
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
73
|
+
const { code: exportDefaultCode } = (0, magicast_1.generateCode)({ $ast: resultAST });
|
|
74
|
+
(0, vitest_1.expect)(exportDefaultCode).toMatchInlineSnapshot(`"withSentryConfig(nextConfig, { org: "inner" })"`);
|
|
75
|
+
});
|
|
76
|
+
(0, vitest_1.it)('should handle complex expressions', () => {
|
|
77
|
+
const mod = (0, magicast_1.parseModule)('export default withSentryConfig(someComplexExpression.withMethods())');
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
79
|
+
const wrappedAst = mod.exports.default.$ast;
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
81
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(wrappedAst);
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
83
|
+
const { code: exportDefaultCode } = (0, magicast_1.generateCode)({ $ast: resultAST });
|
|
84
|
+
(0, vitest_1.expect)(exportDefaultCode).toMatchInlineSnapshot(`"someComplexExpression.withMethods()"`);
|
|
85
|
+
});
|
|
86
|
+
(0, vitest_1.it)('should handle object literals', () => {
|
|
87
|
+
const mod = (0, magicast_1.parseModule)('export default withSentryConfig({ next: "config", obj: { next: "nested" } }, { org: "test" })');
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
89
|
+
const wrappedAst = mod.exports.default.$ast;
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
91
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(wrappedAst);
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
93
|
+
const { code: exportDefaultCode } = (0, magicast_1.generateCode)({ $ast: resultAST });
|
|
94
|
+
(0, vitest_1.expect)(exportDefaultCode).toMatchInlineSnapshot(`"{ next: "config", obj: { next: "nested" } }"`);
|
|
95
|
+
});
|
|
96
|
+
(0, vitest_1.it)('should return unchanged if not a withSentryConfig call', () => {
|
|
97
|
+
const mod = (0, magicast_1.parseModule)('export default someOtherFunction(nextConfig)');
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
99
|
+
const originalAST = mod.exports.default.$ast;
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
101
|
+
const resultAST = (0, utils_1.unwrapSentryConfigAst)(originalAST);
|
|
102
|
+
(0, vitest_1.expect)(resultAST).toBe(originalAST);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
(0, vitest_1.describe)('MJS/TS files', () => {
|
|
107
|
+
(0, vitest_1.it)('should unwrap existing withSentryConfig and re-wrap with new config using AST', () => {
|
|
108
|
+
const existingMjsContent = `import { withSentryConfig } from "@sentry/nextjs";
|
|
109
|
+
|
|
110
|
+
const nextConfig = {};
|
|
111
|
+
|
|
112
|
+
export default withSentryConfig(nextConfig, {
|
|
113
|
+
org: "old-org",
|
|
114
|
+
project: "old-project",
|
|
115
|
+
});`;
|
|
116
|
+
const mod = (0, magicast_1.parseModule)(existingMjsContent);
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
118
|
+
const originalAST = mod.exports.default.$ast;
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
120
|
+
const unwrappedAst = (0, utils_1.unwrapSentryConfigAst)(originalAST);
|
|
121
|
+
// Verify it returns the first argument (nextConfig identifier)
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
123
|
+
(0, vitest_1.expect)(unwrappedAst.type).toBe('Identifier');
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
125
|
+
(0, vitest_1.expect)(unwrappedAst.name).toBe('nextConfig');
|
|
126
|
+
// Create a fresh module to simulate the re-wrapping process
|
|
127
|
+
const freshMod = (0, magicast_1.parseModule)(`import { withSentryConfig } from "@sentry/nextjs";
|
|
128
|
+
|
|
129
|
+
const nextConfig = {};
|
|
130
|
+
|
|
131
|
+
export default nextConfig;`);
|
|
132
|
+
// Apply wrapping
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
134
|
+
freshMod.exports.default = (0, utils_1.wrapWithSentryConfig)(freshMod.exports.default, mockWithSentryConfigOptionsTemplate);
|
|
135
|
+
const newCode = freshMod.generate().code;
|
|
136
|
+
// Verify only one withSentryConfig call exists
|
|
137
|
+
const withSentryConfigMatches = newCode.match(/withSentryConfig\s*\(/g);
|
|
138
|
+
(0, vitest_1.expect)(withSentryConfigMatches).toHaveLength(1);
|
|
139
|
+
(0, vitest_1.expect)(newCode).toContain('test-org');
|
|
140
|
+
(0, vitest_1.expect)(newCode).toContain('test-project');
|
|
141
|
+
(0, vitest_1.expect)(newCode).not.toContain('old-org');
|
|
142
|
+
(0, vitest_1.expect)(newCode).not.toContain('old-project');
|
|
143
|
+
});
|
|
144
|
+
(0, vitest_1.it)('should handle complex nested configurations using AST', () => {
|
|
145
|
+
const existingMjsContent = `import { withSentryConfig } from "@sentry/nextjs";
|
|
146
|
+
|
|
147
|
+
const nextConfig = { experimental: { appDir: true } };
|
|
148
|
+
|
|
149
|
+
export default withSentryConfig(
|
|
150
|
+
withSentryConfig(nextConfig, { org: "nested-org" }),
|
|
151
|
+
{ org: "outer-org" }
|
|
152
|
+
);`;
|
|
153
|
+
const mod = (0, magicast_1.parseModule)(existingMjsContent);
|
|
154
|
+
// First unwrap ----
|
|
155
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
156
|
+
const firstUnwrapAST = (0, utils_1.unwrapSentryConfigAst)(mod.exports.default.$ast);
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
158
|
+
(0, vitest_1.expect)(firstUnwrapAST.type).toBe('CallExpression');
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
160
|
+
(0, vitest_1.expect)(firstUnwrapAST.callee.name).toBe('withSentryConfig');
|
|
161
|
+
const { code: exportDefaultCode1 } = (0, magicast_1.generateCode)({
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
163
|
+
$ast: firstUnwrapAST,
|
|
164
|
+
});
|
|
165
|
+
(0, vitest_1.expect)(exportDefaultCode1).toMatchInlineSnapshot(`"withSentryConfig(nextConfig, { org: "nested-org" })"`);
|
|
166
|
+
// Second unwrap ----
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
168
|
+
const secondUnwrapAST = (0, utils_1.unwrapSentryConfigAst)(firstUnwrapAST);
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
170
|
+
(0, vitest_1.expect)(secondUnwrapAST.type).toBe('Identifier');
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
172
|
+
(0, vitest_1.expect)(secondUnwrapAST.name).toBe('nextConfig');
|
|
173
|
+
const { code: exportDefaultCode2 } = (0, magicast_1.generateCode)({
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
175
|
+
$ast: secondUnwrapAST,
|
|
176
|
+
});
|
|
177
|
+
(0, vitest_1.expect)(exportDefaultCode2).toMatchInlineSnapshot(`"nextConfig"`);
|
|
178
|
+
});
|
|
179
|
+
(0, vitest_1.it)('should handle simple export without existing withSentryConfig using AST', () => {
|
|
180
|
+
const simpleMjsContent = `const nextConfig = {};
|
|
181
|
+
|
|
182
|
+
export default nextConfig;`;
|
|
183
|
+
const mod = (0, magicast_1.parseModule)(simpleMjsContent);
|
|
184
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
185
|
+
const originalAST = mod.exports.default.$ast;
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
187
|
+
const unwrappedAst = (0, utils_1.unwrapSentryConfigAst)(originalAST);
|
|
188
|
+
(0, vitest_1.expect)(unwrappedAst).toBe(originalAST);
|
|
189
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
190
|
+
mod.exports.default = (0, utils_1.wrapWithSentryConfig)(mod.exports.default, mockWithSentryConfigOptionsTemplate);
|
|
191
|
+
const newCode = mod.generate().code;
|
|
192
|
+
// Should have exactly one withSentryConfig call
|
|
193
|
+
const withSentryConfigMatches = newCode.match(/withSentryConfig\s*\(/g);
|
|
194
|
+
(0, vitest_1.expect)(withSentryConfigMatches).toHaveLength(1);
|
|
195
|
+
(0, vitest_1.expect)(newCode).toMatchInlineSnapshot(`
|
|
196
|
+
"const nextConfig = {};
|
|
197
|
+
|
|
198
|
+
export default withSentryConfig(nextConfig, ${sentryOptionsSnapshot});"
|
|
199
|
+
`);
|
|
200
|
+
});
|
|
201
|
+
(0, vitest_1.it)('should handle withSentryConfig(nextConfig) without options using AST', () => {
|
|
202
|
+
const existingMjsContent = `import { withSentryConfig } from "@sentry/nextjs";
|
|
203
|
+
|
|
204
|
+
const nextConfig = {};
|
|
205
|
+
|
|
206
|
+
export default withSentryConfig(nextConfig);`;
|
|
207
|
+
const mod = (0, magicast_1.parseModule)(existingMjsContent);
|
|
208
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
|
209
|
+
const originalAST = mod.exports.default.$ast;
|
|
210
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
211
|
+
const unwrappedAst = (0, utils_1.unwrapSentryConfigAst)(originalAST);
|
|
212
|
+
// Verify it returns the first argument (nextConfig identifier)
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
214
|
+
(0, vitest_1.expect)(unwrappedAst.type).toBe('Identifier');
|
|
215
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
216
|
+
(0, vitest_1.expect)(unwrappedAst.name).toBe('nextConfig');
|
|
217
|
+
// Simulate the re-wrapping process
|
|
218
|
+
const freshMod = (0, magicast_1.parseModule)(`import { withSentryConfig } from "@sentry/nextjs";
|
|
219
|
+
|
|
220
|
+
const nextConfig = {};
|
|
221
|
+
|
|
222
|
+
export default nextConfig;`);
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
224
|
+
freshMod.exports.default = (0, utils_1.wrapWithSentryConfig)(freshMod.exports.default, mockWithSentryConfigOptionsTemplate);
|
|
225
|
+
const newCode = freshMod.generate().code;
|
|
226
|
+
// Should have exactly one withSentryConfig call
|
|
227
|
+
const withSentryConfigMatches = newCode.match(/withSentryConfig\s*\(/g);
|
|
228
|
+
(0, vitest_1.expect)(withSentryConfigMatches).toHaveLength(1);
|
|
229
|
+
(0, vitest_1.expect)(newCode).not.toContain('withSentryConfig(withSentryConfig(');
|
|
230
|
+
(0, vitest_1.expect)(newCode).toMatch(/withSentryConfig\s*\(\s*nextConfig\s*,/);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
const sentryOptionsSnapshot = `{
|
|
235
|
+
// For all available options, see:
|
|
236
|
+
// https://www.npmjs.com/package/@sentry/webpack-plugin#options
|
|
237
|
+
|
|
238
|
+
org: "test-org",
|
|
239
|
+
|
|
240
|
+
project: "test-project",
|
|
241
|
+
|
|
242
|
+
// Only print logs for uploading source maps in CI
|
|
243
|
+
silent: !process.env.CI,
|
|
244
|
+
|
|
245
|
+
// For all available options, see:
|
|
246
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
|
247
|
+
|
|
248
|
+
// Upload a larger set of source maps for prettier stack traces (increases build time)
|
|
249
|
+
widenClientFileUpload: true,
|
|
250
|
+
|
|
251
|
+
// Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
|
|
252
|
+
// This can increase your server load as well as your hosting bill.
|
|
253
|
+
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
|
|
254
|
+
// side errors will fail.
|
|
255
|
+
// tunnelRoute: "/monitoring",
|
|
256
|
+
|
|
257
|
+
// Automatically tree-shake Sentry logger statements to reduce bundle size
|
|
258
|
+
disableLogger: true,
|
|
259
|
+
|
|
260
|
+
// Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
|
|
261
|
+
// See the following for more information:
|
|
262
|
+
// https://docs.sentry.io/product/crons/
|
|
263
|
+
// https://vercel.com/docs/cron-jobs
|
|
264
|
+
automaticVercelMonitors: true
|
|
265
|
+
}`;
|
|
266
|
+
//# sourceMappingURL=wizard-double-wrap-prevention.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard-double-wrap-prevention.test.js","sourceRoot":"","sources":["../../../test/nextjs/wizard-double-wrap-prevention.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect } from 'vitest';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport { getWithSentryConfigOptionsTemplate } from '../../src/nextjs/templates';\nimport {\n unwrapSentryConfigAst,\n wrapWithSentryConfig,\n} from '../../src/nextjs/utils';\n\ndescribe('Next.js wizard double wrap prevention', () => {\n const mockWithSentryConfigOptionsTemplate =\n getWithSentryConfigOptionsTemplate({\n orgSlug: 'test-org',\n projectSlug: 'test-project',\n selfHosted: false,\n sentryUrl: 'https://sentry.io',\n tunnelRoute: false,\n });\n\n describe('unwrapSentryConfigAst utility function', () => {\n describe('AST-based expression unwrapping', () => {\n it('keeps code without withSentryConfig', () => {\n const mod = parseModule('export default nextConfig');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n expect(resultAST).toBe(originalAST);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle plain object literal exports', () => {\n const mod = parseModule(\n `export default { nextConfig: { randomValue: true } }`,\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n\n expect(resultAST).toBe(originalAST);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.type).toBe('ObjectExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.properties).toHaveLength(1);\n });\n\n it('should unwrap withSentryConfig with options', () => {\n const mod = parseModule(\n 'export default withSentryConfig(nextConfig, { org: \"test\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should unwrap withSentryConfig without options', () => {\n const mod = parseModule('export default withSentryConfig(nextConfig)');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle nested withSentryConfig calls', () => {\n const mod = parseModule(\n 'export default withSentryConfig(withSentryConfig(nextConfig, { org: \"inner\" }), { org: \"outer\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // Should unwrap one level and return the inner withSentryConfig call\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.type).toBe('CallExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(resultAST.callee.name).toBe('withSentryConfig');\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"withSentryConfig(nextConfig, { org: \"inner\" })\"`,\n );\n });\n\n it('should handle complex expressions', () => {\n const mod = parseModule(\n 'export default withSentryConfig(someComplexExpression.withMethods())',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"someComplexExpression.withMethods()\"`,\n );\n });\n\n it('should handle object literals', () => {\n const mod = parseModule(\n 'export default withSentryConfig({ next: \"config\", obj: { next: \"nested\" } }, { org: \"test\" })',\n );\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const wrappedAst = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const resultAST = unwrapSentryConfigAst(wrappedAst);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const { code: exportDefaultCode } = generateCode({ $ast: resultAST });\n\n expect(exportDefaultCode).toMatchInlineSnapshot(\n `\"{ next: \"config\", obj: { next: \"nested\" } }\"`,\n );\n });\n\n it('should return unchanged if not a withSentryConfig call', () => {\n const mod = parseModule('export default someOtherFunction(nextConfig)');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const resultAST = unwrapSentryConfigAst(originalAST);\n\n expect(resultAST).toBe(originalAST);\n });\n });\n });\n\n describe('MJS/TS files', () => {\n it('should unwrap existing withSentryConfig and re-wrap with new config using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig, {\n org: \"old-org\",\n project: \"old-project\",\n});`;\n\n const mod = parseModule(existingMjsContent);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n // Verify it returns the first argument (nextConfig identifier)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.name).toBe('nextConfig');\n\n // Create a fresh module to simulate the re-wrapping process\n const freshMod =\n parseModule(`import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default nextConfig;`);\n\n // Apply wrapping\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n freshMod.exports.default = wrapWithSentryConfig(\n freshMod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = freshMod.generate().code;\n\n // Verify only one withSentryConfig call exists\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).toContain('test-org');\n expect(newCode).toContain('test-project');\n expect(newCode).not.toContain('old-org');\n expect(newCode).not.toContain('old-project');\n });\n\n it('should handle complex nested configurations using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = { experimental: { appDir: true } };\n\nexport default withSentryConfig(\n withSentryConfig(nextConfig, { org: \"nested-org\" }),\n { org: \"outer-org\" }\n);`;\n\n const mod = parseModule(existingMjsContent);\n\n // First unwrap ----\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const firstUnwrapAST = unwrapSentryConfigAst(mod.exports.default.$ast);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(firstUnwrapAST.type).toBe('CallExpression');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(firstUnwrapAST.callee.name).toBe('withSentryConfig');\n\n const { code: exportDefaultCode1 } = generateCode({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n $ast: firstUnwrapAST,\n });\n expect(exportDefaultCode1).toMatchInlineSnapshot(\n `\"withSentryConfig(nextConfig, { org: \"nested-org\" })\"`,\n );\n\n // Second unwrap ----\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const secondUnwrapAST = unwrapSentryConfigAst(firstUnwrapAST);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(secondUnwrapAST.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(secondUnwrapAST.name).toBe('nextConfig');\n\n const { code: exportDefaultCode2 } = generateCode({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n $ast: secondUnwrapAST,\n });\n\n expect(exportDefaultCode2).toMatchInlineSnapshot(`\"nextConfig\"`);\n });\n\n it('should handle simple export without existing withSentryConfig using AST', () => {\n const simpleMjsContent = `const nextConfig = {};\n\nexport default nextConfig;`;\n\n const mod = parseModule(simpleMjsContent);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n expect(unwrappedAst).toBe(originalAST);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.default = wrapWithSentryConfig(\n mod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = mod.generate().code;\n\n // Should have exactly one withSentryConfig call\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).toMatchInlineSnapshot(`\n \"const nextConfig = {};\n\n export default withSentryConfig(nextConfig, ${sentryOptionsSnapshot});\"\n `);\n });\n\n it('should handle withSentryConfig(nextConfig) without options using AST', () => {\n const existingMjsContent = `import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig);`;\n\n const mod = parseModule(existingMjsContent);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const originalAST = mod.exports.default.$ast;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const unwrappedAst = unwrapSentryConfigAst(originalAST);\n // Verify it returns the first argument (nextConfig identifier)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.type).toBe('Identifier');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n expect(unwrappedAst.name).toBe('nextConfig');\n\n // Simulate the re-wrapping process\n const freshMod =\n parseModule(`import { withSentryConfig } from \"@sentry/nextjs\";\n\nconst nextConfig = {};\n\nexport default nextConfig;`);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n freshMod.exports.default = wrapWithSentryConfig(\n freshMod.exports.default,\n mockWithSentryConfigOptionsTemplate,\n );\n\n const newCode = freshMod.generate().code;\n\n // Should have exactly one withSentryConfig call\n const withSentryConfigMatches = newCode.match(/withSentryConfig\\s*\\(/g);\n expect(withSentryConfigMatches).toHaveLength(1);\n\n expect(newCode).not.toContain('withSentryConfig(withSentryConfig(');\n expect(newCode).toMatch(/withSentryConfig\\s*\\(\\s*nextConfig\\s*,/);\n });\n });\n});\n\nconst sentryOptionsSnapshot = `{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"test-org\",\n\n project: \"test-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n // tunnelRoute: \"/monitoring\",\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true\n}`;\n"]}
|
|
@@ -19,7 +19,7 @@ config.resolver.assetExts.push(
|
|
|
19
19
|
|
|
20
20
|
module.exports = config;
|
|
21
21
|
`);
|
|
22
|
-
const result = (0, expo_metro_1.patchMetroInMemory)(mod);
|
|
22
|
+
const result = (0, expo_metro_1.patchMetroInMemory)(mod, 'metro.config.js');
|
|
23
23
|
(0, vitest_1.expect)(result).toBe(true);
|
|
24
24
|
(0, vitest_1.expect)((0, magicast_1.generateCode)(mod.$ast).code).toBe(`
|
|
25
25
|
const {
|
|
@@ -45,7 +45,7 @@ const config = getDefaultConfig(__dirname);
|
|
|
45
45
|
|
|
46
46
|
module.exports = config;
|
|
47
47
|
`);
|
|
48
|
-
const result = (0, expo_metro_1.patchMetroInMemory)(mod);
|
|
48
|
+
const result = (0, expo_metro_1.patchMetroInMemory)(mod, 'metro.config.js');
|
|
49
49
|
(0, vitest_1.expect)(result).toBe(true);
|
|
50
50
|
(0, vitest_1.expect)((0, magicast_1.generateCode)(mod.$ast).code).toBe(`
|
|
51
51
|
const { getDefaultConfig, otherExport } = require("expo/metro-config");
|
|
@@ -63,7 +63,7 @@ module.exports = config;
|
|
|
63
63
|
const mod = (0, magicast_1.parseModule)(`
|
|
64
64
|
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
|
|
65
65
|
`);
|
|
66
|
-
const result = (0, expo_metro_1.patchMetroInMemory)(mod);
|
|
66
|
+
const result = (0, expo_metro_1.patchMetroInMemory)(mod, 'metro.config.js');
|
|
67
67
|
(0, vitest_1.expect)(result).toBe(false);
|
|
68
68
|
(0, vitest_1.expect)((0, magicast_1.generateCode)(mod.$ast).code).toBe(`
|
|
69
69
|
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expo-metro.test.js","sourceRoot":"","sources":["../../../test/react-native/expo-metro.test.ts"],"names":[],"mappings":";;AAAA,kFAAkF;AAClF,uCAAqD;AACrD,kEAAuE;AACvE,mCAAgD;AAEhD,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAA,aAAI,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACvC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;;;;;OAYrB,CAAC,CAAC;QAEL,MAAM,MAAM,GAAG,IAAA,+BAAkB,EAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"expo-metro.test.js","sourceRoot":"","sources":["../../../test/react-native/expo-metro.test.ts"],"names":[],"mappings":";;AAAA,kFAAkF;AAClF,uCAAqD;AACrD,kEAAuE;AACvE,mCAAgD;AAEhD,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAA,aAAI,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACvC,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;;;;;;;OAYrB,CAAC,CAAC;QAEL,MAAM,MAAM,GAAG,IAAA,+BAAkB,EAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAC1D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtC;;;;;;;;;;;;;;CAcL,CAAC,IAAI,EAAE,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;;;;;OAMrB,CAAC,CAAC;QAEL,MAAM,MAAM,GAAG,IAAA,+BAAkB,EAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAC1D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtC;;;;;;;;;;CAUL,CAAC,IAAI,EAAE,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,6CAA6C,EAAE,GAAG,EAAE;QACvD,MAAM,GAAG,GAAG,IAAA,sBAAW,EAAC;;CAE3B,CAAC,CAAC;QAEC,MAAM,MAAM,GAAG,IAAA,+BAAkB,EAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAC1D,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,IAAA,uBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtC;;CAEL,CAAC,IAAI,EAAE,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport { patchMetroInMemory } from '../../src/react-native/expo-metro';\nimport { describe, expect, test } from 'vitest';\n\ndescribe('expo-metro config', () => {\n test('patches minimal expo config', () => {\n const mod = parseModule(`\nconst { getDefaultConfig } = require(\"expo/metro-config\");\n\n/** @type {import('expo/metro-config').MetroConfig} */\nconst config = getDefaultConfig(__dirname);\n\nconfig.resolver.assetExts.push(\n // Adds support for .db files for SQLite databases\n 'db'\n);\n\nmodule.exports = config;\n `);\n\n const result = patchMetroInMemory(mod, 'metro.config.js');\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `\nconst {\n getSentryExpoConfig\n} = require(\"@sentry/react-native/metro\");\n\n/** @type {import('expo/metro-config').MetroConfig} */\nconst config = getSentryExpoConfig(__dirname);\n\nconfig.resolver.assetExts.push(\n // Adds support for .db files for SQLite databases\n 'db'\n);\n\nmodule.exports = config;\n`.trim(),\n );\n });\n\n test('keeps expo metro config if other imports are present', () => {\n const mod = parseModule(`\nconst { getDefaultConfig, otherExport } = require(\"expo/metro-config\");\n\nconst config = getDefaultConfig(__dirname);\n\nmodule.exports = config;\n `);\n\n const result = patchMetroInMemory(mod, 'metro.config.js');\n expect(result).toBe(true);\n expect(generateCode(mod.$ast).code).toBe(\n `\nconst { getDefaultConfig, otherExport } = require(\"expo/metro-config\");\n\nconst {\n getSentryExpoConfig\n} = require(\"@sentry/react-native/metro\");\n\nconst config = getSentryExpoConfig(__dirname);\n\nmodule.exports = config;\n`.trim(),\n );\n });\n\n test('does not modify when sentry already present', () => {\n const mod = parseModule(`\nconst { getSentryExpoConfig } = require(\"@sentry/react-native/metro\");\n`);\n\n const result = patchMetroInMemory(mod, 'metro.config.js');\n expect(result).toBe(false);\n expect(generateCode(mod.$ast).code).toBe(\n `\nconst { getSentryExpoConfig } = require(\"@sentry/react-native/metro\");\n`.trim(),\n );\n });\n});\n"]}
|