@vercel/cli-support 65.6.0 → 65.7.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.
@@ -4,10 +4,10 @@ import { dirname as __dirname_ } from 'node:path';
4
4
  const require = __createRequire(import.meta.url);
5
5
  const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __dirname_(__filename);
7
- import{FILTER_DEPRECATION_WARNING,alignTimeRangeToGranularity,canonicalResponseToMetricsResponse,createCanonicalMetricsRequest,usesODataSyntax}from"./chunks/chunk-QFUCWOCL.js";import{init_dist,prepareFlagsDefinitions}from"./chunks/chunk-OAM5NJCU.js";import{EncryptJWT,base64url_exports,jwtDecrypt}from"./chunks/chunk-S3L2OHPO.js";import{require_fast_deep_equal}from"./chunks/chunk-MCRKBVZA.js";import{sanitizeForTerminal}from"./chunks/chunk-5RMIM4S2.js";import{getLinkedFlagsProject,getProjectNameFromFlags}from"./chunks/chunk-LIXU6EGC.js";import{parseSubcommandArguments,requireProjectContext}from"./chunks/chunk-2KINJIWA.js";import{computeGranularity,formatText,generateSparkline}from"./chunks/chunk-6GSI4VMJ.js";import{OBSERVABILITY_METRICS_PATH,getRollupColumnName,handleApiError}from"./chunks/chunk-SXRZZDON.js";import"./chunks/chunk-IVSSTHB6.js";import"./chunks/chunk-GZNDA6SV.js";import{require_dist}from"./chunks/chunk-JELLVPCM.js";import{readStdinText}from"./chunks/chunk-PSOVLGHP.js";import{require_raw_body}from"./chunks/chunk-XOETL6DB.js";import{findCommandShorthands}from"./chunks/chunk-KY7LDQRX.js";import{STANDARD_ENVIRONMENTS}from"./chunks/chunk-7YKFF6CE.js";import{resolveProjectContext}from"./chunks/chunk-RNTS4MJP.js";import{formatProject}from"./chunks/chunk-75JI2SZX.js";import{normalizeRepeatableStringFilters,outputError,resolveTimeRange,validateIntegerRangeWithDefault,validateTimeBound,validateTimeOrder}from"./chunks/chunk-XSQVCDSD.js";import{ellipsizeMiddle,truncateEnd}from"./chunks/chunk-ID663OJ7.js";import{require_open}from"./chunks/chunk-PVASGBEF.js";import"./chunks/chunk-MJ7JIQL3.js";import"./chunks/chunk-7EJQLVWX.js";import{readOnOffOption}from"./chunks/chunk-RMW2FDXS.js";import{getCommandFlags}from"./chunks/chunk-XGTKHQTT.js";import{canPrompt}from"./chunks/chunk-IQ7FPAI4.js";import{formatDate}from"./chunks/chunk-HRR57QNP.js";import"./chunks/chunk-PFD7LETF.js";import{printNextPageCommand}from"./chunks/chunk-KHADRPBJ.js";import{getInvalidSubcommand}from"./chunks/chunk-TG2RCYTH.js";import{formatTable}from"./chunks/chunk-FAELJM4F.js";import{stamp_default}from"./chunks/chunk-A2RZZQEP.js";import{table}from"./chunks/chunk-5SIC5273.js";import{getRenamedOption,reportRenamedOptionError,withWarnings}from"./chunks/chunk-FVIVFDCB.js";import"./chunks/chunk-Q7D7RGXM.js";import{getSubcommand}from"./chunks/chunk-ETV3C2CV.js";import{FLAG_ATTRIBUTE_TYPES,FLAG_CONDITION_LIST_COMPARATORS,FLAG_CONDITION_RHS_OPTIONAL_COMPARATORS,FLAG_EVALUATIONS_DIMENSIONS,FLAG_EVALUATIONS_DIMENSION_NAMES,FLAG_EVALUATIONS_GRANULARITIES,alertsInspectSubcommand,alertsListSubcommand,alertsSubcommand,archiveSubcommand,attackModeDisableSubcommand,attackModeEnableSubcommand,attackModeSubcommand,botManagementSubcommand,commandsStructs,connectionsAddSubcommand,connectionsListSubcommand,connectionsRemoveSubcommand,connectionsSubcommand,createSubcommand6 as createSubcommand,datafileSubcommand,diffSubcommand,disableSubcommand,discardSubcommand,enableSubcommand2 as enableSubcommand,entitiesCreateSubcommand,entitiesListSubcommand,entitiesRemoveSubcommand,entitiesSubcommand,entitiesUpdateSubcommand,evaluationsSubcommand,feedbackCommand,firewallCommand,flagsCommand,formatFlagAttributeTypeList,formatFlagConditionComparator,formatFlagConditionComparatorList,getCommandAliases,getFlagAttributeType,inspectSubcommand9 as inspectSubcommand,ipBlocksBlockSubcommand,ipBlocksListSubcommand,ipBlocksSubcommand,ipBlocksUnblockSubcommand,isBucketingAttribute,isFlagAttributeType,isFlagEvaluationsDimension,isFlagEvaluationsGranularity,isTimestampAttributeType,labelsListSubcommand,labelsSubcommand,listSubcommand14 as listSubcommand,openSubcommand3 as openSubcommand,overrideSubcommand,overviewSubcommand,persistentActionsInspectSubcommand,persistentActionsListSubcommand,persistentActionsSubcommand,prepareSubcommand,publishSubcommand,removeSubcommand8 as removeSubcommand,rolloutSubcommand,rulesAddSubcommand2 as rulesAddSubcommand,rulesAddSubcommand3 as rulesAddSubcommand2,rulesDisableSubcommand,rulesEditSubcommand2 as rulesEditSubcommand,rulesEnableSubcommand,rulesInspectSubcommand,rulesListSubcommand2 as rulesListSubcommand,rulesListSubcommand3 as rulesListSubcommand2,rulesMoveSubcommand,rulesRemoveSubcommand2 as rulesRemoveSubcommand,rulesRemoveSubcommand3 as rulesRemoveSubcommand2,rulesReorderSubcommand,rulesSubcommand2 as rulesSubcommand,rulesSubcommand3 as rulesSubcommand2,rulesUpdateSubcommand,sdkKeysAddSubcommand,sdkKeysListSubcommand,sdkKeysRemoveSubcommand,sdkKeysSubcommand,segmentsCreateSubcommand,segmentsInspectSubcommand,segmentsListSubcommand,segmentsRemoveSubcommand,segmentsSubcommand,segmentsUpdateSubcommand,setSubcommand2 as setSubcommand,splitSubcommand,staleSubcommand,statusSubcommand,systemBypassAddSubcommand,systemBypassListSubcommand,systemBypassRemoveSubcommand,systemBypassSubcommand,systemMitigationsPauseSubcommand,systemMitigationsResumeSubcommand,systemMitigationsSubcommand,targetingEnableSubcommand,targetingSubcommand,targetsAddSubcommand,targetsListSubcommand,targetsRemoveSubcommand,targetsSubcommand,trafficInspectSubcommand,trafficListSubcommand,trafficSubcommand,unarchiveSubcommand,updateSubcommand5 as updateSubcommand,useTargetingSubcommand,versionsDiffSubcommand,versionsListSubcommand,versionsSubcommand}from"./chunks/chunk-MMKG5W42.js";import"./chunks/chunk-O7COT3YB.js";import"./chunks/chunk-2FHZYQPY.js";import"./chunks/chunk-M7LUSXMG.js";import"./chunks/chunk-C6IITJ5S.js";import"./chunks/chunk-TZT3VYZ3.js";import"./chunks/chunk-HMWDOAWO.js";import"./chunks/chunk-QNL22LAW.js";import"./chunks/chunk-UWMPVTXG.js";import"./chunks/chunk-5CZNUB7Y.js";import"./chunks/chunk-AUY363W7.js";import"./chunks/chunk-OTYF3ZZW.js";import"./chunks/chunk-3H36RI7C.js";import"./chunks/chunk-BGWS5R5R.js";import"./chunks/chunk-UJQ6PBRF.js";import"./chunks/chunk-LFOWP74R.js";import"./chunks/chunk-GVPVWHFK.js";import"./chunks/chunk-N5CXIFE2.js";import"./chunks/chunk-FNA4MIOH.js";import"./chunks/chunk-JALVF3C2.js";import"./chunks/chunk-VWHIWUGJ.js";import{printError}from"./chunks/chunk-LCMNJNSQ.js";import{help}from"./chunks/chunk-SLDWAIO3.js";import"./chunks/chunk-67GZ5REA.js";import"./chunks/chunk-BS32OUOC.js";import{TelemetryClient}from"./chunks/chunk-E32IBIXV.js";import"./chunks/chunk-2EYYB6YN.js";import{getScope}from"./chunks/chunk-GKCTMBCM.js";import{require_ms}from"./chunks/chunk-MXTC4ZAQ.js";import"./chunks/chunk-NWGBDBZI.js";import{AGENT_REASON,AGENT_STATUS,buildCommandWithGlobalFlags,buildCommandWithYes,clientObservabilityPlanRecovery,getExitCodeForReason,outputAgentError,shouldEmitNonInteractiveCommandError,writeActionRequired,writeAgentError}from"./chunks/chunk-I7U2XP4X.js";import"./chunks/chunk-EPO7P734.js";import{getProjectByNameOrId,require_pluralize,ua_default}from"./chunks/chunk-TKKGZI7O.js";import{formatAlignedLabel,printAlignedLabel}from"./chunks/chunk-26QK3I2S.js";import"./chunks/chunk-55H6G46X.js";import"./chunks/chunk-4NTBYNFR.js";import{parseArguments}from"./chunks/chunk-F22QLVTX.js";import{quoteArg,teamCache}from"./chunks/chunk-F53OKXYI.js";import{warnDeprecatedInput,warnDeprecatedOption,warnDeprecatedSubcommand}from"./chunks/chunk-7SAEZ4NC.js";import"./chunks/chunk-LUX4PBJL.js";import"./chunks/chunk-OPORM35X.js";import"./chunks/chunk-4SAVH3H7.js";import{ProjectNotFound,isAPIError}from"./chunks/chunk-YCJHUYBJ.js";import{cmd,getCommandName,getCommandNamePlain,packageName}from"./chunks/chunk-JESNVRVR.js";import{output_manager_default,recordCliError}from"./chunks/chunk-DWOJP4ST.js";import"./chunks/chunk-BLUPZPAS.js";import"./chunks/chunk-RM3ZDRYE.js";import"./chunks/chunk-D3AHZ5LI.js";import"./chunks/chunk-2GHZGOWT.js";import"./chunks/chunk-YHPPP3SF.js";import{pkg_default}from"./chunks/chunk-OO572JUC.js";import"./chunks/chunk-PUKYAALC.js";import{SDK_KEY_PATTERN,getFlagsSpecification,getGlobalFlagsFromArgs,getProjectOptionFromArgs}from"./chunks/chunk-A2UZ2O7H.js";import"./chunks/chunk-2BKALEOP.js";import{require_source}from"./chunks/chunk-NB2WLB3J.js";import"./chunks/chunk-ISWW3DKF.js";import"./chunks/chunk-BRQUZ5NC.js";import{fetch,toNodeReadable}from"./chunks/chunk-MY4MONOH.js";import{__toESM}from"./chunks/chunk-BZENIQ7N.js";var import_raw_body=__toESM(require_raw_body(),1);var FeedbackTelemetryClient=class extends TelemetryClient{trackCliArgumentNote(note){note!==void 0&&this.trackCliArgument({arg:"note",value:this.redactedValue})}trackCliOptionField(fields){fields?.length&&this.trackCliOption({option:"field",value:this.redactedValue})}};var FEEDBACK_URL="https://vercel.com/api/feedback/cli",MAX_FEEDBACK_BYTES=1024*1024,FETCH_TIMEOUT_MS=1e4;async function feedback(client){let fail=(reason,message,code)=>(recordCliError({code:reason}),output_manager_default.error(message),code),parsed;try{parsed=parseArguments(client.argv.slice(2),getFlagsSpecification(feedbackCommand.options))}catch{return fail(AGENT_REASON.INVALID_ARGUMENTS,"Invalid feedback arguments. Run vercel feedback --help for usage.",2)}let notes=parsed.args.slice(1),fields=parsed.flags["--field"]??[];if(notes.length===0&&fields.length===0)return client.stdout.write(help(feedbackCommand,{stream:client.stdout,columns:client.stdout.columns??client.stderr.columns})),0;if(notes.length>1)return fail(AGENT_REASON.INVALID_ARGUMENTS,"Pass one note. Quote notes containing spaces, or use vercel feedback - to read stdin.",2);let telemetry=new FeedbackTelemetryClient({opts:{store:client.telemetryEventStore}});telemetry.trackCliArgumentNote(notes[0]),telemetry.trackCliOptionField(fields);let data=Object.create(null);for(let field of fields){let separator=field.indexOf("="),key=field.slice(0,separator).trim();if(separator<1||key==="")return fail(AGENT_REASON.INVALID_ARGUMENTS,"Each --field needs a non-empty key followed by =value. Example: vercel feedback --field topic=deploy.",2);data[key]=field.slice(separator+1)}if(notes.length&&Object.hasOwn(data,"note"))return fail(AGENT_REASON.INVALID_ARGUMENTS,"Provide the note once: use a positional note or --field note=..., rather than both.",2);if(notes[0]==="-"){if(client.stdin.isTTY)return fail(AGENT_REASON.INVALID_ARGUMENTS,"No input was piped to stdin. Pipe a note with: cat notes.md | vercel feedback -",2);try{data.note=await readStdinText(client.stdin,MAX_FEEDBACK_BYTES)}catch(error){return error.type==="entity.too.large"?fail(AGENT_REASON.INVALID_ARGUMENTS,"Feedback is too large. Keep the complete submission below 1 MiB.",2):fail(AGENT_REASON.STDIN_ERROR,"Could not read the feedback note from stdin. Check the input pipe and try again.",1)}}else notes[0]!==void 0&&(data.note=notes[0]);for(let key of Object.keys(data))data[key].trim()||delete data[key];if(!Object.keys(data).length)return fail(AGENT_REASON.INVALID_ARGUMENTS,"Provide a note or at least one named field. Run vercel feedback --help for examples.",2);let canSendTelemetry=client.telemetryEventStore?.enabled??!1,body=JSON.stringify({metadata:canSendTelemetry?{agent:client.isAgent,agent_name:client.isAgent?client.agentName:void 0,cli_version:pkg_default.version,operating_system:process.platform,team_id:client.config.currentTeam??null,user_id:client.authConfig.userId??null,invocation_id:client.telemetryEventStore?.currentInvocationId??null,session_id:client.telemetryEventStore?.currentSessionId??null}:null,data});if(Buffer.byteLength(body)>MAX_FEEDBACK_BYTES)return fail(AGENT_REASON.INVALID_ARGUMENTS,"Feedback is too large. Keep the complete submission below 1 MiB.",2);let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),FETCH_TIMEOUT_MS);timeout.unref?.();try{let response=await fetch(FEEDBACK_URL,{method:"POST",headers:{"content-type":"application/json","user-agent":ua_default},body,redirect:"manual",signal:controller.signal});if(!response.ok)return await response.body?.cancel(),fail(response.status===429?AGENT_REASON.RATE_LIMITED:AGENT_REASON.API_ERROR,`Feedback could not be submitted (HTTP ${response.status}). Try again later.`,1);let responseBody=toNodeReadable(response.body);return JSON.parse(await(0,import_raw_body.default)(responseBody,{limit:64*1024,encoding:"utf8"}).finally(()=>responseBody.destroy()))?.success!==!0?fail(AGENT_REASON.UNKNOWN_OUTCOME,"Could not confirm that Vercel accepted the feedback. It may have been submitted; no automatic retry was made.",1):(client.stdout.write(`Feedback sent
7
+ import{FILTER_DEPRECATION_WARNING,alignTimeRangeToGranularity,canonicalResponseToMetricsResponse,createCanonicalMetricsRequest,usesODataSyntax}from"./chunks/chunk-QFUCWOCL.js";import{init_dist,prepareFlagsDefinitions}from"./chunks/chunk-OAM5NJCU.js";import{EncryptJWT,base64url_exports,jwtDecrypt}from"./chunks/chunk-S3L2OHPO.js";import{require_fast_deep_equal}from"./chunks/chunk-MCRKBVZA.js";import{sanitizeForTerminal}from"./chunks/chunk-5RMIM4S2.js";import{getLinkedFlagsProject,getProjectNameFromFlags}from"./chunks/chunk-LIXU6EGC.js";import{parseSubcommandArguments,requireProjectContext}from"./chunks/chunk-2KINJIWA.js";import{computeGranularity,formatText,generateSparkline}from"./chunks/chunk-6GSI4VMJ.js";import{OBSERVABILITY_METRICS_PATH,getRollupColumnName,handleApiError}from"./chunks/chunk-SXRZZDON.js";import"./chunks/chunk-IVSSTHB6.js";import"./chunks/chunk-GZNDA6SV.js";import{require_dist}from"./chunks/chunk-JELLVPCM.js";import{readStdinText}from"./chunks/chunk-PSOVLGHP.js";import{require_raw_body}from"./chunks/chunk-XOETL6DB.js";import{findCommandShorthands}from"./chunks/chunk-KY7LDQRX.js";import{STANDARD_ENVIRONMENTS}from"./chunks/chunk-7YKFF6CE.js";import{resolveProjectContext}from"./chunks/chunk-RNTS4MJP.js";import{formatProject}from"./chunks/chunk-75JI2SZX.js";import{normalizeRepeatableStringFilters,outputError,resolveTimeRange,validateIntegerRangeWithDefault,validateTimeBound,validateTimeOrder}from"./chunks/chunk-XSQVCDSD.js";import{ellipsizeMiddle,truncateEnd}from"./chunks/chunk-ID663OJ7.js";import{require_open}from"./chunks/chunk-PVASGBEF.js";import"./chunks/chunk-MJ7JIQL3.js";import"./chunks/chunk-7EJQLVWX.js";import{readOnOffOption}from"./chunks/chunk-RMW2FDXS.js";import{getCommandFlags}from"./chunks/chunk-XGTKHQTT.js";import{canPrompt}from"./chunks/chunk-IQ7FPAI4.js";import{formatDate}from"./chunks/chunk-HRR57QNP.js";import"./chunks/chunk-PFD7LETF.js";import{printNextPageCommand}from"./chunks/chunk-KHADRPBJ.js";import{getInvalidSubcommand}from"./chunks/chunk-TG2RCYTH.js";import{formatTable}from"./chunks/chunk-FAELJM4F.js";import{stamp_default}from"./chunks/chunk-A2RZZQEP.js";import{table}from"./chunks/chunk-5SIC5273.js";import{getRenamedOption,reportRenamedOptionError,withWarnings}from"./chunks/chunk-FVIVFDCB.js";import"./chunks/chunk-Q7D7RGXM.js";import{getSubcommand}from"./chunks/chunk-ETV3C2CV.js";import{FLAG_ATTRIBUTE_TYPES,FLAG_CONDITION_LIST_COMPARATORS,FLAG_CONDITION_RHS_OPTIONAL_COMPARATORS,FLAG_EVALUATIONS_DIMENSIONS,FLAG_EVALUATIONS_DIMENSION_NAMES,FLAG_EVALUATIONS_GRANULARITIES,alertsInspectSubcommand,alertsListSubcommand,alertsSubcommand,archiveSubcommand,attackModeDisableSubcommand,attackModeEnableSubcommand,attackModeSubcommand,botManagementSubcommand,commandsStructs,connectionsAddSubcommand,connectionsListSubcommand,connectionsRemoveSubcommand,connectionsSubcommand,createSubcommand6 as createSubcommand,datafileSubcommand,diffSubcommand,disableSubcommand,discardSubcommand,enableSubcommand2 as enableSubcommand,entitiesCreateSubcommand,entitiesListSubcommand,entitiesRemoveSubcommand,entitiesSubcommand,entitiesUpdateSubcommand,evaluationsSubcommand,feedbackCommand,firewallCommand,flagsCommand,formatFlagAttributeTypeList,formatFlagConditionComparator,formatFlagConditionComparatorList,getCommandAliases,getFlagAttributeType,inspectSubcommand9 as inspectSubcommand,ipBlocksBlockSubcommand,ipBlocksListSubcommand,ipBlocksSubcommand,ipBlocksUnblockSubcommand,isBucketingAttribute,isFlagAttributeType,isFlagEvaluationsDimension,isFlagEvaluationsGranularity,isTimestampAttributeType,labelsListSubcommand,labelsSubcommand,listSubcommand14 as listSubcommand,openSubcommand3 as openSubcommand,overrideSubcommand,overviewSubcommand,persistentActionsInspectSubcommand,persistentActionsListSubcommand,persistentActionsSubcommand,prepareSubcommand,publishSubcommand,removeSubcommand8 as removeSubcommand,rolloutSubcommand,rulesAddSubcommand2 as rulesAddSubcommand,rulesAddSubcommand3 as rulesAddSubcommand2,rulesDisableSubcommand,rulesEditSubcommand2 as rulesEditSubcommand,rulesEnableSubcommand,rulesInspectSubcommand,rulesListSubcommand2 as rulesListSubcommand,rulesListSubcommand3 as rulesListSubcommand2,rulesMoveSubcommand,rulesRemoveSubcommand2 as rulesRemoveSubcommand,rulesRemoveSubcommand3 as rulesRemoveSubcommand2,rulesReorderSubcommand,rulesSubcommand2 as rulesSubcommand,rulesSubcommand3 as rulesSubcommand2,rulesUpdateSubcommand,sdkKeysAddSubcommand,sdkKeysListSubcommand,sdkKeysRemoveSubcommand,sdkKeysSubcommand,segmentsCreateSubcommand,segmentsInspectSubcommand,segmentsListSubcommand,segmentsRemoveSubcommand,segmentsSubcommand,segmentsUpdateSubcommand,setSubcommand2 as setSubcommand,splitSubcommand,staleSubcommand,statusSubcommand,systemBypassAddSubcommand,systemBypassListSubcommand,systemBypassRemoveSubcommand,systemBypassSubcommand,systemMitigationsPauseSubcommand,systemMitigationsResumeSubcommand,systemMitigationsSubcommand,targetingEnableSubcommand,targetingSubcommand,targetsAddSubcommand,targetsListSubcommand,targetsRemoveSubcommand,targetsSubcommand,trafficInspectSubcommand,trafficListSubcommand,trafficSubcommand,unarchiveSubcommand,updateSubcommand5 as updateSubcommand,useTargetingSubcommand,versionsDiffSubcommand,versionsListSubcommand,versionsSubcommand}from"./chunks/chunk-767IBETW.js";import"./chunks/chunk-O7COT3YB.js";import"./chunks/chunk-2FHZYQPY.js";import"./chunks/chunk-M7LUSXMG.js";import"./chunks/chunk-C6IITJ5S.js";import"./chunks/chunk-TZT3VYZ3.js";import"./chunks/chunk-HMWDOAWO.js";import"./chunks/chunk-QNL22LAW.js";import"./chunks/chunk-UWMPVTXG.js";import"./chunks/chunk-5CZNUB7Y.js";import"./chunks/chunk-AUY363W7.js";import"./chunks/chunk-OTYF3ZZW.js";import"./chunks/chunk-3H36RI7C.js";import"./chunks/chunk-BGWS5R5R.js";import"./chunks/chunk-UJQ6PBRF.js";import"./chunks/chunk-LFOWP74R.js";import"./chunks/chunk-GVPVWHFK.js";import"./chunks/chunk-N5CXIFE2.js";import"./chunks/chunk-FNA4MIOH.js";import"./chunks/chunk-JALVF3C2.js";import"./chunks/chunk-VWHIWUGJ.js";import{printError}from"./chunks/chunk-LCMNJNSQ.js";import{help}from"./chunks/chunk-SLDWAIO3.js";import"./chunks/chunk-67GZ5REA.js";import"./chunks/chunk-BS32OUOC.js";import{TelemetryClient}from"./chunks/chunk-E32IBIXV.js";import"./chunks/chunk-2EYYB6YN.js";import{getScope}from"./chunks/chunk-GKCTMBCM.js";import{require_ms}from"./chunks/chunk-MXTC4ZAQ.js";import"./chunks/chunk-NWGBDBZI.js";import{AGENT_REASON,AGENT_STATUS,buildCommandWithGlobalFlags,buildCommandWithYes,clientObservabilityPlanRecovery,getExitCodeForReason,outputAgentError,shouldEmitNonInteractiveCommandError,writeActionRequired,writeAgentError}from"./chunks/chunk-I7U2XP4X.js";import"./chunks/chunk-EPO7P734.js";import{getProjectByNameOrId,require_pluralize,ua_default}from"./chunks/chunk-TKKGZI7O.js";import{formatAlignedLabel,printAlignedLabel}from"./chunks/chunk-26QK3I2S.js";import"./chunks/chunk-55H6G46X.js";import"./chunks/chunk-4NTBYNFR.js";import{parseArguments}from"./chunks/chunk-F22QLVTX.js";import{quoteArg,teamCache}from"./chunks/chunk-F53OKXYI.js";import{warnDeprecatedInput,warnDeprecatedOption,warnDeprecatedSubcommand}from"./chunks/chunk-7SAEZ4NC.js";import"./chunks/chunk-LUX4PBJL.js";import"./chunks/chunk-OPORM35X.js";import"./chunks/chunk-4SAVH3H7.js";import{ProjectNotFound,isAPIError}from"./chunks/chunk-YCJHUYBJ.js";import{cmd,getCommandName,getCommandNamePlain,packageName}from"./chunks/chunk-JESNVRVR.js";import{output_manager_default,recordCliError}from"./chunks/chunk-DWOJP4ST.js";import"./chunks/chunk-BLUPZPAS.js";import"./chunks/chunk-RM3ZDRYE.js";import"./chunks/chunk-D3AHZ5LI.js";import"./chunks/chunk-2GHZGOWT.js";import"./chunks/chunk-YHPPP3SF.js";import{pkg_default}from"./chunks/chunk-OO572JUC.js";import"./chunks/chunk-PUKYAALC.js";import{SDK_KEY_PATTERN,getFlagsSpecification,getGlobalFlagsFromArgs,getProjectOptionFromArgs}from"./chunks/chunk-A2UZ2O7H.js";import"./chunks/chunk-2BKALEOP.js";import{require_source}from"./chunks/chunk-NB2WLB3J.js";import"./chunks/chunk-ISWW3DKF.js";import"./chunks/chunk-BRQUZ5NC.js";import{fetch,toNodeReadable}from"./chunks/chunk-MY4MONOH.js";import{__toESM}from"./chunks/chunk-BZENIQ7N.js";var import_raw_body=__toESM(require_raw_body(),1);var FeedbackTelemetryClient=class extends TelemetryClient{trackCliArgumentNote(note){note!==void 0&&this.trackCliArgument({arg:"note",value:this.redactedValue})}trackCliOptionField(fields){fields?.length&&this.trackCliOption({option:"field",value:this.redactedValue})}};var FEEDBACK_URL="https://vercel.com/api/feedback/cli",MAX_FEEDBACK_BYTES=1024*1024,FETCH_TIMEOUT_MS=1e4;async function feedback(client){let fail=(reason,message,code)=>(recordCliError({code:reason}),output_manager_default.error(message),code),parsed;try{parsed=parseArguments(client.argv.slice(2),getFlagsSpecification(feedbackCommand.options))}catch{return fail(AGENT_REASON.INVALID_ARGUMENTS,"Invalid feedback arguments. Run vercel feedback --help for usage.",2)}let notes=parsed.args.slice(1),fields=parsed.flags["--field"]??[];if(notes.length===0&&fields.length===0)return client.stdout.write(help(feedbackCommand,{stream:client.stdout,columns:client.stdout.columns??client.stderr.columns})),0;if(notes.length>1)return fail(AGENT_REASON.INVALID_ARGUMENTS,"Pass one note. Quote notes containing spaces, or use vercel feedback - to read stdin.",2);let telemetry=new FeedbackTelemetryClient({opts:{store:client.telemetryEventStore}});telemetry.trackCliArgumentNote(notes[0]),telemetry.trackCliOptionField(fields);let data=Object.create(null);for(let field of fields){let separator=field.indexOf("="),key=field.slice(0,separator).trim();if(separator<1||key==="")return fail(AGENT_REASON.INVALID_ARGUMENTS,"Each --field needs a non-empty key followed by =value. Example: vercel feedback --field topic=deploy.",2);data[key]=field.slice(separator+1)}if(notes.length&&Object.hasOwn(data,"note"))return fail(AGENT_REASON.INVALID_ARGUMENTS,"Provide the note once: use a positional note or --field note=..., rather than both.",2);if(notes[0]==="-"){if(client.stdin.isTTY)return fail(AGENT_REASON.INVALID_ARGUMENTS,"No input was piped to stdin. Pipe a note with: cat notes.md | vercel feedback -",2);try{data.note=await readStdinText(client.stdin,MAX_FEEDBACK_BYTES)}catch(error){return error.type==="entity.too.large"?fail(AGENT_REASON.INVALID_ARGUMENTS,"Feedback is too large. Keep the complete submission below 1 MiB.",2):fail(AGENT_REASON.STDIN_ERROR,"Could not read the feedback note from stdin. Check the input pipe and try again.",1)}}else notes[0]!==void 0&&(data.note=notes[0]);for(let key of Object.keys(data))data[key].trim()||delete data[key];if(!Object.keys(data).length)return fail(AGENT_REASON.INVALID_ARGUMENTS,"Provide a note or at least one named field. Run vercel feedback --help for examples.",2);let canSendTelemetry=client.telemetryEventStore?.enabled??!1,body=JSON.stringify({metadata:canSendTelemetry?{agent:client.isAgent,agent_name:client.isAgent?client.agentName:void 0,cli_version:pkg_default.version,operating_system:process.platform,team_id:client.config.currentTeam??null,user_id:client.authConfig.userId??null,invocation_id:client.telemetryEventStore?.currentInvocationId??null,session_id:client.telemetryEventStore?.currentSessionId??null}:null,data});if(Buffer.byteLength(body)>MAX_FEEDBACK_BYTES)return fail(AGENT_REASON.INVALID_ARGUMENTS,"Feedback is too large. Keep the complete submission below 1 MiB.",2);let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),FETCH_TIMEOUT_MS);timeout.unref?.();try{let response=await fetch(FEEDBACK_URL,{method:"POST",headers:{"content-type":"application/json","user-agent":ua_default},body,redirect:"manual",signal:controller.signal});if(!response.ok)return await response.body?.cancel(),fail(response.status===429?AGENT_REASON.RATE_LIMITED:AGENT_REASON.API_ERROR,`Feedback could not be submitted (HTTP ${response.status}). Try again later.`,1);let responseBody=toNodeReadable(response.body);return JSON.parse(await(0,import_raw_body.default)(responseBody,{limit:64*1024,encoding:"utf8"}).finally(()=>responseBody.destroy()))?.success!==!0?fail(AGENT_REASON.UNKNOWN_OUTCOME,"Could not confirm that Vercel accepted the feedback. It may have been submitted; no automatic retry was made.",1):(client.stdout.write(`Feedback sent
8
8
  `),0)}catch{return fail(AGENT_REASON.UNKNOWN_OUTCOME,"Could not confirm that Vercel accepted the feedback. Check your connection. It may have been submitted; no automatic retry was made.",1)}finally{clearTimeout(timeout)}}var import_chalk6=__toESM(require_source(),1);var import_chalk2=__toESM(require_source(),1);var import_chalk=__toESM(require_source(),1);var ACTION_COLORS={allow:import_chalk.default.blue,deny:import_chalk.default.red,challenge:import_chalk.default.yellow,log:import_chalk.default.magenta,rate_limit:import_chalk.default.cyan,"rate-limit":import_chalk.default.cyan,bypass:import_chalk.default.green};function labelForAction(action){return action==="rate_limit"||action==="rate-limit"?"Rate Limited":action.split(/[-_]/).filter(Boolean).map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}var MONTHS=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function formatCount(n){return n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}k`:String(Math.round(n))}function pad2(n){return String(n).padStart(2,"0")}function formatUtcTime(ms8,withDate){let d=new Date(ms8),hm=`${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())}`;return withDate?`${MONTHS[d.getUTCMonth()]} ${d.getUTCDate()} ${hm}`:hm}function relativeTime(ts){let diff2=Date.now()-ts;return diff2<6e4?"just now":diff2<36e5?`${Math.floor(diff2/6e4)}m ago`:diff2<864e5?`${Math.floor(diff2/36e5)}h ago`:`${Math.floor(diff2/864e5)}d ago`}function formatUtcDateTime(ms8){return`${formatUtcTime(ms8,!0)} UTC (${relativeTime(ms8)})`}function colorizeDetail(detail){return detail.split(" \xB7 ").map(part=>{let color=ACTION_COLORS[part.toLowerCase().replace(/ /g,"_")];return color?color(part):part}).join(" \xB7 ")}function windowNeedsDate(startMs,endMs){return endMs-startMs>25*36e5}function granularityLabel(granularity){return"minutes"in granularity?`${granularity.minutes}m`:"hours"in granularity?`${granularity.hours}h`:`${granularity.days}d`}function formatActionTrendTable(series){let allTs=new Set;for(let s of series)for(let p of s.timeseries)allTs.add(p.timestamp);let axis=[...allTs].sort(),hasAnyTraffic=series.some(s=>s.total>0||s.timeseries.some(p=>p.value>0));if(series.length===0||axis.length===0||!hasAnyTraffic)return import_chalk.default.dim(" No request data for this period.");let startMs=new Date(axis[0]).getTime(),endMs=new Date(axis[axis.length-1]).getTime(),needsDate=windowNeedsDate(startMs,endMs),rows=[["Action","Trend","Total","Peak","Peak at"].map(h=>import_chalk.default.bold(import_chalk.default.cyan(h)))];for(let s of series){let byTs=new Map(s.timeseries.map(p=>[p.timestamp,p.value])),values=axis.map(t=>byTs.get(t)??0),peak=0,peakTs="";for(let i=0;i<axis.length;i++)values[i]>peak&&(peak=values[i],peakTs=axis[i]);let plain=x=>x,color=s.total>0?ACTION_COLORS[s.action]??plain:import_chalk.default.dim,trend=s.total>0?plain:import_chalk.default.dim;rows.push([color(labelForAction(s.action)),trend(generateSparkline(values)),formatCount(s.total),peak>0?formatCount(peak):"--",peak>0?formatUtcTime(new Date(peakTs).getTime(),needsDate):"--"])}return table(rows,{align:["l","l","r","r","r"],hsep:3}).split(`
9
9
  `).map(line2=>` ${line2}`.trimEnd()).join(`
10
- `)}var NO_SERVER_MESSAGE="Response Error";function apiServerMessage(error){let message=isAPIError(error)?error.serverMessage:void 0;return message&&message!==NO_SERVER_MESSAGE?message:void 0}var FIREWALL_O11Y_ALERT_TYPES=["botId_anomaly","firewallSystemRule_anomaly","firewallCustomRule_anomaly"],FIREWALL_ANOMALY_TYPE="firewall_anomaly",SYS_DOS_MITIGATION_RULE_ID="sys_dos_mitigation",SYSTEM_RULE_ANOMALY_TYPE="firewallSystemRule_anomaly",FIREWALL_ACTIVITY_PLAN_MESSAGE="Traffic and alerts need Observability Plus.",FIREWALL_ALERTS_PARTIAL_ERROR_MESSAGE="Couldn't load every alert source.";function reduceAttackAnomaly(anomaly){return Object.keys(anomaly.affectedHostMap).reduce((acc,host)=>{acc.hosts.push(host);let challenged=anomaly.affectedHostMap[host].ddosAlerts?.["sys_dos_mitigation:challenge"]?.totalReqs||0,denied=anomaly.affectedHostMap[host].ddosAlerts?.["sys_dos_mitigation:deny"]?.totalReqs||0;return acc.challenged+=challenged,acc.denied+=denied,acc.count+=challenged+denied,acc},{hosts:[],challenged:0,denied:0,count:0})}function hostsFromAnomaly(anomaly){return Object.entries(anomaly.affectedHostMap).map(([host,data])=>{let challenged=data.ddosAlerts?.["sys_dos_mitigation:challenge"]?.totalReqs||0,denied=data.ddosAlerts?.["sys_dos_mitigation:deny"]?.totalReqs||0;return{name:host,count:challenged+denied}}).filter(row=>row.count>0).sort((a,b)=>b.count-a.count)}function mapAttackAnomaly(anomaly){let reduced=reduceAttackAnomaly(anomaly),parts=["System rule"];return reduced.denied>0&&parts.push(labelForAction("deny")),reduced.challenged>0&&parts.push(labelForAction("challenge")),{id:`${anomaly.ownerId}-${anomaly.projectId}-${anomaly.startTime}`,title:"DDoS Mitigation",type:FIREWALL_ANOMALY_TYPE,startedAt:anomaly.startTime,resolvedAt:anomaly.endTime||void 0,count:reduced.count,detail:parts.join(" \xB7 "),action:reduced.denied>=reduced.challenged?"deny":"challenge",ruleId:SYS_DOS_MITIGATION_RULE_ID,host:reduced.hosts[0]}}function mapO11yAlert(alert){if(!alert.startedAt)return null;let action=alert.data?.action,ruleId=alert.data?.ruleId,detailParts=[alert.type,action?labelForAction(action):void 0,ruleId].filter(Boolean);return{id:alert.id||`${alert.type}-${alert.startedAt}`,title:alert.title||alert.type||"Firewall alert",type:alert.type||"unknown",startedAt:alert.startedAt,resolvedAt:alert.resolvedAt,count:alert.data?.count,detail:detailParts.filter(p=>p!==alert.title).join(" \xB7 ")||void 0,action,ruleId,path:alert.data?.path}}var ATTACK_STATUS_MAX_DAYS=7;async function getAttackStatus(client,opts){let query=new URLSearchParams;if(query.set("projectId",opts.projectId),query.set("teamId",opts.teamId),opts.sinceDays!==void 0){let sinceDays=Math.min(ATTACK_STATUS_MAX_DAYS,Math.max(1,Math.ceil(opts.sinceDays)));query.set("since",String(sinceDays))}return client.fetch(`/v1/security/firewall/attack-status?${query.toString()}`,{accountId:opts.teamId,signal:opts.signal})}var O11Y_ALERTS_LIMIT=200;async function getFirewallO11yAlerts(client,opts){let query=new URLSearchParams;query.set("teamId",opts.teamId),query.set("projectId",opts.projectId),query.set("from",opts.from.toISOString()),query.set("to",opts.to.toISOString()),query.set("limit",String(O11Y_ALERTS_LIMIT));for(let type of FIREWALL_O11Y_ALERT_TYPES)query.append("types",type);return(await client.fetch(`/alerts/v3/groups?${query.toString()}`,{accountId:opts.teamId,signal:opts.signal})).flatMap(g=>g.alerts??[]).map(mapO11yAlert).filter(a=>a!==null)}var ALERTS_TIMEOUT_MS=2e4;function sourceFailureReason(err){return isAPIError(err)&&err.status===408||err instanceof Error&&(err.name==="TimeoutError"||err.name==="AbortError")?"timed out":isAPIError(err)&&err.status===402?"needs Observability Plus":isAPIError(err)&&typeof err.status=="number"?`HTTP ${err.status}`:err instanceof Error&&err.message?err.message:"unknown error"}function resolveAlertsWindow(opts){let now=Date.now(),to=opts.to??new Date(now),from=opts.from??new Date(to.getTime()-864e5*(opts.sinceDays??1)),sinceDays=opts.sinceDays??Math.max(1,Math.ceil((now-from.getTime())/864e5));return{from,to,sinceDays}}function classifyAlertSourceError(err){if(isAPIError(err)&&(err.status===401||err.status===403))throw err;return isAPIError(err)&&err.status===402?{reason:"plan",message:FIREWALL_ACTIVITY_PLAN_MESSAGE}:{reason:"error",message:apiServerMessage(err)||!isAPIError(err)&&err instanceof Error&&err.message||FIREWALL_ALERTS_PARTIAL_ERROR_MESSAGE}}async function getFirewallAlertsDetailed(client,opts){let{from,to,sinceDays}=resolveAlertsWindow(opts),timeoutMs=opts.timeoutMs??ALERTS_TIMEOUT_MS,signal=AbortSignal.timeout(timeoutMs),[o11yResult,attackResult]=await Promise.allSettled([getFirewallO11yAlerts(client,{...opts,from,to,signal}),getAttackStatus(client,{...opts,sinceDays,signal})]),errors=[],o11yAlerts=[],o11y;o11yResult.status==="fulfilled"?o11yAlerts=o11yResult.value:(o11y=classifyAlertSourceError(o11yResult.reason),errors.push({source:"alerts",message:sourceFailureReason(o11yResult.reason)}));let mappedAttacks=[],attackStatus;attackResult.status==="fulfilled"?mappedAttacks=(attackResult.value.anomalies||[]).map(mapAttackAnomaly):(attackStatus=classifyAlertSourceError(attackResult.reason),errors.push({source:"attackStatus",message:sourceFailureReason(attackResult.reason)}));let resolvedCutoff=from.getTime();return{alerts:mappedAttacks.concat(o11yAlerts.filter(a=>!a.resolvedAt||a.resolvedAt>resolvedCutoff)).sort((a,b)=>!a.resolvedAt&&b.resolvedAt?-1:a.resolvedAt&&!b.resolvedAt?1:b.startedAt-a.startedAt),o11y,attackStatus,errors}}function alertsIncompleteMessage(errors){return`Attack count and alerts may be incomplete: ${errors.map(e=>`${e.source==="alerts"?"alerts":"attack history"} ${e.message}`).join("; ")}.`}function countAttacksMitigated(alerts,windowStartMs,windowEndMs){return alerts.filter(alert=>isAttackAlert(alert)&&alertOverlapsWindow(alert,windowStartMs,windowEndMs)).length}function alertOverlapsWindow(alert,windowStartMs,windowEndMs){return alert.startedAt<=windowEndMs&&(alert.resolvedAt??Number.POSITIVE_INFINITY)>=windowStartMs}function isAttackAlert(alert){return alert.type===FIREWALL_ANOMALY_TYPE?!0:alert.type===SYSTEM_RULE_ANOMALY_TYPE&&alert.ruleId===SYS_DOS_MITIGATION_RULE_ID}var O11Y_ALERT_ID_PREFIX="al_",INSPECT_FALLBACK_DAYS=7;function isO11yAlertId(id){return id.startsWith(O11Y_ALERT_ID_PREFIX)}function parseLegacyAlertStartTime(id){let match=id.match(/-(\d{13})$/);return match?Number(match[1]):void 0}function daysCovering(startMs,endMs){return Math.max(1,Math.ceil((endMs-startMs)/864e5))}function mapGroupAsAlert(group,alertId){let nested=(group.alerts??[]).map(mapO11yAlert).filter(a=>a!==null),hit=nested.find(a=>a.id===alertId)??nested[0];if(hit)return hit;let startedAt=group.recordedStartedAt;return startedAt?mapO11yAlert({id:alertId,title:group.title,type:group.type,startedAt,resolvedAt:group.recordedResolvedAt,data:group.alerts?.[0]?.data}):null}async function getO11yAlertById(client,opts){let query=new URLSearchParams;query.set("teamId",opts.teamId),query.set("projectId",opts.projectId);try{let group=await client.fetch(`/alerts/v3/groups/${encodeURIComponent(opts.alertId)}?${query.toString()}`,{accountId:opts.teamId,signal:opts.signal});return mapGroupAsAlert(group,opts.alertId)}catch(err){if(isAPIError(err)&&err.status===404)return null;throw err}}async function findFirewallAlert(client,opts){let timeoutMs=opts.timeoutMs??ALERTS_TIMEOUT_MS,budget=()=>AbortSignal.timeout(timeoutMs),now=Date.now();if(isO11yAlertId(opts.alertId)){let fromGroup2=await getO11yAlertById(client,{...opts,signal:budget()});if(fromGroup2)return{alert:fromGroup2};let from=new Date(now-864e5*INSPECT_FALLBACK_DAYS),hit=(await getFirewallO11yAlerts(client,{projectId:opts.projectId,teamId:opts.teamId,from,to:new Date(now),signal:budget()})).find(a=>a.id===opts.alertId);return hit?{alert:hit}:null}let startTime=parseLegacyAlertStartTime(opts.alertId),sinceDays=startTime?daysCovering(startTime,now)+1:INSPECT_FALLBACK_DAYS,anomaly=((await getAttackStatus(client,{projectId:opts.projectId,teamId:opts.teamId,sinceDays,signal:budget()}).catch(err=>{if(isAPIError(err)&&(err.status===401||err.status===403))throw err;return{anomalies:[]}})).anomalies||[]).find(a=>`${a.ownerId}-${a.projectId}-${a.startTime}`===opts.alertId);if(anomaly)return{alert:mapAttackAnomaly(anomaly),hosts:hostsFromAnomaly(anomaly)};let fromGroup=await getO11yAlertById(client,{...opts,signal:budget()}).catch(err=>{if(isAPIError(err)&&(err.status===401||err.status===403))throw err;return null});return fromGroup?{alert:fromGroup}:null}var MANAGED_BOT_RULE_IDS=["bot-protection","ai-bots","bot-id"],ALIASES={"bot-protection":"bot-protection","bot protection":"bot-protection",bot_protection:"bot-protection",bot_filter:"bot-protection",managed_bot_protection:"bot-protection",managed_bot_filter:"bot-protection","ai-bots":"ai-bots","ai bots":"ai-bots",ai_bots:"ai-bots",managed_ai_bots:"ai-bots","bot-id":"bot-id",botid:"bot-id",bot_id:"bot-id"},ACTIONS={"bot-protection":["off","log","challenge"],"ai-bots":["allow","log","challenge","deny"],"bot-id":["basic","deep-analysis"]},NAMES={"bot-protection":"Bot Protection","ai-bots":"AI Bots","bot-id":"BotID"},WAF_RULE_IDS={"bot-protection":"managed_bot_protection","ai-bots":"managed_ai_bots"};function resolveManagedBotRuleId(identifier){if(identifier)return ALIASES[identifier.trim().toLowerCase()]}function managedBotActions(id){return ACTIONS[id]}function formatManagedBotAction(action){return action==="deep-analysis"?"Deep Analysis":action.charAt(0).toUpperCase()+action.slice(1)}function botProtectionConfig(managedRules){return managedRules?.bot_filter??managedRules?.bot_protection}function currentBotProtectionAction(config){let ruleset=botProtectionConfig(config?.managedRules);return ruleset?.active?ruleset.action==="log"?"log":"challenge":"off"}function currentAiBotsAction(config){let ruleset=config?.managedRules?.ai_bots;return ruleset?.active?ruleset.action==="challenge"?"challenge":ruleset.action==="deny"?"deny":"log":"allow"}function currentBotIdAction(config){return config?.botIdEnabled?"deep-analysis":"basic"}function getManagedBotRule(config,id){let action=id==="bot-protection"?currentBotProtectionAction(config):id==="ai-bots"?currentAiBotsAction(config):currentBotIdAction(config);return{id,name:NAMES[id],action,wafRuleId:WAF_RULE_IDS[id]}}function getManagedBotRules(config){return MANAGED_BOT_RULE_IDS.map(id=>getManagedBotRule(config,id))}function parseManagedBotAction(id,raw){let action=raw.trim().toLowerCase().replace(/\s+/g,"-"),valid=ACTIONS[id];return valid.includes(action)?{action}:{error:`Invalid action "${raw}" for ${NAMES[id]}. Use ${valid.join(", ")}.`}}function buildManagedBotPatch(id,action){if(id==="bot-id")return{action:"botId.toggle",value:action==="deep-analysis"};let patchId=id==="bot-protection"?"bot_protection":"ai_bots";return action==="off"||action==="allow"?{action:"managedRules.update",id:patchId,value:{active:!1}}:{action:"managedRules.update",id:patchId,value:{active:!0,action}}}function suggestedManagedBotAction(rule){return rule.id==="bot-protection"?rule.action==="challenge"?"log":"challenge":rule.id==="ai-bots"?rule.action==="deny"?"allow":"deny":rule.action==="deep-analysis"?"basic":"deep-analysis"}function managedBotTrafficWarning(id,from,to){if(id==="ai-bots"&&to==="deny")return"AI Bots deny blocks known AI crawlers from this project.";if(id==="bot-protection"&&from==="off"&&to==="challenge")return"Bot Protection challenge will present a verification page to non-browser traffic."}function managedBotJson(rule){return{id:rule.id,name:rule.name,action:rule.action,wafRuleId:rule.wafRuleId??null}}function projectScope(project,teamId,teamSlug){return{type:"project",projectId:project.id,teamId,...teamSlug?{teamSlug}:{},displayName:project.name}}function firewallConfigUrl(scope,path=""){let query=new URLSearchParams;return scope.type==="project"?(query.set("projectId",scope.projectId),scope.teamId&&query.set("teamId",scope.teamId),`/v1/security/firewall/config${path}?${query.toString()}`):(query.set("teamId",scope.teamId),`/v1/security/firewall/team-config${path}?${query.toString()}`)}async function listFirewallConfigs(client,scope){return client.fetch(firewallConfigUrl(scope))}async function activateFirewallConfig(client,scope,configVersion){return client.fetch(firewallConfigUrl(scope,`/${configVersion}/activate`),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})})}var PRIORITY_PROJECT_ENABLE_COMMAND="project priority enable",BUY_PRO_COMMAND="buy pro";function withGlobalFlags(client,commandTemplate,scope,options={}){let template=scope?.type==="team"?`${commandTemplate} --team-level`:commandTemplate;return buildCommandWithGlobalFlags(client.argv,template,void 0,{globalFlags:"all",preserveProject:options.preserveProject??!0,excludeFlags:options.excludeFlags})}async function resolveFirewallScope(client,flags){if(flags["--team-level"]&&flags["--project"]){let message="Cannot specify both --team-level and --project. Use one or the other.";return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.INVALID_ARGUMENTS,message},2),2):(output_manager_default.error(message),2)}if(flags["--team-level"]){let{team}=await getScope(client);if(!team){let message="Team-level firewall requires a team scope. Personal accounts are not supported. Run `vercel switch` to select a team or pass --scope <team>.";return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_SCOPE,message},1),1):(output_manager_default.error(message),1)}return{type:"team",teamId:team.id,displayName:team.slug}}let link=await requireProjectContext(client,"firewall",flags["--project"]);if(typeof link=="number")return link;let{project,org}=link;return{type:"project",projectId:project.id,teamId:org.type==="team"?org.id:void 0,teamSlug:org.type==="team"?org.slug:void 0,displayName:project.name}}function mentionsPriorityProject(message){return/priority\s+project/i.test(message)||/priority\s+tier/i.test(message)}function teamPlan(scope){return scope.teamId?teamCache.get(scope.teamId)?.billing?.plan:void 0}function priorityTeam(scope){let cached=scope.teamId?teamCache.get(scope.teamId):void 0;if(scope.type==="team")return{id:scope.teamId,slug:scope.displayName,name:cached?.name??null,scopeArg:scope.displayName};if(!scope.teamId)return null;let slug=scope.teamSlug??cached?.slug??null;return{id:scope.teamId,slug,name:cached?.name??null,scopeArg:slug??scope.teamId}}function teamLabel(team){return team.name&&team.name!==team.slug?`${team.slug} (${team.name})`:team.slug}function styledCommand(command,plain){return plain?getCommandNamePlain(command):getCommandName(command)}function priorityProjectFix(scope){let excludeFlags=["--non-interactive","--project","--yes","--scope","--team"],project=scope.type==="project"?{id:scope.projectId,name:scope.displayName}:null,team=priorityTeam(scope),plan=teamPlan(scope)??null,data={project,team:team&&{id:team.id,slug:team.slug,name:team.name},plan},projectToken=project?quoteArg(project.name):"<project>",scopeFlag=team?` --scope ${quoteArg(team.scopeArg)}`:"",enable4=`${PRIORITY_PROJECT_ENABLE_COMMAND} ${projectToken}${scopeFlag}`;if(!team){let hint="Priority projects are only available on team accounts. Use --scope to specify one.";return{command:"",hint,plainHint:hint,when:hint,excludeFlags,preserveProject:!1,reason:AGENT_REASON.MISSING_SCOPE,data}}if(plan==="hobby"||plan==="oss"){let upgrade=`${BUY_PRO_COMMAND}${scopeFlag}`,hint=plain2=>`Priority Projects are only available on Pro or Enterprise team plans. Upgrade with ${styledCommand(upgrade,plain2)}, then run ${styledCommand(enable4,plain2)}.`;return{command:upgrade,hint:hint(!1),plainHint:hint(!0),when:"a person has approved upgrading the plan",excludeFlags,preserveProject:!1,reason:AGENT_REASON.PLAN_UPGRADE_REQUIRED,scope:team.scopeArg,data}}let shown=styledCommand(enable4,!1),plain=styledCommand(enable4,!0),placeholder="Replace <project> with a project on this team.";return{command:enable4,hint:project?shown:`${shown} ${placeholder}`,plainHint:project?plain:`${plain} ${placeholder}`,when:project?"user runs this command in an interactive terminal":"Replace <project> with a project on this team.",excludeFlags,preserveProject:!1,reason:AGENT_REASON.PLAN_UPGRADE_REQUIRED,scope:team.scopeArg,data}}function mapFirewallApiError(e,scope,fallback){let err=e;return scope.type==="team"&&err.status===403?err.code==="plan_not_supported"?`Team-level firewall requires an Enterprise plan (current team: "${scope.displayName}"). Pass --scope <team> or run \`vercel switch\` to target a different team.`:`You need to be a team owner to manage the team-level firewall for "${scope.displayName}".${err.message?` (${err.message})`:""}`:err.message||fallback}function priorityProjectMessage(scope,fix){let team=fix.data.team,label=team?.slug!=null?teamLabel({slug:team.slug,name:team.name}):void 0;return scope.type==="project"?label?`This rule requires a Priority project for ${scope.displayName} on team ${label}.`:`This rule requires a Priority project. ${fix.hint}`:label?`This rule requires a Priority project on team ${label}.`:"This rule requires a Priority project."}function failPriorityProjectGate(client,error,scope,opts){let serverMessage=apiServerMessage(error);if(!serverMessage||!mentionsPriorityProject(serverMessage))return null;let fix=priorityProjectFix(scope),message=priorityProjectMessage(scope,fix),payload={status:AGENT_STATUS.ERROR,reason:fix.reason,message,userActionRequired:!0,hint:fix.plainHint,retryable:!1,...fix.scope?{scope:fix.scope}:{},data:fix.data,...fix.command?{next:[{command:buildCommandWithGlobalFlags(client.argv,fix.command,packageName,{globalFlags:"all",preserveProject:!1,excludeFlags:fix.excludeFlags}),when:fix.when}]}:{}};return shouldEmitNonInteractiveCommandError(client)&&outputAgentError(client,payload,1),opts?.json?(output_manager_default.stopSpinner(),writeAgentError(client,payload),1):(output_manager_default.error(message),fix.command&&output_manager_default.log(fix.hint),1)}function getRulePayload(flags){let legacy=flags["--json"];return legacy!==void 0&&flags["--data"]!==void 0?(output_manager_default.error("Can't use --data with --json."),2):(legacy!==void 0&&output_manager_default.warning("--json is deprecated for rule payloads. Use --data."),flags["--data"]??legacy)}async function parseSubcommandArgs(argv,command,client,commandPath){let parsedArgs,fullPath=commandPath||command.name;try{parsedArgs=parseSubcommandArguments(argv,command)}catch(err){if(client?.nonInteractive){let rawMessage=err instanceof Error?err.message:String(err),flags=getGlobalFlagsFromArgs(client.argv.slice(2),{preserveProject:!0});return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.INVALID_ARGUMENTS,message:rawMessage,next:[{command:getCommandNamePlain(`firewall ${fullPath} ${flags.join(" ")}`.trim()),when:"fix options and retry"}]},2),2}return printError(err),2}return parsedArgs}async function confirmAction(client,skipConfirmation,message,details){return skipConfirmation?!0:client.nonInteractive||!client.stdin.isTTY?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`${message} Re-run with --yes to confirm.`,next:[{command:buildCommandWithYes(client.argv),when:"re-run with --yes to confirm"}]}),process.exit(1),!1):(details&&output_manager_default.print(` ${details}
10
+ `)}var NO_SERVER_MESSAGE="Response Error";function apiServerMessage(error){let message=isAPIError(error)?error.serverMessage:void 0;return message&&message!==NO_SERVER_MESSAGE?message:void 0}var FIREWALL_O11Y_ALERT_TYPES=["botId_anomaly","firewallSystemRule_anomaly","firewallCustomRule_anomaly"],FIREWALL_ANOMALY_TYPE="firewall_anomaly",SYS_DOS_MITIGATION_RULE_ID="sys_dos_mitigation",SYSTEM_RULE_ANOMALY_TYPE="firewallSystemRule_anomaly",FIREWALL_ACTIVITY_PLAN_MESSAGE="Traffic and alerts need Observability Plus.",FIREWALL_ALERTS_PARTIAL_ERROR_MESSAGE="Couldn't load every alert source.";function reduceAttackAnomaly(anomaly){return Object.keys(anomaly.affectedHostMap).reduce((acc,host)=>{acc.hosts.push(host);let challenged=anomaly.affectedHostMap[host].ddosAlerts?.["sys_dos_mitigation:challenge"]?.totalReqs||0,denied=anomaly.affectedHostMap[host].ddosAlerts?.["sys_dos_mitigation:deny"]?.totalReqs||0;return acc.challenged+=challenged,acc.denied+=denied,acc.count+=challenged+denied,acc},{hosts:[],challenged:0,denied:0,count:0})}function hostsFromAnomaly(anomaly){return Object.entries(anomaly.affectedHostMap).map(([host,data])=>{let challenged=data.ddosAlerts?.["sys_dos_mitigation:challenge"]?.totalReqs||0,denied=data.ddosAlerts?.["sys_dos_mitigation:deny"]?.totalReqs||0;return{name:host,count:challenged+denied}}).filter(row=>row.count>0).sort((a,b)=>b.count-a.count)}function mapAttackAnomaly(anomaly){let reduced=reduceAttackAnomaly(anomaly),parts=["System rule"];return reduced.denied>0&&parts.push(labelForAction("deny")),reduced.challenged>0&&parts.push(labelForAction("challenge")),{id:`${anomaly.ownerId}-${anomaly.projectId}-${anomaly.startTime}`,title:"DDoS Mitigation",type:FIREWALL_ANOMALY_TYPE,startedAt:anomaly.startTime,resolvedAt:anomaly.endTime||void 0,count:reduced.count,detail:parts.join(" \xB7 "),action:reduced.denied>=reduced.challenged?"deny":"challenge",ruleId:SYS_DOS_MITIGATION_RULE_ID,host:reduced.hosts[0]}}function mapO11yAlert(alert){if(!alert.startedAt)return null;let action=alert.data?.action,ruleId=alert.data?.ruleId,detailParts=[alert.type,action?labelForAction(action):void 0,ruleId].filter(Boolean);return{id:alert.id||`${alert.type}-${alert.startedAt}`,title:alert.title||alert.type||"Firewall alert",type:alert.type||"unknown",startedAt:alert.startedAt,resolvedAt:alert.resolvedAt,count:alert.data?.count,detail:detailParts.filter(p=>p!==alert.title).join(" \xB7 ")||void 0,action,ruleId,path:alert.data?.path}}var ATTACK_STATUS_MAX_DAYS=7;async function getAttackStatus(client,opts){let query=new URLSearchParams;if(query.set("projectId",opts.projectId),query.set("teamId",opts.teamId),opts.sinceDays!==void 0){let sinceDays=Math.min(ATTACK_STATUS_MAX_DAYS,Math.max(1,Math.ceil(opts.sinceDays)));query.set("since",String(sinceDays))}return client.fetch(`/v1/security/firewall/attack-status?${query.toString()}`,{accountId:opts.teamId,signal:opts.signal})}var O11Y_ALERTS_LIMIT=200;async function getFirewallO11yAlerts(client,opts){let query=new URLSearchParams;query.set("teamId",opts.teamId),query.set("projectId",opts.projectId),query.set("from",opts.from.toISOString()),query.set("to",opts.to.toISOString()),query.set("limit",String(O11Y_ALERTS_LIMIT));for(let type of FIREWALL_O11Y_ALERT_TYPES)query.append("types",type);return(await client.fetch(`/alerts/v3/groups?${query.toString()}`,{accountId:opts.teamId,signal:opts.signal})).flatMap(g=>g.alerts??[]).map(mapO11yAlert).filter(a=>a!==null)}var ALERTS_TIMEOUT_MS=2e4;function sourceFailureReason(err){return isAPIError(err)&&err.status===408||err instanceof Error&&(err.name==="TimeoutError"||err.name==="AbortError")?"timed out":isAPIError(err)&&err.status===402?"needs Observability Plus":isAPIError(err)&&typeof err.status=="number"?`HTTP ${err.status}`:err instanceof Error&&err.message?err.message:"unknown error"}function resolveAlertsWindow(opts){let now=Date.now(),to=opts.to??new Date(now),from=opts.from??new Date(to.getTime()-864e5*(opts.sinceDays??1)),sinceDays=opts.sinceDays??Math.max(1,Math.ceil((now-from.getTime())/864e5));return{from,to,sinceDays}}function classifyAlertSourceError(err){if(isAPIError(err)&&(err.status===401||err.status===403))throw err;return isAPIError(err)&&err.status===402?{reason:"plan",message:FIREWALL_ACTIVITY_PLAN_MESSAGE}:{reason:"error",message:apiServerMessage(err)||!isAPIError(err)&&err instanceof Error&&err.message||FIREWALL_ALERTS_PARTIAL_ERROR_MESSAGE}}async function getFirewallAlertsDetailed(client,opts){let{from,to,sinceDays}=resolveAlertsWindow(opts),timeoutMs=opts.timeoutMs??ALERTS_TIMEOUT_MS,signal=AbortSignal.timeout(timeoutMs),[o11yResult,attackResult]=await Promise.allSettled([getFirewallO11yAlerts(client,{...opts,from,to,signal}),getAttackStatus(client,{...opts,sinceDays,signal})]),errors=[],o11yAlerts=[],o11y;o11yResult.status==="fulfilled"?o11yAlerts=o11yResult.value:(o11y=classifyAlertSourceError(o11yResult.reason),errors.push({source:"alerts",message:sourceFailureReason(o11yResult.reason)}));let mappedAttacks=[],attackStatus;attackResult.status==="fulfilled"?mappedAttacks=(attackResult.value.anomalies||[]).map(mapAttackAnomaly):(attackStatus=classifyAlertSourceError(attackResult.reason),errors.push({source:"attackStatus",message:sourceFailureReason(attackResult.reason)}));let resolvedCutoff=from.getTime();return{alerts:mappedAttacks.concat(o11yAlerts.filter(a=>!a.resolvedAt||a.resolvedAt>resolvedCutoff)).sort((a,b)=>!a.resolvedAt&&b.resolvedAt?-1:a.resolvedAt&&!b.resolvedAt?1:b.startedAt-a.startedAt),o11y,attackStatus,errors}}function alertsIncompleteMessage(errors){return`Attack count and alerts may be incomplete: ${errors.map(e=>`${e.source==="alerts"?"alerts":"attack history"} ${e.message}`).join("; ")}.`}function countAttacksMitigated(alerts,windowStartMs,windowEndMs){return alerts.filter(alert=>isAttackAlert(alert)&&alertOverlapsWindow(alert,windowStartMs,windowEndMs)).length}function alertOverlapsWindow(alert,windowStartMs,windowEndMs){return alert.startedAt<=windowEndMs&&(alert.resolvedAt??Number.POSITIVE_INFINITY)>=windowStartMs}function isAttackAlert(alert){return alert.type===FIREWALL_ANOMALY_TYPE?!0:alert.type===SYSTEM_RULE_ANOMALY_TYPE&&alert.ruleId===SYS_DOS_MITIGATION_RULE_ID}var O11Y_ALERT_ID_PREFIX="al_",INSPECT_FALLBACK_DAYS=7;function isO11yAlertId(id){return id.startsWith(O11Y_ALERT_ID_PREFIX)}function parseLegacyAlertStartTime(id){let match=id.match(/-(\d{13})$/);return match?Number(match[1]):void 0}function daysCovering(startMs,endMs){return Math.max(1,Math.ceil((endMs-startMs)/864e5))}function mapGroupAsAlert(group,alertId){let nested=(group.alerts??[]).map(mapO11yAlert).filter(a=>a!==null),hit=nested.find(a=>a.id===alertId)??nested[0];if(hit)return hit;let startedAt=group.recordedStartedAt;return startedAt?mapO11yAlert({id:alertId,title:group.title,type:group.type,startedAt,resolvedAt:group.recordedResolvedAt,data:group.alerts?.[0]?.data}):null}async function getO11yAlertById(client,opts){let query=new URLSearchParams;query.set("teamId",opts.teamId),query.set("projectId",opts.projectId);try{let group=await client.fetch(`/alerts/v3/groups/${encodeURIComponent(opts.alertId)}?${query.toString()}`,{accountId:opts.teamId,signal:opts.signal});return mapGroupAsAlert(group,opts.alertId)}catch(err){if(isAPIError(err)&&err.status===404)return null;throw err}}async function findFirewallAlert(client,opts){let timeoutMs=opts.timeoutMs??ALERTS_TIMEOUT_MS,budget=()=>AbortSignal.timeout(timeoutMs),now=Date.now();if(isO11yAlertId(opts.alertId)){let fromGroup2=await getO11yAlertById(client,{...opts,signal:budget()});if(fromGroup2)return{alert:fromGroup2};let from=new Date(now-864e5*INSPECT_FALLBACK_DAYS),hit=(await getFirewallO11yAlerts(client,{projectId:opts.projectId,teamId:opts.teamId,from,to:new Date(now),signal:budget()})).find(a=>a.id===opts.alertId);return hit?{alert:hit}:null}let startTime=parseLegacyAlertStartTime(opts.alertId),sinceDays=startTime?daysCovering(startTime,now)+1:INSPECT_FALLBACK_DAYS,anomaly=((await getAttackStatus(client,{projectId:opts.projectId,teamId:opts.teamId,sinceDays,signal:budget()}).catch(err=>{if(isAPIError(err)&&(err.status===401||err.status===403))throw err;return{anomalies:[]}})).anomalies||[]).find(a=>`${a.ownerId}-${a.projectId}-${a.startTime}`===opts.alertId);if(anomaly)return{alert:mapAttackAnomaly(anomaly),hosts:hostsFromAnomaly(anomaly)};let fromGroup=await getO11yAlertById(client,{...opts,signal:budget()}).catch(err=>{if(isAPIError(err)&&(err.status===401||err.status===403))throw err;return null});return fromGroup?{alert:fromGroup}:null}var AI_BOTS_CATEGORY_ACTIONS=["allow","log","deny"];function getAiBotsCategories(ruleset,catalogGroups){return[...new Set([...Object.keys(catalogGroups??{}),...Object.keys(ruleset?.ruleGroups??{})])].sort().map(ruleGroupId=>({id:ruleGroupId.replace(/_/g,"-"),ruleGroupId,name:catalogGroups?.[ruleGroupId]?.name??formatCategoryName(ruleGroupId)}))}function formatCategoryName(ruleGroupId){return ruleGroupId.split("_").map(word=>word==="ai"?"AI":word[0].toUpperCase()+word.slice(1)).join(" ")}function getAiBotsCategoryAction(ruleset,ruleGroupId){if(!ruleset?.active)return"allow";let group=ruleset.ruleGroups?.[ruleGroupId];return group?.active===!1?"allow":group?.action??ruleset.action??"log"}function getAiBotsCategoryActionAfterEdit(ruleset,ruleGroupId){if(!ruleset)return"log";if(ruleset.active)return getAiBotsCategoryAction(ruleset,ruleGroupId);let group=ruleset.ruleGroups?.[ruleGroupId];return group?.active?group.action??"log":"allow"}function hasAiBotsCategories(ruleset){return Object.keys(ruleset?.ruleGroups??{}).length>0}function getAiBotsCategoryDetails(ruleset){if(hasAiBotsCategories(ruleset))return getAiBotsCategories(ruleset).map(category=>({...category,action:getAiBotsCategoryAction(ruleset,category.ruleGroupId)}))}function aiBotsJsonStatus(ruleset){let categories=getAiBotsCategoryDetails(ruleset);return{enabled:ruleset?.active??!1,action:categories?null:ruleset?.action??null,...categories?{categories}:{}}}var MANAGED_BOT_RULE_IDS=["bot-protection","ai-bots","bot-id"],ALIASES={"bot-protection":"bot-protection","bot protection":"bot-protection",bot_protection:"bot-protection",bot_filter:"bot-protection",managed_bot_protection:"bot-protection",managed_bot_filter:"bot-protection","ai-bots":"ai-bots","ai bots":"ai-bots",ai_bots:"ai-bots",managed_ai_bots:"ai-bots","bot-id":"bot-id",botid:"bot-id",bot_id:"bot-id"},ACTIONS={"bot-protection":["off","log","challenge"],"ai-bots":["allow","log","challenge","deny"],"bot-id":["basic","deep-analysis"]},NAMES={"bot-protection":"Bot Protection","ai-bots":"AI Bots","bot-id":"BotID"},WAF_RULE_IDS={"bot-protection":"managed_bot_protection","ai-bots":"managed_ai_bots"};function resolveManagedBotRuleId(identifier){if(identifier)return ALIASES[identifier.trim().toLowerCase()]}function managedBotActions(id,category){return category?AI_BOTS_CATEGORY_ACTIONS:ACTIONS[id]}function formatManagedBotAction(action){return action==="deep-analysis"?"Deep Analysis":action.charAt(0).toUpperCase()+action.slice(1)}function botProtectionConfig(managedRules){return managedRules?.bot_filter??managedRules?.bot_protection}function currentBotProtectionAction(config){let ruleset=botProtectionConfig(config?.managedRules);return ruleset?.active?ruleset.action==="log"?"log":"challenge":"off"}function currentAiBotsAction(config){let ruleset=config?.managedRules?.ai_bots;return ruleset?.active?ruleset.action==="challenge"?"challenge":ruleset.action==="deny"?"deny":"log":"allow"}function currentBotIdAction(config){return config?.botIdEnabled?"deep-analysis":"basic"}function getManagedBotRule(config,id){let categories=id==="ai-bots"?getAiBotsCategoryDetails(config?.managedRules?.ai_bots):void 0,action=categories?null:id==="bot-protection"?currentBotProtectionAction(config):id==="ai-bots"?currentAiBotsAction(config):currentBotIdAction(config);return{id,name:NAMES[id],action,wafRuleId:WAF_RULE_IDS[id],...categories?{categories}:{}}}function getManagedBotRules(config){return MANAGED_BOT_RULE_IDS.map(id=>getManagedBotRule(config,id))}function parseManagedBotAction(id,raw,category){let action=raw.trim().toLowerCase().replace(/\s+/g,"-"),valid=managedBotActions(id,category);return valid.includes(action)?{action}:{error:`Invalid action "${raw}" for ${category?.name??NAMES[id]}. Use ${valid.join(", ")}.`}}function buildManagedBotPatch(id,action,category){if(category)return{action:"managedRuleGroup.update",id:"ai_bots",value:{[category.ruleGroupId]:action==="allow"?{active:!1}:{active:!0,action}}};if(id==="bot-id")return{action:"botId.toggle",value:action==="deep-analysis"};let patchId=id==="bot-protection"?"bot_protection":"ai_bots";return action==="off"||action==="allow"?{action:"managedRules.update",id:patchId,value:{active:!1}}:{action:"managedRules.update",id:patchId,value:{active:!0,action}}}function suggestedManagedBotAction(rule){return rule.id==="bot-protection"?rule.action==="challenge"?"log":"challenge":rule.id==="ai-bots"?rule.action==="deny"?"allow":"deny":rule.action==="deep-analysis"?"basic":"deep-analysis"}function managedBotTrafficWarning(id,from,to,category){if(id==="ai-bots"&&to==="deny")return category?`Deny blocks known ${category.name} traffic when published.`:"AI Bots deny blocks known AI crawlers from this project.";if(id==="bot-protection"&&from==="off"&&to==="challenge")return"Bot Protection challenge will present a verification page to non-browser traffic."}function managedBotJson(rule){return{id:rule.id,name:rule.name,action:rule.action,wafRuleId:rule.wafRuleId??null,...rule.categories?{categories:rule.categories}:{}}}function suggestedManagedBotEditCommand(rule){let category=rule.categories?.[0];if(rule.id==="ai-bots"&&!category)return"firewall rules update ai-bots";let action=suggestedManagedBotAction(category?{...rule,action:category.action}:rule);return`firewall rules update ${rule.id}${category?` --category ${category.id}`:""} --action ${action}`}function projectScope(project,teamId,teamSlug){return{type:"project",projectId:project.id,teamId,...teamSlug?{teamSlug}:{},displayName:project.name}}function firewallConfigUrl(scope,path=""){let query=new URLSearchParams;return scope.type==="project"?(query.set("projectId",scope.projectId),scope.teamId&&query.set("teamId",scope.teamId),`/v1/security/firewall/config${path}?${query.toString()}`):(query.set("teamId",scope.teamId),`/v1/security/firewall/team-config${path}?${query.toString()}`)}async function listFirewallConfigs(client,scope){return client.fetch(firewallConfigUrl(scope))}async function activateFirewallConfig(client,scope,configVersion){return client.fetch(firewallConfigUrl(scope,`/${configVersion}/activate`),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})})}var PRIORITY_PROJECT_ENABLE_COMMAND="project priority enable",BUY_PRO_COMMAND="buy pro";function withGlobalFlags(client,commandTemplate,scope,options={}){let template=scope?.type==="team"?`${commandTemplate} --team-level`:commandTemplate;return buildCommandWithGlobalFlags(client.argv,template,void 0,{globalFlags:"all",preserveProject:options.preserveProject??!0,excludeFlags:options.excludeFlags})}async function resolveFirewallScope(client,flags){if(flags["--team-level"]&&flags["--project"]){let message="Cannot specify both --team-level and --project. Use one or the other.";return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.INVALID_ARGUMENTS,message},2),2):(output_manager_default.error(message),2)}if(flags["--team-level"]){let{team}=await getScope(client);if(!team){let message="Team-level firewall requires a team scope. Personal accounts are not supported. Run `vercel switch` to select a team or pass --scope <team>.";return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_SCOPE,message},1),1):(output_manager_default.error(message),1)}return{type:"team",teamId:team.id,displayName:team.slug}}let link=await requireProjectContext(client,"firewall",flags["--project"]);if(typeof link=="number")return link;let{project,org}=link;return{type:"project",projectId:project.id,teamId:org.type==="team"?org.id:void 0,teamSlug:org.type==="team"?org.slug:void 0,displayName:project.name}}function mentionsPriorityProject(message){return/priority\s+project/i.test(message)||/priority\s+tier/i.test(message)}function teamPlan(scope){return scope.teamId?teamCache.get(scope.teamId)?.billing?.plan:void 0}function priorityTeam(scope){let cached=scope.teamId?teamCache.get(scope.teamId):void 0;if(scope.type==="team")return{id:scope.teamId,slug:scope.displayName,name:cached?.name??null,scopeArg:scope.displayName};if(!scope.teamId)return null;let slug=scope.teamSlug??cached?.slug??null;return{id:scope.teamId,slug,name:cached?.name??null,scopeArg:slug??scope.teamId}}function teamLabel(team){return team.name&&team.name!==team.slug?`${team.slug} (${team.name})`:team.slug}function styledCommand(command,plain){return plain?getCommandNamePlain(command):getCommandName(command)}function priorityProjectFix(scope){let excludeFlags=["--non-interactive","--project","--yes","--scope","--team"],project=scope.type==="project"?{id:scope.projectId,name:scope.displayName}:null,team=priorityTeam(scope),plan=teamPlan(scope)??null,data={project,team:team&&{id:team.id,slug:team.slug,name:team.name},plan},projectToken=project?quoteArg(project.name):"<project>",scopeFlag=team?` --scope ${quoteArg(team.scopeArg)}`:"",enable4=`${PRIORITY_PROJECT_ENABLE_COMMAND} ${projectToken}${scopeFlag}`;if(!team){let hint="Priority projects are only available on team accounts. Use --scope to specify one.";return{command:"",hint,plainHint:hint,when:hint,excludeFlags,preserveProject:!1,reason:AGENT_REASON.MISSING_SCOPE,data}}if(plan==="hobby"||plan==="oss"){let upgrade=`${BUY_PRO_COMMAND}${scopeFlag}`,hint=plain2=>`Priority Projects are only available on Pro or Enterprise team plans. Upgrade with ${styledCommand(upgrade,plain2)}, then run ${styledCommand(enable4,plain2)}.`;return{command:upgrade,hint:hint(!1),plainHint:hint(!0),when:"a person has approved upgrading the plan",excludeFlags,preserveProject:!1,reason:AGENT_REASON.PLAN_UPGRADE_REQUIRED,scope:team.scopeArg,data}}let shown=styledCommand(enable4,!1),plain=styledCommand(enable4,!0),placeholder="Replace <project> with a project on this team.";return{command:enable4,hint:project?shown:`${shown} ${placeholder}`,plainHint:project?plain:`${plain} ${placeholder}`,when:project?"user runs this command in an interactive terminal":"Replace <project> with a project on this team.",excludeFlags,preserveProject:!1,reason:AGENT_REASON.PLAN_UPGRADE_REQUIRED,scope:team.scopeArg,data}}function mapFirewallApiError(e,scope,fallback){let err=e;return scope.type==="team"&&err.status===403?err.code==="plan_not_supported"?`Team-level firewall requires an Enterprise plan (current team: "${scope.displayName}"). Pass --scope <team> or run \`vercel switch\` to target a different team.`:`You need to be a team owner to manage the team-level firewall for "${scope.displayName}".${err.message?` (${err.message})`:""}`:err.message||fallback}function priorityProjectMessage(scope,fix){let team=fix.data.team,label=team?.slug!=null?teamLabel({slug:team.slug,name:team.name}):void 0;return scope.type==="project"?label?`This rule requires a Priority project for ${scope.displayName} on team ${label}.`:`This rule requires a Priority project. ${fix.hint}`:label?`This rule requires a Priority project on team ${label}.`:"This rule requires a Priority project."}function failPriorityProjectGate(client,error,scope,opts){let serverMessage=apiServerMessage(error);if(!serverMessage||!mentionsPriorityProject(serverMessage))return null;let fix=priorityProjectFix(scope),message=priorityProjectMessage(scope,fix),payload={status:AGENT_STATUS.ERROR,reason:fix.reason,message,userActionRequired:!0,hint:fix.plainHint,retryable:!1,...fix.scope?{scope:fix.scope}:{},data:fix.data,...fix.command?{next:[{command:buildCommandWithGlobalFlags(client.argv,fix.command,packageName,{globalFlags:"all",preserveProject:!1,excludeFlags:fix.excludeFlags}),when:fix.when}]}:{}};return shouldEmitNonInteractiveCommandError(client)&&outputAgentError(client,payload,1),opts?.json?(output_manager_default.stopSpinner(),writeAgentError(client,payload),1):(output_manager_default.error(message),fix.command&&output_manager_default.log(fix.hint),1)}function getRulePayload(flags){let legacy=flags["--json"];return legacy!==void 0&&flags["--data"]!==void 0?(output_manager_default.error("Can't use --data with --json."),2):(legacy!==void 0&&output_manager_default.warning("--json is deprecated for rule payloads. Use --data."),flags["--data"]??legacy)}async function parseSubcommandArgs(argv,command,client,commandPath){let parsedArgs,fullPath=commandPath||command.name;try{parsedArgs=parseSubcommandArguments(argv,command)}catch(err){if(client?.nonInteractive){let rawMessage=err instanceof Error?err.message:String(err),flags=getGlobalFlagsFromArgs(client.argv.slice(2),{preserveProject:!0});return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.INVALID_ARGUMENTS,message:rawMessage,next:[{command:getCommandNamePlain(`firewall ${fullPath} ${flags.join(" ")}`.trim()),when:"fix options and retry"}]},2),2}return printError(err),2}return parsedArgs}async function confirmAction(client,skipConfirmation,message,details){return skipConfirmation?!0:client.nonInteractive||!client.stdin.isTTY?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`${message} Re-run with --yes to confirm.`,next:[{command:buildCommandWithYes(client.argv),when:"re-run with --yes to confirm"}]}),process.exit(1),!1):(details&&output_manager_default.print(` ${details}
11
11
  `),await client.input.confirm(message,!1))}function firewallPermissionMessage(action,projectName){return`You don't have permission to ${action} for ${projectName}. Ask a team owner to grant access.`}function failFirewall(client,opts){let reason=opts.reason??AGENT_REASON.INVALID_ARGUMENTS,exitCode=getExitCodeForReason(reason);return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason,message:opts.message,...opts.fix?.hint?{hint:opts.fix.hint}:{},next:[...opts.fix?.command?[{command:withGlobalFlags(client,opts.fix.command,void 0,{excludeFlags:opts.fix.excludeFlags,preserveProject:opts.fix.preserveProject}),...opts.fix.when?{when:opts.fix.when}:{}}]:[],...opts.nextCommand?[{command:withGlobalFlags(client,opts.nextCommand)}]:[]]},exitCode),exitCode):(output_manager_default.error(opts.message),opts.fix&&output_manager_default.log(opts.fix.hint),exitCode)}function failFirewallObservabilityPlan(client,error,projectName){let message=apiServerMessage(error)??FIREWALL_ACTIVITY_PLAN_MESSAGE,fix=clientObservabilityPlanRecovery(client,error,message,projectName);return failFirewall(client,{message,fix,reason:AGENT_REASON.API_ERROR})}function refuseManagedBotMutation(client,scope,identifier,verb){if(scope.type!=="project")return null;let id=resolveManagedBotRuleId(identifier);if(!id)return null;let command=`firewall rules update ${id} --action <action>`;return failFirewall(client,{message:`Can't ${verb} "${identifier}". That's a managed bot rule.`,reason:AGENT_REASON.INVALID_ARGUMENTS,fix:{command,hint:`Use ${import_chalk2.default.cyan(withGlobalFlags(client,command,scope))} to change it.`,when:"change the managed bot rule instead"}})}function isRetryableApiError(error){return isAPIError(error)&&(error.status>=500||error.status===429)}function failFirewallApi(client,e,opts){if(isAPIError(e)&&(e.status===401||e.status===403))return failFirewall(client,{message:firewallPermissionMessage(opts.permissionAction,opts.projectName),reason:AGENT_REASON.PERMISSION_DENIED});if(e instanceof Error&&(e.name==="TimeoutError"||e.name==="AbortError")){let job=opts.timeoutJob??"firewall data";return failFirewall(client,{message:`Timed out waiting for ${job}. Re-run the command \u2014 the next try is usually faster.`,nextCommand:opts.nextCommand,reason:AGENT_REASON.API_ERROR})}let msg=e instanceof Error&&e.message?e.message:opts.fallback;return failFirewall(client,{message:msg,nextCommand:isRetryableApiError(e)?opts.nextCommand:void 0,reason:AGENT_REASON.API_ERROR})}function outputJson(client,data){output_manager_default.stopSpinner(),client.stdout.write(JSON.stringify(data,null,2)+`
12
12
  `)}async function detectExistingDraft(client,scope){let{draft}=await listFirewallConfigs(client,scope);return draft!==null&&draft.changes.length>0}async function offerAutoPublish(client,scope,hadExistingDraft,opts){if(output_manager_default.print(`
13
13
  ${import_chalk2.default.gray(`This change is staged. Run ${import_chalk2.default.cyan(withGlobalFlags(client,"firewall publish",scope))} to make it live, or ${import_chalk2.default.cyan(withGlobalFlags(client,"firewall discard",scope))} to undo.`)}
@@ -20,22 +20,22 @@ import{FILTER_DEPRECATION_WARNING,alignTimeRangeToGranularity,canonicalResponseT
20
20
  `)}var import_chalk4=__toESM(require_source(),1);var OVERVIEW_TOP_RULES=8,MAX_RULE_VALUE_WIDTH=40;function formatOverviewOutput(opts){let lines=[],windowStartMs=new Date(opts.startTime).getTime(),windowEndMs=new Date(opts.endTime).getTime(),needsDate=windowNeedsDate(windowStartMs,windowEndMs),attacksSuffix=opts.attacksMitigatedIncomplete?` ${import_chalk4.default.dim("\xB7 at least, some alerts unread")}`:"";lines.push(` ${import_chalk4.default.bold("Attacks mitigated")} (this window) ${formatCount(opts.attacksMitigated)}${attacksSuffix}`),lines.push("");let allTs=new Set;for(let s of opts.series)for(let p of s.timeseries)allTs.add(p.timestamp);let axis=[...allTs].sort(),bucket=opts.granularity?granularityLabel(opts.granularity):void 0,rangeLabel=`${formatUtcTime(windowStartMs,!0)} \u2013 ${formatUtcTime(windowEndMs,!0)} UTC`,pointsLabel=axis.length>0?` \xB7 ${axis.length} point${axis.length===1?"":"s"}${bucket?` (${bucket} each)`:""}`:"";lines.push(` ${import_chalk4.default.bold("Requests by Action")} ${rangeLabel+pointsLabel}`);let hasAnyTraffic=opts.series.some(s=>s.total>0||s.timeseries.some(p=>p.value>0));if(opts.series.length===0||axis.length===0||!hasAnyTraffic)lines.push(import_chalk4.default.dim(" No request data for this period."));else{let rows=[["Action","Trend","Total","Peak","Peak at"].map(h=>import_chalk4.default.bold(import_chalk4.default.cyan(h)))];for(let s of opts.series){let byTs=new Map(s.timeseries.map(p=>[p.timestamp,p.value])),values=axis.map(t=>byTs.get(t)??0),peak=0,peakTs="";for(let i=0;i<axis.length;i++)values[i]>peak&&(peak=values[i],peakTs=axis[i]);let plain=x=>x,color=s.total>0?ACTION_COLORS[s.action]??plain:import_chalk4.default.dim,trend=s.total>0?plain:import_chalk4.default.dim;rows.push([color(labelForAction(s.action)),trend(generateSparkline(values)),formatCount(s.total),peak>0?formatCount(peak):"--",peak>0?formatUtcTime(new Date(peakTs).getTime(),needsDate):"--"])}let rendered=table(rows,{align:["l","l","r","r","r"],hsep:3});for(let line2 of rendered.split(`
21
21
  `))lines.push(` ${line2}`.trimEnd())}if(lines.push(""),lines.push(` ${import_chalk4.default.bold("Rules")} (top ${OVERVIEW_TOP_RULES})`),opts.rules.length===0)lines.push(import_chalk4.default.dim(" No rule traffic for this period."));else{let rows=[["Rule","Requests","Id"].map(h=>import_chalk4.default.bold(import_chalk4.default.cyan(h)))];for(let r of opts.rules)rows.push([ellipsizeMiddle(r.name,MAX_RULE_VALUE_WIDTH),formatCount(r.total),ellipsizeMiddle(r.id,MAX_RULE_VALUE_WIDTH)]);let rendered=table(rows,{align:["l","r","l"],hsep:3});for(let line2 of rendered.split(`
22
22
  `))lines.push(` ${line2}`.trimEnd())}if(opts.annotations.length>0){lines.push(""),lines.push(import_chalk4.default.bold(" Alerts in this window"));for(let a of opts.annotations.slice(0,8)){let when=formatUtcTime(a.startedAt,needsDate),ago=`(${relativeTime(a.startedAt)})`,count=a.count!==void 0?` \xB7 ${formatCount(a.count)}`:"",detail=a.detail?` \xB7 ${colorizeDetail(a.detail)}`:"";lines.push(` ${import_chalk4.default.yellow("!")} ${when} UTC ${ago} ${a.title}${detail}${count}`)}}return lines.push(""),lines.join(`
23
- `)}var import_chalk5=__toESM(require_source(),1);var PLAN_UNAVAILABLE="Requires Pro or Enterprise",MS_PER_SECOND=1e3,MS_PER_MINUTE=60*MS_PER_SECOND,MS_PER_HOUR=60*MS_PER_MINUTE;function formatDuration(ms8){let hours=Math.floor(ms8/MS_PER_HOUR),minutes=Math.floor(ms8%MS_PER_HOUR/MS_PER_MINUTE);return`${hours}h ${minutes}m`}function isAllSourcesBypass(ip){return ip==="0.0.0.0/0"||ip==="::/0"}var MAX_EXPIRY_SECONDS=4102444800;function parseExpirySeconds(expiry){if(!expiry||!/^\d+$/.test(expiry))return null;let seconds=Number(expiry);return Number.isSafeInteger(seconds)&&seconds<=MAX_EXPIRY_SECONDS?seconds:null}function allSourcesBypassExpiries(firewallBypassIps=[],bypass=[]){let expiries=[];for(let entry of firewallBypassIps){let[ip,expiry]=entry.split("#");isAllSourcesBypass(ip)&&expiries.push(parseExpirySeconds(expiry))}for(let rule of bypass??[])!isAllSourcesBypass(rule.Ip)||rule.Domain!=="*"||expiries.push(rule.ExpiresAt??null);return expiries}function getMitigationsStatus(firewallBypassIps,bypass){let expiries=allSourcesBypassExpiries(firewallBypassIps,bypass);if(expiries.includes(null))return{paused:!0};let nowSeconds=Date.now()/MS_PER_SECOND,unexpired=expiries.filter(expiry=>expiry!==null&&expiry>nowSeconds);return unexpired.length?{paused:!0,resumesAt:Math.max(...unexpired)}:{paused:!1}}function formatAttackModeStatus(status2){if(!status2.enabled)return import_chalk5.default.dim("Off");if(status2.activeUntil){let remainingMs=status2.activeUntil-Date.now();return remainingMs<=0?import_chalk5.default.dim("Off (expired)"):import_chalk5.default.red(`On (expires in ${formatDuration(remainingMs)})`)}return import_chalk5.default.red("On")}function formatMitigationsStatus(status2){if(!status2.paused)return import_chalk5.default.green("Active");if(status2.resumesAt!==void 0){let remainingMs=status2.resumesAt*MS_PER_SECOND-Date.now();if(remainingMs>0)return import_chalk5.default.yellow(`Paused (auto-resumes in ${formatDuration(remainingMs)})`)}return import_chalk5.default.yellow("Paused")}function formatStatusOutput(opts){let{active,draft,bypass,attackMode,firewallBypassIps}=opts,lines=[];if(lines.push(formatAlignedLabel("Firewall",active?active.firewallEnabled?import_chalk5.default.green("Enabled"):import_chalk5.default.red("Disabled"):import_chalk5.default.dim("Not configured"))),bypass===null)lines.push(formatAlignedLabel("Bypass",import_chalk5.default.dim(PLAN_UNAVAILABLE)));else{let regularBypasses=bypass.filter(b=>!isAllSourcesBypass(b.Ip));lines.push(formatAlignedLabel("Bypass",`${regularBypasses.length} IP${regularBypasses.length!==1?"s":""}`))}if(lines.push(formatAlignedLabel("Mitigations",formatMitigationsStatus(getMitigationsStatus(firewallBypassIps,bypass)))),attackMode&&lines.push(formatAlignedLabel("Attack Mode",formatAttackModeStatus(attackMode))),active){lines.push(formatAlignedLabel("IP Blocks",String(active.ips.length)));let activeRules=active.rules.filter(r=>r.active).length,inactiveRules=active.rules.filter(r=>!r.active).length;lines.push(formatAlignedLabel("Rules",`${activeRules} active, ${inactiveRules} inactive (${active.rules.length} total)`))}if(lines.push(formatAlignedLabel("Bot Protection",formatBotProtectionStatus(getBotProtectionConfig(active?.managedRules)))),lines.push(formatAlignedLabel("AI Bots",formatAiBotsStatus(active?.managedRules?.ai_bots))),lines.push(formatAlignedLabel("OWASP",formatOwaspStatus(active?.managedRules?.owasp))),draft&&draft.changes.length>0){lines.push(""),lines.push(formatAlignedLabel("Draft",import_chalk5.default.yellow(`${draft.changes.length} unpublished change${draft.changes.length!==1?"s":""}`)));let activeRulesMap=new Map((active?.rules||[]).map(r=>[r.id,r]));lines.push(formatDiffOutput(draft.changes,activeRulesMap))}return lines.join(`
23
+ `)}var import_chalk5=__toESM(require_source(),1);var PLAN_UNAVAILABLE="Requires Pro or Enterprise",MS_PER_SECOND=1e3,MS_PER_MINUTE=60*MS_PER_SECOND,MS_PER_HOUR=60*MS_PER_MINUTE;function formatDuration(ms8){let hours=Math.floor(ms8/MS_PER_HOUR),minutes=Math.floor(ms8%MS_PER_HOUR/MS_PER_MINUTE);return`${hours}h ${minutes}m`}function isAllSourcesBypass(ip){return ip==="0.0.0.0/0"||ip==="::/0"}var MAX_EXPIRY_SECONDS=4102444800;function parseExpirySeconds(expiry){if(!expiry||!/^\d+$/.test(expiry))return null;let seconds=Number(expiry);return Number.isSafeInteger(seconds)&&seconds<=MAX_EXPIRY_SECONDS?seconds:null}function allSourcesBypassExpiries(firewallBypassIps=[],bypass=[]){let expiries=[];for(let entry of firewallBypassIps){let[ip,expiry]=entry.split("#");isAllSourcesBypass(ip)&&expiries.push(parseExpirySeconds(expiry))}for(let rule of bypass??[])!isAllSourcesBypass(rule.Ip)||rule.Domain!=="*"||expiries.push(rule.ExpiresAt??null);return expiries}function getMitigationsStatus(firewallBypassIps,bypass){let expiries=allSourcesBypassExpiries(firewallBypassIps,bypass);if(expiries.includes(null))return{paused:!0};let nowSeconds=Date.now()/MS_PER_SECOND,unexpired=expiries.filter(expiry=>expiry!==null&&expiry>nowSeconds);return unexpired.length?{paused:!0,resumesAt:Math.max(...unexpired)}:{paused:!1}}function formatAttackModeStatus(status2){if(!status2.enabled)return import_chalk5.default.dim("Off");if(status2.activeUntil){let remainingMs=status2.activeUntil-Date.now();return remainingMs<=0?import_chalk5.default.dim("Off (expired)"):import_chalk5.default.red(`On (expires in ${formatDuration(remainingMs)})`)}return import_chalk5.default.red("On")}function formatMitigationsStatus(status2){if(!status2.paused)return import_chalk5.default.green("Active");if(status2.resumesAt!==void 0){let remainingMs=status2.resumesAt*MS_PER_SECOND-Date.now();if(remainingMs>0)return import_chalk5.default.yellow(`Paused (auto-resumes in ${formatDuration(remainingMs)})`)}return import_chalk5.default.yellow("Paused")}function formatStatusOutput(opts){let{active,draft,bypass,attackMode,firewallBypassIps}=opts,lines=[];if(lines.push(formatAlignedLabel("Firewall",active?active.firewallEnabled?import_chalk5.default.green("Enabled"):import_chalk5.default.red("Disabled"):import_chalk5.default.dim("Not configured"))),bypass===null)lines.push(formatAlignedLabel("Bypass",import_chalk5.default.dim(PLAN_UNAVAILABLE)));else{let regularBypasses=bypass.filter(b=>!isAllSourcesBypass(b.Ip));lines.push(formatAlignedLabel("Bypass",`${regularBypasses.length} IP${regularBypasses.length!==1?"s":""}`))}if(lines.push(formatAlignedLabel("Mitigations",formatMitigationsStatus(getMitigationsStatus(firewallBypassIps,bypass)))),attackMode&&lines.push(formatAlignedLabel("Attack Mode",formatAttackModeStatus(attackMode))),active){lines.push(formatAlignedLabel("IP Blocks",String(active.ips.length)));let activeRules=active.rules.filter(r=>r.active).length,inactiveRules=active.rules.filter(r=>!r.active).length;lines.push(formatAlignedLabel("Rules",`${activeRules} active, ${inactiveRules} inactive (${active.rules.length} total)`))}lines.push(formatAlignedLabel("Bot Protection",formatBotProtectionStatus(getBotProtectionConfig(active?.managedRules))));let aiBotsCategories=getAiBotsCategoryDetails(active?.managedRules?.ai_bots);if(aiBotsCategories)for(let category of aiBotsCategories)lines.push(formatAlignedLabel(category.name,colorManagedBotAction(category.action)));else lines.push(formatAlignedLabel("AI Bots",formatAiBotsStatus(active?.managedRules?.ai_bots)));if(lines.push(formatAlignedLabel("OWASP",formatOwaspStatus(active?.managedRules?.owasp))),draft&&draft.changes.length>0){lines.push(""),lines.push(formatAlignedLabel("Draft",import_chalk5.default.yellow(`${draft.changes.length} unpublished change${draft.changes.length!==1?"s":""}`)));let activeRulesMap=new Map((active?.rules||[]).map(r=>[r.id,r]));lines.push(formatDiffOutput(draft.changes,activeRulesMap))}return lines.join(`
24
24
  `)}function formatBypassTable(bypasses){let lines=[],domains=bypasses.map(b=>b.Domain==="*"?"All domains":b.Domain),ipWidth=Math.max(7,...bypasses.map(b=>b.Ip.length)),domainWidth=Math.max(6,...domains.map(d=>d.length)),gap=3;lines.push(` ${import_chalk5.default.dim("IP/CIDR".padEnd(ipWidth+gap))}${import_chalk5.default.dim("Domain".padEnd(domainWidth+gap))}${import_chalk5.default.dim("Note")}`);for(let i=0;i<bypasses.length;i++){let bypass=bypasses[i],ip=bypass.Ip.padEnd(ipWidth+gap),domain=domains[i].padEnd(domainWidth+gap),note=bypass.Note||"";lines.push(` ${ip}${domain}${note}`)}return lines.join(`
25
25
  `)}function annotateIpRules(activeIps,draftIps,changes){if(!draftIps)return activeIps.map(rule=>({rule,status:"live"}));let addedIds=new Set(changes.filter(c=>c.action==="ip.insert").map(c=>c.id).filter(id=>id!=null)),removedIds=new Set(changes.filter(c=>c.action==="ip.remove").map(c=>c.id).filter(id=>id!=null)),modifiedIds=new Set(changes.filter(c=>c.action==="ip.update").map(c=>c.id).filter(id=>id!=null)),result=[];for(let rule of draftIps)addedIds.has(rule.id)?result.push({rule,status:"added"}):modifiedIds.has(rule.id)?result.push({rule,status:"modified"}):result.push({rule,status:"live"});for(let rule of activeIps)removedIds.has(rule.id)&&result.push({rule,status:"removed"});return result}function formatIpBlocksTable(annotated){let lines=[],hostnames=annotated.map(a=>a.rule.hostname==="*"||a.rule.hostname===""?"All hosts":a.rule.hostname),gap=3,prefixWidth=2,ipWidth=Math.max(7,...annotated.map(a=>a.rule.ip.length)),hostnameWidth=Math.max(8,...hostnames.map(h=>h.length));lines.push(` ${" ".repeat(prefixWidth)}${import_chalk5.default.dim("IP/CIDR".padEnd(ipWidth+gap))}${import_chalk5.default.dim("Hostname".padEnd(hostnameWidth+gap))}${import_chalk5.default.dim("Notes")}`);for(let i=0;i<annotated.length;i++){let{rule,status:status2}=annotated[i],ip=rule.ip.padEnd(ipWidth+gap),hostname=hostnames[i].padEnd(hostnameWidth+gap),notes=rule.notes||"",prefix=" ",colorFn=s=>s;status2==="added"?(prefix="+ ",colorFn=import_chalk5.default.green):status2==="removed"?(prefix="- ",colorFn=import_chalk5.default.red):status2==="modified"&&(prefix="~ ",colorFn=import_chalk5.default.yellow),lines.push(colorFn(` ${prefix}${ip}${hostname}${notes}`))}return lines.join(`
26
- `)}function getDiffSymbol(action){return action.endsWith(".insert")?{symbol:"+",color:import_chalk5.default.green}:action.endsWith(".remove")?{symbol:"-",color:import_chalk5.default.red}:{symbol:"~",color:import_chalk5.default.yellow}}function formatChangeDescription(change,activeRules){let{action,id,value}=change;switch(action){case"rules.insert":return`Added rule "${value?.name||id||"unknown"}"`;case"rules.update":{let draft=value,ruleName=draft?.name||id||"unknown";if(activeRules&&id&&draft&&typeof draft.active=="boolean"){let activeRule=activeRules.get(id);if(activeRule&&activeRule.active!==draft.active){let nameUnchanged=activeRule.name===draft.name,conditionsUnchanged=JSON.stringify(activeRule.conditionGroup)===JSON.stringify(draft.conditionGroup),actionUnchanged=JSON.stringify(activeRule.action)===JSON.stringify(draft.action),descriptionUnchanged=(activeRule.description||"")===(draft.description||"");if(nameUnchanged&&conditionsUnchanged&&actionUnchanged&&descriptionUnchanged)return draft.active?`Enabled rule "${ruleName}"`:`Disabled rule "${ruleName}"`}}return`Modified rule "${ruleName}"`}case"rules.remove":return`Removed rule "${id||"unknown"}"`;case"rules.priority":return`Reordered rule "${value?.name||id||"unknown"}"`;case"ip.insert":return`Added IP block ${value?.ip||"unknown"}`;case"ip.remove":return`Removed IP block ${id||"unknown"}`;case"ip.update":return`Modified IP block ${value?.ip||id||"unknown"}`;case"firewallEnabled":return`${value?"Enabled":"Disabled"} firewall`;case"crs.update":return"Updated OWASP CRS configuration";case"crs.disable":return"Disabled OWASP CRS";case"managedRules.update":return"Updated managed ruleset configuration";case"managedRuleGroup.update":return"Updated managed rule group";case"botId.toggle":return`${value?"Enabled":"Disabled"} Bot ID detection`;case"ja3Enabled":return`${value?"Enabled":"Disabled"} JA3 fingerprinting`;case"ja4Enabled":return`${value?"Enabled":"Disabled"} JA4 fingerprinting`;case"logHeaders.update":return"Updated log headers configuration";default:return`${action}${id?` (${id})`:""}`}}function formatRuleFieldDiff(activeRule,draftValue){let lines=[];if(draftValue.name&&activeRule.name!==draftValue.name&&lines.push(import_chalk5.default.yellow(` ~ Name: "${activeRule.name}" \u2192 "${draftValue.name}"`)),draftValue.action&&JSON.stringify(activeRule.action)!==JSON.stringify(draftValue.action)){let oldAction=formatActionDisplay(activeRule.action),newAction=formatActionDisplay(draftValue.action);lines.push(import_chalk5.default.yellow(` ~ Action: ${oldAction} \u2192 ${newAction}`))}if(draftValue.conditionGroup&&JSON.stringify(activeRule.conditionGroup)!==JSON.stringify(draftValue.conditionGroup)){let oldConditions=new Set(activeRule.conditionGroup.flatMap(g=>g.conditions.map(c=>formatConditionCompact(c)))),newConditions=new Set(draftValue.conditionGroup.flatMap(g=>g.conditions.map(c=>formatConditionCompact(c)))),added=[...newConditions].filter(c=>!oldConditions.has(c)),removed=[...oldConditions].filter(c=>!newConditions.has(c));for(let c of added)lines.push(import_chalk5.default.green(` + Condition: ${c}`));for(let c of removed)lines.push(import_chalk5.default.red(` - Condition: ${c}`));added.length===0&&removed.length===0&&lines.push(import_chalk5.default.yellow(" ~ Condition groups restructured"))}return lines}var CHANGE_ACTION_ORDER={firewallEnabled:0,"rules.insert":1,"rules.update":2,"rules.remove":3,"rules.priority":4,"ip.insert":5,"ip.update":6,"ip.remove":7,"crs.update":8,"crs.disable":9,"managedRules.update":10,"managedRuleGroup.update":11,"botId.toggle":12,ja3Enabled:13,ja4Enabled:14,"logHeaders.update":15};function formatDiffOutput(changes,activeRules){let lines=[],sorted=[...changes].sort((a,b)=>(CHANGE_ACTION_ORDER[a.action]??99)-(CHANGE_ACTION_ORDER[b.action]??99));for(let change of sorted){let{symbol,color}=getDiffSymbol(change.action),description=formatChangeDescription(change,activeRules);if(lines.push(color(` ${symbol} ${description}`)),change.action==="rules.update"&&activeRules&&change.id){let activeRule=activeRules.get(change.id);if(activeRule&&change.value){let subLines=formatRuleFieldDiff(activeRule,change.value);lines.push(...subLines)}}}return lines.join(`
26
+ `)}function getDiffSymbol(action){return action.endsWith(".insert")?{symbol:"+",color:import_chalk5.default.green}:action.endsWith(".remove")?{symbol:"-",color:import_chalk5.default.red}:{symbol:"~",color:import_chalk5.default.yellow}}function formatChangeDescription(change,activeRules){let{action,id,value}=change;switch(action){case"rules.insert":return`Added rule "${value?.name||id||"unknown"}"`;case"rules.update":{let draft=value,ruleName=draft?.name||id||"unknown";if(activeRules&&id&&draft&&typeof draft.active=="boolean"){let activeRule=activeRules.get(id);if(activeRule&&activeRule.active!==draft.active){let nameUnchanged=activeRule.name===draft.name,conditionsUnchanged=JSON.stringify(activeRule.conditionGroup)===JSON.stringify(draft.conditionGroup),actionUnchanged=JSON.stringify(activeRule.action)===JSON.stringify(draft.action),descriptionUnchanged=(activeRule.description||"")===(draft.description||"");if(nameUnchanged&&conditionsUnchanged&&actionUnchanged&&descriptionUnchanged)return draft.active?`Enabled rule "${ruleName}"`:`Disabled rule "${ruleName}"`}}return`Modified rule "${ruleName}"`}case"rules.remove":return`Removed rule "${id||"unknown"}"`;case"rules.priority":return`Reordered rule "${value?.name||id||"unknown"}"`;case"ip.insert":return`Added IP block ${value?.ip||"unknown"}`;case"ip.remove":return`Removed IP block ${id||"unknown"}`;case"ip.update":return`Modified IP block ${value?.ip||id||"unknown"}`;case"firewallEnabled":return`${value?"Enabled":"Disabled"} firewall`;case"crs.update":return"Updated OWASP CRS configuration";case"crs.disable":return"Disabled OWASP CRS";case"managedRules.update":return"Updated managed ruleset configuration";case"managedRuleGroup.update":{if(id!=="ai_bots")return"Updated managed rule group";let groups=value??{};return`Updated AI Bots: ${getAiBotsCategories({active:!0,ruleGroups:groups}).map(category=>{let group=groups[category.ruleGroupId],action2=group.active===!1?"allow":group.action;return`${category.name} \u2192 ${action2?formatManagedBotAction(action2):"Inherited action"}`}).join(", ")}`}case"botId.toggle":return`${value?"Enabled":"Disabled"} Bot ID detection`;case"ja3Enabled":return`${value?"Enabled":"Disabled"} JA3 fingerprinting`;case"ja4Enabled":return`${value?"Enabled":"Disabled"} JA4 fingerprinting`;case"logHeaders.update":return"Updated log headers configuration";default:return`${action}${id?` (${id})`:""}`}}function formatRuleFieldDiff(activeRule,draftValue){let lines=[];if(draftValue.name&&activeRule.name!==draftValue.name&&lines.push(import_chalk5.default.yellow(` ~ Name: "${activeRule.name}" \u2192 "${draftValue.name}"`)),draftValue.action&&JSON.stringify(activeRule.action)!==JSON.stringify(draftValue.action)){let oldAction=formatActionDisplay(activeRule.action),newAction=formatActionDisplay(draftValue.action);lines.push(import_chalk5.default.yellow(` ~ Action: ${oldAction} \u2192 ${newAction}`))}if(draftValue.conditionGroup&&JSON.stringify(activeRule.conditionGroup)!==JSON.stringify(draftValue.conditionGroup)){let oldConditions=new Set(activeRule.conditionGroup.flatMap(g=>g.conditions.map(c=>formatConditionCompact(c)))),newConditions=new Set(draftValue.conditionGroup.flatMap(g=>g.conditions.map(c=>formatConditionCompact(c)))),added=[...newConditions].filter(c=>!oldConditions.has(c)),removed=[...oldConditions].filter(c=>!newConditions.has(c));for(let c of added)lines.push(import_chalk5.default.green(` + Condition: ${c}`));for(let c of removed)lines.push(import_chalk5.default.red(` - Condition: ${c}`));added.length===0&&removed.length===0&&lines.push(import_chalk5.default.yellow(" ~ Condition groups restructured"))}return lines}var CHANGE_ACTION_ORDER={firewallEnabled:0,"rules.insert":1,"rules.update":2,"rules.remove":3,"rules.priority":4,"ip.insert":5,"ip.update":6,"ip.remove":7,"crs.update":8,"crs.disable":9,"managedRules.update":10,"managedRuleGroup.update":11,"botId.toggle":12,ja3Enabled:13,ja4Enabled:14,"logHeaders.update":15};function formatDiffOutput(changes,activeRules){let lines=[],sorted=[...changes].sort((a,b)=>(CHANGE_ACTION_ORDER[a.action]??99)-(CHANGE_ACTION_ORDER[b.action]??99));for(let change of sorted){let{symbol,color}=getDiffSymbol(change.action),description=formatChangeDescription(change,activeRules);if(lines.push(color(` ${symbol} ${description}`)),change.action==="rules.update"&&activeRules&&change.id){let activeRule=activeRules.get(change.id);if(activeRule&&change.value){let subLines=formatRuleFieldDiff(activeRule,change.value);lines.push(...subLines)}}}return lines.join(`
27
27
  `)}var OPERATOR_LABELS={eq:"equals",neq:"does not equal",re:"matches regex",ex:"exists",nex:"does not exist",inc:"is any of",ninc:"is not any of",pre:"starts with",suf:"ends with",sub:"contains",gt:">",gte:">=",lt:"<",lte:"<="},NEGATED_OPERATOR_LABELS={eq:"does not equal",neq:"equals",re:"does not match regex",ex:"does not exist",nex:"exists",inc:"is not any of",ninc:"is any of",pre:"does not start with",suf:"does not end with",sub:"does not contain",gt:"NOT >",gte:"NOT >=",lt:"NOT <",lte:"NOT <="},CONDITION_TYPE_LABELS={path:"path",raw_path:"raw path",target_path:"target path",route:"route",server_action:"server action",method:"method",host:"host",protocol:"protocol",scheme:"scheme",environment:"environment",region:"region",ip_address:"IP address",user_agent:"user agent",geo_country:"geo country",geo_continent:"geo continent",geo_country_region:"state/region",geo_city:"geo city",geo_as_number:"geo AS number",header:"header",cookie:"cookie",query:"query string",ja3_digest:"JA3 digest",ja4_digest:"JA4 digest",request_body:"request body",rate_limit_api_id:"rate limit API ID",bot_name:"bot name",bot_category:"bot category"};function getConditionTypeLabel(type,key){let label=CONDITION_TYPE_LABELS[type]||type;return key?`${label}[${key}]`:label}function getOperatorLabel(op,neg){return neg?NEGATED_OPERATOR_LABELS[op]||`NOT ${OPERATOR_LABELS[op]||op}`:OPERATOR_LABELS[op]||op}function formatConditionValue(condition){return condition.op==="ex"||condition.op==="nex"?"":Array.isArray(condition.value)?condition.value.join(", "):String(condition.value??"")}function formatConditionCompact(condition){let type=getConditionTypeLabel(condition.type,condition.key),op=getOperatorLabel(condition.op,condition.neg),value=formatConditionValue(condition);return value?`${type} ${op} ${value}`:`${type} ${op}`}function formatActionDisplay(action){let mitigate=action.mitigate;if(!mitigate)return import_chalk5.default.dim("None");let actionType=mitigate.action,duration=mitigate.actionDuration;switch(actionType){case"deny":return duration?`Deny (${duration})`:"Deny";case"challenge":return duration?`Challenge (${duration})`:"Challenge";case"log":return"Log";case"bypass":return"Bypass";case"rate_limit":{let rl=mitigate.rateLimit;return rl?`Rate Limit (${rl.limit}/${rl.window}s)`:"Rate Limit"}case"redirect":{let rd=mitigate.redirect;if(rd){let code=rd.permanent?"301":"307";return`Redirect \u2192 ${rd.location} (${code})`}return"Redirect"}default:return actionType}}function formatActionType(action){let type=action.mitigate?.action;return type?type==="rate_limit"?"Rate Limit":type.charAt(0).toUpperCase()+type.slice(1):"None"}function annotateRules(activeRules,draftRules,changes){if(!draftRules)return activeRules.map(rule=>({rule,status:"live"}));let addedIds=new Set(changes.filter(c=>c.action==="rules.insert").map(c=>c.id).filter(id=>id!=null)),removedIds=new Set(changes.filter(c=>c.action==="rules.remove").map(c=>c.id).filter(id=>id!=null)),modifiedIds=new Set(changes.filter(c=>c.action==="rules.update"||c.action==="rules.priority").map(c=>c.id).filter(id=>id!=null)),result=[];for(let rule of draftRules)addedIds.has(rule.id)?result.push({rule,status:"added"}):modifiedIds.has(rule.id)?result.push({rule,status:"modified"}):result.push({rule,status:"live"});for(let rule of activeRules)removedIds.has(rule.id)&&result.push({rule,status:"removed"});return result}function formatActionCompact(action){let mitigate=action.mitigate;if(!mitigate)return"None";let actionType=mitigate.action,duration=mitigate.actionDuration;switch(actionType){case"deny":return duration?`Deny (${duration})`:"Deny";case"challenge":return duration?`Challenge (${duration})`:"Challenge";case"log":return"Log";case"bypass":return"Bypass";case"rate_limit":{let rl=mitigate.rateLimit;return rl?`Rate Limit (${rl.limit}/${rl.window}s)`:"Rate Limit"}case"redirect":return`Redirect (${mitigate.redirect?.permanent?"301":"307"})`;default:return actionType}}function formatRulesTable(annotated,columns=80){let lines=[],numWidth=Math.max(1,String(annotated.length).length),actionTexts=annotated.map(a=>formatActionCompact(a.rule.action)),nameWidth=Math.max(4,...annotated.map(a=>a.rule.name.length)),actionWidth=Math.max(6,...actionTexts.map(t=>t.length)),width=columns>0?columns:80,overflow=2+2+numWidth+3+nameWidth+3+actionWidth+3+8-width;if(overflow>0){let nameShrink=Math.min(overflow,Math.max(0,nameWidth-4));nameWidth-=nameShrink,overflow-=nameShrink}if(overflow>0){let actionShrink=Math.min(overflow,Math.max(0,actionWidth-6));actionWidth-=actionShrink}lines.push(` ${" ".repeat(2)}${import_chalk5.default.dim("#".padEnd(numWidth+3))}${import_chalk5.default.dim("Name".padEnd(nameWidth+3))}${import_chalk5.default.dim("Action".padEnd(actionWidth+3))}${import_chalk5.default.dim("Status")}`);for(let i=0;i<annotated.length;i++){let{rule,status:status2}=annotated[i],num=String(i+1).padEnd(numWidth+3),name=truncateEnd(rule.name,nameWidth,{omission:"\u2026"}).padEnd(nameWidth+3),actionText=truncateEnd(actionTexts[i],actionWidth,{omission:"\u2026"}).padEnd(actionWidth+3),prefix=" ",colorFn=s=>s;status2==="added"?(prefix="+ ",colorFn=import_chalk5.default.green):status2==="removed"?(prefix="- ",colorFn=import_chalk5.default.red):status2==="modified"&&(prefix="~ ",colorFn=import_chalk5.default.yellow);let activeStatusText=rule.active?"Enabled":"Disabled",activeStatus=status2==="removed"?import_chalk5.default.dim(activeStatusText):rule.active?import_chalk5.default.green(activeStatusText):import_chalk5.default.red(activeStatusText);lines.push(colorFn(` ${prefix}${num}${name}${actionText}${activeStatus}`));let idIndent=" ".repeat(2+numWidth+3);lines.push(colorFn(` ${idIndent}${import_chalk5.default.dim(rule.id)}`))}return lines.join(`
28
- `)}function colorManagedBotAction(action){let label=formatManagedBotAction(action);if(action==="off"||action==="allow"||action==="basic")return import_chalk5.default.dim(label);if(action==="deep-analysis")return import_chalk5.default.green(label);let color=ACTION_COLORS[action];return color?color(label):label}function formatManagedBotRulesTable(rules2){let lines=[],nameWidth=Math.max(4,...rules2.map(r=>r.name.length)),actionWidth=Math.max(6,...rules2.map(r=>formatManagedBotAction(r.action).length));lines.push(` ${import_chalk5.default.bold("Managed")}`),lines.push(""),lines.push(` ${import_chalk5.default.dim("Name".padEnd(nameWidth+3))}${import_chalk5.default.dim("Action".padEnd(actionWidth+3))}${import_chalk5.default.dim("ID")}`);for(let rule of rules2){let name=rule.name.padEnd(nameWidth+3),actionLabel=formatManagedBotAction(rule.action),actionPad=" ".repeat(Math.max(0,actionWidth+3-actionLabel.length));lines.push(` ${name}${colorManagedBotAction(rule.action)}${actionPad}${import_chalk5.default.dim(rule.id)}`)}return lines.join(`
29
- `)}function formatManagedBotRuleDetail(rule){let lines=[];return lines.push(formatAlignedLabel("Rule",rule.name)),lines.push(formatAlignedLabel("ID",import_chalk5.default.dim(rule.id))),rule.wafRuleId&&lines.push(formatAlignedLabel("WAF ID",import_chalk5.default.dim(rule.wafRuleId))),lines.push(formatAlignedLabel("Action",colorManagedBotAction(rule.action))),lines.join(`
28
+ `)}function colorManagedBotAction(action){let label=formatManagedBotAction(action);if(action==="off"||action==="allow"||action==="basic")return import_chalk5.default.dim(label);if(action==="deep-analysis")return import_chalk5.default.green(label);let color=ACTION_COLORS[action];return color?color(label):label}function formatManagedBotRulesTable(rules2){let rows=rules2.flatMap(rule=>[{name:rule.name,action:rule.action,id:rule.id},...(rule.categories??[]).map(category=>({name:` ${category.name}`,action:category.action,id:category.id}))]),lines=[],gap=3,nameWidth=Math.max(4,...rows.map(r=>r.name.length)),actionWidth=Math.max(6,...rows.map(r=>r.action?formatManagedBotAction(r.action).length:0));lines.push(` ${import_chalk5.default.bold("Managed")}`),lines.push(""),lines.push(` ${import_chalk5.default.dim("Name".padEnd(nameWidth+gap))}${import_chalk5.default.dim("Action".padEnd(actionWidth+gap))}${import_chalk5.default.dim("ID")}`);for(let row of rows){let name=row.name.padEnd(nameWidth+gap),actionLabel=row.action?formatManagedBotAction(row.action):"",actionPad=" ".repeat(Math.max(0,actionWidth+gap-actionLabel.length)),action=row.action?colorManagedBotAction(row.action):"";lines.push(` ${name}${action}${actionPad}${import_chalk5.default.dim(row.id)}`)}return lines.join(`
29
+ `)}function formatManagedBotRuleDetail(rule){let lines=[];lines.push(formatAlignedLabel("Rule",rule.name)),lines.push(formatAlignedLabel("ID",import_chalk5.default.dim(rule.id))),rule.wafRuleId&&lines.push(formatAlignedLabel("WAF ID",import_chalk5.default.dim(rule.wafRuleId))),rule.action&&lines.push(formatAlignedLabel("Action",colorManagedBotAction(rule.action)));for(let category of rule.categories??[])lines.push(formatAlignedLabel(category.name,colorManagedBotAction(category.action)));return lines.join(`
30
30
  `)}function formatConditionGroup(group,groupIndex,totalGroups){let lines=[],label=totalGroups>1?`Group ${groupIndex+1} (AND):`:"Conditions:";lines.push(` ${import_chalk5.default.dim(label)}`);for(let condition of group.conditions)lines.push(` ${formatConditionCompact(condition)}`);return lines.join(`
31
31
  `)}function formatRuleExpanded(rule,index){let lines=[],prefix=index!==void 0?`${index+1}. `:"",status2=rule.active?import_chalk5.default.green("Enabled"):import_chalk5.default.red("Disabled");if(lines.push(` ${prefix}${import_chalk5.default.bold(rule.name)} [${status2}]`),rule.description&&lines.push(` ${import_chalk5.default.dim(rule.description)}`),lines.push(""),rule.conditionGroup.length===0)lines.push(` ${import_chalk5.default.dim("No conditions")}`);else for(let i=0;i<rule.conditionGroup.length;i++)lines.push(formatConditionGroup(rule.conditionGroup[i],i,rule.conditionGroup.length)),i<rule.conditionGroup.length-1&&lines.push(` ${import_chalk5.default.dim("OR")}`);lines.push(""),lines.push(` ${import_chalk5.default.dim("Action:")} ${formatActionType(rule.action)}`);let duration=rule.action.mitigate?.actionDuration;duration&&rule.action.mitigate?.action!=="rate_limit"&&lines.push(` ${import_chalk5.default.dim("Duration:")} ${duration}`);let rl=rule.action.mitigate?.rateLimit;if(rl&&(lines.push(` ${import_chalk5.default.dim("Rate Limit:")} ${rl.limit} req / ${rl.window}s (${rl.algo})`),lines.push(` ${import_chalk5.default.dim("Keys:")} ${rl.keys.join(", ")}`),rl.action)){let exceeded=duration?`${rl.action} (${duration})`:rl.action;lines.push(` ${import_chalk5.default.dim("If exceeded:")} ${exceeded}`)}let rd=rule.action.mitigate?.redirect;return rd&&lines.push(` ${import_chalk5.default.dim("Redirect:")} ${rd.location} (${rd.permanent?"301 permanent":"307 temporary"})`),lines.join(`
32
32
  `)}function formatRuleDetail(rule){let lines=[];if(lines.push(` ${import_chalk5.default.bold("Rule:")} ${rule.name}`),lines.push(` ${import_chalk5.default.bold("ID:")} ${import_chalk5.default.dim(rule.id)}`),lines.push(` ${import_chalk5.default.bold("Status:")} ${rule.active?import_chalk5.default.green("Enabled"):import_chalk5.default.red("Disabled")}`),rule.description&&lines.push(` ${import_chalk5.default.bold("Description:")} ${rule.description}`),lines.push(""),rule.conditionGroup.length===0)lines.push(` ${import_chalk5.default.bold("Conditions:")} ${import_chalk5.default.dim("No conditions")}`);else{lines.push(` ${import_chalk5.default.bold("Conditions:")}`);for(let i=0;i<rule.conditionGroup.length;i++){rule.conditionGroup.length>1&&lines.push(` ${import_chalk5.default.dim(`Group ${i+1} (AND):`)}`);for(let condition of rule.conditionGroup[i].conditions)lines.push(` ${formatConditionCompact(condition)}`);i<rule.conditionGroup.length-1&&lines.push(` ${import_chalk5.default.dim("OR")}`)}}lines.push(""),lines.push(` ${import_chalk5.default.bold("Action:")} ${formatActionType(rule.action)}`);let duration=rule.action.mitigate?.actionDuration;duration&&rule.action.mitigate?.action!=="rate_limit"&&lines.push(` ${import_chalk5.default.bold("Duration:")} ${duration}`);let rl=rule.action.mitigate?.rateLimit;if(rl&&(lines.push(` ${import_chalk5.default.bold("Rate Limit:")}`),lines.push(` Algorithm: ${rl.algo}`),lines.push(` Window: ${rl.window}s`),lines.push(` Limit: ${rl.limit} requests`),lines.push(` Keys: ${rl.keys.join(", ")}`),rl.action)){let exceeded=duration?`${rl.action} (${duration})`:rl.action;lines.push(` If exceeded: ${exceeded}`)}let rd=rule.action.mitigate?.redirect;return rd&&(lines.push(` ${import_chalk5.default.bold("Redirect:")}`),lines.push(` Location: ${rd.location}`),lines.push(` Type: ${rd.permanent?"301 (permanent)":"307 (temporary)"}`)),lines.join(`
33
- `)}function hasOwaspEntitlement(planInfo){return!!(planInfo?.hasSecurityPlus||planInfo?.isEnterprise)}function getBotProtectionConfig(managedRules){return managedRules?.bot_filter??managedRules?.bot_protection}function formatBotProtectionStatus(ruleset){return ruleset?.active?ruleset.action==="log"?ACTION_COLORS.log("Log"):ruleset.action==="deny"?ACTION_COLORS.deny("Deny"):ACTION_COLORS.challenge("Challenge"):import_chalk5.default.dim("Off")}function formatAiBotsStatus(ruleset){return ruleset?.active?ruleset.action==="log"?ACTION_COLORS.log("Log"):ruleset.action==="challenge"?ACTION_COLORS.challenge("Challenge"):ACTION_COLORS.deny("Deny"):import_chalk5.default.dim("Allow")}function formatOwaspStatus(ruleset){if(!ruleset?.active)return import_chalk5.default.dim("Off");let groups=ruleset.ruleGroups?Object.values(ruleset.ruleGroups):void 0;if(groups&&groups.length>0){let activeGroups=groups.filter(g=>g.active).length;return import_chalk5.default.green(`On (${activeGroups} of ${groups.length} groups)`)}return import_chalk5.default.green("On")}function owaspJsonStatus(ruleset,planInfo){let enabled=!!ruleset?.active,action=enabled?ruleset?.action??null:null;return enabled||hasOwaspEntitlement(planInfo)?{enabled,action}:{enabled:!1,action:null,requiresUpgrade:!0,upgrade:"security-plus"}}var PIPELINE_TOPOLOGY=[{id:"system-rules",order:1,group:"system-rules",label:"System Rules",description:"Vercel-managed protections covering multiple threat categories",configurable:!1,skippableBy:["system"]},{id:"attack-mode",order:2,group:null,label:"Attack Challenge Mode",description:"Challenges all visitors with a verification page when enabled",configurable:!0,skippableBy:[]},{id:"ip-blocking",order:3,group:"custom-rules",label:"IP Blocking",description:"User-configured IP and CIDR block rules",configurable:!0,skippableBy:[]},{id:"custom-rules",order:4,group:"custom-rules",label:"Custom Firewall Rules",description:"User-configured firewall rules",configurable:!0,skippableBy:[]},{id:"bot-management",order:5,group:"managed-rulesets",label:"Bot Management",description:"Automated bot detection and verification",configurable:!0,skippableBy:["system","custom"]},{id:"managed-rulesets",order:6,group:"managed-rulesets",label:"Managed Rulesets",description:"OWASP Top 10 and other curated security rulesets",configurable:!0,skippableBy:["custom"]},{id:"deployment-routing",order:7,group:"routing",label:"Deployment Routing",description:"The request is routed to the deployment and the response is generated",configurable:!1,skippableBy:[]},{id:"response-returned",order:8,group:"routing",label:"Response Returned",description:"If no rules blocked the request, the response is returned",configurable:!1,skippableBy:[]}],BOT_PROTECTION_KEYS=new Set(["bot_filter","bot_protection"]),RULESET_LABELS={owasp:"OWASP",ai_bots:"AI Bots",traffic_sources:"Traffic Sources",vercel_ruleset:"Vercel Ruleset"},ALWAYS_REPORTED_RULESETS=["owasp","ai_bots"];function rulesetId(key){return key.replace(/_/g,"-")}function rulesetLabel(key){return RULESET_LABELS[key]??key.split("_").map(part=>part.charAt(0).toUpperCase()+part.slice(1)).join(" ")}function countCustomBypassRules(active){return active?.rules.filter(r=>r.active&&r.action.mitigate?.action==="bypass").length??0}function getManagedRulesetStates(managedRules,planInfo){return[...ALWAYS_REPORTED_RULESETS,...Object.keys(managedRules??{}).filter(key=>!BOT_PROTECTION_KEYS.has(key)&&!ALWAYS_REPORTED_RULESETS.includes(key))].map(key=>[key,managedRules?.[key]]).map(([key,value])=>{let id=rulesetId(key),label=rulesetLabel(key);if(key==="owasp"){let owasp=owaspJsonStatus(value,planInfo);return owasp.requiresUpgrade?{id,label,state:"unavailable",unavailable:{reason:"plan",upgrade:owasp.upgrade}}:{id,label,state:owasp.enabled?"active":"inactive",action:owasp.action}}return{id,label,state:value?.active?"active":"inactive",action:value?.active?value.action??null:null}})}function getManagedRulesetsState(rulesets){let configurable=rulesets.filter(r=>r.state!=="unavailable"),active=configurable.filter(r=>r.state==="active").length;return active===0?"inactive":active===configurable.length?"active":"partial"}function getFirewallPipeline(opts){let{active,bypass,attackMode,planInfo,firewallBypassIps}=opts,systemBypassIps=bypass?.filter(b=>!isAllSourcesBypass(b.Ip))??[],customBypassRules=countCustomBypassRules(active),bypasses={system:bypass===null?{state:"unknown",skips:[]}:{state:systemBypassIps.length>0?"active":"inactive",count:systemBypassIps.length,skips:[]},custom:{state:customBypassRules>0?"active":"inactive",count:customBypassRules,skips:[]}};for(let kind of["system","custom"])bypasses[kind].skips=PIPELINE_TOPOLOGY.filter(s=>s.skippableBy.includes(kind)).map(s=>s.id);let mitigationsPaused=getMitigationsStatus(firewallBypassIps,bypass).paused,botProtection=getBotProtectionConfig(active?.managedRules),managedRulesets=getManagedRulesetStates(active?.managedRules,planInfo),activeRules=active?.rules.filter(r=>r.active).length??0,ipBlocks=active?.ips.length??0,requestFlow=PIPELINE_TOPOLOGY.map(topology=>{let skippedBy=topology.skippableBy.filter(kind=>bypasses[kind].state==="active"),base={...topology,skippedBy};switch(topology.id){case"system-rules":return{...base,state:mitigationsPaused?"inactive":"active"};case"attack-mode":return{...base,state:attackMode?.enabled?"active":"inactive"};case"ip-blocking":return{...base,state:ipBlocks>0?"active":"inactive",count:ipBlocks};case"custom-rules":return{...base,state:active?.firewallEnabled&&activeRules>0?"active":"inactive",count:activeRules};case"bot-management":return{...base,state:botProtection?.active?"active":"inactive",action:botProtection?.action??null};case"managed-rulesets":return{...base,state:getManagedRulesetsState(managedRulesets),count:managedRulesets.filter(r=>r.state==="active").length,rulesets:managedRulesets};default:return{...base,state:"terminal"}}});return{bypasses,requestFlow}}function isPlanGatedError(error){return isAPIError(error)&&error.status===402}function planGateMessage(error){return apiServerMessage(error)??"IP Bypass requires a Pro or Enterprise plan."}function readBypassResult(result){if(result.status==="fulfilled")return{bypass:result.value.result};if(!isPlanGatedError(result.reason))throw result.reason;return{bypass:null,unavailable:{reason:"plan",message:planGateMessage(result.reason)}}}function resolveFirewallEntitlements(planInfo,project){return{isEnterprise:planInfo?.isEnterprise,hasSecurityPlus:!!(planInfo?.hasSecurityPlus||project.security?.securityPlus)}}function isActivityUnavailable(error){return isAPIError(error)&&error.status===402}function activityIssue(error){if(isActivityUnavailable(error))return{reason:"plan",message:FIREWALL_ACTIVITY_PLAN_MESSAGE};if(isActivityTimeout(error))return{reason:"timeout",message:"Traffic and alerts timed out."}}function unwrap(result){if(result.status==="rejected")throw result.reason;return result.value}var ACTIVITY_WINDOW_MS=24*60*60*1e3;async function fetchActivity(client,projectId,teamId,active){let granularity={hours:1},now=new Date,{startTime,endTime}=alignQueryWindow(new Date(now.getTime()-ACTIVITY_WINDOW_MS),now,granularity);output_manager_default.spinner("Fetching firewall activity");let[metrics,alertsResult,topRules]=await Promise.all([getFirewallMetrics(client,{projectId,ownerId:teamId,startTime,endTime,granularity}),getFirewallAlertsDetailed(client,{projectId,teamId,sinceDays:1}),getTopList(client,{ownerId:teamId,projectId,groupBy:[RULE_ID_DIMENSION],filter:RULE_TRAFFIC_FILTER,startTime,endTime,top:topListFetchCount(OVERVIEW_TOP_RULES)})]),rules2=topRules.filter(row=>row.values[RULE_ID_DIMENSION]).slice(0,OVERVIEW_TOP_RULES).map(row=>{let id=row.values[RULE_ID_DIMENSION];return{id,name:resolveRuleDisplayName(id,active),total:row.total}}),windowStart=startTime.getTime(),windowEnd=endTime.getTime(),annotations=alertsResult.alerts.filter(a=>alertOverlapsWindow(a,windowStart,windowEnd));return{metrics,rules:rules2,annotations,attacksMitigated:countAttacksMitigated(alertsResult.alerts,windowStart,windowEnd),alertsUnavailable:alertsResult.errors.length>0?{sources:alertsResult.errors.map(e=>e.source),message:alertsIncompleteMessage(alertsResult.errors)}:void 0}}async function overview(client,argv){let parsed=await parseSubcommandArgs(argv,overviewSubcommand,client);if(typeof parsed=="number")return parsed;let asJson=!!parsed.flags["--json"],suggestedCommand=`firewall overview${asJson?" --json":""}`,link=await requireProjectContext(client,"firewall",parsed.flags["--project"]);if(typeof link=="number")return link;let{project,org}=link,teamId=org.type==="team"?org.id:void 0;output_manager_default.spinner(`Fetching firewall overview for ${import_chalk6.default.bold(project.name)}`);try{let[configResult,bypassResult,projectResult,planResult]=await Promise.allSettled([listFirewallConfigs(client,projectScope(project,teamId)),getBypass(client,project.id,{teamId}),client.fetch(`/v9/projects/${encodeURIComponent(project.id)}`,{accountId:teamId}),fetchPlanInfo(client)]),{active,draft}=unwrap(configResult),freshProject=unwrap(projectResult),{bypass,unavailable:bypassUnavailable}=readBypassResult(bypassResult),planInfo=resolveFirewallEntitlements(planResult.status==="fulfilled"?planResult.value:void 0,freshProject),attackMode={enabled:freshProject.security?.attackModeEnabled??!1,activeUntil:freshProject.security?.attackModeActiveUntil},activity=null,activityIssueFound;if(teamId)try{activity=await fetchActivity(client,project.id,teamId,active)}catch(e){let issue=activityIssue(e);if(!issue)throw e;activityIssueFound=issue}return asJson?(outputJson(client,{active,draft,bypass,...bypassUnavailable?{bypassUnavailable}:{},attackMode,period:activity?{start:activity.metrics.startTime,end:activity.metrics.endTime,granularity:activity.metrics.granularity}:null,stats:activity?{attacksMitigated:activity.attacksMitigated,...activity.metrics.totals}:null,series:activity?.metrics.series.map(({action,timeseries})=>({action,timeseries}))??null,topRules:activity?.rules??null,annotations:activity?.annotations??null,...activityIssueFound?{activityUnavailable:activityIssueFound}:{},...activity?.alertsUnavailable?{alertsUnavailable:activity.alertsUnavailable}:{}}),0):(output_manager_default.print(`
33
+ `)}function hasOwaspEntitlement(planInfo){return!!(planInfo?.hasSecurityPlus||planInfo?.isEnterprise)}function getBotProtectionConfig(managedRules){return managedRules?.bot_filter??managedRules?.bot_protection}function formatBotProtectionStatus(ruleset){return ruleset?.active?ruleset.action==="log"?ACTION_COLORS.log("Log"):ruleset.action==="deny"?ACTION_COLORS.deny("Deny"):ACTION_COLORS.challenge("Challenge"):import_chalk5.default.dim("Off")}function formatAiBotsStatus(ruleset){return ruleset?.active?ruleset.action==="log"?ACTION_COLORS.log("Log"):ruleset.action==="challenge"?ACTION_COLORS.challenge("Challenge"):ACTION_COLORS.deny("Deny"):import_chalk5.default.dim("Allow")}function formatOwaspStatus(ruleset){if(!ruleset?.active)return import_chalk5.default.dim("Off");let groups=ruleset.ruleGroups?Object.values(ruleset.ruleGroups):void 0;if(groups&&groups.length>0){let activeGroups=groups.filter(g=>g.active).length;return import_chalk5.default.green(`On (${activeGroups} of ${groups.length} groups)`)}return import_chalk5.default.green("On")}function owaspJsonStatus(ruleset,planInfo){let enabled=!!ruleset?.active,action=enabled?ruleset?.action??null:null;return enabled||hasOwaspEntitlement(planInfo)?{enabled,action}:{enabled:!1,action:null,requiresUpgrade:!0,upgrade:"security-plus"}}var PIPELINE_TOPOLOGY=[{id:"system-rules",order:1,group:"system-rules",label:"System Rules",description:"Vercel-managed protections covering multiple threat categories",configurable:!1,skippableBy:["system"]},{id:"attack-mode",order:2,group:null,label:"Attack Challenge Mode",description:"Challenges all visitors with a verification page when enabled",configurable:!0,skippableBy:[]},{id:"ip-blocking",order:3,group:"custom-rules",label:"IP Blocking",description:"User-configured IP and CIDR block rules",configurable:!0,skippableBy:[]},{id:"custom-rules",order:4,group:"custom-rules",label:"Custom Firewall Rules",description:"User-configured firewall rules",configurable:!0,skippableBy:[]},{id:"bot-management",order:5,group:"managed-rulesets",label:"Bot Management",description:"Automated bot detection and verification",configurable:!0,skippableBy:["system","custom"]},{id:"managed-rulesets",order:6,group:"managed-rulesets",label:"Managed Rulesets",description:"OWASP Top 10 and other curated security rulesets",configurable:!0,skippableBy:["custom"]},{id:"deployment-routing",order:7,group:"routing",label:"Deployment Routing",description:"The request is routed to the deployment and the response is generated",configurable:!1,skippableBy:[]},{id:"response-returned",order:8,group:"routing",label:"Response Returned",description:"If no rules blocked the request, the response is returned",configurable:!1,skippableBy:[]}],BOT_PROTECTION_KEYS=new Set(["bot_filter","bot_protection"]),RULESET_LABELS={owasp:"OWASP",ai_bots:"AI Bots",traffic_sources:"Traffic Sources",vercel_ruleset:"Vercel Ruleset"},ALWAYS_REPORTED_RULESETS=["owasp","ai_bots"];function rulesetId(key){return key.replace(/_/g,"-")}function rulesetLabel(key){return RULESET_LABELS[key]??key.split("_").map(part=>part.charAt(0).toUpperCase()+part.slice(1)).join(" ")}function countCustomBypassRules(active){return active?.rules.filter(r=>r.active&&r.action.mitigate?.action==="bypass").length??0}function getManagedRulesetStates(managedRules,planInfo){return[...ALWAYS_REPORTED_RULESETS,...Object.keys(managedRules??{}).filter(key=>!BOT_PROTECTION_KEYS.has(key)&&!ALWAYS_REPORTED_RULESETS.includes(key))].map(key=>[key,managedRules?.[key]]).map(([key,value])=>{let id=rulesetId(key),label=rulesetLabel(key);if(key==="owasp"){let owasp=owaspJsonStatus(value,planInfo);return owasp.requiresUpgrade?{id,label,state:"unavailable",unavailable:{reason:"plan",upgrade:owasp.upgrade}}:{id,label,state:owasp.enabled?"active":"inactive",action:owasp.action}}let categories=key==="ai_bots"?getAiBotsCategoryDetails(value):void 0;return categories?{id,label,state:value?.active?"active":"inactive",action:null,categories}:{id,label,state:value?.active?"active":"inactive",action:value?.active?value.action??null:null}})}function getManagedRulesetsState(rulesets){let configurable=rulesets.filter(r=>r.state!=="unavailable"),active=configurable.filter(r=>r.state==="active").length;return active===0?"inactive":active===configurable.length?"active":"partial"}function getFirewallPipeline(opts){let{active,bypass,attackMode,planInfo,firewallBypassIps}=opts,systemBypassIps=bypass?.filter(b=>!isAllSourcesBypass(b.Ip))??[],customBypassRules=countCustomBypassRules(active),bypasses={system:bypass===null?{state:"unknown",skips:[]}:{state:systemBypassIps.length>0?"active":"inactive",count:systemBypassIps.length,skips:[]},custom:{state:customBypassRules>0?"active":"inactive",count:customBypassRules,skips:[]}};for(let kind of["system","custom"])bypasses[kind].skips=PIPELINE_TOPOLOGY.filter(s=>s.skippableBy.includes(kind)).map(s=>s.id);let mitigationsPaused=getMitigationsStatus(firewallBypassIps,bypass).paused,botProtection=getBotProtectionConfig(active?.managedRules),managedRulesets=getManagedRulesetStates(active?.managedRules,planInfo),activeRules=active?.rules.filter(r=>r.active).length??0,ipBlocks=active?.ips.length??0,requestFlow=PIPELINE_TOPOLOGY.map(topology=>{let skippedBy=topology.skippableBy.filter(kind=>bypasses[kind].state==="active"),base={...topology,skippedBy};switch(topology.id){case"system-rules":return{...base,state:mitigationsPaused?"inactive":"active"};case"attack-mode":return{...base,state:attackMode?.enabled?"active":"inactive"};case"ip-blocking":return{...base,state:ipBlocks>0?"active":"inactive",count:ipBlocks};case"custom-rules":return{...base,state:active?.firewallEnabled&&activeRules>0?"active":"inactive",count:activeRules};case"bot-management":return{...base,state:botProtection?.active?"active":"inactive",action:botProtection?.action??null};case"managed-rulesets":return{...base,state:getManagedRulesetsState(managedRulesets),count:managedRulesets.filter(r=>r.state==="active").length,rulesets:managedRulesets};default:return{...base,state:"terminal"}}});return{bypasses,requestFlow}}function isPlanGatedError(error){return isAPIError(error)&&error.status===402}function planGateMessage(error){return apiServerMessage(error)??"IP Bypass requires a Pro or Enterprise plan."}function readBypassResult(result){if(result.status==="fulfilled")return{bypass:result.value.result};if(!isPlanGatedError(result.reason))throw result.reason;return{bypass:null,unavailable:{reason:"plan",message:planGateMessage(result.reason)}}}function resolveFirewallEntitlements(planInfo,project){return{isEnterprise:planInfo?.isEnterprise,hasSecurityPlus:!!(planInfo?.hasSecurityPlus||project.security?.securityPlus)}}function isActivityUnavailable(error){return isAPIError(error)&&error.status===402}function activityIssue(error){if(isActivityUnavailable(error))return{reason:"plan",message:FIREWALL_ACTIVITY_PLAN_MESSAGE};if(isActivityTimeout(error))return{reason:"timeout",message:"Traffic and alerts timed out."}}function unwrap(result){if(result.status==="rejected")throw result.reason;return result.value}var ACTIVITY_WINDOW_MS=24*60*60*1e3;async function fetchActivity(client,projectId,teamId,active){let granularity={hours:1},now=new Date,{startTime,endTime}=alignQueryWindow(new Date(now.getTime()-ACTIVITY_WINDOW_MS),now,granularity);output_manager_default.spinner("Fetching firewall activity");let[metrics,alertsResult,topRules]=await Promise.all([getFirewallMetrics(client,{projectId,ownerId:teamId,startTime,endTime,granularity}),getFirewallAlertsDetailed(client,{projectId,teamId,sinceDays:1}),getTopList(client,{ownerId:teamId,projectId,groupBy:[RULE_ID_DIMENSION],filter:RULE_TRAFFIC_FILTER,startTime,endTime,top:topListFetchCount(OVERVIEW_TOP_RULES)})]),rules2=topRules.filter(row=>row.values[RULE_ID_DIMENSION]).slice(0,OVERVIEW_TOP_RULES).map(row=>{let id=row.values[RULE_ID_DIMENSION];return{id,name:resolveRuleDisplayName(id,active),total:row.total}}),windowStart=startTime.getTime(),windowEnd=endTime.getTime(),annotations=alertsResult.alerts.filter(a=>alertOverlapsWindow(a,windowStart,windowEnd));return{metrics,rules:rules2,annotations,attacksMitigated:countAttacksMitigated(alertsResult.alerts,windowStart,windowEnd),alertsUnavailable:alertsResult.errors.length>0?{sources:alertsResult.errors.map(e=>e.source),message:alertsIncompleteMessage(alertsResult.errors)}:void 0}}async function overview(client,argv){let parsed=await parseSubcommandArgs(argv,overviewSubcommand,client);if(typeof parsed=="number")return parsed;let asJson=!!parsed.flags["--json"],suggestedCommand=`firewall overview${asJson?" --json":""}`,link=await requireProjectContext(client,"firewall",parsed.flags["--project"]);if(typeof link=="number")return link;let{project,org}=link,teamId=org.type==="team"?org.id:void 0;output_manager_default.spinner(`Fetching firewall overview for ${import_chalk6.default.bold(project.name)}`);try{let[configResult,bypassResult,projectResult,planResult]=await Promise.allSettled([listFirewallConfigs(client,projectScope(project,teamId)),getBypass(client,project.id,{teamId}),client.fetch(`/v9/projects/${encodeURIComponent(project.id)}`,{accountId:teamId}),fetchPlanInfo(client)]),{active,draft}=unwrap(configResult),freshProject=unwrap(projectResult),{bypass,unavailable:bypassUnavailable}=readBypassResult(bypassResult),planInfo=resolveFirewallEntitlements(planResult.status==="fulfilled"?planResult.value:void 0,freshProject),attackMode={enabled:freshProject.security?.attackModeEnabled??!1,activeUntil:freshProject.security?.attackModeActiveUntil},activity=null,activityIssueFound;if(teamId)try{activity=await fetchActivity(client,project.id,teamId,active)}catch(e){let issue=activityIssue(e);if(!issue)throw e;activityIssueFound=issue}return asJson?(outputJson(client,{active,draft,bypass,...bypassUnavailable?{bypassUnavailable}:{},attackMode,period:activity?{start:activity.metrics.startTime,end:activity.metrics.endTime,granularity:activity.metrics.granularity}:null,stats:activity?{attacksMitigated:activity.attacksMitigated,...activity.metrics.totals}:null,series:activity?.metrics.series.map(({action,timeseries})=>({action,timeseries}))??null,topRules:activity?.rules??null,annotations:activity?.annotations??null,...activityIssueFound?{activityUnavailable:activityIssueFound}:{},...activity?.alertsUnavailable?{alertsUnavailable:activity.alertsUnavailable}:{}}),0):(output_manager_default.print(`
34
34
  `),output_manager_default.print(formatStatusOutput({active,draft,bypass,attackMode,planInfo,firewallBypassIps:freshProject.security?.firewallBypassIps})),output_manager_default.print(`
35
35
 
36
36
  `),activityIssueFound&&output_manager_default.print(` ${import_chalk6.default.dim(activityIssueFound.message)}
37
37
  `),activity&&output_manager_default.print(formatOverviewOutput({series:activity.metrics.series,attacksMitigated:activity.attacksMitigated,attacksMitigatedIncomplete:!!activity.alertsUnavailable,annotations:activity.annotations,rules:activity.rules,startTime:activity.metrics.startTime,endTime:activity.metrics.endTime,granularity:activity.metrics.granularity})),activity?.alertsUnavailable&&output_manager_default.print(` ${import_chalk6.default.dim(activity.alertsUnavailable.message)}
38
- `),0)}catch(e){return failFirewallApi(client,e,{fallback:"Failed to fetch firewall overview",nextCommand:suggestedCommand,permissionAction:"read firewall configuration",projectName:project.name,timeoutJob:"firewall overview"})}}var import_chalk7=__toESM(require_source(),1);function unwrap2(result){if(result.status==="rejected")throw result.reason;return result.value}async function status(client,argv){let parsed=await parseSubcommandArgs(argv,statusSubcommand,client);if(typeof parsed=="number")return parsed;let asJson=!!parsed.flags["--json"],suggestedCommand=`firewall status${asJson?" --json":""}`,link=await requireProjectContext(client,"firewall",parsed.flags["--project"]);if(typeof link=="number")return link;let{project,org}=link,teamId=org.type==="team"?org.id:void 0;output_manager_default.spinner(`Fetching firewall status for ${import_chalk7.default.bold(project.name)}`);try{let[configResult,bypassResult,projectResult,planResult]=await Promise.allSettled([listFirewallConfigs(client,projectScope(project,teamId)),getBypass(client,project.id,{teamId}),client.fetch(`/v9/projects/${encodeURIComponent(project.id)}`,{accountId:teamId}),fetchPlanInfo(client)]),{active,draft}=unwrap2(configResult),freshProject=unwrap2(projectResult),{bypass,unavailable:bypassUnavailable}=readBypassResult(bypassResult),planInfo=resolveFirewallEntitlements(planResult.status==="fulfilled"?planResult.value:void 0,freshProject),attackMode={enabled:freshProject.security?.attackModeEnabled??!1,activeUntil:freshProject.security?.attackModeActiveUntil};if(asJson){let botProtection=getBotProtectionConfig(active?.managedRules),aiBots=active?.managedRules?.ai_bots;return outputJson(client,{firewallEnabled:active?.firewallEnabled??!1,attackMode,bypass,...bypassUnavailable?{bypassUnavailable}:{},botProtection:{enabled:botProtection?.active??!1,action:botProtection?.action??null},aiBots:{enabled:aiBots?.active??!1,action:aiBots?.action??null},owasp:owaspJsonStatus(active?.managedRules?.owasp,planInfo),...getFirewallPipeline({active,bypass,attackMode,planInfo,firewallBypassIps:freshProject.security?.firewallBypassIps}),rules:{active:active?.rules.filter(r=>r.active).length??0,inactive:active?.rules.filter(r=>!r.active).length??0,total:active?.rules.length??0},ipBlocks:active?.ips.length??0,draftChanges:draft?.changes.length??0}),0}return output_manager_default.print(`
38
+ `),0)}catch(e){return failFirewallApi(client,e,{fallback:"Failed to fetch firewall overview",nextCommand:suggestedCommand,permissionAction:"read firewall configuration",projectName:project.name,timeoutJob:"firewall overview"})}}var import_chalk7=__toESM(require_source(),1);function unwrap2(result){if(result.status==="rejected")throw result.reason;return result.value}async function status(client,argv){let parsed=await parseSubcommandArgs(argv,statusSubcommand,client);if(typeof parsed=="number")return parsed;let asJson=!!parsed.flags["--json"],suggestedCommand=`firewall status${asJson?" --json":""}`,link=await requireProjectContext(client,"firewall",parsed.flags["--project"]);if(typeof link=="number")return link;let{project,org}=link,teamId=org.type==="team"?org.id:void 0;output_manager_default.spinner(`Fetching firewall status for ${import_chalk7.default.bold(project.name)}`);try{let[configResult,bypassResult,projectResult,planResult]=await Promise.allSettled([listFirewallConfigs(client,projectScope(project,teamId)),getBypass(client,project.id,{teamId}),client.fetch(`/v9/projects/${encodeURIComponent(project.id)}`,{accountId:teamId}),fetchPlanInfo(client)]),{active,draft}=unwrap2(configResult),freshProject=unwrap2(projectResult),{bypass,unavailable:bypassUnavailable}=readBypassResult(bypassResult),planInfo=resolveFirewallEntitlements(planResult.status==="fulfilled"?planResult.value:void 0,freshProject),attackMode={enabled:freshProject.security?.attackModeEnabled??!1,activeUntil:freshProject.security?.attackModeActiveUntil};if(asJson){let botProtection=getBotProtectionConfig(active?.managedRules),aiBots=active?.managedRules?.ai_bots;return outputJson(client,{firewallEnabled:active?.firewallEnabled??!1,attackMode,bypass,...bypassUnavailable?{bypassUnavailable}:{},botProtection:{enabled:botProtection?.active??!1,action:botProtection?.action??null},aiBots:aiBotsJsonStatus(aiBots),owasp:owaspJsonStatus(active?.managedRules?.owasp,planInfo),...getFirewallPipeline({active,bypass,attackMode,planInfo,firewallBypassIps:freshProject.security?.firewallBypassIps}),rules:{active:active?.rules.filter(r=>r.active).length??0,inactive:active?.rules.filter(r=>!r.active).length??0,total:active?.rules.length??0},ipBlocks:active?.ips.length??0,draftChanges:draft?.changes.length??0}),0}return output_manager_default.print(`
39
39
  `),output_manager_default.print(formatStatusOutput({active,draft,bypass,attackMode,planInfo,firewallBypassIps:freshProject.security?.firewallBypassIps})),output_manager_default.print(`
40
40
 
41
41
  `),0}catch(e){return failFirewallApi(client,e,{fallback:"Failed to fetch firewall status",nextCommand:suggestedCommand,permissionAction:"read firewall status",projectName:project.name,timeoutJob:"firewall status"})}finally{output_manager_default.stopSpinner()}}var import_chalk8=__toESM(require_source(),1);async function diff(client,argv){let parsed=await parseSubcommandArgs(argv,diffSubcommand,client);if(typeof parsed=="number")return parsed;let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;output_manager_default.spinner(`Fetching draft changes for ${import_chalk8.default.bold(scope.displayName)}`);try{let{active,draft}=await listFirewallConfigs(client,scope);if(!draft||draft.changes.length===0)return parsed.flags["--json"]?(outputJson(client,{changes:[]}),0):(output_manager_default.log("No pending changes."),0);if(parsed.flags["--json"])return outputJson(client,{changes:draft.changes}),0;let activeRulesMap=new Map((active?.rules||[]).map(r=>[r.id,r]));return output_manager_default.print(`
@@ -65,7 +65,7 @@ ${formatIpBlocksTable(annotated)}
65
65
  `):output_manager_default.print(`
66
66
  ${import_chalk18.default.dim("Showing live configuration.")}
67
67
  `),output_manager_default.print(`
68
- `),0}catch(e){let msg=mapFirewallApiError(e,scope,"Failed to fetch IP blocking rules");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,"firewall ip-blocks list",scope)}]}),process.exit(1),1):(output_manager_default.error(msg),1)}}var import_chalk19=__toESM(require_source(),1);async function patchFirewallDraft(client,scope,patch){return client.fetch(firewallConfigUrl(scope,"/draft"),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(patch)})}async function block(client,argv){let parsed=await parseSubcommandArgs(argv,ipBlocksBlockSubcommand,client,"ip-blocks block");if(typeof parsed=="number")return parsed;let ip=parsed.args[0];if(!ip)return output_manager_default.error("Missing required argument: <ip>"),2;let ipError=validateBlockingIp(ip);if(ipError)return output_manager_default.error(ipError),1;let hostnameFlag=parsed.flags["--hostname"],hostname=hostnameFlag&&hostnameFlag!==""?hostnameFlag:"*",notes=parsed.flags["--notes"];if(hostname!=="*"){let hostnameError=validateHostname(hostname);if(hostnameError)return output_manager_default.error(hostnameError),1}if(notes){let noteError=validateNote(notes);if(noteError)return output_manager_default.error(noteError),1}let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;let hostnameLabel=hostname==="*"||hostname===""?"all hosts":hostname;if(!await confirmAction(client,parsed.flags["--yes"],`Block ${import_chalk19.default.bold(ip)} on ${import_chalk19.default.bold(hostnameLabel)}?`))return output_manager_default.log("Canceled"),0;let blockStamp=stamp_default();output_manager_default.spinner("Staging IP block rule");try{let hadExistingDraft=await detectExistingDraft(client,scope);return await patchFirewallDraft(client,scope,{action:"ip.insert",id:null,value:{ip,hostname,action:"deny",...notes?{notes}:{}}}),output_manager_default.log(`${import_chalk19.default.cyan("Success!")} IP block for ${import_chalk19.default.bold(ip)} on ${import_chalk19.default.bold(hostnameLabel)} staged ${import_chalk19.default.gray(blockStamp())}`),await offerAutoPublish(client,scope,hadExistingDraft,{skipPrompts:parsed.flags["--yes"]}),0}catch(e){let msg=mapFirewallApiError(e,scope,"Failed to stage IP block rule");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,`firewall ip-blocks block ${ip}${hostname!=="*"?` --hostname ${hostname}`:""} --yes`,scope)}]}),process.exit(1),1):(output_manager_default.error(msg),1)}}var import_chalk20=__toESM(require_source(),1);async function unblock(client,argv){let parsed=await parseSubcommandArgs(argv,ipBlocksUnblockSubcommand,client,"ip-blocks unblock");if(typeof parsed=="number")return parsed;let identifier=parsed.args[0];if(!identifier)return output_manager_default.error("Missing required argument: <id-or-ip>"),2;let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;output_manager_default.spinner(`Fetching IP blocking rules for ${import_chalk20.default.bold(scope.displayName)}`);try{let{active,draft}=await listFirewallConfigs(client,scope),currentIps=draft?.ips||active?.ips||[],hostnameFlag=parsed.flags["--hostname"],matches=resolveIpRule(currentIps,identifier);if(hostnameFlag&&matches.length>1){let filtered=matches.filter(r=>r.hostname.toLowerCase()===hostnameFlag.toLowerCase());filtered.length>0&&(matches=filtered)}if(matches.length===0)return output_manager_default.error(`No IP block found for "${identifier}". Run ${import_chalk20.default.cyan(withGlobalFlags(client,"firewall ip-blocks list",scope))} to view all rules.`),1;let rule=matches[0];if(matches.length>1){if(output_manager_default.stopSpinner(),client.nonInteractive||!client.stdin.isTTY)return client.nonInteractive&&outputAgentError(client,{status:"error",reason:"ambiguous_match",message:`Multiple IP blocks match "${identifier}". Use --hostname to narrow the match or specify the full rule ID.`,next:matches.map(r=>({command:withGlobalFlags(client,`firewall ip-blocks unblock "${identifier}" --hostname "${r.hostname}" --yes`,scope),when:`unblock on ${r.hostname==="*"?"all hosts":r.hostname}`}))},1),output_manager_default.error(`Multiple IP blocks match "${identifier}". Use --hostname to narrow the match or specify the full rule ID.`),1;let selectedId=await client.input.select({message:`Multiple IP blocks match "${identifier}". Select one:`,choices:matches.map(r=>({value:r.id,name:`${r.ip} on ${r.hostname==="*"?"all hosts":r.hostname} (${r.action})${r.notes?` \u2014 ${r.notes}`:""}`}))}),selected=matches.find(r=>r.id===selectedId);if(!selected)return output_manager_default.error("No rule selected"),1;rule=selected}let hostnameLabel=rule.hostname==="*"||rule.hostname===""?"all hosts":rule.hostname;if(output_manager_default.stopSpinner(),!await confirmAction(client,parsed.flags["--yes"],`Remove IP block for ${import_chalk20.default.bold(rule.ip)} on ${import_chalk20.default.bold(hostnameLabel)}?`))return output_manager_default.log("Canceled"),0;let unblockStamp=stamp_default();output_manager_default.spinner("Staging IP block removal");let hadExistingDraft=draft!==null&&draft.changes.length>0;return await patchFirewallDraft(client,scope,{action:"ip.remove",id:rule.id,value:null}),output_manager_default.log(`${import_chalk20.default.cyan("Success!")} IP block removal for ${import_chalk20.default.bold(rule.ip)} staged ${import_chalk20.default.gray(unblockStamp())}`),await offerAutoPublish(client,scope,hadExistingDraft,{skipPrompts:parsed.flags["--yes"]}),0}catch(e){let msg=mapFirewallApiError(e,scope,"Failed to stage IP block removal");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,`firewall ip-blocks unblock ${identifier} --yes`,scope)}]}),process.exit(1),1):(output_manager_default.error(msg),1)}}var COMMAND_CONFIG4={list:getCommandAliases(ipBlocksListSubcommand),block:getCommandAliases(ipBlocksBlockSubcommand),unblock:getCommandAliases(ipBlocksUnblockSubcommand)};async function main4(client,args,telemetry){let flagsSpecification=getFlagsSpecification(ipBlocksSubcommand.options),parsedArgs;try{parsedArgs=parseArguments(args,flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let{subcommand,args:subArgs,subcommandOriginal}=getSubcommand(parsedArgs.args,COMMAND_CONFIG4),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("firewall","ip-blocks"),output_manager_default.print(help(ipBlocksSubcommand,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns}))}switch(subcommand){case"list":return needHelp?(telemetry.trackCliFlagHelp("firewall",`ip-blocks:${subcommandOriginal}`),printHelp(ipBlocksListSubcommand),0):(telemetry.trackCliSubcommandIpBlocksList(subcommandOriginal),list2(client,subArgs));case"block":return needHelp?(telemetry.trackCliFlagHelp("firewall",`ip-blocks:${subcommandOriginal}`),printHelp(ipBlocksBlockSubcommand),0):(telemetry.trackCliSubcommandIpBlocksBlock(subcommandOriginal),block(client,subArgs));case"unblock":return needHelp?(telemetry.trackCliFlagHelp("firewall",`ip-blocks:${subcommandOriginal}`),printHelp(ipBlocksUnblockSubcommand),0):(telemetry.trackCliSubcommandIpBlocksUnblock(subcommandOriginal),subcommandOriginal==="rm"&&warnDeprecatedSubcommand(client,"firewall ip-blocks rm","firewall ip-blocks unblock"),unblock(client,subArgs));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG4)),output_manager_default.print(help(ipBlocksSubcommand,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns})),2}}var import_chalk21=__toESM(require_source(),1);function unpublishedRuleChangeCount(changes){return changes.filter(c=>c.action.startsWith("rules.")||c.action==="managedRules.update"||c.action==="botId.toggle").length}async function list3(client,argv){let parsed=await parseSubcommandArgs(argv,rulesListSubcommand,client,"rules list");if(typeof parsed=="number")return parsed;let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;output_manager_default.spinner(`Fetching rules for ${import_chalk21.default.bold(scope.displayName)}`);try{let{active,draft}=await listFirewallConfigs(client,scope),config=draft??active,managed=scope.type==="project"?getManagedBotRules(config):[],activeRules=active?.rules||[],draftRules=draft?.rules||null,changes=draft?.changes||[],annotated=annotateRules(activeRules,draftRules,changes);if(parsed.flags["--json"])return outputJson(client,{...scope.type==="project"?{managed:managed.map(managedBotJson)}:{},rules:annotated.map(a=>({...a.rule,_status:a.status})),hasDraft:changes.length>0,pendingChanges:changes.length}),0;if(scope.type==="project"&&output_manager_default.print(`
68
+ `),0}catch(e){let msg=mapFirewallApiError(e,scope,"Failed to fetch IP blocking rules");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,"firewall ip-blocks list",scope)}]}),process.exit(1),1):(output_manager_default.error(msg),1)}}var import_chalk19=__toESM(require_source(),1);async function patchFirewallDraft(client,scope,patch){return client.fetch(firewallConfigUrl(scope,"/draft"),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(patch)})}async function block(client,argv){let parsed=await parseSubcommandArgs(argv,ipBlocksBlockSubcommand,client,"ip-blocks block");if(typeof parsed=="number")return parsed;let ip=parsed.args[0];if(!ip)return output_manager_default.error("Missing required argument: <ip>"),2;let ipError=validateBlockingIp(ip);if(ipError)return output_manager_default.error(ipError),1;let hostnameFlag=parsed.flags["--hostname"],hostname=hostnameFlag&&hostnameFlag!==""?hostnameFlag:"*",notes=parsed.flags["--notes"];if(hostname!=="*"){let hostnameError=validateHostname(hostname);if(hostnameError)return output_manager_default.error(hostnameError),1}if(notes){let noteError=validateNote(notes);if(noteError)return output_manager_default.error(noteError),1}let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;let hostnameLabel=hostname==="*"||hostname===""?"all hosts":hostname;if(!await confirmAction(client,parsed.flags["--yes"],`Block ${import_chalk19.default.bold(ip)} on ${import_chalk19.default.bold(hostnameLabel)}?`))return output_manager_default.log("Canceled"),0;let blockStamp=stamp_default();output_manager_default.spinner("Staging IP block rule");try{let hadExistingDraft=await detectExistingDraft(client,scope);return await patchFirewallDraft(client,scope,{action:"ip.insert",id:null,value:{ip,hostname,action:"deny",...notes?{notes}:{}}}),output_manager_default.log(`${import_chalk19.default.cyan("Success!")} IP block for ${import_chalk19.default.bold(ip)} on ${import_chalk19.default.bold(hostnameLabel)} staged ${import_chalk19.default.gray(blockStamp())}`),await offerAutoPublish(client,scope,hadExistingDraft,{skipPrompts:parsed.flags["--yes"]}),0}catch(e){let msg=mapFirewallApiError(e,scope,"Failed to stage IP block rule");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,`firewall ip-blocks block ${ip}${hostname!=="*"?` --hostname ${hostname}`:""} --yes`,scope)}]}),process.exit(1),1):(output_manager_default.error(msg),1)}}var import_chalk20=__toESM(require_source(),1);async function unblock(client,argv){let parsed=await parseSubcommandArgs(argv,ipBlocksUnblockSubcommand,client,"ip-blocks unblock");if(typeof parsed=="number")return parsed;let identifier=parsed.args[0];if(!identifier)return output_manager_default.error("Missing required argument: <id-or-ip>"),2;let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;output_manager_default.spinner(`Fetching IP blocking rules for ${import_chalk20.default.bold(scope.displayName)}`);try{let{active,draft}=await listFirewallConfigs(client,scope),currentIps=draft?.ips||active?.ips||[],hostnameFlag=parsed.flags["--hostname"],matches=resolveIpRule(currentIps,identifier);if(hostnameFlag&&matches.length>1){let filtered=matches.filter(r=>r.hostname.toLowerCase()===hostnameFlag.toLowerCase());filtered.length>0&&(matches=filtered)}if(matches.length===0)return output_manager_default.error(`No IP block found for "${identifier}". Run ${import_chalk20.default.cyan(withGlobalFlags(client,"firewall ip-blocks list",scope))} to view all rules.`),1;let rule=matches[0];if(matches.length>1){if(output_manager_default.stopSpinner(),client.nonInteractive||!client.stdin.isTTY)return client.nonInteractive&&outputAgentError(client,{status:"error",reason:"ambiguous_match",message:`Multiple IP blocks match "${identifier}". Use --hostname to narrow the match or specify the full rule ID.`,next:matches.map(r=>({command:withGlobalFlags(client,`firewall ip-blocks unblock "${identifier}" --hostname "${r.hostname}" --yes`,scope),when:`unblock on ${r.hostname==="*"?"all hosts":r.hostname}`}))},1),output_manager_default.error(`Multiple IP blocks match "${identifier}". Use --hostname to narrow the match or specify the full rule ID.`),1;let selectedId=await client.input.select({message:`Multiple IP blocks match "${identifier}". Select one:`,choices:matches.map(r=>({value:r.id,name:`${r.ip} on ${r.hostname==="*"?"all hosts":r.hostname} (${r.action})${r.notes?` \u2014 ${r.notes}`:""}`}))}),selected=matches.find(r=>r.id===selectedId);if(!selected)return output_manager_default.error("No rule selected"),1;rule=selected}let hostnameLabel=rule.hostname==="*"||rule.hostname===""?"all hosts":rule.hostname;if(output_manager_default.stopSpinner(),!await confirmAction(client,parsed.flags["--yes"],`Remove IP block for ${import_chalk20.default.bold(rule.ip)} on ${import_chalk20.default.bold(hostnameLabel)}?`))return output_manager_default.log("Canceled"),0;let unblockStamp=stamp_default();output_manager_default.spinner("Staging IP block removal");let hadExistingDraft=draft!==null&&draft.changes.length>0;return await patchFirewallDraft(client,scope,{action:"ip.remove",id:rule.id,value:null}),output_manager_default.log(`${import_chalk20.default.cyan("Success!")} IP block removal for ${import_chalk20.default.bold(rule.ip)} staged ${import_chalk20.default.gray(unblockStamp())}`),await offerAutoPublish(client,scope,hadExistingDraft,{skipPrompts:parsed.flags["--yes"]}),0}catch(e){let msg=mapFirewallApiError(e,scope,"Failed to stage IP block removal");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,`firewall ip-blocks unblock ${identifier} --yes`,scope)}]}),process.exit(1),1):(output_manager_default.error(msg),1)}}var COMMAND_CONFIG4={list:getCommandAliases(ipBlocksListSubcommand),block:getCommandAliases(ipBlocksBlockSubcommand),unblock:getCommandAliases(ipBlocksUnblockSubcommand)};async function main4(client,args,telemetry){let flagsSpecification=getFlagsSpecification(ipBlocksSubcommand.options),parsedArgs;try{parsedArgs=parseArguments(args,flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let{subcommand,args:subArgs,subcommandOriginal}=getSubcommand(parsedArgs.args,COMMAND_CONFIG4),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("firewall","ip-blocks"),output_manager_default.print(help(ipBlocksSubcommand,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns}))}switch(subcommand){case"list":return needHelp?(telemetry.trackCliFlagHelp("firewall",`ip-blocks:${subcommandOriginal}`),printHelp(ipBlocksListSubcommand),0):(telemetry.trackCliSubcommandIpBlocksList(subcommandOriginal),list2(client,subArgs));case"block":return needHelp?(telemetry.trackCliFlagHelp("firewall",`ip-blocks:${subcommandOriginal}`),printHelp(ipBlocksBlockSubcommand),0):(telemetry.trackCliSubcommandIpBlocksBlock(subcommandOriginal),block(client,subArgs));case"unblock":return needHelp?(telemetry.trackCliFlagHelp("firewall",`ip-blocks:${subcommandOriginal}`),printHelp(ipBlocksUnblockSubcommand),0):(telemetry.trackCliSubcommandIpBlocksUnblock(subcommandOriginal),subcommandOriginal==="rm"&&warnDeprecatedSubcommand(client,"firewall ip-blocks rm","firewall ip-blocks unblock"),unblock(client,subArgs));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG4)),output_manager_default.print(help(ipBlocksSubcommand,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns})),2}}var import_chalk21=__toESM(require_source(),1);function unpublishedRuleChangeCount(changes){return changes.filter(c=>c.action.startsWith("rules.")||c.action==="managedRules.update"||c.action==="managedRuleGroup.update"||c.action==="botId.toggle").length}async function list3(client,argv){let parsed=await parseSubcommandArgs(argv,rulesListSubcommand,client,"rules list");if(typeof parsed=="number")return parsed;let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;output_manager_default.spinner(`Fetching rules for ${import_chalk21.default.bold(scope.displayName)}`);try{let{active,draft}=await listFirewallConfigs(client,scope),config=draft??active,managed=scope.type==="project"?getManagedBotRules(config):[],activeRules=active?.rules||[],draftRules=draft?.rules||null,changes=draft?.changes||[],annotated=annotateRules(activeRules,draftRules,changes);if(parsed.flags["--json"])return outputJson(client,{...scope.type==="project"?{managed:managed.map(managedBotJson)}:{},rules:annotated.map(a=>({...a.rule,_status:a.status})),hasDraft:changes.length>0,pendingChanges:changes.length}),0;if(scope.type==="project"&&output_manager_default.print(`
69
69
  ${formatManagedBotRulesTable(managed)}
70
70
  `),annotated.length===0)if(scope.type==="project")output_manager_default.print(`
71
71
  ${import_chalk21.default.bold("Custom")}
@@ -94,7 +94,7 @@ ${formatManagedBotRulesTable(managed)}
94
94
  ${formatManagedBotRuleDetail(managed)}
95
95
  `),output_manager_default.print(`
96
96
  ${import_chalk22.default.dim(" Change this rule:")}
97
- ${withGlobalFlags(client,`firewall rules update ${managed.id} --action ${suggestedManagedBotAction(managed)}`,scope)}
97
+ ${withGlobalFlags(client,suggestedManagedBotEditCommand(managed),scope)}
98
98
 
99
99
  `),0)}let currentRules=draft?.rules||active?.rules||[],matches=resolveRule(currentRules,identifier);if(matches.length===0)return output_manager_default.stopSpinner(),client.nonInteractive&&outputAgentError(client,{status:"error",reason:"not_found",message:`No rule found for "${identifier}".`,next:[{command:withGlobalFlags(client,"firewall rules list",scope),when:"list rules"}]},1),output_manager_default.error(`No rule found for "${identifier}". Run ${import_chalk22.default.cyan(withGlobalFlags(client,"firewall rules list",scope))} to view all rules.`),1;let rule=matches[0];if(matches.length>1){if(output_manager_default.stopSpinner(),client.nonInteractive||!client.stdin.isTTY)return client.nonInteractive&&outputAgentError(client,{status:"error",reason:"ambiguous_match",message:`Multiple rules match "${identifier}". Specify the full rule ID.`,next:matches.map(r=>({command:withGlobalFlags(client,`firewall rules inspect "${r.id}"`,scope),when:`inspect "${r.name}"`}))},1),output_manager_default.error(`Multiple rules match "${identifier}". Specify the full rule ID to disambiguate.`),1;let selectedId=await client.input.select({message:`Multiple rules match "${identifier}". Select one:`,choices:matches.map(r=>({value:r.id,name:`${r.name} [${r.active?"Enabled":"Disabled"}] (${r.id})`}))}),selected=matches.find(r=>r.id===selectedId);if(!selected)return output_manager_default.error("No rule selected"),1;rule=selected}return parsed.flags["--json"]?(outputJson(client,rule),0):(output_manager_default.print(`
100
100
  ${formatRuleDetail(rule)}
@@ -129,15 +129,15 @@ ${formatRuleExpanded(updatedPreview)}
129
129
  `);continue}catch(e){output_manager_default.stopSpinner();let priority=failPriorityProjectGate(client,e,scope);if(priority!==null)return priority;let error=e;output_manager_default.error(`Failed to regenerate: ${error.message||"Unknown error"}`);continue}}if(choice==="edit-manual"){let prePopulated={...currentRule,id:"(new)"},modified=await runInteractiveEditLoop(client,prePopulated);if(!modified)continue;return createFromGenerated(client,scope,modified,opts)}if(choice==="discard")return output_manager_default.log("Discarded"),0}}async function createFromGenerated(client,scope,rule,opts){let createStamp=stamp_default();output_manager_default.spinner("Staging rule");try{let hadExistingDraft=await detectExistingDraft(client,scope);return await patchFirewallDraft(client,scope,{action:"rules.insert",id:null,value:{name:rule.name,description:rule.description,active:rule.active!==!1,conditionGroup:rule.conditionGroup,action:rule.action}}),output_manager_default.log(`${import_chalk25.default.cyan("Success!")} Rule "${import_chalk25.default.bold(rule.name)}" staged ${import_chalk25.default.gray(createStamp())}`),printActionImpactWarning(rule.action),await offerAutoPublish(client,scope,hadExistingDraft,{skipPrompts:opts.skipPrompts}),0}catch(e){output_manager_default.stopSpinner();let priority=failPriorityProjectGate(client,e,scope);if(priority!==null)return priority;let msg=e.message||"Failed to stage rule";return client.nonInteractive&&outputAgentError(client,{status:"error",reason:"staging_failed",message:msg,next:[{command:withGlobalFlags(client,"firewall rules add --yes"),when:"try again"}]},1),output_manager_default.error(msg),1}}async function add2(client,argv){let parsed=await parseSubcommandArgs(argv,rulesAddSubcommand,client,"rules add");if(typeof parsed=="number")return parsed;let aiPrompt=parsed.flags["--ai"],jsonInput=getRulePayload(parsed.flags);if(typeof jsonInput=="number")return jsonInput;let conditionFlags=parsed.flags["--condition"];if([aiPrompt,jsonInput,conditionFlags].filter(Boolean).length>1)return output_manager_default.error("Cannot use --ai, --data, and --condition together. Use only one mode."),1;if(aiPrompt){if(parsed.flags["--team-level"])return output_manager_default.error("AI mode is not available with --team-level. Use --data or --condition options instead."),1;if(client.nonInteractive||!client.stdin.isTTY)return client.nonInteractive&&outputAgentError(client,{status:"error",reason:"ai_not_available",message:"AI mode is not available in non-interactive mode. AI-generated rules require human review before staging. Use --data or --condition options instead.",next:[{command:withGlobalFlags(client,`firewall rules add "Name" --condition '{"type":"path","op":"pre","value":"/api"}' --action deny --yes`),when:"create with options"},{command:withGlobalFlags(client,`firewall rules add --data '{"name":"...","conditionGroup":[...],"action":{...}}' --yes`),when:"create with JSON"}]}),output_manager_default.error("AI mode is not available in non-interactive mode. Use --data or --condition options instead."),1;let scope=await resolveFirewallScope(client,parsed.flags);return typeof scope=="number"?scope:scope.type==="team"?(output_manager_default.error("AI mode is not available with --team-level. Use --data or --condition options instead."),1):handleAIAdd(client,{id:scope.projectId,name:scope.displayName},scope.teamId,{prompt:aiPrompt,name:parsed.args[0],skipPrompts:!!parsed.flags["--yes"],teamSlug:scope.teamSlug})}if(jsonInput)return handleJsonAdd(client,parsed,jsonInput);if(conditionFlags)return handleFlagAdd(client,parsed,conditionFlags);if(client.stdin.isTTY&&!client.nonInteractive){let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;let mode=await client.input.select({message:"How would you like to create the rule?",choices:[...scope.type==="project"?[{value:"ai",name:"Describe what you want (AI-powered)"}]:[],{value:"manual",name:"Build manually (step by step)"},{value:"json",name:"Paste JSON"}]});if(mode==="ai"&&scope.type==="project")return handleAIAdd(client,{id:scope.projectId,name:scope.displayName},scope.teamId,{skipPrompts:!1,teamSlug:scope.teamSlug});if(mode==="json"){let jsonStr=await client.input.text({message:"Paste the JSON rule definition:"});return handleJsonAdd(client,parsed,jsonStr)}return addInteractive(client,scope,{skipPrompts:!!parsed.flags["--yes"]})}return client.nonInteractive&&outputAgentError(client,{status:"error",reason:"missing_flags",message:"No rule definition provided. Use --data or --condition options.",next:[{command:withGlobalFlags(client,`firewall rules add "Name" --condition '{"type":"path","op":"pre","value":"/api"}' --action deny --yes`),when:"create with options"},{command:withGlobalFlags(client,`firewall rules add --data '{"name":"Name","conditionGroup":[...],"action":{"mitigate":{"action":"deny"}}}' --yes`),when:"create with JSON"}]}),output_manager_default.error("Interactive mode is not available. Use --ai, --data, or --condition options to create a rule."),2}async function handleJsonAdd(client,parsed,jsonStr){let ruleData;try{ruleData=JSON.parse(jsonStr)}catch{return output_manager_default.error("Invalid JSON. Please provide a valid JSON object."),2}if(!ruleData.name||typeof ruleData.name!="string")return output_manager_default.error('JSON must include a "name" field (string).'),1;if(!ruleData.conditionGroup||!Array.isArray(ruleData.conditionGroup))return output_manager_default.error('JSON must include a "conditionGroup" field (array).'),1;for(let i=0;i<ruleData.conditionGroup.length;i++){let group=ruleData.conditionGroup[i];if(!group.conditions||!Array.isArray(group.conditions))return output_manager_default.error(`conditionGroup[${i}] must have a "conditions" array.`),1;for(let j=0;j<group.conditions.length;j++){let cond=group.conditions[j];if(!cond.type||typeof cond.type!="string")return output_manager_default.error(`conditionGroup[${i}].conditions[${j}] must have a "type" field.`),1;if(!cond.op||typeof cond.op!="string")return output_manager_default.error(`conditionGroup[${i}].conditions[${j}] must have an "op" field.`),1}}if(!ruleData.action||typeof ruleData.action!="object")return output_manager_default.error('JSON must include an "action" field (object).'),1;let actionObj=ruleData.action;if(!actionObj.mitigate||typeof actionObj.mitigate!="object")return output_manager_default.error('action must have a "mitigate" field. Example: { "mitigate": { "action": "deny" } }'),1;let mitigateObj=actionObj.mitigate;if(!mitigateObj.action||typeof mitigateObj.action!="string")return output_manager_default.error('action.mitigate must have an "action" field (string). Valid: deny, challenge, rate_limit, log, redirect.'),1;if(ruleData.name.length>160)return output_manager_default.error("Rule name must be 160 characters or less."),1;if(ruleData.description&&ruleData.description.length>256)return output_manager_default.error("Rule description must be 256 characters or less."),1;if(ruleData.conditionGroup.length>25)return output_manager_default.error("Maximum 25 condition groups allowed."),1;let rule={name:ruleData.name,description:ruleData.description,active:ruleData.active!==!1,conditionGroup:ruleData.conditionGroup,action:ruleData.action};return createRule(client,parsed,rule)}async function handleFlagAdd(client,parsed,conditionFlags){let name=parsed.args[0];if(!name)return output_manager_default.error(`Missing rule name. Provide as the first argument: ${import_chalk26.default.cyan(withGlobalFlags(client,'firewall rules add "Rule name" --condition ...'))}`),1;if(name.length>160)return output_manager_default.error("Rule name must be 160 characters or less."),1;let rawArgs=parsed.flags["--condition"];if(!rawArgs||rawArgs.length===0)return output_manager_default.error("At least one --condition is required."),2;let hasOr=parsed.flags["--or"],conditionGroups;if(hasOr){let interleaved=[],condValues=[...rawArgs],condIdx=0;for(let arg of client.argv)arg==="--or"?interleaved.push("--or"):(arg==="--condition"||arg.startsWith("--condition="))&&condIdx<condValues.length&&(interleaved.push(condValues[condIdx]),condIdx++);let result=parseConditionFlags(interleaved);if(typeof result=="string")return output_manager_default.error(result),1;conditionGroups=result.groups}else{let result=parseConditionFlags(rawArgs);if(typeof result=="string")return output_manager_default.error(result),1;conditionGroups=result.groups}let actionType=parsed.flags["--action"];if(!actionType)return output_manager_default.error(`Missing --action. Valid actions: ${VALID_ACTIONS.join(", ")}`),1;if(!VALID_ACTIONS.includes(actionType))return output_manager_default.error(`Invalid action "${actionType}". Valid actions: ${VALID_ACTIONS.join(", ")}`),1;let action=buildActionFromFlags(parsed.flags,actionType);if(typeof action=="string")return output_manager_default.error(action),1;let description=parsed.flags["--description"];if(description&&description.length>256)return output_manager_default.error("Rule description must be 256 characters or less."),1;parsed.flags["--disabled"]&&warnDeprecatedInput(client,"--disabled","--no-enable");let active=!(parsed.flags["--no-enable"]||parsed.flags["--disabled"]);return createRule(client,parsed,{name,description,active,conditionGroup:conditionGroups,action})}async function createRule(client,parsed,rule){let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;let reserved=refuseManagedBotMutation(client,scope,rule.name,"add a custom rule named");if(reserved!==null)return reserved;let previewRule={...rule,id:"(new)"};if(output_manager_default.print(`
130
130
  ${formatRuleExpanded(previewRule)}
131
131
 
132
- `),!await confirmAction(client,parsed.flags["--yes"],"Create this rule?"))return output_manager_default.log("Canceled"),0;let createStamp=stamp_default();output_manager_default.spinner("Staging rule");try{let hadExistingDraft=await detectExistingDraft(client,scope);return await patchFirewallDraft(client,scope,{action:"rules.insert",id:null,value:rule}),output_manager_default.log(`${import_chalk26.default.cyan("Success!")} Rule "${import_chalk26.default.bold(rule.name)}" staged ${import_chalk26.default.gray(createStamp())}`),printActionImpactWarning(rule.action),await offerAutoPublish(client,scope,hadExistingDraft,{skipPrompts:parsed.flags["--yes"]}),0}catch(e){let priority=failPriorityProjectGate(client,e,scope);if(priority!==null)return priority;let msg=mapFirewallApiError(e,scope,"Failed to stage rule");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,"firewall rules add --yes",scope)}]}),1):(output_manager_default.error(msg),1)}}var import_chalk28=__toESM(require_source(),1);var import_chalk27=__toESM(require_source(),1);var UNSUPPORTED_FLAGS=["--ai","--data","--json","--condition","--name","--description","--duration","--enable","--no-enable","--enabled","--disabled","--rate-limit-algo","--rate-limit-window","--rate-limit-requests","--rate-limit-keys","--rate-limit-action","--redirect-url","--redirect-permanent","--or"];async function editManagedBotRule(client,opts){let used=UNSUPPORTED_FLAGS.filter(flag=>{let value=opts.flags[flag];return Array.isArray(value)?value.length>0:!!value});if(used.length>0){let command=`firewall rules update ${opts.id} --action <action>`;return failFirewall(client,{message:`Can't use ${used.join(", ")} on managed bot rules. Use --action.`,reason:AGENT_REASON.INVALID_ARGUMENTS,fix:{command,hint:`Use ${import_chalk27.default.cyan(withGlobalFlags(client,command,opts.scope))} to change it.`,when:"edit with --action"}})}let current=getManagedBotRule(opts.config,opts.id),rawAction=opts.flags["--action"],hasActionFlag=!!rawAction;if(!rawAction){if(client.nonInteractive||!client.stdin.isTTY){let command=`firewall rules update ${opts.id} --action <action>`;return failFirewall(client,{message:`Specify --action for ${current.name}. Run ${import_chalk27.default.cyan(withGlobalFlags(client,`firewall rules inspect ${opts.id}`,opts.scope))} to see the current value.`,reason:AGENT_REASON.MISSING_ARGUMENTS,fix:{command,hint:`Use ${import_chalk27.default.cyan(withGlobalFlags(client,command,opts.scope))}.`,when:"set --action"}})}output_manager_default.print(`
132
+ `),!await confirmAction(client,parsed.flags["--yes"],"Create this rule?"))return output_manager_default.log("Canceled"),0;let createStamp=stamp_default();output_manager_default.spinner("Staging rule");try{let hadExistingDraft=await detectExistingDraft(client,scope);return await patchFirewallDraft(client,scope,{action:"rules.insert",id:null,value:rule}),output_manager_default.log(`${import_chalk26.default.cyan("Success!")} Rule "${import_chalk26.default.bold(rule.name)}" staged ${import_chalk26.default.gray(createStamp())}`),printActionImpactWarning(rule.action),await offerAutoPublish(client,scope,hadExistingDraft,{skipPrompts:parsed.flags["--yes"]}),0}catch(e){let priority=failPriorityProjectGate(client,e,scope);if(priority!==null)return priority;let msg=mapFirewallApiError(e,scope,"Failed to stage rule");return client.nonInteractive?(outputAgentError(client,{status:"error",reason:"api_error",message:msg,next:[{command:withGlobalFlags(client,"firewall rules add --yes",scope)}]}),1):(output_manager_default.error(msg),1)}}var import_chalk28=__toESM(require_source(),1);var import_chalk27=__toESM(require_source(),1);async function getManagedRulesets(client,scope){let query=new URLSearchParams({aiBotsCategories:"true"});return scope.type==="project"&&query.set("projectId",scope.projectId),scope.teamId&&query.set("teamId",scope.teamId),client.fetch(`/v1/security/firewall/managed-rules?${query}`)}var FirewallTelemetryClient=class extends TelemetryClient{trackCliOptionCategory(value,categories){value!==void 0&&this.trackCliOption({option:"category",value:categories.some(category=>category.id===value)?value:this.redactedValue})}trackCliFlagTeamLevel(value){value&&this.trackCliFlag("team-level")}trackCliSubcommandStatus(actual){this.trackCliSubcommand({subcommand:"status",value:actual})}trackCliSubcommandOverview(actual){this.trackCliSubcommand({subcommand:"overview",value:actual})}trackCliSubcommandDiff(actual){this.trackCliSubcommand({subcommand:"diff",value:actual})}trackCliSubcommandPublish(actual){this.trackCliSubcommand({subcommand:"publish",value:actual})}trackCliSubcommandDiscard(actual){this.trackCliSubcommand({subcommand:"discard",value:actual})}trackCliSubcommandRules(actual){this.trackCliSubcommand({subcommand:"rules",value:actual})}trackCliSubcommandRulesList(actual){this.trackCliSubcommand({subcommand:"rules:list",value:actual})}trackCliSubcommandRulesInspect(actual){this.trackCliSubcommand({subcommand:"rules:inspect",value:actual})}trackCliSubcommandRulesAdd(actual){this.trackCliSubcommand({subcommand:"rules:add",value:actual})}trackCliSubcommandRulesUpdate(actual){this.trackCliSubcommand({subcommand:"rules:update",value:actual})}trackCliSubcommandRulesEnable(actual){this.trackCliSubcommand({subcommand:"rules:enable",value:actual})}trackCliSubcommandRulesDisable(actual){this.trackCliSubcommand({subcommand:"rules:disable",value:actual})}trackCliSubcommandRulesRemove(actual){this.trackCliSubcommand({subcommand:"rules:remove",value:actual})}trackCliSubcommandRulesReorder(actual){this.trackCliSubcommand({subcommand:"rules:reorder",value:actual})}trackCliSubcommandRulesMove(actual){this.trackCliSubcommand({subcommand:"rules:move",value:actual})}trackCliSubcommandIpBlocks(actual){this.trackCliSubcommand({subcommand:"ip-blocks",value:actual})}trackCliSubcommandIpBlocksList(actual){this.trackCliSubcommand({subcommand:"ip-blocks:list",value:actual})}trackCliSubcommandIpBlocksBlock(actual){this.trackCliSubcommand({subcommand:"ip-blocks:block",value:actual})}trackCliSubcommandIpBlocksUnblock(actual){this.trackCliSubcommand({subcommand:"ip-blocks:unblock",value:actual})}trackCliSubcommandSystemBypass(actual){this.trackCliSubcommand({subcommand:"system-bypass",value:actual})}trackCliSubcommandSystemBypassList(actual){this.trackCliSubcommand({subcommand:"system-bypass:list",value:actual})}trackCliSubcommandSystemBypassAdd(actual){this.trackCliSubcommand({subcommand:"system-bypass:add",value:actual})}trackCliSubcommandSystemBypassRemove(actual){this.trackCliSubcommand({subcommand:"system-bypass:remove",value:actual})}trackCliSubcommandAttackMode(actual){this.trackCliSubcommand({subcommand:"attack-mode",value:actual})}trackCliSubcommandAttackModeEnable(actual){this.trackCliSubcommand({subcommand:"attack-mode:enable",value:actual})}trackCliSubcommandAttackModeDisable(actual){this.trackCliSubcommand({subcommand:"attack-mode:disable",value:actual})}trackCliSubcommandSystemMitigations(actual){this.trackCliSubcommand({subcommand:"system-mitigations",value:actual})}trackCliSubcommandSystemMitigationsPause(actual){this.trackCliSubcommand({subcommand:"system-mitigations:pause",value:actual})}trackCliSubcommandSystemMitigationsResume(actual){this.trackCliSubcommand({subcommand:"system-mitigations:resume",value:actual})}trackCliSubcommandAlerts(actual){this.trackCliSubcommand({subcommand:"alerts",value:actual})}trackCliSubcommandAlertsList(actual){this.trackCliSubcommand({subcommand:"alerts:list",value:actual})}trackCliSubcommandAlertsInspect(actual){this.trackCliSubcommand({subcommand:"alerts:inspect",value:actual})}trackCliSubcommandPersistentActions(actual){this.trackCliSubcommand({subcommand:"persistent-actions",value:actual})}trackCliSubcommandPersistentActionsList(actual){this.trackCliSubcommand({subcommand:"persistent-actions:list",value:actual})}trackCliSubcommandPersistentActionsInspect(actual){this.trackCliSubcommand({subcommand:"persistent-actions:inspect",value:actual})}trackCliSubcommandTraffic(actual){this.trackCliSubcommand({subcommand:"traffic",value:actual})}trackCliSubcommandTrafficList(actual){this.trackCliSubcommand({subcommand:"traffic:list",value:actual})}trackCliSubcommandTrafficInspect(actual){this.trackCliSubcommand({subcommand:"traffic:inspect",value:actual})}trackCliSubcommandBotManagement(actual){this.trackCliSubcommand({subcommand:"bot-management",value:actual})}};var UNSUPPORTED_FLAGS=["--ai","--data","--json","--condition","--name","--description","--duration","--enable","--no-enable","--enabled","--disabled","--rate-limit-algo","--rate-limit-window","--rate-limit-requests","--rate-limit-keys","--rate-limit-action","--redirect-url","--redirect-permanent","--or"];function aiBotsEnableWarning(ruleset,categories,edited){if(ruleset?.active)return;let turnedOn=categories.flatMap(category=>{if(category.id===edited.id)return[];let action=getAiBotsCategoryActionAfterEdit(ruleset,category.ruleGroupId);return action==="allow"?[]:[`${category.name} action will be set to ${formatManagedBotAction(action)}`]});if(turnedOn.length!==0)return`Publishing turns AI Bots ${ruleset?"back on":"on"}, so ${turnedOn.join(" and ")}.`}async function editManagedBotRule(client,opts){let used=UNSUPPORTED_FLAGS.filter(flag=>{let value=opts.flags[flag];return Array.isArray(value)?value.length>0:!!value});if(used.length>0){let command=`firewall rules update ${opts.id} --action <action>`;return failFirewall(client,{message:`Can't use ${used.join(", ")} on managed bot rules. Use --action.`,reason:AGENT_REASON.INVALID_ARGUMENTS,fix:{command,hint:`Use ${import_chalk27.default.cyan(withGlobalFlags(client,command,opts.scope))} to change it.`,when:"edit with --action"}})}let ruleset=opts.config?.managedRules?.ai_bots,rawCategory=opts.flags["--category"],categories=[];if(opts.id==="ai-bots"){categories=getAiBotsCategories(ruleset);try{let catalog=await getManagedRulesets(client,opts.scope);categories=getAiBotsCategories(ruleset,catalog.ai_bots?.ruleGroups)}catch(error){if(categories.length===0)return failFirewallApi(client,error,{fallback:"Failed to read the AI Bots catalog",permissionAction:"read managed firewall rulesets",projectName:opts.scope.displayName,nextCommand:"firewall rules inspect ai-bots",timeoutJob:"AI Bots catalog"})}new FirewallTelemetryClient({opts:{store:client.telemetryEventStore}}).trackCliOptionCategory(rawCategory,categories)}let category=categories.find(item=>item.id===rawCategory);if(rawCategory!==void 0&&!category)return failFirewall(client,{message:categories.length>0?`Invalid category "${rawCategory}" for AI Bots. Use ${categories.map(item=>item.id).join(", ")}.`:"AI Bots categories are not available for this project. Use firewall rules update ai-bots --action <action> to edit the ruleset.",reason:AGENT_REASON.INVALID_ARGUMENTS});let current=getManagedBotRule(opts.config,opts.id),rawAction=opts.flags["--action"],needsCategory=categories.length>0&&!category,prompting=!rawAction||needsCategory;if(prompting){if(client.nonInteractive||!client.stdin.isTTY){let command=categories.length>0?`firewall rules update ${opts.id} --category ${category?.id??"<category>"} --action <action>`:`firewall rules update ${opts.id} --action <action>`;return failFirewall(client,{message:`Specify ${needsCategory?`--category (${categories.map(item=>item.id).join(", ")}) and --action`:"--action"} for ${current.name}. Run ${import_chalk27.default.cyan(withGlobalFlags(client,`firewall rules inspect ${opts.id}`,opts.scope))} to see the current value.`,reason:AGENT_REASON.MISSING_ARGUMENTS,fix:{command,hint:`Use ${import_chalk27.default.cyan(withGlobalFlags(client,command,opts.scope))}.`,when:needsCategory?"set --category and --action":"set --action"}})}output_manager_default.print(`
133
133
  ${formatManagedBotRuleDetail(current)}
134
134
 
135
- `),rawAction=await client.input.select({message:"Action?",choices:managedBotActions(opts.id).map(action=>({value:action,name:formatManagedBotAction(action)}))})}let parsedAction=parseManagedBotAction(opts.id,rawAction);if("error"in parsedAction){let command=`firewall rules update ${opts.id} --action <action>`;return failFirewall(client,{message:parsedAction.error,reason:AGENT_REASON.INVALID_ARGUMENTS,fix:{command,hint:`Use ${import_chalk27.default.cyan(withGlobalFlags(client,command,opts.scope))}.`,when:"set a valid --action"}})}if(parsedAction.action===current.action)return output_manager_default.log(`No changes detected. ${current.name} is already ${formatManagedBotAction(current.action)}.`),0;if(opts.id==="bot-id"&&parsedAction.action==="deep-analysis")try{let{team}=await getScope(client);if(team?.billing?.plan==="hobby")return failFirewall(client,{message:"BotID Deep Analysis is not available on the Hobby plan.",reason:AGENT_REASON.PLAN_UPGRADE_REQUIRED})}catch{}let warning=managedBotTrafficWarning(opts.id,current.action,parsedAction.action);if(hasActionFlag&&output_manager_default.print(`
136
- ${formatManagedBotRuleDetail({...current,action:parsedAction.action})}
135
+ `)}needsCategory&&(category=await client.input.select({message:"Category?",choices:categories.map(item=>({value:item,name:`${item.name} \u2014 ${formatManagedBotAction(getAiBotsCategoryAction(ruleset,item.ruleGroupId))}`}))})),rawAction||(rawAction=await client.input.select({message:"Action?",choices:managedBotActions(opts.id,category).map(action=>({value:action,name:formatManagedBotAction(action)}))}));let parsedAction=parseManagedBotAction(opts.id,rawAction,category);if("error"in parsedAction){let command=`firewall rules update ${opts.id}${category?` --category ${category.id}`:""} --action <action>`;return failFirewall(client,{message:parsedAction.error,reason:AGENT_REASON.INVALID_ARGUMENTS,fix:{command,hint:`Use ${import_chalk27.default.cyan(withGlobalFlags(client,command,opts.scope))}.`,when:"set a valid --action"}})}let name=category?.name??current.name,currentAction=category?ruleset?.ruleGroups?.[category.ruleGroupId]?getAiBotsCategoryActionAfterEdit(ruleset,category.ruleGroupId):getAiBotsCategoryAction(ruleset,category.ruleGroupId):current.action;if(parsedAction.action===currentAction)return output_manager_default.log(`No changes detected. ${name} is already ${formatManagedBotAction(parsedAction.action)}.`),0;if(opts.id==="bot-id"&&parsedAction.action==="deep-analysis")try{let{team}=await getScope(client);if(team?.billing?.plan==="hobby")return failFirewall(client,{message:"BotID Deep Analysis is not available on the Hobby plan.",reason:AGENT_REASON.PLAN_UPGRADE_REQUIRED})}catch{}let warning=[managedBotTrafficWarning(opts.id,currentAction,parsedAction.action,category),category&&aiBotsEnableWarning(ruleset,categories,category)].filter(Boolean).join(" ");if(!prompting){let preview=category?{...current,action:null,categories:categories.map(item=>({...item,action:item.id===category.id?parsedAction.action:getAiBotsCategoryActionAfterEdit(ruleset,item.ruleGroupId)}))}:{...current,action:parsedAction.action};output_manager_default.print(`
136
+ ${formatManagedBotRuleDetail(preview)}
137
137
 
138
- `),!await confirmAction(client,opts.flags["--yes"],`Save ${current.name} \u2192 ${formatManagedBotAction(parsedAction.action)}?`,warning))return output_manager_default.log("Canceled"),0;let editStamp=stamp_default();output_manager_default.spinner("Staging changes");try{let hadExistingDraft=await detectExistingDraft(client,opts.scope);return await patchFirewallDraft(client,opts.scope,buildManagedBotPatch(opts.id,parsedAction.action)),output_manager_default.log(`${import_chalk27.default.cyan("Success!")} ${current.name} updated to ${import_chalk27.default.bold(formatManagedBotAction(parsedAction.action))} and staged ${import_chalk27.default.gray(editStamp())}`),opts.id==="bot-id"&&parsedAction.action==="deep-analysis"&&output_manager_default.print(`
138
+ `)}if(warning&&opts.flags["--yes"]&&output_manager_default.warning(warning),!await confirmAction(client,opts.flags["--yes"],`Save ${name} \u2192 ${formatManagedBotAction(parsedAction.action)}?`,warning||void 0))return output_manager_default.log("Canceled"),0;let editStamp=stamp_default();output_manager_default.spinner("Staging changes");try{let hadExistingDraft=await detectExistingDraft(client,opts.scope);return await patchFirewallDraft(client,opts.scope,buildManagedBotPatch(opts.id,parsedAction.action,category)),output_manager_default.log(`${import_chalk27.default.cyan("Success!")} ${name} updated to ${import_chalk27.default.bold(formatManagedBotAction(parsedAction.action))} and staged ${import_chalk27.default.gray(editStamp())}`),opts.id==="bot-id"&&parsedAction.action==="deep-analysis"&&output_manager_default.print(`
139
139
  ${import_chalk27.default.dim("Install the BotID SDK in your app:")} ${import_chalk27.default.cyan("npm i botid")}
140
- `),await offerAutoPublish(client,opts.scope,hadExistingDraft,{skipPrompts:opts.flags["--yes"]}),0}catch(e){output_manager_default.stopSpinner();let priority=failPriorityProjectGate(client,e,opts.scope);if(priority!==null)return priority;let command=`firewall rules update ${opts.id} --action ${parsedAction.action}`;return failFirewall(client,{message:mapFirewallApiError(e,opts.scope,"Failed to stage bot rule changes"),nextCommand:command,reason:AGENT_REASON.API_ERROR})}}async function edit(client,argv){let parsed=await parseSubcommandArgs(argv,rulesEditSubcommand,client,"rules update");if(typeof parsed=="number")return parsed;let identifier=parsed.args[0],scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;output_manager_default.spinner(`Fetching rules for ${import_chalk28.default.bold(scope.displayName)}`);let{active,draft}=await listFirewallConfigs(client,scope),config=draft??active,currentRules=draft?.rules||active?.rules||[],managedRules=scope.type==="project"?getManagedBotRules(config):[];if(!identifier){if(output_manager_default.stopSpinner(),client.nonInteractive||!client.stdin.isTTY)return output_manager_default.error(`Missing required argument: <name-or-id>. Run ${import_chalk28.default.cyan(withGlobalFlags(client,"firewall rules list",scope))} to see all rules.`),2;if(currentRules.length===0&&managedRules.length===0)return output_manager_default.error("No custom rules configured. Create one first with `vercel firewall rules add`."),1;let selectedId=await client.input.select({message:"Select a rule to update:",choices:[...managedRules.map(r=>({value:r.id,name:`${r.name} \u2014 ${formatManagedBotAction(r.action)} (${r.id})`})),...currentRules.map(r=>({value:r.id,name:`${r.name} [${r.active?"Enabled":"Disabled"}] \u2014 ${formatActionDisplay(r.action)}`}))]}),selectedManaged=resolveManagedBotRuleId(selectedId);if(selectedManaged)return editManagedBotRule(client,{id:selectedManaged,flags:parsed.flags,scope,config});let selected=currentRules.find(r=>r.id===selectedId);if(!selected)return output_manager_default.error("No rule selected"),1;identifier=selected.id}let managedId=scope.type==="project"?resolveManagedBotRuleId(identifier):void 0;if(managedId)return output_manager_default.stopSpinner(),editManagedBotRule(client,{id:managedId,flags:parsed.flags,scope,config});let matches=resolveRule(currentRules,identifier);if(matches.length===0)return output_manager_default.error(`No rule found for "${identifier}". Run ${import_chalk28.default.cyan(withGlobalFlags(client,"firewall rules list",scope))} to view all rules.`),1;let originalRule=matches[0];if(matches.length>1){if(output_manager_default.stopSpinner(),client.nonInteractive||!client.stdin.isTTY)return output_manager_default.error(`Multiple rules match "${identifier}". Specify the full rule ID to disambiguate.`),1;let selectedId=await client.input.select({message:`Multiple rules match "${identifier}". Select one:`,choices:matches.map(r=>({value:r.id,name:`${r.name} [${r.active?"Enabled":"Disabled"}] (${r.id})`}))}),selected=matches.find(r=>r.id===selectedId);if(!selected)return output_manager_default.error("No rule selected"),1;originalRule=selected}output_manager_default.stopSpinner();let aiPrompt=parsed.flags["--ai"],jsonInput=getRulePayload(parsed.flags);if(typeof jsonInput=="number")return jsonInput;let conditionFlags=parsed.flags["--condition"];if([aiPrompt,jsonInput,conditionFlags].filter(Boolean).length>1)return output_manager_default.error("Cannot use --ai, --data, and --condition together. Use only one mode."),1;if(aiPrompt)return scope.type==="team"?(output_manager_default.error("AI mode is not available with --team-level. Use --data or option-based editing instead."),1):client.nonInteractive||!client.stdin.isTTY?(client.nonInteractive&&outputAgentError(client,{status:"error",reason:"ai_not_available",message:"AI mode is not available in non-interactive mode. AI-generated changes require human review. Use --data or option-based editing instead.",next:[{command:withGlobalFlags(client,`firewall rules update "${identifier}" --action challenge --yes`),when:"edit with options"},{command:withGlobalFlags(client,`firewall rules update "${identifier}" --data '{"name":"...","conditionGroup":[...],"action":{...}}' --yes`),when:"edit with JSON"}]}),output_manager_default.error("AI mode is not available in non-interactive mode. Use --data or option-based editing instead."),1):handleAIEdit(client,{id:scope.projectId,name:scope.displayName},scope.teamId,originalRule,{prompt:aiPrompt,skipPrompts:!!parsed.flags["--yes"]});if(jsonInput)return handleJsonEdit(client,parsed,originalRule,jsonInput,scope);if(conditionFlags||parsed.flags["--action"]||parsed.flags["--name"]||parsed.flags["--description"]!==void 0||parsed.flags["--duration"]||parsed.flags["--enable"]||parsed.flags["--no-enable"]||parsed.flags["--enabled"]||parsed.flags["--disabled"]||parsed.flags["--rate-limit-algo"]||parsed.flags["--rate-limit-window"]||parsed.flags["--rate-limit-requests"]||parsed.flags["--rate-limit-keys"]||parsed.flags["--rate-limit-action"]||parsed.flags["--redirect-url"]||parsed.flags["--redirect-permanent"])return handleFlagEdit(client,parsed,originalRule,argv,scope);if(client.stdin.isTTY&&!client.nonInteractive){if(output_manager_default.print(`
140
+ `),await offerAutoPublish(client,opts.scope,hadExistingDraft,{skipPrompts:opts.flags["--yes"]}),0}catch(e){output_manager_default.stopSpinner();let priority=failPriorityProjectGate(client,e,opts.scope);if(priority!==null)return priority;let command=`firewall rules update ${opts.id}${category?` --category ${category.id}`:""} --action ${parsedAction.action}`;return failFirewall(client,{message:mapFirewallApiError(e,opts.scope,"Failed to stage bot rule changes"),nextCommand:command,reason:AGENT_REASON.API_ERROR})}}async function edit(client,argv){let parsed=await parseSubcommandArgs(argv,rulesEditSubcommand,client,"rules update");if(typeof parsed=="number")return parsed;let identifier=parsed.args[0],category=parsed.flags["--category"];if(category!==void 0&&(parsed.flags["--team-level"]||identifier&&resolveManagedBotRuleId(identifier)!=="ai-bots"))return failFirewall(client,{message:"--category is only supported for the project-level AI Bots ruleset.",reason:AGENT_REASON.INVALID_ARGUMENTS});let scope=await resolveFirewallScope(client,parsed.flags);if(typeof scope=="number")return scope;output_manager_default.spinner(`Fetching rules for ${import_chalk28.default.bold(scope.displayName)}`);let{active,draft}=await listFirewallConfigs(client,scope),config=draft??active,currentRules=draft?.rules||active?.rules||[],managedRules=scope.type==="project"?getManagedBotRules(config):[];if(!identifier){if(output_manager_default.stopSpinner(),client.nonInteractive||!client.stdin.isTTY)return output_manager_default.error(`Missing required argument: <name-or-id>. Run ${import_chalk28.default.cyan(withGlobalFlags(client,"firewall rules list",scope))} to see all rules.`),2;if(currentRules.length===0&&managedRules.length===0)return output_manager_default.error("No custom rules configured. Create one first with `vercel firewall rules add`."),1;let selectedId=await client.input.select({message:"Select a rule to update:",choices:[...managedRules.filter(r=>category===void 0||r.id==="ai-bots").map(r=>({value:r.id,name:r.action?`${r.name} \u2014 ${formatManagedBotAction(r.action)} (${r.id})`:`${r.name} (${r.id})`})),...(category===void 0?currentRules:[]).map(r=>({value:r.id,name:`${r.name} [${r.active?"Enabled":"Disabled"}] \u2014 ${formatActionDisplay(r.action)}`}))]}),selectedManaged=resolveManagedBotRuleId(selectedId);if(selectedManaged)return editManagedBotRule(client,{id:selectedManaged,flags:parsed.flags,scope,config});let selected=currentRules.find(r=>r.id===selectedId);if(!selected)return output_manager_default.error("No rule selected"),1;identifier=selected.id}let managedId=scope.type==="project"?resolveManagedBotRuleId(identifier):void 0;if(managedId)return output_manager_default.stopSpinner(),editManagedBotRule(client,{id:managedId,flags:parsed.flags,scope,config});let matches=resolveRule(currentRules,identifier);if(matches.length===0)return output_manager_default.error(`No rule found for "${identifier}". Run ${import_chalk28.default.cyan(withGlobalFlags(client,"firewall rules list",scope))} to view all rules.`),1;let originalRule=matches[0];if(matches.length>1){if(output_manager_default.stopSpinner(),client.nonInteractive||!client.stdin.isTTY)return output_manager_default.error(`Multiple rules match "${identifier}". Specify the full rule ID to disambiguate.`),1;let selectedId=await client.input.select({message:`Multiple rules match "${identifier}". Select one:`,choices:matches.map(r=>({value:r.id,name:`${r.name} [${r.active?"Enabled":"Disabled"}] (${r.id})`}))}),selected=matches.find(r=>r.id===selectedId);if(!selected)return output_manager_default.error("No rule selected"),1;originalRule=selected}output_manager_default.stopSpinner();let aiPrompt=parsed.flags["--ai"],jsonInput=getRulePayload(parsed.flags);if(typeof jsonInput=="number")return jsonInput;let conditionFlags=parsed.flags["--condition"];if([aiPrompt,jsonInput,conditionFlags].filter(Boolean).length>1)return output_manager_default.error("Cannot use --ai, --data, and --condition together. Use only one mode."),1;if(aiPrompt)return scope.type==="team"?(output_manager_default.error("AI mode is not available with --team-level. Use --data or option-based editing instead."),1):client.nonInteractive||!client.stdin.isTTY?(client.nonInteractive&&outputAgentError(client,{status:"error",reason:"ai_not_available",message:"AI mode is not available in non-interactive mode. AI-generated changes require human review. Use --data or option-based editing instead.",next:[{command:withGlobalFlags(client,`firewall rules update "${identifier}" --action challenge --yes`),when:"edit with options"},{command:withGlobalFlags(client,`firewall rules update "${identifier}" --data '{"name":"...","conditionGroup":[...],"action":{...}}' --yes`),when:"edit with JSON"}]}),output_manager_default.error("AI mode is not available in non-interactive mode. Use --data or option-based editing instead."),1):handleAIEdit(client,{id:scope.projectId,name:scope.displayName},scope.teamId,originalRule,{prompt:aiPrompt,skipPrompts:!!parsed.flags["--yes"]});if(jsonInput)return handleJsonEdit(client,parsed,originalRule,jsonInput,scope);if(conditionFlags||parsed.flags["--action"]||parsed.flags["--name"]||parsed.flags["--description"]!==void 0||parsed.flags["--duration"]||parsed.flags["--enable"]||parsed.flags["--no-enable"]||parsed.flags["--enabled"]||parsed.flags["--disabled"]||parsed.flags["--rate-limit-algo"]||parsed.flags["--rate-limit-window"]||parsed.flags["--rate-limit-requests"]||parsed.flags["--rate-limit-keys"]||parsed.flags["--rate-limit-action"]||parsed.flags["--redirect-url"]||parsed.flags["--redirect-permanent"])return handleFlagEdit(client,parsed,originalRule,argv,scope);if(client.stdin.isTTY&&!client.nonInteractive){if(output_manager_default.print(`
141
141
  ${import_chalk28.default.bold("Current rule:")}
142
142
  `),output_manager_default.print(`${formatRuleExpanded(originalRule)}
143
143
 
@@ -196,12 +196,12 @@ ${nextSteps(client,dimension.alias)}
196
196
  ${formatManagedBotRulesTable(managed)}
197
197
  `),unknownBotTraffic&&output_manager_default.print(`
198
198
  ${formatTrafficTopList(unknownBotTraffic)}
199
- `);let steps=managed.map(rule=>{let action=suggestedManagedBotAction(rule);return[`Change ${rule.name}`,`firewall rules update ${rule.id} --action ${action}`]});return unknownBotTraffic&&!unknownBotTraffic.unavailable&&steps.push(["Break unknown bot traffic down further","firewall traffic inspect unknown-bot <category>"]),output_manager_default.print(`
199
+ `);let steps=managed.map(rule=>[`Change ${rule.categories?.[0]?.name??rule.name}`,suggestedManagedBotEditCommand(rule)]);return unknownBotTraffic&&!unknownBotTraffic.unavailable&&steps.push(["Break unknown bot traffic down further","firewall traffic inspect unknown-bot <category>"]),output_manager_default.print(`
200
200
  ${import_chalk41.default.bold("Next steps:")}
201
201
  ${steps.flatMap(([why,command])=>[import_chalk41.default.dim(` ${why}`),` ${withGlobalFlags(client,command)}`]).join(`
202
202
  `)}
203
203
 
204
- `),0}catch(e){return failFirewallApi(client,e,{fallback:"Failed to fetch bot management",nextCommand:"firewall bot-management",permissionAction:"read firewall config",projectName:project.name,timeoutJob:"bot management"})}finally{output_manager_default.stopSpinner()}}async function loadUnknownBotTraffic(client,projectId,teamId){let dimension=getDimension("unknown-bot"),title=dimension?.widgetTitle??"Unknown Bot Traffic",unavailable=error=>({dimension:"unknown-bot",title,rows:[],unavailable:isActivityUnavailable6(error)?"plan":isUnsupportedDimension(error)?"filter":isRateLimited(error)?"rate-limit":isActivityTimeout(error)?"timeout":"error",retrySeconds:rateLimitRetrySeconds(error),message:isRateLimited(error)?apiServerMessage(error):void 0});if(!dimension)return unavailable(new Error("unknown-bot dimension missing"));let endTime=new Date,startTime=new Date(endTime.getTime()-DEFAULT_TRAFFIC_WINDOW_MS);try{let rows=await getTopList(client,{projectId,ownerId:teamId,startTime,endTime,metric:dimension.metric,groupBy:[dimension.field],filter:andFilters(dimension.excludeFilter,dimension.extraFilter),top:topListFetchCount(UNKNOWN_BOT_TOP)});return{dimension:dimension.alias,title,rows:toTopListRows(rows,dimension.field).slice(0,UNKNOWN_BOT_TOP)}}catch(e){return output_manager_default.debug(isAPIError(e)?`Unknown bot traffic query failed: status=${e.status} code=${e.code??"(none)"} message=${e.serverMessage}`:`Unknown bot traffic query failed: ${e instanceof Error?e.message:String(e)}`),unavailable(e)}}var FirewallTelemetryClient=class extends TelemetryClient{trackCliFlagTeamLevel(value){value&&this.trackCliFlag("team-level")}trackCliSubcommandStatus(actual){this.trackCliSubcommand({subcommand:"status",value:actual})}trackCliSubcommandOverview(actual){this.trackCliSubcommand({subcommand:"overview",value:actual})}trackCliSubcommandDiff(actual){this.trackCliSubcommand({subcommand:"diff",value:actual})}trackCliSubcommandPublish(actual){this.trackCliSubcommand({subcommand:"publish",value:actual})}trackCliSubcommandDiscard(actual){this.trackCliSubcommand({subcommand:"discard",value:actual})}trackCliSubcommandRules(actual){this.trackCliSubcommand({subcommand:"rules",value:actual})}trackCliSubcommandRulesList(actual){this.trackCliSubcommand({subcommand:"rules:list",value:actual})}trackCliSubcommandRulesInspect(actual){this.trackCliSubcommand({subcommand:"rules:inspect",value:actual})}trackCliSubcommandRulesAdd(actual){this.trackCliSubcommand({subcommand:"rules:add",value:actual})}trackCliSubcommandRulesUpdate(actual){this.trackCliSubcommand({subcommand:"rules:update",value:actual})}trackCliSubcommandRulesEnable(actual){this.trackCliSubcommand({subcommand:"rules:enable",value:actual})}trackCliSubcommandRulesDisable(actual){this.trackCliSubcommand({subcommand:"rules:disable",value:actual})}trackCliSubcommandRulesRemove(actual){this.trackCliSubcommand({subcommand:"rules:remove",value:actual})}trackCliSubcommandRulesReorder(actual){this.trackCliSubcommand({subcommand:"rules:reorder",value:actual})}trackCliSubcommandRulesMove(actual){this.trackCliSubcommand({subcommand:"rules:move",value:actual})}trackCliSubcommandIpBlocks(actual){this.trackCliSubcommand({subcommand:"ip-blocks",value:actual})}trackCliSubcommandIpBlocksList(actual){this.trackCliSubcommand({subcommand:"ip-blocks:list",value:actual})}trackCliSubcommandIpBlocksBlock(actual){this.trackCliSubcommand({subcommand:"ip-blocks:block",value:actual})}trackCliSubcommandIpBlocksUnblock(actual){this.trackCliSubcommand({subcommand:"ip-blocks:unblock",value:actual})}trackCliSubcommandSystemBypass(actual){this.trackCliSubcommand({subcommand:"system-bypass",value:actual})}trackCliSubcommandSystemBypassList(actual){this.trackCliSubcommand({subcommand:"system-bypass:list",value:actual})}trackCliSubcommandSystemBypassAdd(actual){this.trackCliSubcommand({subcommand:"system-bypass:add",value:actual})}trackCliSubcommandSystemBypassRemove(actual){this.trackCliSubcommand({subcommand:"system-bypass:remove",value:actual})}trackCliSubcommandAttackMode(actual){this.trackCliSubcommand({subcommand:"attack-mode",value:actual})}trackCliSubcommandAttackModeEnable(actual){this.trackCliSubcommand({subcommand:"attack-mode:enable",value:actual})}trackCliSubcommandAttackModeDisable(actual){this.trackCliSubcommand({subcommand:"attack-mode:disable",value:actual})}trackCliSubcommandSystemMitigations(actual){this.trackCliSubcommand({subcommand:"system-mitigations",value:actual})}trackCliSubcommandSystemMitigationsPause(actual){this.trackCliSubcommand({subcommand:"system-mitigations:pause",value:actual})}trackCliSubcommandSystemMitigationsResume(actual){this.trackCliSubcommand({subcommand:"system-mitigations:resume",value:actual})}trackCliSubcommandAlerts(actual){this.trackCliSubcommand({subcommand:"alerts",value:actual})}trackCliSubcommandAlertsList(actual){this.trackCliSubcommand({subcommand:"alerts:list",value:actual})}trackCliSubcommandAlertsInspect(actual){this.trackCliSubcommand({subcommand:"alerts:inspect",value:actual})}trackCliSubcommandPersistentActions(actual){this.trackCliSubcommand({subcommand:"persistent-actions",value:actual})}trackCliSubcommandPersistentActionsList(actual){this.trackCliSubcommand({subcommand:"persistent-actions:list",value:actual})}trackCliSubcommandPersistentActionsInspect(actual){this.trackCliSubcommand({subcommand:"persistent-actions:inspect",value:actual})}trackCliSubcommandTraffic(actual){this.trackCliSubcommand({subcommand:"traffic",value:actual})}trackCliSubcommandTrafficList(actual){this.trackCliSubcommand({subcommand:"traffic:list",value:actual})}trackCliSubcommandTrafficInspect(actual){this.trackCliSubcommand({subcommand:"traffic:inspect",value:actual})}trackCliSubcommandBotManagement(actual){this.trackCliSubcommand({subcommand:"bot-management",value:actual})}};var COMMAND_CONFIG9={overview:getCommandAliases(overviewSubcommand),status:getCommandAliases(statusSubcommand),rules:getCommandAliases(rulesSubcommand),diff:getCommandAliases(diffSubcommand),publish:getCommandAliases(publishSubcommand),discard:getCommandAliases(discardSubcommand),"ip-blocks":getCommandAliases(ipBlocksSubcommand),"system-bypass":getCommandAliases(systemBypassSubcommand),"attack-mode":getCommandAliases(attackModeSubcommand),"system-mitigations":getCommandAliases(systemMitigationsSubcommand),alerts:getCommandAliases(alertsSubcommand),"persistent-actions":getCommandAliases(persistentActionsSubcommand),traffic:getCommandAliases(trafficSubcommand),"bot-management":getCommandAliases(botManagementSubcommand)};async function main9(client){let telemetry=new FirewallTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(firewallCommand.options);try{parsedArgs=parseArguments(client.argv.slice(2),flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let subArgs=parsedArgs.args.slice(1),{subcommand,args,subcommandOriginal}=getSubcommand(subArgs,COMMAND_CONFIG9),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("firewall"),output_manager_default.print(help(firewallCommand,{stream:client.stderr,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns}))}switch(subcommand&&!needHelp&&(telemetry.trackCliOptionProject(getProjectOptionFromArgs(args)),telemetry.trackCliFlagTeamLevel(args.includes("--team-level"))),subcommand){case"status":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(statusSubcommand),0):(telemetry.trackCliSubcommandStatus(subcommandOriginal),status(client,args));case"overview":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(overviewSubcommand),0):(telemetry.trackCliSubcommandOverview(subcommandOriginal),overview(client,args));case"diff":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(diffSubcommand),0):(telemetry.trackCliSubcommandDiff(subcommandOriginal),diff(client,args));case"publish":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(publishSubcommand),0):(telemetry.trackCliSubcommandPublish(subcommandOriginal),publish(client,args));case"discard":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(discardSubcommand),0):(telemetry.trackCliSubcommandDiscard(subcommandOriginal),discard(client,args));case"rules":{telemetry.trackCliSubcommandRules(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main5(client,nestedArgs,telemetry)}case"ip-blocks":{telemetry.trackCliSubcommandIpBlocks(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main4(client,nestedArgs,telemetry)}case"system-bypass":{telemetry.trackCliSubcommandSystemBypass(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main(client,nestedArgs,telemetry)}case"attack-mode":{telemetry.trackCliSubcommandAttackMode(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main2(client,nestedArgs,telemetry)}case"system-mitigations":{telemetry.trackCliSubcommandSystemMitigations(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main3(client,nestedArgs,telemetry)}case"alerts":{telemetry.trackCliSubcommandAlerts(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main6(client,nestedArgs,telemetry)}case"persistent-actions":{telemetry.trackCliSubcommandPersistentActions(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main7(client,nestedArgs,telemetry)}case"traffic":{telemetry.trackCliSubcommandTraffic(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main8(client,nestedArgs,telemetry)}case"bot-management":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(botManagementSubcommand),0):(telemetry.trackCliSubcommandBotManagement(subcommandOriginal),botManagement(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG9)),output_manager_default.print(help(firewallCommand,{stream:client.stderr,columns:client.stderr.columns})),2}}var FlagsTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandInspect(actual){this.trackCliSubcommand({subcommand:"inspect",value:actual})}trackCliSubcommandVersions(actual){this.trackCliSubcommand({subcommand:"versions",value:actual})}trackCliSubcommandEvaluations(actual){this.trackCliSubcommand({subcommand:"evaluations",value:actual})}trackCliSubcommandStale(actual){this.trackCliSubcommand({subcommand:"stale",value:actual})}trackCliSubcommandOpen(actual){this.trackCliSubcommand({subcommand:"open",value:actual})}trackCliSubcommandCreate(actual){this.trackCliSubcommand({subcommand:"create",value:actual})}trackCliSubcommandUpdate(actual){this.trackCliSubcommand({subcommand:"update",value:actual})}trackCliSubcommandSet(actual){this.trackCliSubcommand({subcommand:"set",value:actual})}trackCliSubcommandTargeting(actual){this.trackCliSubcommand({subcommand:"targeting",value:actual})}trackCliSubcommandUseTargeting(actual){this.trackCliSubcommand({subcommand:"use-targeting",value:actual})}trackCliSubcommandSplit(actual){this.trackCliSubcommand({subcommand:"split",value:actual})}trackCliSubcommandRollout(actual){this.trackCliSubcommand({subcommand:"rollout",value:actual})}trackCliSubcommandDelete(actual){this.trackCliSubcommand({subcommand:"delete",value:actual})}trackCliSubcommandArchive(actual){this.trackCliSubcommand({subcommand:"archive",value:actual})}trackCliSubcommandUnarchive(actual){this.trackCliSubcommand({subcommand:"unarchive",value:actual})}trackCliSubcommandDisable(actual){this.trackCliSubcommand({subcommand:"disable",value:actual})}trackCliSubcommandEnable(actual){this.trackCliSubcommand({subcommand:"enable",value:actual})}trackCliSubcommandSdkKeys(actual){this.trackCliSubcommand({subcommand:"sdk-keys",value:actual})}trackCliSubcommandConnections(actual){this.trackCliSubcommand({subcommand:"connections",value:actual})}trackCliSubcommandSegments(actual){this.trackCliSubcommand({subcommand:"segments",value:actual})}trackCliSubcommandEntities(actual){this.trackCliSubcommand({subcommand:"entities",value:actual})}trackCliSubcommandLabels(actual){this.trackCliSubcommand({subcommand:"labels",value:actual})}trackCliSubcommandRules(actual){this.trackCliSubcommand({subcommand:"rules",value:actual})}trackCliSubcommandTargets(actual){this.trackCliSubcommand({subcommand:"targets",value:actual})}trackCliSubcommandPrepare(actual){this.trackCliSubcommand({subcommand:"prepare",value:actual})}trackCliSubcommandDatafile(actual){this.trackCliSubcommand({subcommand:"datafile",value:actual})}trackCliSubcommandOverride(actual){this.trackCliSubcommand({subcommand:"override",value:actual})}};var import_chalk42=__toESM(require_source(),1),import_ms=__toESM(require_ms(),1),import_pluralize=__toESM(require_pluralize(),1);function flagUrl(projectId,flagIdOrSlug){return`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/flags/${encodeURIComponent(flagIdOrSlug)}`}async function fetchFlagForUpdate(client,projectId,flagIdOrSlug){output_manager_default.debug(`Fetching feature flag ${flagIdOrSlug} for project ${projectId} with ETag`);let response=await client.fetch(flagUrl(projectId,flagIdOrSlug),{json:!1}),etag=response.headers.get("etag");if(!etag)throw new Error("Unable to update flag safely because the flag ETag is missing.");return{flag:await response.json(),etag}}async function updateFlag(client,projectId,flagIdOrSlug,request,options){output_manager_default.debug(`Updating feature flag ${flagIdOrSlug} for project ${projectId}`);let url=flagUrl(projectId,flagIdOrSlug);return await client.fetch(url,{method:"PATCH",headers:options?.ifMatch?{"If-Match":options.ifMatch}:void 0,body:request})}var MAX_FLAGS_PAGE_LIMIT=100,MAX_FLAG_VERSIONS_PAGE_LIMIT=100;async function getFlags(client,projectId,options={}){let{state="active",tags,createdBy,maintainerIds,limit,cursor}=options;output_manager_default.debug(`Fetching feature flags for project ${projectId}`);let basePath=`/v2/projects/${encodeURIComponent(projectId)}/feature-flags/flags`,buildQuery=(pageLimit,pageCursor2)=>{let query=new URLSearchParams;query.set("state",state),query.set("limit",String(pageLimit)),pageCursor2&&query.set("cursor",pageCursor2),createdBy&&query.set("createdBy",createdBy);for(let tag of tags??[])query.append("tags",tag);for(let maintainerId of maintainerIds??[])query.append("maintainerIds",maintainerId);return query.toString()};if(limit!==void 0||cursor!==void 0){let pageLimit=Math.min(limit??MAX_FLAGS_PAGE_LIMIT,MAX_FLAGS_PAGE_LIMIT),response=await client.fetch(`${basePath}?${buildQuery(pageLimit,cursor)}`);return{flags:response.data,next:response.pagination?.next??null}}let flags=[],pageCursor;do{let response=await client.fetch(`${basePath}?${buildQuery(MAX_FLAGS_PAGE_LIMIT,pageCursor)}`);flags.push(...response.data),pageCursor=response.pagination?.next??void 0}while(pageCursor);return{flags,next:null}}async function getFlag(client,projectId,flagIdOrSlug){output_manager_default.debug(`Fetching feature flag ${flagIdOrSlug} for project ${projectId}`);let url=flagUrl(projectId,flagIdOrSlug);return await client.fetch(url)}async function getFlagSettings(client,projectId){return output_manager_default.debug(`Fetching feature flag settings for project ${projectId}`),await client.fetch(flagSettingsUrl(projectId))}async function updateFlagSettings(client,projectId,request){return output_manager_default.debug(`Updating feature flag settings for project ${projectId}`),client.fetch(flagSettingsUrl(projectId),{method:"PATCH",body:request})}function flagSettingsUrl(projectId){return`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/settings`}async function getFlagVersions(client,projectId,flagIdOrSlug,options={}){output_manager_default.debug(`Fetching feature flag versions for ${flagIdOrSlug} in project ${projectId}`);let query=new URLSearchParams;query.set("withMetadata","true"),options.environment&&query.set("environment",options.environment),options.limit!==void 0&&query.set("limit",String(options.limit)),options.cursor&&query.set("cursor",options.cursor);let url=`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/flags/${encodeURIComponent(flagIdOrSlug)}/versions?${query.toString()}`,response=await client.fetch(url),next=response.pagination?.next??(response.pagination?.hasNext?response.pagination.cursor:null)??null;return{versions:response.versions,next}}var FlagsLsTelemetryClient=class extends TelemetryClient{trackCliOptionState(state){state&&this.trackCliOption({option:"state",value:state})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}trackCliOptionTag(tags){tags&&tags.length>0&&this.trackCliOption({option:"tag",value:this.redactedValue})}trackCliOptionCreatedBy(createdBy){createdBy&&this.trackCliOption({option:"created-by",value:this.redactedValue})}trackCliOptionMaintainer(maintainerIds){maintainerIds&&maintainerIds.length>0&&this.trackCliOption({option:"maintainer",value:this.redactedValue})}trackCliOptionMaintainerId(maintainerIds){maintainerIds&&maintainerIds.length>0&&this.trackCliOption({option:"maintainer-id",value:this.redactedValue})}trackCliOptionLimit(limit){limit!==void 0&&this.trackCliOption({option:"limit",value:String(limit)})}trackCliOptionNext(next){next&&this.trackCliOption({option:"next",value:this.redactedValue})}};async function ls(client,argv){let telemetryClient=new FlagsLsTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(listSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{flags}=parsedArgs,state=flags["--state"]||"active",tags=flags["--tag"],createdBy=flags["--created-by"],limit=flags["--limit"],next=flags["--next"],json=flags["--json"],projectName=getProjectNameFromFlags(flags),maintainer=getRenamedOption(flags,"--maintainer","--maintainer-id",{json});if(telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionState(state),telemetryClient.trackCliOptionTag(tags),telemetryClient.trackCliOptionCreatedBy(createdBy),telemetryClient.trackCliOptionMaintainer(flags["--maintainer"]),telemetryClient.trackCliOptionMaintainerId(flags["--maintainer-id"]),telemetryClient.trackCliOptionLimit(limit),telemetryClient.trackCliOptionNext(next),telemetryClient.trackCliFlagJson(json),"error"in maintainer)return reportRenamedOptionError(client,maintainer.error,{json});let maintainerIds=maintainer.value;if(limit!==void 0&&(!Number.isInteger(limit)||limit<1||limit>MAX_FLAGS_PAGE_LIMIT))return output_manager_default.error(`The --limit option must be an integer between 1 and ${MAX_FLAGS_PAGE_LIMIT}.`),2;let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return output_manager_default.error(`Your codebase isn't linked to a project on Vercel. Pass --project <name>, or run ${getCommandName("link")} to link it.`),1;client.config.currentTeam=link.org.type==="team"?link.org.id:void 0;let{project,org}=link,projectSlugLink=formatProject(org.slug,project.name),lsStamp=stamp_default();output_manager_default.spinner(`Fetching ${state} feature flags for ${projectSlugLink}`);try{let{flags:flagsList,next:nextCursor}=await getFlags(client,project.id,{state,tags,createdBy,maintainerIds,limit,cursor:next});if(output_manager_default.stopSpinner(),json)outputJson2(client,flagsList,nextCursor,[maintainer.warning]);else if(flagsList.length===0)output_manager_default.log(`No ${state} feature flags found for ${projectSlugLink} ${import_chalk42.default.gray(lsStamp())}`);else if(output_manager_default.log(`${(0,import_pluralize.default)("feature flag",flagsList.length,!0)} found for ${projectSlugLink} ${import_chalk42.default.gray(lsStamp())}`),printFlagsTable(flagsList),nextCursor){let nextCmd=buildNextPageCommand(flags,tags,maintainerIds,nextCursor);output_manager_default.print(`
204
+ `),0}catch(e){return failFirewallApi(client,e,{fallback:"Failed to fetch bot management",nextCommand:"firewall bot-management",permissionAction:"read firewall config",projectName:project.name,timeoutJob:"bot management"})}finally{output_manager_default.stopSpinner()}}async function loadUnknownBotTraffic(client,projectId,teamId){let dimension=getDimension("unknown-bot"),title=dimension?.widgetTitle??"Unknown Bot Traffic",unavailable=error=>({dimension:"unknown-bot",title,rows:[],unavailable:isActivityUnavailable6(error)?"plan":isUnsupportedDimension(error)?"filter":isRateLimited(error)?"rate-limit":isActivityTimeout(error)?"timeout":"error",retrySeconds:rateLimitRetrySeconds(error),message:isRateLimited(error)?apiServerMessage(error):void 0});if(!dimension)return unavailable(new Error("unknown-bot dimension missing"));let endTime=new Date,startTime=new Date(endTime.getTime()-DEFAULT_TRAFFIC_WINDOW_MS);try{let rows=await getTopList(client,{projectId,ownerId:teamId,startTime,endTime,metric:dimension.metric,groupBy:[dimension.field],filter:andFilters(dimension.excludeFilter,dimension.extraFilter),top:topListFetchCount(UNKNOWN_BOT_TOP)});return{dimension:dimension.alias,title,rows:toTopListRows(rows,dimension.field).slice(0,UNKNOWN_BOT_TOP)}}catch(e){return output_manager_default.debug(isAPIError(e)?`Unknown bot traffic query failed: status=${e.status} code=${e.code??"(none)"} message=${e.serverMessage}`:`Unknown bot traffic query failed: ${e instanceof Error?e.message:String(e)}`),unavailable(e)}}var COMMAND_CONFIG9={overview:getCommandAliases(overviewSubcommand),status:getCommandAliases(statusSubcommand),rules:getCommandAliases(rulesSubcommand),diff:getCommandAliases(diffSubcommand),publish:getCommandAliases(publishSubcommand),discard:getCommandAliases(discardSubcommand),"ip-blocks":getCommandAliases(ipBlocksSubcommand),"system-bypass":getCommandAliases(systemBypassSubcommand),"attack-mode":getCommandAliases(attackModeSubcommand),"system-mitigations":getCommandAliases(systemMitigationsSubcommand),alerts:getCommandAliases(alertsSubcommand),"persistent-actions":getCommandAliases(persistentActionsSubcommand),traffic:getCommandAliases(trafficSubcommand),"bot-management":getCommandAliases(botManagementSubcommand)};async function main9(client){let telemetry=new FirewallTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(firewallCommand.options);try{parsedArgs=parseArguments(client.argv.slice(2),flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let subArgs=parsedArgs.args.slice(1),{subcommand,args,subcommandOriginal}=getSubcommand(subArgs,COMMAND_CONFIG9),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("firewall"),output_manager_default.print(help(firewallCommand,{stream:client.stderr,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:firewallCommand,columns:client.stderr.columns}))}switch(subcommand&&!needHelp&&(telemetry.trackCliOptionProject(getProjectOptionFromArgs(args)),telemetry.trackCliFlagTeamLevel(args.includes("--team-level"))),subcommand){case"status":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(statusSubcommand),0):(telemetry.trackCliSubcommandStatus(subcommandOriginal),status(client,args));case"overview":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(overviewSubcommand),0):(telemetry.trackCliSubcommandOverview(subcommandOriginal),overview(client,args));case"diff":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(diffSubcommand),0):(telemetry.trackCliSubcommandDiff(subcommandOriginal),diff(client,args));case"publish":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(publishSubcommand),0):(telemetry.trackCliSubcommandPublish(subcommandOriginal),publish(client,args));case"discard":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(discardSubcommand),0):(telemetry.trackCliSubcommandDiscard(subcommandOriginal),discard(client,args));case"rules":{telemetry.trackCliSubcommandRules(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main5(client,nestedArgs,telemetry)}case"ip-blocks":{telemetry.trackCliSubcommandIpBlocks(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main4(client,nestedArgs,telemetry)}case"system-bypass":{telemetry.trackCliSubcommandSystemBypass(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main(client,nestedArgs,telemetry)}case"attack-mode":{telemetry.trackCliSubcommandAttackMode(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main2(client,nestedArgs,telemetry)}case"system-mitigations":{telemetry.trackCliSubcommandSystemMitigations(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main3(client,nestedArgs,telemetry)}case"alerts":{telemetry.trackCliSubcommandAlerts(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main6(client,nestedArgs,telemetry)}case"persistent-actions":{telemetry.trackCliSubcommandPersistentActions(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main7(client,nestedArgs,telemetry)}case"traffic":{telemetry.trackCliSubcommandTraffic(subcommandOriginal);let nestedArgs=needHelp?[...args,"--help"]:args;return main8(client,nestedArgs,telemetry)}case"bot-management":return needHelp?(telemetry.trackCliFlagHelp("firewall",subcommandOriginal),printHelp(botManagementSubcommand),0):(telemetry.trackCliSubcommandBotManagement(subcommandOriginal),botManagement(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG9)),output_manager_default.print(help(firewallCommand,{stream:client.stderr,columns:client.stderr.columns})),2}}var FlagsTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandInspect(actual){this.trackCliSubcommand({subcommand:"inspect",value:actual})}trackCliSubcommandVersions(actual){this.trackCliSubcommand({subcommand:"versions",value:actual})}trackCliSubcommandEvaluations(actual){this.trackCliSubcommand({subcommand:"evaluations",value:actual})}trackCliSubcommandStale(actual){this.trackCliSubcommand({subcommand:"stale",value:actual})}trackCliSubcommandOpen(actual){this.trackCliSubcommand({subcommand:"open",value:actual})}trackCliSubcommandCreate(actual){this.trackCliSubcommand({subcommand:"create",value:actual})}trackCliSubcommandUpdate(actual){this.trackCliSubcommand({subcommand:"update",value:actual})}trackCliSubcommandSet(actual){this.trackCliSubcommand({subcommand:"set",value:actual})}trackCliSubcommandTargeting(actual){this.trackCliSubcommand({subcommand:"targeting",value:actual})}trackCliSubcommandUseTargeting(actual){this.trackCliSubcommand({subcommand:"use-targeting",value:actual})}trackCliSubcommandSplit(actual){this.trackCliSubcommand({subcommand:"split",value:actual})}trackCliSubcommandRollout(actual){this.trackCliSubcommand({subcommand:"rollout",value:actual})}trackCliSubcommandDelete(actual){this.trackCliSubcommand({subcommand:"delete",value:actual})}trackCliSubcommandArchive(actual){this.trackCliSubcommand({subcommand:"archive",value:actual})}trackCliSubcommandUnarchive(actual){this.trackCliSubcommand({subcommand:"unarchive",value:actual})}trackCliSubcommandDisable(actual){this.trackCliSubcommand({subcommand:"disable",value:actual})}trackCliSubcommandEnable(actual){this.trackCliSubcommand({subcommand:"enable",value:actual})}trackCliSubcommandSdkKeys(actual){this.trackCliSubcommand({subcommand:"sdk-keys",value:actual})}trackCliSubcommandConnections(actual){this.trackCliSubcommand({subcommand:"connections",value:actual})}trackCliSubcommandSegments(actual){this.trackCliSubcommand({subcommand:"segments",value:actual})}trackCliSubcommandEntities(actual){this.trackCliSubcommand({subcommand:"entities",value:actual})}trackCliSubcommandLabels(actual){this.trackCliSubcommand({subcommand:"labels",value:actual})}trackCliSubcommandRules(actual){this.trackCliSubcommand({subcommand:"rules",value:actual})}trackCliSubcommandTargets(actual){this.trackCliSubcommand({subcommand:"targets",value:actual})}trackCliSubcommandPrepare(actual){this.trackCliSubcommand({subcommand:"prepare",value:actual})}trackCliSubcommandDatafile(actual){this.trackCliSubcommand({subcommand:"datafile",value:actual})}trackCliSubcommandOverride(actual){this.trackCliSubcommand({subcommand:"override",value:actual})}};var import_chalk42=__toESM(require_source(),1),import_ms=__toESM(require_ms(),1),import_pluralize=__toESM(require_pluralize(),1);function flagUrl(projectId,flagIdOrSlug){return`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/flags/${encodeURIComponent(flagIdOrSlug)}`}async function fetchFlagForUpdate(client,projectId,flagIdOrSlug){output_manager_default.debug(`Fetching feature flag ${flagIdOrSlug} for project ${projectId} with ETag`);let response=await client.fetch(flagUrl(projectId,flagIdOrSlug),{json:!1}),etag=response.headers.get("etag");if(!etag)throw new Error("Unable to update flag safely because the flag ETag is missing.");return{flag:await response.json(),etag}}async function updateFlag(client,projectId,flagIdOrSlug,request,options){output_manager_default.debug(`Updating feature flag ${flagIdOrSlug} for project ${projectId}`);let url=flagUrl(projectId,flagIdOrSlug);return await client.fetch(url,{method:"PATCH",headers:options?.ifMatch?{"If-Match":options.ifMatch}:void 0,body:request})}var MAX_FLAGS_PAGE_LIMIT=100,MAX_FLAG_VERSIONS_PAGE_LIMIT=100;async function getFlags(client,projectId,options={}){let{state="active",tags,createdBy,maintainerIds,limit,cursor}=options;output_manager_default.debug(`Fetching feature flags for project ${projectId}`);let basePath=`/v2/projects/${encodeURIComponent(projectId)}/feature-flags/flags`,buildQuery=(pageLimit,pageCursor2)=>{let query=new URLSearchParams;query.set("state",state),query.set("limit",String(pageLimit)),pageCursor2&&query.set("cursor",pageCursor2),createdBy&&query.set("createdBy",createdBy);for(let tag of tags??[])query.append("tags",tag);for(let maintainerId of maintainerIds??[])query.append("maintainerIds",maintainerId);return query.toString()};if(limit!==void 0||cursor!==void 0){let pageLimit=Math.min(limit??MAX_FLAGS_PAGE_LIMIT,MAX_FLAGS_PAGE_LIMIT),response=await client.fetch(`${basePath}?${buildQuery(pageLimit,cursor)}`);return{flags:response.data,next:response.pagination?.next??null}}let flags=[],pageCursor;do{let response=await client.fetch(`${basePath}?${buildQuery(MAX_FLAGS_PAGE_LIMIT,pageCursor)}`);flags.push(...response.data),pageCursor=response.pagination?.next??void 0}while(pageCursor);return{flags,next:null}}async function getFlag(client,projectId,flagIdOrSlug){output_manager_default.debug(`Fetching feature flag ${flagIdOrSlug} for project ${projectId}`);let url=flagUrl(projectId,flagIdOrSlug);return await client.fetch(url)}async function getFlagSettings(client,projectId){return output_manager_default.debug(`Fetching feature flag settings for project ${projectId}`),await client.fetch(flagSettingsUrl(projectId))}async function updateFlagSettings(client,projectId,request){return output_manager_default.debug(`Updating feature flag settings for project ${projectId}`),client.fetch(flagSettingsUrl(projectId),{method:"PATCH",body:request})}function flagSettingsUrl(projectId){return`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/settings`}async function getFlagVersions(client,projectId,flagIdOrSlug,options={}){output_manager_default.debug(`Fetching feature flag versions for ${flagIdOrSlug} in project ${projectId}`);let query=new URLSearchParams;query.set("withMetadata","true"),options.environment&&query.set("environment",options.environment),options.limit!==void 0&&query.set("limit",String(options.limit)),options.cursor&&query.set("cursor",options.cursor);let url=`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/flags/${encodeURIComponent(flagIdOrSlug)}/versions?${query.toString()}`,response=await client.fetch(url),next=response.pagination?.next??(response.pagination?.hasNext?response.pagination.cursor:null)??null;return{versions:response.versions,next}}var FlagsLsTelemetryClient=class extends TelemetryClient{trackCliOptionState(state){state&&this.trackCliOption({option:"state",value:state})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}trackCliOptionTag(tags){tags&&tags.length>0&&this.trackCliOption({option:"tag",value:this.redactedValue})}trackCliOptionCreatedBy(createdBy){createdBy&&this.trackCliOption({option:"created-by",value:this.redactedValue})}trackCliOptionMaintainer(maintainerIds){maintainerIds&&maintainerIds.length>0&&this.trackCliOption({option:"maintainer",value:this.redactedValue})}trackCliOptionMaintainerId(maintainerIds){maintainerIds&&maintainerIds.length>0&&this.trackCliOption({option:"maintainer-id",value:this.redactedValue})}trackCliOptionLimit(limit){limit!==void 0&&this.trackCliOption({option:"limit",value:String(limit)})}trackCliOptionNext(next){next&&this.trackCliOption({option:"next",value:this.redactedValue})}};async function ls(client,argv){let telemetryClient=new FlagsLsTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(listSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{flags}=parsedArgs,state=flags["--state"]||"active",tags=flags["--tag"],createdBy=flags["--created-by"],limit=flags["--limit"],next=flags["--next"],json=flags["--json"],projectName=getProjectNameFromFlags(flags),maintainer=getRenamedOption(flags,"--maintainer","--maintainer-id",{json});if(telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionState(state),telemetryClient.trackCliOptionTag(tags),telemetryClient.trackCliOptionCreatedBy(createdBy),telemetryClient.trackCliOptionMaintainer(flags["--maintainer"]),telemetryClient.trackCliOptionMaintainerId(flags["--maintainer-id"]),telemetryClient.trackCliOptionLimit(limit),telemetryClient.trackCliOptionNext(next),telemetryClient.trackCliFlagJson(json),"error"in maintainer)return reportRenamedOptionError(client,maintainer.error,{json});let maintainerIds=maintainer.value;if(limit!==void 0&&(!Number.isInteger(limit)||limit<1||limit>MAX_FLAGS_PAGE_LIMIT))return output_manager_default.error(`The --limit option must be an integer between 1 and ${MAX_FLAGS_PAGE_LIMIT}.`),2;let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return output_manager_default.error(`Your codebase isn't linked to a project on Vercel. Pass --project <name>, or run ${getCommandName("link")} to link it.`),1;client.config.currentTeam=link.org.type==="team"?link.org.id:void 0;let{project,org}=link,projectSlugLink=formatProject(org.slug,project.name),lsStamp=stamp_default();output_manager_default.spinner(`Fetching ${state} feature flags for ${projectSlugLink}`);try{let{flags:flagsList,next:nextCursor}=await getFlags(client,project.id,{state,tags,createdBy,maintainerIds,limit,cursor:next});if(output_manager_default.stopSpinner(),json)outputJson2(client,flagsList,nextCursor,[maintainer.warning]);else if(flagsList.length===0)output_manager_default.log(`No ${state} feature flags found for ${projectSlugLink} ${import_chalk42.default.gray(lsStamp())}`);else if(output_manager_default.log(`${(0,import_pluralize.default)("feature flag",flagsList.length,!0)} found for ${projectSlugLink} ${import_chalk42.default.gray(lsStamp())}`),printFlagsTable(flagsList),nextCursor){let nextCmd=buildNextPageCommand(flags,tags,maintainerIds,nextCursor);output_manager_default.print(`
205
205
  `),printNextPageCommand(getCommandNamePlain(nextCmd))}}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function buildNextPageCommand(flags,tags,maintainerIds,nextCursor){let baseFlags=getCommandFlags(flags,["_","--tag","--maintainer","--maintainer-id","--next","--json"]),repeatable=[...(tags??[]).map(tag=>`--tag ${quoteArg(tag)}`),...(maintainerIds??[]).map(id=>`--maintainer ${quoteArg(id)}`)],suffix=repeatable.length>0?` ${repeatable.join(" ")}`:"";return`flags ls${baseFlags}${suffix} --next ${nextCursor}`}function outputJson2(client,flags,next,warnings){let jsonOutput={flags:flags.map(flag=>({id:flag.id,slug:flag.slug,description:flag.description??null,kind:flag.kind,state:flag.state,variants:flag.variants,createdAt:flag.createdAt,updatedAt:flag.updatedAt})),pagination:{next}};client.stdout.write(`${JSON.stringify(withWarnings(jsonOutput,warnings),null,2)}
206
206
  `)}function printFlagsTable(flags){let headers=["Name","Kind","State","Variants","Updated"],now=Date.now(),rows=flags.map(flag=>[import_chalk42.default.bold(flag.slug),flag.kind,flag.state==="active"?import_chalk42.default.green(flag.state):import_chalk42.default.gray(flag.state),String(flag.variants.length),(0,import_ms.default)(now-flag.updatedAt)+" ago"]),table2=formatTable(headers,["l","l","l","r","l"],[{name:"",rows}]);output_manager_default.print(`
207
207
  ${table2}