@sentry/wizard 3.11.0 → 3.12.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 +7 -0
- package/dist/package.json +1 -1
- package/dist/src/android/android-wizard.js +8 -0
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/android/code-tools.d.ts +8 -0
- package/dist/src/android/code-tools.js +20 -8
- package/dist/src/android/code-tools.js.map +1 -1
- package/dist/src/android/gradle.js +6 -1
- package/dist/src/android/gradle.js.map +1 -1
- package/dist/src/sourcemaps/tools/vite.js +36 -111
- package/dist/src/sourcemaps/tools/vite.js.map +1 -1
- package/dist/src/sourcemaps/tools/webpack.d.ts +6 -1
- package/dist/src/sourcemaps/tools/webpack.js +290 -25
- package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup.js +2 -2
- package/dist/src/sveltekit/sdk-setup.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +7 -3
- package/dist/src/utils/ast-utils.js +20 -5
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack-utils.d.ts +52 -0
- package/dist/src/utils/clack-utils.js +169 -12
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/test/android/code-tools.test.d.ts +1 -0
- package/dist/test/android/code-tools.test.js +34 -0
- package/dist/test/android/code-tools.test.js.map +1 -0
- package/dist/test/sourcemaps/tools/webpack.test.d.ts +1 -0
- package/dist/test/sourcemaps/tools/webpack.test.js +179 -0
- package/dist/test/sourcemaps/tools/webpack.test.js.map +1 -0
- package/dist/test/utils/ast-utils.test.js +42 -7
- package/dist/test/utils/ast-utils.test.js.map +1 -1
- package/dist/test/utils/clack-utils.test.d.ts +1 -0
- package/dist/test/utils/clack-utils.test.js +200 -0
- package/dist/test/utils/clack-utils.test.js.map +1 -0
- package/package.json +1 -1
- package/src/android/android-wizard.ts +8 -0
- package/src/android/code-tools.ts +21 -7
- package/src/android/gradle.ts +6 -1
- package/src/sourcemaps/tools/vite.ts +22 -88
- package/src/sourcemaps/tools/webpack.ts +369 -30
- package/src/sveltekit/sdk-setup.ts +6 -2
- package/src/utils/ast-utils.ts +23 -7
- package/src/utils/clack-utils.ts +150 -2
- package/test/android/code-tools.test.ts +49 -0
- package/test/sourcemaps/tools/webpack.test.ts +303 -0
- package/test/utils/ast-utils.test.ts +28 -9
- package/test/utils/clack-utils.test.ts +142 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../../src/utils/ast-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAyB;
|
|
1
|
+
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../../src/utils/ast-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAyB;AAEzB,6CAAiC;AAIjC;;;GAGG;AACH,SAAgB,QAAQ,CACtB,QAAgB,EAChB,SAAoD;IAApD,0BAAA,EAAA,aAAuB,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;IAEpD,OAAO,SAAS;SACb,GAAG,CAAC,UAAC,IAAI,IAAK,OAAA,UAAG,QAAQ,SAAG,IAAI,CAAE,EAApB,CAAoB,CAAC;SACnC,IAAI,CAAC,UAAC,IAAI,IAAK,OAAA,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAnB,CAAmB,CAAC,CAAC;AACzC,CAAC;AAPD,4BAOC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,OAAkB;IACjD,IAAI,WAAW,GAAwB,KAAK,CAAC;IAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;QACpB,kBAAkB,YAAC,IAAI;YACrB,WAAW,GAAG,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACpE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QACD,YAAY,YAAC,IAAI;;YACf,WAAW;gBACT,WAAW,KAAI,MAAA,IAAI,CAAC,IAAI,CAAC,KAAK,0CAAE,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA,CAAC;YACpE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,CAAC,WAAW,CAAC;AACvB,CAAC;AAfD,4CAeC","sourcesContent":["import * as fs from 'fs';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\n/**\n * Checks if a file where we don't know its concrete file type yet exists\n * and returns the full path to the file with the correct file type.\n */\nexport function findFile(\n filePath: string,\n fileTypes: string[] = ['.js', '.ts', '.mjs', '.cjs'],\n): string | undefined {\n return fileTypes\n .map((type) => `${filePath}${type}`)\n .find((file) => fs.existsSync(file));\n}\n\n/**\n * checks for require('@sentry/*') syntax\n */\nexport function hasSentryContent(program: t.Program): boolean {\n let foundSentry: boolean | undefined = false;\n recast.visit(program, {\n visitStringLiteral(path) {\n foundSentry = foundSentry || path.node.value.startsWith('@sentry/');\n this.traverse(path);\n },\n visitLiteral(path) {\n foundSentry =\n foundSentry || path.node.value?.toString().startsWith('@sentry/');\n this.traverse(path);\n },\n });\n\n return !!foundSentry;\n}\n"]}
|
|
@@ -53,3 +53,55 @@ export declare function getOrAskForProjectData(options: WizardOptions, platform?
|
|
|
53
53
|
selectedProject: SentryProjectData;
|
|
54
54
|
authToken: string;
|
|
55
55
|
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Asks users if they have a config file for @param tool (e.g. Vite).
|
|
58
|
+
* If yes, asks users to specify the path to their config file.
|
|
59
|
+
*
|
|
60
|
+
* Use this helper function as a fallback mechanism if the lookup for
|
|
61
|
+
* a config file with its most usual location/name fails.
|
|
62
|
+
*
|
|
63
|
+
* @param toolName Name of the tool for which we're looking for the config file
|
|
64
|
+
* @param configFileName Name of the most common config file name (e.g. vite.config.js)
|
|
65
|
+
*
|
|
66
|
+
* @returns a user path to the config file or undefined if the user doesn't have a config file
|
|
67
|
+
*/
|
|
68
|
+
export declare function askForToolConfigPath(toolName: string, configFileName: string): Promise<string | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Prints copy/paste-able instructions to the console.
|
|
71
|
+
* Afterwards asks the user if they added the code snippet to their file.
|
|
72
|
+
*
|
|
73
|
+
* While there's no point in providing a "no" answer here, it gives users time to fulfill the
|
|
74
|
+
* task before the wizard continues with additional steps.
|
|
75
|
+
*
|
|
76
|
+
* Use this function if you want to show users instructions on how to add/modify
|
|
77
|
+
* code in their file. This is helpful if automatic insertion failed or is not possible/feasible.
|
|
78
|
+
*
|
|
79
|
+
* @param filename the name of the file to which the code snippet should be applied.
|
|
80
|
+
* If a path is provided, only the filename will be used.
|
|
81
|
+
* @param codeSnippet the snippet to be printed.
|
|
82
|
+
* Make sure to follow the diff-like format of highlighting lines that require changes
|
|
83
|
+
* and showing unchanged lines in gray.
|
|
84
|
+
*
|
|
85
|
+
* TODO: Link to wizard spec (develop) once it is live
|
|
86
|
+
* TODO: refactor copy paste instructions across different wizards to use this function.
|
|
87
|
+
* this might require adding a custom message parameter to the function
|
|
88
|
+
*/
|
|
89
|
+
export declare function showCopyPasteInstructions(filename: string, codeSnippet: string): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Creates a new config file with the given @param filepath and @param codeSnippet.
|
|
92
|
+
*
|
|
93
|
+
* Use this function to create a new config file for users. This is useful
|
|
94
|
+
* when users answered that they don't yet have a config file for a tool.
|
|
95
|
+
*
|
|
96
|
+
* (This doesn't mean that they don't yet have some other way of configuring
|
|
97
|
+
* their tool but we can leave it up to them to figure out how to merge configs
|
|
98
|
+
* here.)
|
|
99
|
+
*
|
|
100
|
+
* @param filepath absolute path to the new config file
|
|
101
|
+
* @param codeSnippet the snippet to be inserted into the file
|
|
102
|
+
* @param moreInformation (optional) the message to be printed after the file was created
|
|
103
|
+
* For example, this can be a link to more information about configuring the tool.
|
|
104
|
+
*
|
|
105
|
+
* @returns true on sucess, false otherwise
|
|
106
|
+
*/
|
|
107
|
+
export declare function createNewConfigFile(filepath: string, codeSnippet: string, moreInformation?: string): Promise<boolean>;
|
|
@@ -58,11 +58,20 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
58
58
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
62
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
63
|
+
if (ar || !(i in from)) {
|
|
64
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
65
|
+
ar[i] = from[i];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
69
|
+
};
|
|
61
70
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
62
71
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
63
72
|
};
|
|
64
73
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
-
exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliConfig = exports.installPackage = exports.askForItemSelection = exports.askToInstallSentryCLI = exports.confirmContinueEvenThoughNoGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.sourceMapsCliSetupConfig = exports.SENTRY_PROPERTIES_FILE = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
|
|
74
|
+
exports.createNewConfigFile = exports.showCopyPasteInstructions = exports.askForToolConfigPath = exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliConfig = exports.installPackage = exports.askForItemSelection = exports.askToInstallSentryCLI = exports.confirmContinueEvenThoughNoGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.sourceMapsCliSetupConfig = exports.SENTRY_PROPERTIES_FILE = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
|
|
66
75
|
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
67
76
|
var clack = __importStar(require("@clack/prompts"));
|
|
68
77
|
var axios_1 = __importDefault(require("axios"));
|
|
@@ -76,6 +85,7 @@ var Sentry = __importStar(require("@sentry/node"));
|
|
|
76
85
|
var package_json_1 = require("./package-json");
|
|
77
86
|
var telemetry_1 = require("../telemetry");
|
|
78
87
|
var package_manager_1 = require("./package-manager");
|
|
88
|
+
var debug_1 = require("./debug");
|
|
79
89
|
var opn = require('opn');
|
|
80
90
|
exports.SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';
|
|
81
91
|
exports.SENTRY_CLI_RC_FILE = '.sentryclirc';
|
|
@@ -756,19 +766,27 @@ function askForWizardLogin(options) {
|
|
|
756
766
|
}
|
|
757
767
|
function askForProjectSelection(projects) {
|
|
758
768
|
return __awaiter(this, void 0, void 0, function () {
|
|
759
|
-
var selection;
|
|
769
|
+
var label, sortedProjects, selection;
|
|
760
770
|
return __generator(this, function (_a) {
|
|
761
771
|
switch (_a.label) {
|
|
762
|
-
case 0:
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
+
case 0:
|
|
773
|
+
label = function (project) {
|
|
774
|
+
return "".concat(project.organization.slug, "/").concat(project.slug);
|
|
775
|
+
};
|
|
776
|
+
sortedProjects = __spreadArray([], projects, true);
|
|
777
|
+
sortedProjects.sort(function (a, b) {
|
|
778
|
+
return label(a).localeCompare(label(b));
|
|
779
|
+
});
|
|
780
|
+
return [4 /*yield*/, abortIfCancelled(clack.select({
|
|
781
|
+
maxItems: 12,
|
|
782
|
+
message: 'Select your Sentry project.',
|
|
783
|
+
options: sortedProjects.map(function (project) {
|
|
784
|
+
return {
|
|
785
|
+
value: project,
|
|
786
|
+
label: label(project),
|
|
787
|
+
};
|
|
788
|
+
}),
|
|
789
|
+
}))];
|
|
772
790
|
case 1:
|
|
773
791
|
selection = _a.sent();
|
|
774
792
|
Sentry.setTag('project', selection.slug);
|
|
@@ -779,4 +797,143 @@ function askForProjectSelection(projects) {
|
|
|
779
797
|
});
|
|
780
798
|
});
|
|
781
799
|
}
|
|
800
|
+
/**
|
|
801
|
+
* Asks users if they have a config file for @param tool (e.g. Vite).
|
|
802
|
+
* If yes, asks users to specify the path to their config file.
|
|
803
|
+
*
|
|
804
|
+
* Use this helper function as a fallback mechanism if the lookup for
|
|
805
|
+
* a config file with its most usual location/name fails.
|
|
806
|
+
*
|
|
807
|
+
* @param toolName Name of the tool for which we're looking for the config file
|
|
808
|
+
* @param configFileName Name of the most common config file name (e.g. vite.config.js)
|
|
809
|
+
*
|
|
810
|
+
* @returns a user path to the config file or undefined if the user doesn't have a config file
|
|
811
|
+
*/
|
|
812
|
+
function askForToolConfigPath(toolName, configFileName) {
|
|
813
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
814
|
+
var hasConfig;
|
|
815
|
+
return __generator(this, function (_a) {
|
|
816
|
+
switch (_a.label) {
|
|
817
|
+
case 0: return [4 /*yield*/, abortIfCancelled(clack.confirm({
|
|
818
|
+
message: "Do you have a ".concat(toolName, " config file (e.g. ").concat(chalk_1.default.cyan(configFileName), "?"),
|
|
819
|
+
initialValue: true,
|
|
820
|
+
}))];
|
|
821
|
+
case 1:
|
|
822
|
+
hasConfig = _a.sent();
|
|
823
|
+
if (!hasConfig) {
|
|
824
|
+
return [2 /*return*/, undefined];
|
|
825
|
+
}
|
|
826
|
+
return [4 /*yield*/, abortIfCancelled(clack.text({
|
|
827
|
+
message: "Please enter the path to your ".concat(toolName, " config file:"),
|
|
828
|
+
placeholder: path.join('.', configFileName),
|
|
829
|
+
validate: function (value) {
|
|
830
|
+
if (!value) {
|
|
831
|
+
return 'Please enter a path.';
|
|
832
|
+
}
|
|
833
|
+
try {
|
|
834
|
+
fs.accessSync(value);
|
|
835
|
+
}
|
|
836
|
+
catch (_a) {
|
|
837
|
+
return 'Could not access the file at this path.';
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
}))];
|
|
841
|
+
case 2: return [2 /*return*/, _a.sent()];
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
exports.askForToolConfigPath = askForToolConfigPath;
|
|
847
|
+
/**
|
|
848
|
+
* Prints copy/paste-able instructions to the console.
|
|
849
|
+
* Afterwards asks the user if they added the code snippet to their file.
|
|
850
|
+
*
|
|
851
|
+
* While there's no point in providing a "no" answer here, it gives users time to fulfill the
|
|
852
|
+
* task before the wizard continues with additional steps.
|
|
853
|
+
*
|
|
854
|
+
* Use this function if you want to show users instructions on how to add/modify
|
|
855
|
+
* code in their file. This is helpful if automatic insertion failed or is not possible/feasible.
|
|
856
|
+
*
|
|
857
|
+
* @param filename the name of the file to which the code snippet should be applied.
|
|
858
|
+
* If a path is provided, only the filename will be used.
|
|
859
|
+
* @param codeSnippet the snippet to be printed.
|
|
860
|
+
* Make sure to follow the diff-like format of highlighting lines that require changes
|
|
861
|
+
* and showing unchanged lines in gray.
|
|
862
|
+
*
|
|
863
|
+
* TODO: Link to wizard spec (develop) once it is live
|
|
864
|
+
* TODO: refactor copy paste instructions across different wizards to use this function.
|
|
865
|
+
* this might require adding a custom message parameter to the function
|
|
866
|
+
*/
|
|
867
|
+
function showCopyPasteInstructions(filename, codeSnippet) {
|
|
868
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
869
|
+
return __generator(this, function (_a) {
|
|
870
|
+
switch (_a.label) {
|
|
871
|
+
case 0:
|
|
872
|
+
clack.log.step("Add the following code to your ".concat(chalk_1.default.cyan(path.basename(filename)), " file:"));
|
|
873
|
+
// Intentionally logging directly to console here so that the code can be copied/pasted directly
|
|
874
|
+
// eslint-disable-next-line no-console
|
|
875
|
+
console.log("\n".concat(codeSnippet));
|
|
876
|
+
return [4 /*yield*/, abortIfCancelled(clack.select({
|
|
877
|
+
message: 'Did you apply the snippet above?',
|
|
878
|
+
options: [{ label: 'Yes, continue!', value: true }],
|
|
879
|
+
initialValue: true,
|
|
880
|
+
}))];
|
|
881
|
+
case 1:
|
|
882
|
+
_a.sent();
|
|
883
|
+
return [2 /*return*/];
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
exports.showCopyPasteInstructions = showCopyPasteInstructions;
|
|
889
|
+
/**
|
|
890
|
+
* Creates a new config file with the given @param filepath and @param codeSnippet.
|
|
891
|
+
*
|
|
892
|
+
* Use this function to create a new config file for users. This is useful
|
|
893
|
+
* when users answered that they don't yet have a config file for a tool.
|
|
894
|
+
*
|
|
895
|
+
* (This doesn't mean that they don't yet have some other way of configuring
|
|
896
|
+
* their tool but we can leave it up to them to figure out how to merge configs
|
|
897
|
+
* here.)
|
|
898
|
+
*
|
|
899
|
+
* @param filepath absolute path to the new config file
|
|
900
|
+
* @param codeSnippet the snippet to be inserted into the file
|
|
901
|
+
* @param moreInformation (optional) the message to be printed after the file was created
|
|
902
|
+
* For example, this can be a link to more information about configuring the tool.
|
|
903
|
+
*
|
|
904
|
+
* @returns true on sucess, false otherwise
|
|
905
|
+
*/
|
|
906
|
+
function createNewConfigFile(filepath, codeSnippet, moreInformation) {
|
|
907
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
908
|
+
var prettyFilename, e_3;
|
|
909
|
+
return __generator(this, function (_a) {
|
|
910
|
+
switch (_a.label) {
|
|
911
|
+
case 0:
|
|
912
|
+
if (!path.isAbsolute(filepath)) {
|
|
913
|
+
(0, debug_1.debug)("createNewConfigFile: filepath is not absolute: ".concat(filepath));
|
|
914
|
+
return [2 /*return*/, false];
|
|
915
|
+
}
|
|
916
|
+
prettyFilename = chalk_1.default.cyan(path.relative(process.cwd(), filepath));
|
|
917
|
+
_a.label = 1;
|
|
918
|
+
case 1:
|
|
919
|
+
_a.trys.push([1, 3, , 4]);
|
|
920
|
+
return [4 /*yield*/, fs.promises.writeFile(filepath, codeSnippet)];
|
|
921
|
+
case 2:
|
|
922
|
+
_a.sent();
|
|
923
|
+
clack.log.success("Added new ".concat(prettyFilename, " file."));
|
|
924
|
+
if (moreInformation) {
|
|
925
|
+
clack.log.info(chalk_1.default.gray(moreInformation));
|
|
926
|
+
}
|
|
927
|
+
return [2 /*return*/, true];
|
|
928
|
+
case 3:
|
|
929
|
+
e_3 = _a.sent();
|
|
930
|
+
(0, debug_1.debug)(e_3);
|
|
931
|
+
clack.log.warn("Could not create a new ".concat(prettyFilename, " file. Please create one manually and follow the instructions below."));
|
|
932
|
+
return [3 /*break*/, 4];
|
|
933
|
+
case 4: return [2 /*return*/, false];
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
exports.createNewConfigFile = createNewConfigFile;
|
|
782
939
|
//# sourceMappingURL=clack-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clack-utils.js","sourceRoot":"","sources":["../../../src/utils/clack-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport axios from 'axios';\nimport chalk from 'chalk';\nimport * as childProcess from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { setInterval } from 'timers';\nimport { URL } from 'url';\nimport * as Sentry from '@sentry/node';\nimport { hasPackageInstalled, PackageDotJson } from './package-json';\nimport { SentryProjectData, WizardOptions } from './types';\nimport { traceStep } from '../telemetry';\nimport {\n detectPackageManger,\n PackageManager,\n installPackageWithPackageManager,\n packageManagers,\n} from './package-manager';\n\nconst opn = require('opn') as (\n url: string,\n) => Promise<childProcess.ChildProcess>;\n\nexport const SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';\nexport const SENTRY_CLI_RC_FILE = '.sentryclirc';\nexport const SENTRY_PROPERTIES_FILE = 'sentry.properties';\n\nconst SAAS_URL = 'https://sentry.io/';\n\ninterface WizardProjectData {\n apiKeys: {\n token: string;\n };\n projects: SentryProjectData[];\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n}\n\nexport const sourceMapsCliSetupConfig: CliSetupConfig = {\n filename: SENTRY_CLI_RC_FILE,\n name: 'source maps',\n likelyAlreadyHasAuthToken: function (contents: string): boolean {\n return !!(contents.includes('[auth]') && contents.match(/token=./g));\n },\n tokenContent: function (authToken: string): string {\n return `[auth]\\ntoken=${authToken}`;\n },\n likelyAlreadyHasOrgAndProject: function (contents: string): boolean {\n return !!(\n contents.includes('[defaults]') &&\n contents.match(/org=./g) &&\n contents.match(/project=./g)\n );\n },\n orgAndProjContent: function (org: string, project: string): string {\n return `[defaults]\\norg=${org}\\nproject=${project}`;\n },\n};\n\nexport async function abort(message?: string, status?: number): Promise<never> {\n clack.outro(message ?? 'Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n sentryTransaction?.setStatus('aborted');\n sentryTransaction?.finish();\n const sentrySession = sentryHub.getScope().getSession();\n if (sentrySession) {\n sentrySession.status = status === 0 ? 'abnormal' : 'crashed';\n sentryHub.captureSession(true);\n }\n await Sentry.flush(3000);\n return process.exit(status ?? 1);\n}\n\nexport async function abortIfCancelled<T>(\n input: T | Promise<T>,\n): Promise<Exclude<T, symbol>> {\n if (clack.isCancel(await input)) {\n clack.cancel('Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n sentryTransaction?.setStatus('cancelled');\n sentryTransaction?.finish();\n sentryHub.captureSession(true);\n await Sentry.flush(3000);\n process.exit(0);\n } else {\n return input as Exclude<T, symbol>;\n }\n}\n\nexport function printWelcome(options: {\n wizardName: string;\n promoCode?: string;\n message?: string;\n telemetryEnabled?: boolean;\n}): void {\n let wizardPackage: { version?: string } = {};\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wizardPackage = require(path.join(\n path.dirname(require.resolve('@sentry/wizard')),\n '..',\n 'package.json',\n ));\n } catch {\n // We don't need to have this\n }\n\n // eslint-disable-next-line no-console\n console.log('');\n clack.intro(chalk.inverse(` ${options.wizardName} `));\n\n let welcomeText =\n options.message ||\n 'This Wizard will help you set up Sentry for your application.\\nThank you for using Sentry :)';\n\n if (options.promoCode) {\n welcomeText += `\\n\\nUsing promo-code: ${options.promoCode}`;\n }\n\n if (wizardPackage.version) {\n welcomeText += `\\n\\nVersion: ${wizardPackage.version}`;\n }\n\n if (options.telemetryEnabled) {\n welcomeText += `\\n\\nYou are using the Sentry Wizard with telemetry enabled. This helps us improve the Wizard.\\nYou can disable it at any time by running \\`sentry-wizard --disable-telemetry\\`.`;\n }\n\n clack.note(welcomeText);\n}\n\nexport async function confirmContinueEvenThoughNoGitRepo(): Promise<void> {\n try {\n childProcess.execSync('git rev-parse --is-inside-work-tree', {\n stdio: 'ignore',\n });\n } catch {\n const continueWithoutGit = await abortIfCancelled(\n clack.confirm({\n message:\n 'You are not inside a git repository. The wizard will create and update files. Do you still want to continue?',\n }),\n );\n\n Sentry.setTag('continue-without-git', continueWithoutGit);\n\n if (!continueWithoutGit) {\n await abort(undefined, 0);\n }\n }\n}\n\nexport async function askToInstallSentryCLI(): Promise<boolean> {\n return await abortIfCancelled(\n clack.confirm({\n message:\n \"You don't have Sentry CLI installed. Do you want to install it?\",\n }),\n );\n}\n\nexport async function askForItemSelection(\n items: string[],\n message: string,\n): Promise<{ value: string; index: number }> {\n const selection: { value: string; index: number } | symbol =\n await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: message,\n options: items.map((item, index) => {\n return {\n value: { value: item, index: index },\n label: item,\n };\n }),\n }),\n );\n\n return selection;\n}\n\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n askBeforeUpdating = true,\n}: {\n packageName: string;\n alreadyInstalled: boolean;\n askBeforeUpdating?: boolean;\n}): Promise<void> {\n if (alreadyInstalled && askBeforeUpdating) {\n const shouldUpdatePackage = await abortIfCancelled(\n clack.confirm({\n message: `The ${chalk.bold.cyan(\n packageName,\n )} package is already installed. Do you want to update it to the latest version?`,\n }),\n );\n\n if (!shouldUpdatePackage) {\n return;\n }\n }\n\n const sdkInstallSpinner = clack.spinner();\n\n const packageManager = await getPackageManager();\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk.bold.cyan(\n packageName,\n )} with ${chalk.bold(packageManager.label)}.`,\n );\n\n try {\n await installPackageWithPackageManager(packageManager, packageName);\n } catch (e) {\n sdkInstallSpinner.stop('Installation failed.');\n clack.log.error(\n `${chalk.red(\n 'Encountered the following error during installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n 'If you think this issue is caused by the Sentry wizard, let us know here:\\nhttps://github.com/getsentry/sentry-wizard/issues',\n )}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(\n packageName,\n )} with ${chalk.bold(packageManager.label)}.`,\n );\n}\n\nasync function addOrgAndProjectToSentryCliRc(\n org: string,\n project: string,\n setupConfig: CliSetupConfig,\n): Promise<void> {\n const configContents = fs.readFileSync(\n path.join(process.cwd(), setupConfig.filename),\n 'utf8',\n );\n\n if (setupConfig.likelyAlreadyHasOrgAndProject(configContents)) {\n clack.log.warn(\n `${chalk.bold(\n setupConfig.filename,\n )} already has org and project. Will not add them.`,\n );\n } else {\n try {\n await fs.promises.appendFile(\n path.join(process.cwd(), setupConfig.filename),\n `\\n${setupConfig.orgAndProjContent(org, project)}\\n`,\n );\n } catch (e) {\n clack.log.warn(\n `${chalk.bold(\n setupConfig.filename,\n )} could not be updated with org and project.`,\n );\n }\n }\n}\n\nexport async function addSentryCliConfig(\n authToken: string,\n setupConfig: CliSetupConfig = sourceMapsCliSetupConfig,\n orgSlug?: string,\n projectSlug?: string,\n): Promise<void> {\n const configExists = fs.existsSync(\n path.join(process.cwd(), setupConfig.filename),\n );\n if (configExists) {\n const configContents = fs.readFileSync(\n path.join(process.cwd(), setupConfig.filename),\n 'utf8',\n );\n\n if (setupConfig.likelyAlreadyHasAuthToken(configContents)) {\n clack.log.warn(\n `${chalk.bold(\n setupConfig.filename,\n )} already has auth token. Will not add one.`,\n );\n } else {\n try {\n await fs.promises.writeFile(\n path.join(process.cwd(), setupConfig.filename),\n `${configContents}\\n${setupConfig.tokenContent(authToken)}\\n`,\n { encoding: 'utf8', flag: 'w' },\n );\n clack.log.success(\n chalk.greenBright(\n `Added auth token to ${chalk.bold(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n ),\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.bold(\n setupConfig.filename,\n )}. Uploading ${\n setupConfig.name\n } during build will likely not work locally.`,\n );\n }\n }\n } else {\n try {\n await fs.promises.writeFile(\n path.join(process.cwd(), setupConfig.filename),\n `${setupConfig.tokenContent(authToken)}\\n`,\n { encoding: 'utf8', flag: 'w' },\n );\n clack.log.success(\n chalk.greenBright(\n `Created ${chalk.bold(\n setupConfig.filename,\n )} with auth token for you to test uploading ${\n setupConfig.name\n } locally.`,\n ),\n );\n } catch {\n clack.log.warning(\n `Failed to create ${chalk.bold(\n setupConfig.filename,\n )} with auth token. Uploading ${\n setupConfig.name\n } during build will likely not work locally.`,\n );\n }\n }\n\n if (orgSlug && projectSlug) {\n await addOrgAndProjectToSentryCliRc(orgSlug, projectSlug, setupConfig);\n }\n\n await addAuthTokenFileToGitIgnore(setupConfig.filename);\n}\n\nexport async function addDotEnvSentryBuildPluginFile(\n authToken: string,\n): Promise<void> {\n const envVarContent = `# DO NOT commit this file to your repository!\n# The SENTRY_AUTH_TOKEN variable is picked up by the Sentry Build Plugin.\n# It's used for authentication when uploading source maps.\n# You can also set this env variable in your own \\`.env\\` files and remove this file.\nSENTRY_AUTH_TOKEN=\"${authToken}\"\n`;\n\n const dotEnvFilePath = path.join(process.cwd(), SENTRY_DOT_ENV_FILE);\n const dotEnvFileExists = fs.existsSync(dotEnvFilePath);\n\n if (dotEnvFileExists) {\n const dotEnvFileContent = fs.readFileSync(dotEnvFilePath, 'utf8');\n\n const hasAuthToken = !!dotEnvFileContent.match(\n /^\\s*SENTRY_AUTH_TOKEN\\s*=/g,\n );\n\n if (hasAuthToken) {\n clack.log.warn(\n `${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )} already has auth token. Will not add one.`,\n );\n } else {\n try {\n await fs.promises.writeFile(\n dotEnvFilePath,\n `${dotEnvFileContent}\\n${envVarContent}`,\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n clack.log.success(\n `Added auth token to ${chalk.bold(SENTRY_DOT_ENV_FILE)}`,\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )}. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n } else {\n try {\n await fs.promises.writeFile(dotEnvFilePath, envVarContent, {\n encoding: 'utf8',\n flag: 'w',\n });\n clack.log.success(\n `Created ${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )} with auth token for you to test source map uploading locally.`,\n );\n } catch {\n clack.log.warning(\n `Failed to create ${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )} with auth token. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n\n await addAuthTokenFileToGitIgnore(SENTRY_DOT_ENV_FILE);\n}\n\nasync function addAuthTokenFileToGitIgnore(filename: string): Promise<void> {\n //TODO: Add a check to see if the file is already ignored in .gitignore\n try {\n await fs.promises.appendFile(\n path.join(process.cwd(), '.gitignore'),\n `\\n# Sentry Auth Token\\n${filename}\\n`,\n { encoding: 'utf8' },\n );\n clack.log.success(\n chalk.greenBright(\n `Added ${chalk.bold(filename)} to ${chalk.bold('.gitignore')}.`,\n ),\n );\n } catch {\n clack.log.error(\n `Failed adding ${chalk.bold(filename)} to ${chalk.bold(\n '.gitignore',\n )}. Please add it manually!`,\n );\n }\n}\n\nexport async function ensurePackageIsInstalled(\n packageJson: PackageDotJson,\n packageId: string,\n packageName: string,\n) {\n if (!hasPackageInstalled(packageId, packageJson)) {\n const continueWithoutPackage = await abortIfCancelled(\n clack.confirm({\n message: `${packageName} does not seem to be installed. Do you still want to continue?`,\n initialValue: false,\n }),\n );\n\n if (!continueWithoutPackage) {\n await abort(undefined, 0);\n }\n }\n}\n\nexport async function getPackageDotJson(): Promise<PackageDotJson> {\n const packageJsonFileContents = await fs.promises\n .readFile(path.join(process.cwd(), 'package.json'), 'utf8')\n .catch(() => {\n clack.log.error(\n 'Could not find package.json. Make sure to run the wizard in the root of your app!',\n );\n return abort();\n });\n\n let packageJson: PackageDotJson | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch {\n clack.log.error(\n 'Unable to parse your package.json. Make sure it has a valid format!',\n );\n\n await abort();\n }\n\n return packageJson || {};\n}\n\nasync function getPackageManager(): Promise<PackageManager> {\n const detectedPackageManager = detectPackageManger();\n\n if (detectedPackageManager) {\n return detectedPackageManager;\n }\n\n const selectedPackageManager: PackageManager | symbol =\n await abortIfCancelled(\n clack.select({\n message: 'Please select your package manager.',\n options: packageManagers.map((packageManager) => ({\n value: packageManager,\n label: packageManager.label,\n })),\n }),\n );\n\n Sentry.setTag('package-manager', selectedPackageManager.name);\n\n return selectedPackageManager;\n}\n\nexport function isUsingTypeScript() {\n try {\n return fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));\n } catch {\n return false;\n }\n}\n\n/**\n * Checks if we already got project data from a previous wizard invocation.\n * If yes, this data is returned.\n * Otherwise, we start the login flow and ask the user to select a project.\n *\n * Use this function to get project data for the wizard.\n *\n * @param options wizard options\n * @param platform the platform of the wizard\n * @returns project data (org, project, token, url)\n */\nexport async function getOrAskForProjectData(\n options: WizardOptions,\n platform?:\n | 'javascript-nextjs'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android',\n): Promise<{\n sentryUrl: string;\n selfHosted: boolean;\n selectedProject: SentryProjectData;\n authToken: string;\n}> {\n if (options.preSelectedProject) {\n return {\n selfHosted: options.preSelectedProject.selfHosted,\n sentryUrl: options.url ?? SAAS_URL,\n authToken: options.preSelectedProject.authToken,\n selectedProject: options.preSelectedProject.project,\n };\n }\n const { url: sentryUrl, selfHosted } = await traceStep(\n 'ask-self-hosted',\n () => askForSelfHosted(options.url),\n );\n\n const { projects, apiKeys } = await traceStep('login', () =>\n askForWizardLogin({\n promoCode: options.promoCode,\n url: sentryUrl,\n platform: platform,\n }),\n );\n\n if (!projects || !projects.length) {\n clack.log.error(\n 'No projects found. Please create a project in Sentry and try again.',\n );\n Sentry.setTag('no-projects-found', true);\n await abort();\n }\n\n const selectedProject = await traceStep('select-project', () =>\n askForProjectSelection(projects),\n );\n\n return {\n sentryUrl,\n selfHosted,\n authToken: apiKeys.token,\n selectedProject,\n };\n}\n\n/**\n * Asks users if they are using SaaS or self-hosted Sentry and returns the validated URL.\n *\n * If users started the wizard with a --url arg, that URL is used as the default and we skip\n * the self-hosted question. However, the passed url is still validated and in case it's\n * invalid, users are asked to enter a new one until it is valid.\n *\n * @param urlFromArgs the url passed via the --url arg\n */\nasync function askForSelfHosted(urlFromArgs?: string): Promise<{\n url: string;\n selfHosted: boolean;\n}> {\n if (!urlFromArgs) {\n const choice: 'saas' | 'self-hosted' | symbol = await abortIfCancelled(\n clack.select({\n message: 'Are you using Sentry SaaS or self-hosted Sentry?',\n options: [\n { value: 'saas', label: 'Sentry SaaS (sentry.io)' },\n {\n value: 'self-hosted',\n label: 'Self-hosted/on-premise/single-tenant',\n },\n ],\n }),\n );\n\n if (choice === 'saas') {\n Sentry.setTag('url', SAAS_URL);\n Sentry.setTag('self-hosted', false);\n return { url: SAAS_URL, selfHosted: false };\n }\n }\n\n let validUrl: string | undefined;\n let tmpUrlFromArgs = urlFromArgs;\n\n while (validUrl === undefined) {\n const url =\n tmpUrlFromArgs ||\n (await abortIfCancelled(\n clack.text({\n message: `Please enter the URL of your ${\n urlFromArgs ? '' : 'self-hosted '\n }Sentry instance.`,\n placeholder: 'https://sentry.io/',\n }),\n ));\n tmpUrlFromArgs = undefined;\n\n try {\n validUrl = new URL(url).toString();\n\n // We assume everywhere else that the URL ends in a slash\n if (!validUrl.endsWith('/')) {\n validUrl += '/';\n }\n } catch {\n clack.log.error(\n 'Please enter a valid URL. (It should look something like \"https://sentry.mydomain.com/\")',\n );\n }\n }\n\n const isSelfHostedUrl = new URL(validUrl).host !== new URL(SAAS_URL).host;\n\n Sentry.setTag('url', validUrl);\n Sentry.setTag('self-hosted', isSelfHostedUrl);\n\n return { url: validUrl, selfHosted: true };\n}\n\nasync function askForWizardLogin(options: {\n url: string;\n promoCode?: string;\n platform?:\n | 'javascript-nextjs'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android';\n}): Promise<WizardProjectData> {\n Sentry.setTag('has-promo-code', !!options.promoCode);\n\n let hasSentryAccount = await clack.confirm({\n message: 'Do you already have a Sentry account?',\n });\n\n hasSentryAccount = await abortIfCancelled(hasSentryAccount);\n\n Sentry.setTag('already-has-sentry-account', hasSentryAccount);\n\n let wizardHash: string;\n try {\n wizardHash = (\n await axios.get<{ hash: string }>(`${options.url}api/0/wizard/`)\n ).data.hash;\n } catch {\n if (options.url !== SAAS_URL) {\n clack.log.error('Loading Wizard failed. Did you provide the right URL?');\n await abort(\n chalk.red(\n 'Please check your configuration and try again.\\n\\n Let us know if you think this is an issue with the wizard or Sentry: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n } else {\n clack.log.error('Loading Wizard failed.');\n await abort(\n chalk.red(\n 'Please try again in a few minutes and let us know if this issue persists: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n }\n }\n\n const loginUrl = new URL(\n `${options.url}account/settings/wizard/${wizardHash!}/`,\n );\n\n if (!hasSentryAccount) {\n loginUrl.searchParams.set('signup', '1');\n if (options.platform) {\n loginUrl.searchParams.set('project_platform', options.platform);\n }\n }\n\n if (options.promoCode) {\n loginUrl.searchParams.set('code', options.promoCode);\n }\n\n const urlToOpen = loginUrl.toString();\n clack.log.info(\n `${chalk.bold(\n `If the browser window didn't open automatically, please open the following link to ${\n hasSentryAccount ? 'log' : 'sign'\n } into Sentry:`,\n )}\\n\\n${chalk.cyan(urlToOpen)}`,\n );\n\n opn(urlToOpen).catch(() => {\n // opn throws in environments that don't have a browser (e.g. remote shells) so we just noop here\n });\n\n const loginSpinner = clack.spinner();\n\n loginSpinner.start('Waiting for you to log in using the link above');\n\n const data = await new Promise<WizardProjectData>((resolve) => {\n const pollingInterval = setInterval(() => {\n axios\n .get<WizardProjectData>(`${options.url}api/0/wizard/${wizardHash}/`, {\n headers: {\n 'Accept-Encoding': 'deflate',\n },\n })\n .then((result) => {\n resolve(result.data);\n clearTimeout(timeout);\n clearInterval(pollingInterval);\n void axios.delete(`${options.url}api/0/wizard/${wizardHash}/`);\n })\n .catch(() => {\n // noop - just try again\n });\n }, 500);\n\n const timeout = setTimeout(() => {\n clearInterval(pollingInterval);\n loginSpinner.stop(\n 'Login timed out. No worries - it happens to the best of us.',\n );\n\n Sentry.setTag('opened-wizard-link', false);\n void abort('Please restart the Wizard and log in to complete the setup.');\n }, 180_000);\n });\n\n loginSpinner.stop('Login complete.');\n Sentry.setTag('opened-wizard-link', true);\n\n return data;\n}\n\nasync function askForProjectSelection(\n projects: SentryProjectData[],\n): Promise<SentryProjectData> {\n const selection: SentryProjectData | symbol = await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: 'Select your Sentry project.',\n options: projects.map((project) => {\n return {\n value: project,\n label: `${project.organization.slug}/${project.slug}`,\n };\n }),\n }),\n );\n\n Sentry.setTag('project', selection.slug);\n Sentry.setTag('project-platform', selection.platform);\n Sentry.setUser({ id: selection.organization.slug });\n\n return selection;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"clack-utils.js","sourceRoot":"","sources":["../../../src/utils/clack-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport axios from 'axios';\nimport chalk from 'chalk';\nimport * as childProcess from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { setInterval } from 'timers';\nimport { URL } from 'url';\nimport * as Sentry from '@sentry/node';\nimport { hasPackageInstalled, PackageDotJson } from './package-json';\nimport { SentryProjectData, WizardOptions } from './types';\nimport { traceStep } from '../telemetry';\nimport {\n detectPackageManger,\n PackageManager,\n installPackageWithPackageManager,\n packageManagers,\n} from './package-manager';\nimport { debug } from './debug';\n\nconst opn = require('opn') as (\n url: string,\n) => Promise<childProcess.ChildProcess>;\n\nexport const SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';\nexport const SENTRY_CLI_RC_FILE = '.sentryclirc';\nexport const SENTRY_PROPERTIES_FILE = 'sentry.properties';\n\nconst SAAS_URL = 'https://sentry.io/';\n\ninterface WizardProjectData {\n apiKeys: {\n token: string;\n };\n projects: SentryProjectData[];\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n}\n\nexport const sourceMapsCliSetupConfig: CliSetupConfig = {\n filename: SENTRY_CLI_RC_FILE,\n name: 'source maps',\n likelyAlreadyHasAuthToken: function (contents: string): boolean {\n return !!(contents.includes('[auth]') && contents.match(/token=./g));\n },\n tokenContent: function (authToken: string): string {\n return `[auth]\\ntoken=${authToken}`;\n },\n likelyAlreadyHasOrgAndProject: function (contents: string): boolean {\n return !!(\n contents.includes('[defaults]') &&\n contents.match(/org=./g) &&\n contents.match(/project=./g)\n );\n },\n orgAndProjContent: function (org: string, project: string): string {\n return `[defaults]\\norg=${org}\\nproject=${project}`;\n },\n};\n\nexport async function abort(message?: string, status?: number): Promise<never> {\n clack.outro(message ?? 'Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n sentryTransaction?.setStatus('aborted');\n sentryTransaction?.finish();\n const sentrySession = sentryHub.getScope().getSession();\n if (sentrySession) {\n sentrySession.status = status === 0 ? 'abnormal' : 'crashed';\n sentryHub.captureSession(true);\n }\n await Sentry.flush(3000);\n return process.exit(status ?? 1);\n}\n\nexport async function abortIfCancelled<T>(\n input: T | Promise<T>,\n): Promise<Exclude<T, symbol>> {\n if (clack.isCancel(await input)) {\n clack.cancel('Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n sentryTransaction?.setStatus('cancelled');\n sentryTransaction?.finish();\n sentryHub.captureSession(true);\n await Sentry.flush(3000);\n process.exit(0);\n } else {\n return input as Exclude<T, symbol>;\n }\n}\n\nexport function printWelcome(options: {\n wizardName: string;\n promoCode?: string;\n message?: string;\n telemetryEnabled?: boolean;\n}): void {\n let wizardPackage: { version?: string } = {};\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wizardPackage = require(path.join(\n path.dirname(require.resolve('@sentry/wizard')),\n '..',\n 'package.json',\n ));\n } catch {\n // We don't need to have this\n }\n\n // eslint-disable-next-line no-console\n console.log('');\n clack.intro(chalk.inverse(` ${options.wizardName} `));\n\n let welcomeText =\n options.message ||\n 'This Wizard will help you set up Sentry for your application.\\nThank you for using Sentry :)';\n\n if (options.promoCode) {\n welcomeText += `\\n\\nUsing promo-code: ${options.promoCode}`;\n }\n\n if (wizardPackage.version) {\n welcomeText += `\\n\\nVersion: ${wizardPackage.version}`;\n }\n\n if (options.telemetryEnabled) {\n welcomeText += `\\n\\nYou are using the Sentry Wizard with telemetry enabled. This helps us improve the Wizard.\\nYou can disable it at any time by running \\`sentry-wizard --disable-telemetry\\`.`;\n }\n\n clack.note(welcomeText);\n}\n\nexport async function confirmContinueEvenThoughNoGitRepo(): Promise<void> {\n try {\n childProcess.execSync('git rev-parse --is-inside-work-tree', {\n stdio: 'ignore',\n });\n } catch {\n const continueWithoutGit = await abortIfCancelled(\n clack.confirm({\n message:\n 'You are not inside a git repository. The wizard will create and update files. Do you still want to continue?',\n }),\n );\n\n Sentry.setTag('continue-without-git', continueWithoutGit);\n\n if (!continueWithoutGit) {\n await abort(undefined, 0);\n }\n }\n}\n\nexport async function askToInstallSentryCLI(): Promise<boolean> {\n return await abortIfCancelled(\n clack.confirm({\n message:\n \"You don't have Sentry CLI installed. Do you want to install it?\",\n }),\n );\n}\n\nexport async function askForItemSelection(\n items: string[],\n message: string,\n): Promise<{ value: string; index: number }> {\n const selection: { value: string; index: number } | symbol =\n await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: message,\n options: items.map((item, index) => {\n return {\n value: { value: item, index: index },\n label: item,\n };\n }),\n }),\n );\n\n return selection;\n}\n\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n askBeforeUpdating = true,\n}: {\n packageName: string;\n alreadyInstalled: boolean;\n askBeforeUpdating?: boolean;\n}): Promise<void> {\n if (alreadyInstalled && askBeforeUpdating) {\n const shouldUpdatePackage = await abortIfCancelled(\n clack.confirm({\n message: `The ${chalk.bold.cyan(\n packageName,\n )} package is already installed. Do you want to update it to the latest version?`,\n }),\n );\n\n if (!shouldUpdatePackage) {\n return;\n }\n }\n\n const sdkInstallSpinner = clack.spinner();\n\n const packageManager = await getPackageManager();\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk.bold.cyan(\n packageName,\n )} with ${chalk.bold(packageManager.label)}.`,\n );\n\n try {\n await installPackageWithPackageManager(packageManager, packageName);\n } catch (e) {\n sdkInstallSpinner.stop('Installation failed.');\n clack.log.error(\n `${chalk.red(\n 'Encountered the following error during installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n 'If you think this issue is caused by the Sentry wizard, let us know here:\\nhttps://github.com/getsentry/sentry-wizard/issues',\n )}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(\n packageName,\n )} with ${chalk.bold(packageManager.label)}.`,\n );\n}\n\nasync function addOrgAndProjectToSentryCliRc(\n org: string,\n project: string,\n setupConfig: CliSetupConfig,\n): Promise<void> {\n const configContents = fs.readFileSync(\n path.join(process.cwd(), setupConfig.filename),\n 'utf8',\n );\n\n if (setupConfig.likelyAlreadyHasOrgAndProject(configContents)) {\n clack.log.warn(\n `${chalk.bold(\n setupConfig.filename,\n )} already has org and project. Will not add them.`,\n );\n } else {\n try {\n await fs.promises.appendFile(\n path.join(process.cwd(), setupConfig.filename),\n `\\n${setupConfig.orgAndProjContent(org, project)}\\n`,\n );\n } catch (e) {\n clack.log.warn(\n `${chalk.bold(\n setupConfig.filename,\n )} could not be updated with org and project.`,\n );\n }\n }\n}\n\nexport async function addSentryCliConfig(\n authToken: string,\n setupConfig: CliSetupConfig = sourceMapsCliSetupConfig,\n orgSlug?: string,\n projectSlug?: string,\n): Promise<void> {\n const configExists = fs.existsSync(\n path.join(process.cwd(), setupConfig.filename),\n );\n if (configExists) {\n const configContents = fs.readFileSync(\n path.join(process.cwd(), setupConfig.filename),\n 'utf8',\n );\n\n if (setupConfig.likelyAlreadyHasAuthToken(configContents)) {\n clack.log.warn(\n `${chalk.bold(\n setupConfig.filename,\n )} already has auth token. Will not add one.`,\n );\n } else {\n try {\n await fs.promises.writeFile(\n path.join(process.cwd(), setupConfig.filename),\n `${configContents}\\n${setupConfig.tokenContent(authToken)}\\n`,\n { encoding: 'utf8', flag: 'w' },\n );\n clack.log.success(\n chalk.greenBright(\n `Added auth token to ${chalk.bold(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n ),\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.bold(\n setupConfig.filename,\n )}. Uploading ${\n setupConfig.name\n } during build will likely not work locally.`,\n );\n }\n }\n } else {\n try {\n await fs.promises.writeFile(\n path.join(process.cwd(), setupConfig.filename),\n `${setupConfig.tokenContent(authToken)}\\n`,\n { encoding: 'utf8', flag: 'w' },\n );\n clack.log.success(\n chalk.greenBright(\n `Created ${chalk.bold(\n setupConfig.filename,\n )} with auth token for you to test uploading ${\n setupConfig.name\n } locally.`,\n ),\n );\n } catch {\n clack.log.warning(\n `Failed to create ${chalk.bold(\n setupConfig.filename,\n )} with auth token. Uploading ${\n setupConfig.name\n } during build will likely not work locally.`,\n );\n }\n }\n\n if (orgSlug && projectSlug) {\n await addOrgAndProjectToSentryCliRc(orgSlug, projectSlug, setupConfig);\n }\n\n await addAuthTokenFileToGitIgnore(setupConfig.filename);\n}\n\nexport async function addDotEnvSentryBuildPluginFile(\n authToken: string,\n): Promise<void> {\n const envVarContent = `# DO NOT commit this file to your repository!\n# The SENTRY_AUTH_TOKEN variable is picked up by the Sentry Build Plugin.\n# It's used for authentication when uploading source maps.\n# You can also set this env variable in your own \\`.env\\` files and remove this file.\nSENTRY_AUTH_TOKEN=\"${authToken}\"\n`;\n\n const dotEnvFilePath = path.join(process.cwd(), SENTRY_DOT_ENV_FILE);\n const dotEnvFileExists = fs.existsSync(dotEnvFilePath);\n\n if (dotEnvFileExists) {\n const dotEnvFileContent = fs.readFileSync(dotEnvFilePath, 'utf8');\n\n const hasAuthToken = !!dotEnvFileContent.match(\n /^\\s*SENTRY_AUTH_TOKEN\\s*=/g,\n );\n\n if (hasAuthToken) {\n clack.log.warn(\n `${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )} already has auth token. Will not add one.`,\n );\n } else {\n try {\n await fs.promises.writeFile(\n dotEnvFilePath,\n `${dotEnvFileContent}\\n${envVarContent}`,\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n clack.log.success(\n `Added auth token to ${chalk.bold(SENTRY_DOT_ENV_FILE)}`,\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )}. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n } else {\n try {\n await fs.promises.writeFile(dotEnvFilePath, envVarContent, {\n encoding: 'utf8',\n flag: 'w',\n });\n clack.log.success(\n `Created ${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )} with auth token for you to test source map uploading locally.`,\n );\n } catch {\n clack.log.warning(\n `Failed to create ${chalk.bold(\n SENTRY_DOT_ENV_FILE,\n )} with auth token. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n\n await addAuthTokenFileToGitIgnore(SENTRY_DOT_ENV_FILE);\n}\n\nasync function addAuthTokenFileToGitIgnore(filename: string): Promise<void> {\n //TODO: Add a check to see if the file is already ignored in .gitignore\n try {\n await fs.promises.appendFile(\n path.join(process.cwd(), '.gitignore'),\n `\\n# Sentry Auth Token\\n${filename}\\n`,\n { encoding: 'utf8' },\n );\n clack.log.success(\n chalk.greenBright(\n `Added ${chalk.bold(filename)} to ${chalk.bold('.gitignore')}.`,\n ),\n );\n } catch {\n clack.log.error(\n `Failed adding ${chalk.bold(filename)} to ${chalk.bold(\n '.gitignore',\n )}. Please add it manually!`,\n );\n }\n}\n\nexport async function ensurePackageIsInstalled(\n packageJson: PackageDotJson,\n packageId: string,\n packageName: string,\n) {\n if (!hasPackageInstalled(packageId, packageJson)) {\n const continueWithoutPackage = await abortIfCancelled(\n clack.confirm({\n message: `${packageName} does not seem to be installed. Do you still want to continue?`,\n initialValue: false,\n }),\n );\n\n if (!continueWithoutPackage) {\n await abort(undefined, 0);\n }\n }\n}\n\nexport async function getPackageDotJson(): Promise<PackageDotJson> {\n const packageJsonFileContents = await fs.promises\n .readFile(path.join(process.cwd(), 'package.json'), 'utf8')\n .catch(() => {\n clack.log.error(\n 'Could not find package.json. Make sure to run the wizard in the root of your app!',\n );\n return abort();\n });\n\n let packageJson: PackageDotJson | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch {\n clack.log.error(\n 'Unable to parse your package.json. Make sure it has a valid format!',\n );\n\n await abort();\n }\n\n return packageJson || {};\n}\n\nasync function getPackageManager(): Promise<PackageManager> {\n const detectedPackageManager = detectPackageManger();\n\n if (detectedPackageManager) {\n return detectedPackageManager;\n }\n\n const selectedPackageManager: PackageManager | symbol =\n await abortIfCancelled(\n clack.select({\n message: 'Please select your package manager.',\n options: packageManagers.map((packageManager) => ({\n value: packageManager,\n label: packageManager.label,\n })),\n }),\n );\n\n Sentry.setTag('package-manager', selectedPackageManager.name);\n\n return selectedPackageManager;\n}\n\nexport function isUsingTypeScript() {\n try {\n return fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));\n } catch {\n return false;\n }\n}\n\n/**\n * Checks if we already got project data from a previous wizard invocation.\n * If yes, this data is returned.\n * Otherwise, we start the login flow and ask the user to select a project.\n *\n * Use this function to get project data for the wizard.\n *\n * @param options wizard options\n * @param platform the platform of the wizard\n * @returns project data (org, project, token, url)\n */\nexport async function getOrAskForProjectData(\n options: WizardOptions,\n platform?:\n | 'javascript-nextjs'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android',\n): Promise<{\n sentryUrl: string;\n selfHosted: boolean;\n selectedProject: SentryProjectData;\n authToken: string;\n}> {\n if (options.preSelectedProject) {\n return {\n selfHosted: options.preSelectedProject.selfHosted,\n sentryUrl: options.url ?? SAAS_URL,\n authToken: options.preSelectedProject.authToken,\n selectedProject: options.preSelectedProject.project,\n };\n }\n const { url: sentryUrl, selfHosted } = await traceStep(\n 'ask-self-hosted',\n () => askForSelfHosted(options.url),\n );\n\n const { projects, apiKeys } = await traceStep('login', () =>\n askForWizardLogin({\n promoCode: options.promoCode,\n url: sentryUrl,\n platform: platform,\n }),\n );\n\n if (!projects || !projects.length) {\n clack.log.error(\n 'No projects found. Please create a project in Sentry and try again.',\n );\n Sentry.setTag('no-projects-found', true);\n await abort();\n }\n\n const selectedProject = await traceStep('select-project', () =>\n askForProjectSelection(projects),\n );\n\n return {\n sentryUrl,\n selfHosted,\n authToken: apiKeys.token,\n selectedProject,\n };\n}\n\n/**\n * Asks users if they are using SaaS or self-hosted Sentry and returns the validated URL.\n *\n * If users started the wizard with a --url arg, that URL is used as the default and we skip\n * the self-hosted question. However, the passed url is still validated and in case it's\n * invalid, users are asked to enter a new one until it is valid.\n *\n * @param urlFromArgs the url passed via the --url arg\n */\nasync function askForSelfHosted(urlFromArgs?: string): Promise<{\n url: string;\n selfHosted: boolean;\n}> {\n if (!urlFromArgs) {\n const choice: 'saas' | 'self-hosted' | symbol = await abortIfCancelled(\n clack.select({\n message: 'Are you using Sentry SaaS or self-hosted Sentry?',\n options: [\n { value: 'saas', label: 'Sentry SaaS (sentry.io)' },\n {\n value: 'self-hosted',\n label: 'Self-hosted/on-premise/single-tenant',\n },\n ],\n }),\n );\n\n if (choice === 'saas') {\n Sentry.setTag('url', SAAS_URL);\n Sentry.setTag('self-hosted', false);\n return { url: SAAS_URL, selfHosted: false };\n }\n }\n\n let validUrl: string | undefined;\n let tmpUrlFromArgs = urlFromArgs;\n\n while (validUrl === undefined) {\n const url =\n tmpUrlFromArgs ||\n (await abortIfCancelled(\n clack.text({\n message: `Please enter the URL of your ${\n urlFromArgs ? '' : 'self-hosted '\n }Sentry instance.`,\n placeholder: 'https://sentry.io/',\n }),\n ));\n tmpUrlFromArgs = undefined;\n\n try {\n validUrl = new URL(url).toString();\n\n // We assume everywhere else that the URL ends in a slash\n if (!validUrl.endsWith('/')) {\n validUrl += '/';\n }\n } catch {\n clack.log.error(\n 'Please enter a valid URL. (It should look something like \"https://sentry.mydomain.com/\")',\n );\n }\n }\n\n const isSelfHostedUrl = new URL(validUrl).host !== new URL(SAAS_URL).host;\n\n Sentry.setTag('url', validUrl);\n Sentry.setTag('self-hosted', isSelfHostedUrl);\n\n return { url: validUrl, selfHosted: true };\n}\n\nasync function askForWizardLogin(options: {\n url: string;\n promoCode?: string;\n platform?:\n | 'javascript-nextjs'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android';\n}): Promise<WizardProjectData> {\n Sentry.setTag('has-promo-code', !!options.promoCode);\n\n let hasSentryAccount = await clack.confirm({\n message: 'Do you already have a Sentry account?',\n });\n\n hasSentryAccount = await abortIfCancelled(hasSentryAccount);\n\n Sentry.setTag('already-has-sentry-account', hasSentryAccount);\n\n let wizardHash: string;\n try {\n wizardHash = (\n await axios.get<{ hash: string }>(`${options.url}api/0/wizard/`)\n ).data.hash;\n } catch {\n if (options.url !== SAAS_URL) {\n clack.log.error('Loading Wizard failed. Did you provide the right URL?');\n await abort(\n chalk.red(\n 'Please check your configuration and try again.\\n\\n Let us know if you think this is an issue with the wizard or Sentry: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n } else {\n clack.log.error('Loading Wizard failed.');\n await abort(\n chalk.red(\n 'Please try again in a few minutes and let us know if this issue persists: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n }\n }\n\n const loginUrl = new URL(\n `${options.url}account/settings/wizard/${wizardHash!}/`,\n );\n\n if (!hasSentryAccount) {\n loginUrl.searchParams.set('signup', '1');\n if (options.platform) {\n loginUrl.searchParams.set('project_platform', options.platform);\n }\n }\n\n if (options.promoCode) {\n loginUrl.searchParams.set('code', options.promoCode);\n }\n\n const urlToOpen = loginUrl.toString();\n clack.log.info(\n `${chalk.bold(\n `If the browser window didn't open automatically, please open the following link to ${\n hasSentryAccount ? 'log' : 'sign'\n } into Sentry:`,\n )}\\n\\n${chalk.cyan(urlToOpen)}`,\n );\n\n opn(urlToOpen).catch(() => {\n // opn throws in environments that don't have a browser (e.g. remote shells) so we just noop here\n });\n\n const loginSpinner = clack.spinner();\n\n loginSpinner.start('Waiting for you to log in using the link above');\n\n const data = await new Promise<WizardProjectData>((resolve) => {\n const pollingInterval = setInterval(() => {\n axios\n .get<WizardProjectData>(`${options.url}api/0/wizard/${wizardHash}/`, {\n headers: {\n 'Accept-Encoding': 'deflate',\n },\n })\n .then((result) => {\n resolve(result.data);\n clearTimeout(timeout);\n clearInterval(pollingInterval);\n void axios.delete(`${options.url}api/0/wizard/${wizardHash}/`);\n })\n .catch(() => {\n // noop - just try again\n });\n }, 500);\n\n const timeout = setTimeout(() => {\n clearInterval(pollingInterval);\n loginSpinner.stop(\n 'Login timed out. No worries - it happens to the best of us.',\n );\n\n Sentry.setTag('opened-wizard-link', false);\n void abort('Please restart the Wizard and log in to complete the setup.');\n }, 180_000);\n });\n\n loginSpinner.stop('Login complete.');\n Sentry.setTag('opened-wizard-link', true);\n\n return data;\n}\n\nasync function askForProjectSelection(\n projects: SentryProjectData[],\n): Promise<SentryProjectData> {\n const label = (project: SentryProjectData): string => {\n return `${project.organization.slug}/${project.slug}`;\n };\n const sortedProjects = [...projects];\n sortedProjects.sort((a: SentryProjectData, b: SentryProjectData) => {\n return label(a).localeCompare(label(b));\n });\n const selection: SentryProjectData | symbol = await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: 'Select your Sentry project.',\n options: sortedProjects.map((project) => {\n return {\n value: project,\n label: label(project),\n };\n }),\n }),\n );\n\n Sentry.setTag('project', selection.slug);\n Sentry.setTag('project-platform', selection.platform);\n Sentry.setUser({ id: selection.organization.slug });\n\n return selection;\n}\n\n/**\n * Asks users if they have a config file for @param tool (e.g. Vite).\n * If yes, asks users to specify the path to their config file.\n *\n * Use this helper function as a fallback mechanism if the lookup for\n * a config file with its most usual location/name fails.\n *\n * @param toolName Name of the tool for which we're looking for the config file\n * @param configFileName Name of the most common config file name (e.g. vite.config.js)\n *\n * @returns a user path to the config file or undefined if the user doesn't have a config file\n */\nexport async function askForToolConfigPath(\n toolName: string,\n configFileName: string,\n): Promise<string | undefined> {\n const hasConfig = await abortIfCancelled(\n clack.confirm({\n message: `Do you have a ${toolName} config file (e.g. ${chalk.cyan(\n configFileName,\n )}?`,\n initialValue: true,\n }),\n );\n\n if (!hasConfig) {\n return undefined;\n }\n\n return await abortIfCancelled(\n clack.text({\n message: `Please enter the path to your ${toolName} config file:`,\n placeholder: path.join('.', configFileName),\n validate: (value) => {\n if (!value) {\n return 'Please enter a path.';\n }\n\n try {\n fs.accessSync(value);\n } catch {\n return 'Could not access the file at this path.';\n }\n },\n }),\n );\n}\n\n/**\n * Prints copy/paste-able instructions to the console.\n * Afterwards asks the user if they added the code snippet to their file.\n *\n * While there's no point in providing a \"no\" answer here, it gives users time to fulfill the\n * task before the wizard continues with additional steps.\n *\n * Use this function if you want to show users instructions on how to add/modify\n * code in their file. This is helpful if automatic insertion failed or is not possible/feasible.\n *\n * @param filename the name of the file to which the code snippet should be applied.\n * If a path is provided, only the filename will be used.\n * @param codeSnippet the snippet to be printed.\n * Make sure to follow the diff-like format of highlighting lines that require changes\n * and showing unchanged lines in gray.\n *\n * TODO: Link to wizard spec (develop) once it is live\n * TODO: refactor copy paste instructions across different wizards to use this function.\n * this might require adding a custom message parameter to the function\n */\nexport async function showCopyPasteInstructions(\n filename: string,\n codeSnippet: string,\n): Promise<void> {\n clack.log.step(\n `Add the following code to your ${chalk.cyan(\n path.basename(filename),\n )} file:`,\n );\n\n // Intentionally logging directly to console here so that the code can be copied/pasted directly\n // eslint-disable-next-line no-console\n console.log(`\\n${codeSnippet}`);\n\n await abortIfCancelled(\n clack.select({\n message: 'Did you apply the snippet above?',\n options: [{ label: 'Yes, continue!', value: true }],\n initialValue: true,\n }),\n );\n}\n\n/**\n * Creates a new config file with the given @param filepath and @param codeSnippet.\n *\n * Use this function to create a new config file for users. This is useful\n * when users answered that they don't yet have a config file for a tool.\n *\n * (This doesn't mean that they don't yet have some other way of configuring\n * their tool but we can leave it up to them to figure out how to merge configs\n * here.)\n *\n * @param filepath absolute path to the new config file\n * @param codeSnippet the snippet to be inserted into the file\n * @param moreInformation (optional) the message to be printed after the file was created\n * For example, this can be a link to more information about configuring the tool.\n *\n * @returns true on sucess, false otherwise\n */\nexport async function createNewConfigFile(\n filepath: string,\n codeSnippet: string,\n moreInformation?: string,\n): Promise<boolean> {\n if (!path.isAbsolute(filepath)) {\n debug(`createNewConfigFile: filepath is not absolute: ${filepath}`);\n return false;\n }\n\n const prettyFilename = chalk.cyan(path.relative(process.cwd(), filepath));\n\n try {\n await fs.promises.writeFile(filepath, codeSnippet);\n\n clack.log.success(`Added new ${prettyFilename} file.`);\n\n if (moreInformation) {\n clack.log.info(chalk.gray(moreInformation));\n }\n\n return true;\n } catch (e) {\n debug(e);\n clack.log.warn(\n `Could not create a new ${prettyFilename} file. Please create one manually and follow the instructions below.`,\n );\n }\n\n return false;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//@ts-ignore
|
|
4
|
+
var code_tools_1 = require("../../src/android/code-tools");
|
|
5
|
+
describe('code-tools', function () {
|
|
6
|
+
describe('getLastImportLineLocation', function () {
|
|
7
|
+
it('returns proper line index', function () {
|
|
8
|
+
var code = "import a.b.c;\n" + "//<insert-location>\n" + "class X {}";
|
|
9
|
+
expect((0, code_tools_1.getLastImportLineLocation)(code)).toBe(code.indexOf('//<insert-location>'));
|
|
10
|
+
});
|
|
11
|
+
it('returns proper line index when static import is used', function () {
|
|
12
|
+
var code = "import static a.b.c;\n" + "//<insert-location>\n" + "class X {}";
|
|
13
|
+
expect((0, code_tools_1.getLastImportLineLocation)(code)).toBe(code.indexOf('//<insert-location>'));
|
|
14
|
+
});
|
|
15
|
+
it('returns proper line index when wildcard import is used', function () {
|
|
16
|
+
var code = "import a.b.*\n" + "//<insert-location>\n" + "class X {}";
|
|
17
|
+
expect((0, code_tools_1.getLastImportLineLocation)(code)).toBe(code.indexOf('//<insert-location>'));
|
|
18
|
+
});
|
|
19
|
+
it('returns proper line index when alias import is used', function () {
|
|
20
|
+
var code = "import static a.b.c as d\n" + "//<insert-location>\n" + "class X {}";
|
|
21
|
+
expect((0, code_tools_1.getLastImportLineLocation)(code)).toBe(code.indexOf('//<insert-location>'));
|
|
22
|
+
});
|
|
23
|
+
it('returns proper line index when multiple imports are present', function () {
|
|
24
|
+
var code = "import static a.b.c as d\n" +
|
|
25
|
+
"import a.b.*\n" +
|
|
26
|
+
"import static a.b.c;\n" +
|
|
27
|
+
"import a.b.c;\n" +
|
|
28
|
+
"//<insert-location>\n" +
|
|
29
|
+
"class X {}";
|
|
30
|
+
expect((0, code_tools_1.getLastImportLineLocation)(code)).toBe(code.indexOf('//<insert-location>'));
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=code-tools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-tools.test.js","sourceRoot":"","sources":["../../../test/android/code-tools.test.ts"],"names":[],"mappings":";;AAAA,YAAY;AACZ,2DAAyE;AAEzE,QAAQ,CAAC,YAAY,EAAE;IACrB,QAAQ,CAAC,2BAA2B,EAAE;QACpC,EAAE,CAAC,2BAA2B,EAAE;YAC9B,IAAM,IAAI,GAAG,iBAAiB,GAAG,uBAAuB,GAAG,YAAY,CAAC;YACxE,MAAM,CAAC,IAAA,sCAAyB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC1C,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE;YACzD,IAAM,IAAI,GACR,wBAAwB,GAAG,uBAAuB,GAAG,YAAY,CAAC;YACpE,MAAM,CAAC,IAAA,sCAAyB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC1C,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE;YAC3D,IAAM,IAAI,GAAG,gBAAgB,GAAG,uBAAuB,GAAG,YAAY,CAAC;YACvE,MAAM,CAAC,IAAA,sCAAyB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC1C,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE;YACxD,IAAM,IAAI,GACR,4BAA4B,GAAG,uBAAuB,GAAG,YAAY,CAAC;YACxE,MAAM,CAAC,IAAA,sCAAyB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC1C,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6DAA6D,EAAE;YAChE,IAAM,IAAI,GACR,4BAA4B;gBAC5B,gBAAgB;gBAChB,wBAAwB;gBACxB,iBAAiB;gBACjB,uBAAuB;gBACvB,YAAY,CAAC;YACf,MAAM,CAAC,IAAA,sCAAyB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC1C,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["//@ts-ignore\nimport { getLastImportLineLocation } from '../../src/android/code-tools';\n\ndescribe('code-tools', () => {\n describe('getLastImportLineLocation', () => {\n it('returns proper line index', () => {\n const code = `import a.b.c;\\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 static import is used', () => {\n const code =\n `import static a.b.c;\\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 wildcard import is used', () => {\n const code = `import a.b.*\\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 static a.b.c as d\\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 multiple imports are present', () => {\n const code =\n `import static a.b.c as d\\n` +\n `import a.b.*\\n` +\n `import static a.b.c;\\n` +\n `import a.b.c;\\n` +\n `//<insert-location>\\n` +\n `class X {}`;\n expect(getLastImportLineLocation(code)).toBe(\n code.indexOf('//<insert-location>'),\n );\n });\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|