11import { Logger } from "./sentry/logger" ;
2- import { IncludeEntry as UserIncludeEntry , Options as UserOptions } from "./types" ;
3- import { arrayify } from "./utils" ;
2+ import { Options as UserOptions } from "./types" ;
3+ import { determineReleaseName } from "./utils" ;
44
5- type RequiredInternalOptions = Required <
6- Pick <
7- UserOptions ,
8- | "finalize"
9- | "dryRun"
10- | "debug"
11- | "silent"
12- | "cleanArtifacts"
13- | "telemetry"
14- | "_experiments"
15- | "injectRelease"
16- | "uploadSourceMaps"
17- >
18- > ;
19-
20- type OptionalInternalOptions = Partial <
21- Pick <
22- UserOptions ,
23- | "org"
24- | "project"
25- | "authToken"
26- | "url"
27- | "vcsRemote"
28- | "dist"
29- | "errorHandler"
30- | "setCommits"
31- | "deploy"
32- | "configFile"
33- | "headers"
34- | "sourcemaps"
35- | "release"
36- >
37- > ;
38-
39- type NormalizedInternalOptions = {
40- releaseInjectionTargets : ( string | RegExp ) [ ] | ( ( filePath : string ) => boolean ) | undefined ;
41- include : InternalIncludeEntry [ ] ;
42- } ;
43-
44- export type NormalizedOptions = RequiredInternalOptions &
45- OptionalInternalOptions &
46- NormalizedInternalOptions ;
47-
48- type RequiredInternalIncludeEntry = Required <
49- Pick <
50- UserIncludeEntry ,
51- "paths" | "ext" | "stripCommonPrefix" | "sourceMapReference" | "rewrite" | "validate"
52- >
53- > ;
54-
55- type OptionalInternalIncludeEntry = Partial <
56- Pick < UserIncludeEntry , "ignoreFile" | "urlPrefix" | "urlSuffix" | "stripPrefix" >
57- > ;
58-
59- export type InternalIncludeEntry = RequiredInternalIncludeEntry &
60- OptionalInternalIncludeEntry & {
61- ignore : string [ ] ;
62- } ;
5+ export type NormalizedOptions = ReturnType < typeof normalizeUserOptions > ;
636
647export const SENTRY_SAAS_URL = "https://sentry.io" ;
658
669export function normalizeUserOptions ( userOptions : UserOptions ) {
6710 const options = {
68- // include is the only strictly required option
69- // (normalizeInclude needs all userOptions to access top-level include options)
70- include : normalizeInclude ( userOptions ) ,
71-
72- // These options must be set b/c we need them for release injection.
73- // They can also be set as environment variables. Technically, they
74- // could be set in the config file but this would be too late for
75- // release injection because we only pass the config file path
76- // to the CLI
7711 org : userOptions . org ?? process . env [ "SENTRY_ORG" ] ,
7812 project : userOptions . project ?? process . env [ "SENTRY_PROJECT" ] ,
79- // Falling back to the empty string here b/c at a later point, we use
80- // Sentry CLI to determine a release if none was specified via options
81- // or env vars. In case we don't find one, we'll bail at that point.
82- release : userOptions . release ?? process . env [ "SENTRY_RELEASE" ] ,
83- // We technically don't need the URL for anything release-specific
84- // but we want to make sure that we're only sending Sentry data
85- // of SaaS customers. Hence we want to read it anyway.
13+ authToken : userOptions . authToken , // env var: `SENTRY_AUTH_TOKEN`
8614 url : userOptions . url ?? process . env [ "SENTRY_URL" ] ?? SENTRY_SAAS_URL ,
87-
88- // Options with default values
89- finalize : userOptions . finalize ?? true ,
90- cleanArtifacts : userOptions . cleanArtifacts ?? false ,
91- dryRun : userOptions . dryRun ?? false ,
15+ headers : userOptions . headers ,
9216 debug : userOptions . debug ?? false ,
9317 silent : userOptions . silent ?? false ,
18+ errorHandler : userOptions . errorHandler ,
9419 telemetry : userOptions . telemetry ?? true ,
95- injectRelease : userOptions . injectRelease ?? true ,
96- uploadSourceMaps : userOptions . uploadSourceMaps ?? true ,
20+ disable : userOptions . disable ?? false ,
9721 sourcemaps : userOptions . sourcemaps ,
22+ release : {
23+ name : determineReleaseName ( ) ,
24+ inject : true ,
25+ create : true ,
26+ finalize : true ,
27+ vcsRemote : process . env [ "SENTRY_VSC_REMOTE" ] ?? "origin" ,
28+ cleanArtifacts : false ,
29+ ...userOptions . release ,
30+ } ,
9831 _experiments : userOptions . _experiments ?? { } ,
99-
100- // These options and can also be set via env variables or the config file.
101- // If they're set in the options, we simply pass them to the CLI constructor.
102- // Sentry CLI will internally query env variables and read its config file if
103- // the passed options are undefined.
104- authToken : userOptions . authToken , // env var: `SENTRY_AUTH_TOKEN`
105-
106- headers : userOptions . headers ,
107-
108- vcsRemote : userOptions . vcsRemote , // env var: `SENTRY_VSC_REMOTE`
109-
110- // Optional options
111- setCommits : userOptions . setCommits ,
112- deploy : userOptions . deploy ,
113- releaseInjectionTargets : normalizeReleaseInjectionTargets ( userOptions . releaseInjectionTargets ) ,
114- dist : userOptions . dist ,
115- errorHandler : userOptions . errorHandler ,
116- configFile : userOptions . configFile ,
11732 } ;
11833
11934 return options ;
12035}
12136
122- /**
123- * Converts the user-facing `releaseInjectionTargets` option to the internal
124- * `releaseInjectionTargets` option
125- */
126- function normalizeReleaseInjectionTargets (
127- userReleaseInjectionTargets : UserOptions [ "releaseInjectionTargets" ]
128- ) : ( string | RegExp ) [ ] | ( ( filePath : string ) => boolean ) | undefined {
129- if ( userReleaseInjectionTargets === undefined ) {
130- return undefined ;
131- } else if ( typeof userReleaseInjectionTargets === "function" ) {
132- return userReleaseInjectionTargets ;
133- } else {
134- return arrayify ( userReleaseInjectionTargets ) ;
135- }
136- }
137-
138- /**
139- * Converts the user-facing `include` option to the internal `include` option,
140- * resulting in an array of `InternalIncludeEntry` objects. This later on lets us
141- * work with only one type of include data structure instead of multiple.
142- *
143- * During the process, we hoist top-level include options (e.g. urlPrefix) into each
144- * object if they were not alrady specified in an `IncludeEntry`, making every object
145- * fully self-contained. This is also the reason why we pass the entire options
146- * object and not just `include`.
147- *
148- * @param userOptions the entire user-facing `options` object
149- *
150- * @return an array of `InternalIncludeEntry` objects.
151- */
152- function normalizeInclude ( userOptions : UserOptions ) : InternalIncludeEntry [ ] {
153- if ( ! userOptions . include ) {
154- return [ ] ;
155- }
156-
157- return arrayify ( userOptions . include )
158- . map ( ( includeItem ) =>
159- typeof includeItem === "string" ? { paths : [ includeItem ] } : includeItem
160- )
161- . map ( ( userIncludeEntry ) => normalizeIncludeEntry ( userOptions , userIncludeEntry ) ) ;
162- }
163-
164- /**
165- * Besides array-ifying the `ignore` option, this function hoists top level options into the items of the `include`
166- * option. This is to simplify the handling of of the `include` items later on.
167- */
168- function normalizeIncludeEntry (
169- userOptions : UserOptions ,
170- includeEntry : UserIncludeEntry
171- ) : InternalIncludeEntry {
172- const ignoreOption = includeEntry . ignore ?? userOptions . ignore ?? [ "node_modules" ] ;
173- const ignore = Array . isArray ( ignoreOption ) ? ignoreOption : [ ignoreOption ] ;
174-
175- // We're prefixing all entries in the `ext` option with a `.` (if it isn't already) to align with Node.js' `path.extname()`
176- const ext = includeEntry . ext ?? userOptions . ext ?? [ "js" , "map" , "jsbundle" , "bundle" ] ;
177- const dotPrefixedExt = ext . map ( ( extension ) => `.${ extension . replace ( / ^ \. / , "" ) } ` ) ;
178-
179- return {
180- paths : includeEntry . paths ,
181- ignore,
182- ignoreFile : includeEntry . ignoreFile ?? userOptions . ignoreFile ,
183- ext : dotPrefixedExt ,
184- urlPrefix : includeEntry . urlPrefix ?? userOptions . urlPrefix ,
185- urlSuffix : includeEntry . urlSuffix ?? userOptions . urlSuffix ,
186- stripPrefix : includeEntry . stripPrefix ?? userOptions . stripPrefix ,
187- stripCommonPrefix : includeEntry . stripCommonPrefix ?? userOptions . stripCommonPrefix ?? false ,
188- sourceMapReference : includeEntry . sourceMapReference ?? userOptions . sourceMapReference ?? true ,
189- rewrite : includeEntry . rewrite ?? userOptions . rewrite ?? true ,
190- validate : includeEntry . validate ?? userOptions . validate ?? false ,
191- } ;
192- }
193-
19437/**
19538 * Validates a few combinations of options that are not checked by Sentry CLI.
19639 *
@@ -204,7 +47,7 @@ function normalizeIncludeEntry(
20447 * @returns `true` if the options are valid, `false` otherwise
20548 */
20649export function validateOptions ( options : NormalizedOptions , logger : Logger ) : boolean {
207- const setCommits = options . setCommits ;
50+ const setCommits = options . release ?. setCommits ;
20851 if ( setCommits ) {
20952 if ( ! setCommits . auto && ! ( setCommits . repo && setCommits . commit ) ) {
21053 logger . error (
@@ -222,7 +65,7 @@ export function validateOptions(options: NormalizedOptions, logger: Logger): boo
22265 }
22366 }
22467
225- if ( options . deploy && ! options . deploy . env ) {
68+ if ( options . release ?. deploy && ! options . release ? .deploy . env ) {
22669 logger . error (
22770 "The `deploy` option was specified but is missing the required `env` property." ,
22871 "Please set the `env` property."
0 commit comments