@vercel/cli-support 65.7.0 → 65.8.0-snapshot-c4f338842961
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/add-6R2L3B6P.js +8 -0
- package/dist/chunks/add-O4YI4D5H.js +8 -0
- package/dist/chunks/add-W7MDOZMC.js +8 -0
- package/dist/chunks/build-UOKGUTFN.js +7 -0
- package/dist/chunks/chunk-2EYHCJQO.js +22 -0
- package/dist/chunks/{chunk-I64T5ZML.js → chunk-2NMEPXG3.js} +1 -1
- package/dist/chunks/{chunk-H3E4YX2M.js → chunk-3IRPFJ2G.js} +1 -1
- package/dist/chunks/{chunk-DCX2PBSX.js → chunk-3P4Y46MS.js} +1 -1
- package/dist/chunks/{chunk-E32IBIXV.js → chunk-4BIGNS67.js} +1 -1
- package/dist/chunks/{chunk-LIXU6EGC.js → chunk-4JE57EBL.js} +1 -1
- package/dist/chunks/{chunk-RD2VHI66.js → chunk-4K3O7QWS.js} +1 -1
- package/dist/chunks/{chunk-SKDLXVRO.js → chunk-4NDWIUKJ.js} +1 -1
- package/dist/chunks/{chunk-KBFHUWSQ.js → chunk-4UIMSZZB.js} +1 -1
- package/dist/chunks/{chunk-3E364MJE.js → chunk-5O7CRJE5.js} +1 -1
- package/dist/chunks/{chunk-N36OHJVQ.js → chunk-64VMAYM6.js} +1 -1
- package/dist/chunks/{chunk-S52O6DKC.js → chunk-AA3JM33J.js} +1 -1
- package/dist/chunks/{chunk-OS5I5TXU.js → chunk-APWCVJAG.js} +1 -1
- package/dist/chunks/chunk-BPR5CLQM.js +8 -0
- package/dist/chunks/{chunk-A7E3WORN.js → chunk-C7D43G3N.js} +1 -1
- package/dist/chunks/{chunk-EOK43KMC.js → chunk-CCD7E322.js} +1 -1
- package/dist/chunks/chunk-CNOJCW2I.js +21 -0
- package/dist/chunks/{chunk-UWGWRZP5.js → chunk-CS6E5XNQ.js} +1 -1
- package/dist/chunks/{chunk-MJ7JIQL3.js → chunk-D2XEF6G4.js} +1 -1
- package/dist/chunks/{chunk-HOOQ7ZMB.js → chunk-DPZFKHW3.js} +1 -1
- package/dist/chunks/{chunk-OORHGYZ3.js → chunk-EDLTSAD2.js} +1 -1
- package/dist/chunks/{chunk-JPEIHA57.js → chunk-EMORYAJQ.js} +1 -1
- package/dist/chunks/{chunk-HKZKGIBQ.js → chunk-ET5ARPPO.js} +1 -1
- package/dist/chunks/{chunk-TYL6IYR4.js → chunk-F34TG2V3.js} +1 -1
- package/dist/chunks/{chunk-RNTS4MJP.js → chunk-FJ5CNQDD.js} +1 -1
- package/dist/chunks/chunk-FOQK3VTY.js +8 -0
- package/dist/chunks/{chunk-767IBETW.js → chunk-FXF3NEJM.js} +3 -3
- package/dist/chunks/{chunk-G62JX3C5.js → chunk-GSXTCMKC.js} +1 -1
- package/dist/chunks/{chunk-2KINJIWA.js → chunk-H73G2ROF.js} +1 -1
- package/dist/chunks/{chunk-GKCTMBCM.js → chunk-IFXMG2WQ.js} +1 -1
- package/dist/chunks/{chunk-WRHQTUHU.js → chunk-J4OVLASZ.js} +1 -1
- package/dist/chunks/{chunk-VT2IZBPL.js → chunk-JAOYF7AW.js} +1 -1
- package/dist/chunks/{chunk-FSBAVQQP.js → chunk-JQTSETXH.js} +1 -1
- package/dist/chunks/{chunk-MYTOHLYZ.js → chunk-JYK7ZIZW.js} +1 -1
- package/dist/chunks/{chunk-5ULKEPKM.js → chunk-K3TCWYVX.js} +1 -1
- package/dist/chunks/{chunk-SAUBWYQJ.js → chunk-KPO6VDR2.js} +1 -1
- package/dist/chunks/{chunk-QRYQADGN.js → chunk-LBTMGBAK.js} +1 -1
- package/dist/chunks/{chunk-X4K3UJN7.js → chunk-MBJT3CNI.js} +1 -1
- package/dist/chunks/{chunk-GAGROISK.js → chunk-OCRNZT7G.js} +1 -1
- package/dist/chunks/chunk-OER4YAWM.js +7 -0
- package/dist/chunks/{chunk-GV2ZL4IE.js → chunk-OETX5QG4.js} +1 -1
- package/dist/chunks/{chunk-OEPDTNS3.js → chunk-P2SVNHTJ.js} +1 -1
- package/dist/chunks/{chunk-HTOZY5SI.js → chunk-QAYWROXQ.js} +1 -1
- package/dist/chunks/{chunk-VKJVYR4T.js → chunk-QGGJ5VVZ.js} +1 -1
- package/dist/chunks/{chunk-F6MHQRDG.js → chunk-RGQZXLV4.js} +1 -1
- package/dist/chunks/chunk-RHFPMM4R.js +70 -0
- package/dist/chunks/{chunk-WZAJYSJZ.js → chunk-RKWPLZJX.js} +1 -1
- package/dist/chunks/{chunk-43WS2YU4.js → chunk-RPWGUQSE.js} +1 -1
- package/dist/chunks/{chunk-FN3W5CJQ.js → chunk-RUXABBNV.js} +1 -1
- package/dist/chunks/{chunk-3DFEM7ZL.js → chunk-RVXE4MXS.js} +1 -1
- package/dist/chunks/chunk-SJA2LZ4O.js +24 -0
- package/dist/chunks/{chunk-2H4UEVTG.js → chunk-SOGL2HOD.js} +1 -1
- package/dist/chunks/{chunk-5XCOIFBD.js → chunk-SUMMI76H.js} +1 -1
- package/dist/chunks/{chunk-RCUDI7OF.js → chunk-T34C75TI.js} +1 -1
- package/dist/chunks/{chunk-FBYA6LLM.js → chunk-U3J7VS56.js} +1 -1
- package/dist/chunks/{chunk-4P6IRBBK.js → chunk-UF7QYHFU.js} +1 -1
- package/dist/chunks/{chunk-CNE5UGJC.js → chunk-UKJAWDQX.js} +1 -1
- package/dist/chunks/{chunk-DPM33VFZ.js → chunk-UMMQR6WI.js} +1 -1
- package/dist/chunks/{chunk-GTHPBDPB.js → chunk-VM3R6MAM.js} +2 -2
- package/dist/chunks/{chunk-A4UOBMZR.js → chunk-WGPYUXIC.js} +1 -1
- package/dist/chunks/{chunk-RQVIMYKN.js → chunk-WZ2R4Z7N.js} +1 -1
- package/dist/chunks/{chunk-YT3QAZQF.js → chunk-YEOOTTBB.js} +1 -1
- package/dist/chunks/clear-P2GBQ7OM.js +8 -0
- package/dist/chunks/compile-vercel-config-SPFLKB2T.js +7 -0
- package/dist/chunks/{config-3AXLL3GO.js → config-BI7WYZWB.js} +1 -1
- package/dist/chunks/config-PR2PEOA7.js +8 -0
- package/dist/chunks/delete-BZ3NLCTU.js +9 -0
- package/dist/chunks/delete-PUEGS2CP.js +10 -0
- package/dist/chunks/{detect-projects-EYF4ZSYF.js → detect-projects-A4H2ZEAP.js} +1 -1
- package/dist/chunks/detect-services-HHGBWOND.js +7 -0
- package/dist/chunks/disable-UYLN3HPM.js +7 -0
- package/dist/chunks/discard-NMRN5PS4.js +14 -0
- package/dist/chunks/edit-KA7OSMJA.js +9 -0
- package/dist/chunks/edit-UQ4J2OQ7.js +8 -0
- package/dist/chunks/enable-7FM67BEJ.js +7 -0
- package/dist/chunks/{exec-PX4GTZNE.js → exec-R5BDGSGP.js} +1 -1
- package/dist/chunks/{export-4RZRCFX7.js → export-FV6WM43O.js} +1 -1
- package/dist/chunks/future-3WF7CSGN.js +7 -0
- package/dist/chunks/generate-cert-for-deploy-3OBDQ2R3.js +7 -0
- package/dist/chunks/{image-UPFKBULX.js → image-SYY2IBOV.js} +1 -1
- package/dist/chunks/import-builders-IJYZSEBY.js +7 -0
- package/dist/chunks/inspect-3NZE4UWJ.js +13 -0
- package/dist/chunks/{inspect-2SCDEURI.js → inspect-DLADA2SX.js} +1 -1
- package/dist/chunks/inspect-J4WU7N2Z.js +9 -0
- package/dist/chunks/{inspect-IOKO45PV.js → inspect-W3RVFJLM.js} +1 -1
- package/dist/chunks/{inspect-UJAAVGJT.js → inspect-ZUHCIZFW.js} +1 -1
- package/dist/chunks/{list-PC4ZVIHQ.js → list-6EZHEJGK.js} +1 -1
- package/dist/chunks/list-GLYYBTWD.js +12 -0
- package/dist/chunks/{list-34Z62YFO.js → list-L4ZCXNAN.js} +1 -1
- package/dist/chunks/login-4OUKTVIZ.js +7 -0
- package/dist/chunks/login-E6L7CG3P.js +9 -0
- package/dist/chunks/logs-XHJPPHQ7.js +7 -0
- package/dist/chunks/{ls-PQBYVYPW.js → ls-36K3OMRV.js} +1 -1
- package/dist/chunks/{ls-ZK5ESMRT.js → ls-E75T2PHD.js} +1 -1
- package/dist/chunks/{ls-HQHXDVPG.js → ls-EIGVX2LB.js} +1 -1
- package/dist/chunks/{ls-MDTI26PW.js → ls-GSMTVAMC.js} +1 -1
- package/dist/chunks/{ls-FL3FCE2T.js → ls-IGICS6HZ.js} +1 -1
- package/dist/chunks/ls-PA4OVQ43.js +11 -0
- package/dist/chunks/ls-RKILAXZ4.js +8 -0
- package/dist/chunks/mutate-4L6XPD7X.js +9 -0
- package/dist/chunks/{notifications-A46PC7QX.js → notifications-IAKFNMTC.js} +1 -1
- package/dist/chunks/open-62S7LSPT.js +7 -0
- package/dist/chunks/{openapi-5QWHDLKR.js → openapi-SO34WDBK.js} +1 -1
- package/dist/chunks/{permissions-MCOS247Q.js → permissions-T2KL34JP.js} +1 -1
- package/dist/chunks/{plugin-offer-ZMTZG6FR.js → plugin-offer-HMNGWYIC.js} +1 -1
- package/dist/chunks/prompt-missing-credentials-WTRJREZF.js +7 -0
- package/dist/chunks/publish-EFZO7IO2.js +15 -0
- package/dist/chunks/pull-GVFCZAHC.js +7 -0
- package/dist/chunks/purchase-domain-if-available-PJMKV5BI.js +7 -0
- package/dist/chunks/push-PHTW37LC.js +7 -0
- package/dist/chunks/{query-OG4FG2AO.js → query-CUU7RRG6.js} +1 -1
- package/dist/chunks/reauthenticate-7P3C7ASY.js +7 -0
- package/dist/chunks/reorder-EBYXIVUZ.js +10 -0
- package/dist/chunks/reply-CBBADKE5.js +9 -0
- package/dist/chunks/resolve-KKFBXTIX.js +12 -0
- package/dist/chunks/resolve-agent-team-BBBIQWFZ.js +7 -0
- package/dist/chunks/restore-D4JUHPJ7.js +16 -0
- package/dist/chunks/rm-CRDLGD4Y.js +8 -0
- package/dist/chunks/rm-DSAXELZD.js +8 -0
- package/dist/chunks/rm-HXDTYZ3G.js +8 -0
- package/dist/chunks/rm-TDI6GXCE.js +8 -0
- package/dist/chunks/rm-XAUKTN2C.js +8 -0
- package/dist/chunks/{routes-LQGTKBXU.js → routes-RWILS4LA.js} +1 -1
- package/dist/chunks/rule-inspect-RKUBC35D.js +8 -0
- package/dist/chunks/{schema-H5RRV4J3.js → schema-5G57LHUD.js} +1 -1
- package/dist/chunks/schema-WSHKYL5H.js +14 -0
- package/dist/chunks/select-org-OKHCDXNF.js +7 -0
- package/dist/chunks/set-PBM7ZMZ7.js +7 -0
- package/dist/chunks/setup-and-link-PVMEKIYD.js +7 -0
- package/dist/chunks/{skills-CY57F35A.js → skills-4WEJZT7E.js} +1 -1
- package/dist/chunks/{tags-WAVSTC2G.js → tags-WUAMDEUU.js} +1 -1
- package/dist/chunks/{update-4LNUD2AB.js → update-IKZXIUYB.js} +1 -1
- package/dist/commands/build/index.js +1 -1
- package/dist/commands/deploy/index.js +5 -5
- package/dist/commands/dev/index.js +3 -3
- package/dist/commands/env/index.js +5 -2
- package/dist/commands/link/index.js +1 -1
- package/dist/commands/list/index.js +1 -1
- package/dist/commands/project/index.js +2 -2
- package/dist/commands-account.js +1 -1
- package/dist/commands-ai.js +2 -2
- package/dist/commands-blob.js +1 -1
- package/dist/commands-core.js +5 -5
- package/dist/commands-deployments.js +1 -1
- package/dist/commands-flags.js +82 -64
- package/dist/commands-integrations.js +1 -1
- package/dist/commands-observability.js +2 -2
- package/dist/commands-routing.js +3 -3
- package/dist/index.js +5 -5
- package/dist/internal-build.js +1 -1
- package/dist/native-download.js +1 -1
- package/dist/package.json +59 -59
- package/dist/version.mjs +1 -1
- package/package.json +52 -52
- package/dist/chunks/add-7G5PAIUN.js +0 -8
- package/dist/chunks/add-LA2T477X.js +0 -8
- package/dist/chunks/add-TPDABQQA.js +0 -8
- package/dist/chunks/build-A463NBA2.js +0 -7
- package/dist/chunks/chunk-DFXYDOFX.js +0 -20
- package/dist/chunks/chunk-I7YEXDVF.js +0 -22
- package/dist/chunks/chunk-LAINBICC.js +0 -7
- package/dist/chunks/chunk-MY4MONOH.js +0 -7
- package/dist/chunks/chunk-PH3ZOT3L.js +0 -21
- package/dist/chunks/chunk-QBP6E2YB.js +0 -24
- package/dist/chunks/chunk-QDQ4NHQN.js +0 -8
- package/dist/chunks/chunk-S22GZWJS.js +0 -8
- package/dist/chunks/chunk-TKKGZI7O.js +0 -57
- package/dist/chunks/clear-ISIDZTUZ.js +0 -8
- package/dist/chunks/compile-vercel-config-CZVX4OWQ.js +0 -7
- package/dist/chunks/config-MAFBMJV3.js +0 -8
- package/dist/chunks/delete-LLQFSC7R.js +0 -10
- package/dist/chunks/delete-PIFKRZEO.js +0 -9
- package/dist/chunks/detect-services-LNYPPBJP.js +0 -7
- package/dist/chunks/disable-7JLE53D2.js +0 -7
- package/dist/chunks/discard-EXDT6QIK.js +0 -14
- package/dist/chunks/edit-3NOKVF5V.js +0 -9
- package/dist/chunks/edit-BQCPB3ZR.js +0 -8
- package/dist/chunks/enable-KYVZIXZM.js +0 -7
- package/dist/chunks/future-YZGJX6FF.js +0 -7
- package/dist/chunks/generate-cert-for-deploy-I236CHA2.js +0 -7
- package/dist/chunks/import-builders-JEJRMLNC.js +0 -7
- package/dist/chunks/inspect-BMBFYISW.js +0 -13
- package/dist/chunks/inspect-P246VXF5.js +0 -9
- package/dist/chunks/list-WL3WA7CS.js +0 -12
- package/dist/chunks/login-BOBO3TKA.js +0 -9
- package/dist/chunks/login-RAN3UBFA.js +0 -7
- package/dist/chunks/logs-L3VFH7SK.js +0 -7
- package/dist/chunks/ls-FKECGTP3.js +0 -11
- package/dist/chunks/ls-NQVH63KO.js +0 -8
- package/dist/chunks/mutate-6OEPBAJF.js +0 -9
- package/dist/chunks/open-QWJQWDZD.js +0 -7
- package/dist/chunks/prompt-missing-credentials-AUJFBZRC.js +0 -7
- package/dist/chunks/publish-CQ5FHKNN.js +0 -15
- package/dist/chunks/pull-RVNTGJ4C.js +0 -7
- package/dist/chunks/purchase-domain-if-available-6FAGFFWC.js +0 -7
- package/dist/chunks/push-IBOUSKO7.js +0 -7
- package/dist/chunks/reauthenticate-TVQDXIFS.js +0 -7
- package/dist/chunks/reorder-LWKTDFSH.js +0 -10
- package/dist/chunks/reply-5CE2KUD7.js +0 -9
- package/dist/chunks/resolve-S35UEM35.js +0 -12
- package/dist/chunks/resolve-agent-team-DXHF7XLU.js +0 -7
- package/dist/chunks/restore-K66POLY7.js +0 -16
- package/dist/chunks/rm-6PBYTCDC.js +0 -8
- package/dist/chunks/rm-C4FXH2RT.js +0 -8
- package/dist/chunks/rm-C73EKJS4.js +0 -8
- package/dist/chunks/rm-MNT5XIGK.js +0 -8
- package/dist/chunks/rm-VJOHV243.js +0 -8
- package/dist/chunks/rule-inspect-4EBB5IDK.js +0 -8
- package/dist/chunks/schema-S32JRZH5.js +0 -14
- package/dist/chunks/select-org-VTLOMQYC.js +0 -7
- package/dist/chunks/set-52J54LJU.js +0 -7
- package/dist/chunks/setup-and-link-XGBTMVW7.js +0 -7
package/dist/commands-flags.js
CHANGED
|
@@ -4,15 +4,15 @@ 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-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
|
-
`),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(
|
|
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-4JE57EBL.js";import{parseSubcommandArguments,requireProjectContext}from"./chunks/chunk-H73G2ROF.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-FJ5CNQDD.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-D2XEF6G4.js";import{readOnOffOption}from"./chunks/chunk-RMW2FDXS.js";import{getCommandFlags}from"./chunks/chunk-XGTKHQTT.js";import{canPrompt,canPromptOnTerminal}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,cleanupSubcommand,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-FXF3NEJM.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,remoteText}from"./chunks/chunk-SLDWAIO3.js";import"./chunks/chunk-67GZ5REA.js";import"./chunks/chunk-BS32OUOC.js";import{getScope}from"./chunks/chunk-IFXMG2WQ.js";import{TelemetryClient}from"./chunks/chunk-4BIGNS67.js";import"./chunks/chunk-2EYYB6YN.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,isPromptCanceledError,require_pluralize,sleep,ua_default}from"./chunks/chunk-RHFPMM4R.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{require_ms}from"./chunks/chunk-MXTC4ZAQ.js";import"./chunks/chunk-OCR5CRTH.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"./chunks/chunk-5O7CRJE5.js";import{fetch,toNodeReadable}from"./chunks/chunk-U3J7VS56.js";import"./chunks/chunk-7EJQLVWX.js";import"./chunks/chunk-SCV7XEEO.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
|
+
`),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(ms9,withDate){let d=new Date(ms9),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(ms9){return`${formatUtcTime(ms9,!0)} UTC (${relativeTime(ms9)})`}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
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.`)}
|
|
14
14
|
`),!hadExistingDraft&&!opts.skipPrompts&&client.stdin.isTTY&&!client.nonInteractive){if(output_manager_default.print(`
|
|
15
|
-
`),await client.input.confirm("This is the only draft change. Publish to production now?",!1)){let publishStamp=stamp_default();output_manager_default.spinner("Publishing to production");try{await activateFirewallConfig(client,scope,"draft"),output_manager_default.log(`${import_chalk2.default.cyan("Published")} to production ${import_chalk2.default.gray(publishStamp())}`)}catch(e){output_manager_default.error(`Failed to publish to production: ${mapFirewallApiError(e,scope,"Unknown error")}`)}}}else hadExistingDraft&&output_manager_default.warn(`There are other draft changes. Review with ${import_chalk2.default.cyan(withGlobalFlags(client,"firewall diff",scope))} before publishing.`)}function resolveIpRule(ips,identifier){if(!identifier)return[];let byId=ips.find(r=>r.id===identifier);if(byId)return[byId];let query=identifier.toLowerCase(),byIp=ips.filter(r=>r.ip.toLowerCase()===query);return byIp.length>0?byIp:ips.filter(r=>r.id.toLowerCase().includes(query))}function resolveRule(rules2,identifier){if(!identifier)return[];let byId=rules2.find(r=>r.id===identifier);if(byId)return[byId];let query=identifier.toLowerCase(),byName=rules2.filter(r=>r.name.toLowerCase()===query);if(byName.length>0)return byName;let byPartialName=rules2.filter(r=>r.name.toLowerCase().includes(query));return byPartialName.length>0?byPartialName:rules2.filter(r=>r.id.toLowerCase().includes(query))}function printActionImpactWarning(action){let actionType=action.mitigate?.action;if(actionType)switch(actionType){case"deny":output_manager_default.warn("This rule will deny matching requests. Legitimate traffic may be blocked if conditions are too broad.");break;case"challenge":output_manager_default.warn("This rule will challenge matching requests with a verification page. Some legitimate users or automated clients may be unable to complete the challenge.");break;case"rate_limit":output_manager_default.warn("This rule will rate limit matching requests. Legitimate traffic may be throttled if the limit is too low or keys are too broad.");break;default:break}}async function getBypass(client,projectId,options={}){let{teamId}=options,query=new URLSearchParams;query.set("projectId",projectId),teamId&&query.set("teamId",teamId);let url=`/v1/security/firewall/bypass?${query.toString()}`;return client.fetch(url)}import{isIP}from"node:net";var STRING_OPS=["eq","inc"],STRING_MATCH_OPS=["sub","pre","suf","re"],KEY_EXISTS_OPS=["ex"],STRING_ONLY=[...STRING_OPS],STRING_AND_MATCH=[...STRING_OPS,...STRING_MATCH_OPS],STRING_MATCH_AND_EXISTS=[...STRING_OPS,...STRING_MATCH_OPS,...KEY_EXISTS_OPS],CONDITION_TYPES=[{type:"path",displayName:"Request Path",description:"URL path of the request",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"route",displayName:"Route",description:"Route pattern (e.g., /blog/[slug])",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"raw_path",displayName:"Raw Path",description:"Pre-rewrite URL path",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"server_action",displayName:"Server Action Name",description:"Next.js Server Action name",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"method",displayName:"Method",description:"HTTP method (GET, POST, DELETE, etc.)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"GET",value:"GET"},{label:"HEAD",value:"HEAD"},{label:"POST",value:"POST"},{label:"DELETE",value:"DELETE"},{label:"PATCH",value:"PATCH"},{label:"PUT",value:"PUT"},{label:"CONNECT",value:"CONNECT"},{label:"OPTIONS",value:"OPTIONS"},{label:"TRACE",value:"TRACE"},{label:"DEBUG",value:"DEBUG"},{label:"QUERY",value:"QUERY"}]},{type:"host",displayName:"Hostname",description:"Request hostname",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"protocol",displayName:"Protocol",description:"HTTP protocol version (HTTP/1.1, HTTP/2.0)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"HTTP/1.1",value:"HTTP/1.1"},{label:"HTTP/2.0",value:"HTTP/2.0"}]},{type:"environment",displayName:"Environment",description:"Deployment environment (preview, production)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"Preview",value:"preview"},{label:"Production",value:"production"}]},{type:"region",displayName:"Vercel Region",description:"Edge region serving the request",category:"request",requiresKey:!1,operators:STRING_ONLY},{type:"target_path",displayName:"Target Path",description:"Post-rewrite destination path",category:"request",requiresKey:!1,operators:STRING_AND_MATCH,valueValidation:"path"},{type:"scheme",displayName:"Scheme",description:"Request scheme (http, https)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"http",value:"http"},{label:"https",value:"https"}]},{type:"rate_limit_api_id",displayName:"Rate Limit API ID",description:"Identifier for rate-limit API grouping",category:"request",requiresKey:!1,operators:STRING_ONLY},{type:"ip_address",displayName:"IP Address",description:"Client IP address or CIDR range",category:"client",requiresKey:!1,operators:STRING_ONLY},{type:"user_agent",displayName:"User Agent",description:"Client User-Agent string",category:"client",requiresKey:!1,operators:STRING_AND_MATCH},{type:"geo_country",displayName:"Country",description:"Country code (ISO 3166-1 alpha-2)",category:"geo",requiresKey:!1,operators:STRING_ONLY},{type:"geo_continent",displayName:"Continent",description:"Continent code (AF, AN, AS, EU, NA, OC, SA)",category:"geo",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"Africa (AF)",value:"AF"},{label:"Antarctica (AN)",value:"AN"},{label:"Asia (AS)",value:"AS"},{label:"Europe (EU)",value:"EU"},{label:"North America (NA)",value:"NA"},{label:"Oceania (OC)",value:"OC"},{label:"South America (SA)",value:"SA"}]},{type:"geo_city",displayName:"City",description:"City name",category:"geo",requiresKey:!1,operators:STRING_AND_MATCH},{type:"geo_country_region",displayName:"State / Region",description:"State or region code",category:"geo",requiresKey:!1,operators:STRING_AND_MATCH},{type:"geo_as_number",displayName:"AS Number",description:"Autonomous System Number",category:"geo",requiresKey:!1,operators:STRING_AND_MATCH,valueValidation:"digits"},{type:"header",displayName:"Request Header",description:"HTTP request header (requires key)",category:"key-value",requiresKey:!0,operators:STRING_MATCH_AND_EXISTS},{type:"query",displayName:"Query Parameter",description:"URL query parameter (requires key)",category:"key-value",requiresKey:!0,operators:STRING_MATCH_AND_EXISTS},{type:"cookie",displayName:"Cookie",description:"HTTP cookie (requires key)",category:"key-value",requiresKey:!0,operators:STRING_MATCH_AND_EXISTS},{type:"ja4_digest",displayName:"JA4 Digest",description:"JA4 TLS fingerprint",category:"security",requiresKey:!1,operators:STRING_AND_MATCH},{type:"ja3_digest",displayName:"JA3 Digest",description:"JA3 TLS fingerprint",category:"security",requiresKey:!1,operators:STRING_AND_MATCH,planRequirement:"enterprise"},{type:"bot_name",displayName:"Bot Name",description:"Verified bot name",category:"bot",requiresKey:!1,operators:STRING_AND_MATCH,planRequirement:"security-plus"},{type:"bot_category",displayName:"Bot Category",description:"Verified bot category",category:"bot",requiresKey:!1,operators:STRING_AND_MATCH,planRequirement:"security-plus"}],CONDITION_TYPE_MAP=Object.fromEntries(CONDITION_TYPES.map(ct=>[ct.type,ct])),ALL_OPERATORS=["eq","neq","inc","ninc","sub","pre","suf","re","ex","nex","gt","gte","lt","lte"],CATEGORY_LABELS={request:"Request",client:"Client",geo:"Geo / Location","key-value":"Key-Value (Header / Query / Cookie)",security:"Security / TLS",bot:"Bot Detection"},VALID_ACTIONS=["deny","challenge","log","bypass","rate_limit","redirect"],VALID_DURATIONS=["1m","5m","15m","30m","1h"],VALID_ALGORITHMS=["fixed_window","token_bucket"];async function fetchPlanInfo(client){try{let{team}=await getScope(client);if(team)return{isEnterprise:team.billing.plan==="enterprise",hasSecurityPlus:team.securityPlus?.enabled===!0,known:!0}}catch{}return{isEnterprise:!1,hasSecurityPlus:!1,known:!1}}function getAvailableConditionTypes(planInfo){return CONDITION_TYPES.filter(ct=>!(ct.deprecated||ct.planRequirement==="enterprise"&&!planInfo?.isEnterprise||ct.planRequirement==="security-plus"&&!planInfo?.hasSecurityPlus))}function getActionLabel(action){return{deny:"Deny \u2014 Block traffic (403)",challenge:"Challenge \u2014 Verify at security checkpoint",log:"Log \u2014 Monitor without blocking",bypass:"Bypass \u2014 Skip other custom rules",rate_limit:"Rate Limit \u2014 Enforce request limits",redirect:"Redirect \u2014 Send to a different URL"}[action]||action}function getOperatorDisplayName(op,neg){let pair={eq:["equals","does not equal"],inc:["is any of","is not any of"],sub:["contains","does not contain"],pre:["starts with","does not start with"],suf:["ends with","does not end with"],re:["matches regex","does not match regex"],ex:["exists","does not exist"]}[op];return pair?neg?pair[1]:pair[0]:neg?`NOT ${op}`:op}function validateConditionValue(val,meta){if(!meta?.valueValidation)return!0;switch(meta.valueValidation){case"path":return val.startsWith("/")?!0:"Path must start with /";case"ip":{if(isIP(val))return!0;let slashIdx=val.lastIndexOf("/");if(slashIdx!==-1){let ip=val.slice(0,slashIdx),prefix=Number.parseInt(val.slice(slashIdx+1),10);if(isIP(ip)&&!Number.isNaN(prefix)&&prefix>=0)return!0}return"Please enter a valid IP address or CIDR range."}case"hostname":return/^[A-Za-z0-9-]{1,63}(?:\.[A-Za-z0-9-]{1,63})*$/.test(val)?!0:"Please enter a valid hostname.";case"digits":return/^\d+$/.test(val)?!0:"Please enter digits only.";default:return!0}}var FIREWALL_ACTION_METRIC="vercel.firewall_action.count";var VALUE_ALIAS="value",DEFAULT_TIMEOUT_MS=45e3,ActivityTimeoutError=class extends Error{constructor(message){super(message),this.name="ActivityTimeoutError"}};function isRateLimited(error){return isAPIError(error)&&error.status===429}function rateLimitRetrySeconds(error){if(!isRateLimited(error))return;let ms8=error.retryAfterMs;if(!(typeof ms8!="number"||ms8<=0))return Math.ceil(ms8/1e3)}function isActivityTimeout(error){return isAPIError(error)&&error.status===408||error instanceof Error&&error.name==="ActivityTimeoutError"}function toBucketSeconds(granularity){return"minutes"in granularity?granularity.minutes*60:"hours"in granularity?granularity.hours*60*60:granularity.days*24*60*60}function alignQueryWindow(startTime,endTime,granularity){let stepMs=granularity?toBucketSeconds(granularity)*1e3:1e3;return{startTime:new Date(Math.floor(startTime.getTime()/stepMs)*stepMs),endTime:new Date(Math.ceil(endTime.getTime()/stepMs)*stepMs)}}async function queryFirewallObservability(client,opts){let groupBy=opts.groupBy??[],window=alignQueryWindow(opts.startTime,opts.endTime,opts.granularity),bucketed=opts.granularity!==void 0,ranked=groupBy.length>0&&opts.limit!==void 0,body={scope:{ownerId:opts.ownerId,projectIds:[opts.projectId]},timeRange:{start:window.startTime.toISOString(),end:window.endTime.toISOString()},metrics:{[VALUE_ALIAS]:{metric:opts.metric??FIREWALL_ACTION_METRIC,aggregation:"count"}},outputs:[VALUE_ALIAS],...opts.granularity?{bucketSeconds:toBucketSeconds(opts.granularity)}:{},...groupBy.length>0?{groupBy}:{},...opts.filter?{filter:opts.filter}:{},...ranked&&bucketed?{seriesSelection:{limit:opts.limit,mode:opts.approximateSelection?"approximate":"exact",rankBy:[{metric:VALUE_ALIAS,direction:"desc"}]}}:{},...ranked&&!bucketed?{rowLimit:opts.limit,orderBy:[{metric:VALUE_ALIAS,direction:"desc"}]}:{}},timeoutMs=opts.timeoutMs??DEFAULT_TIMEOUT_MS,response;try{response=await client.fetch(OBSERVABILITY_METRICS_PATH,{method:"POST",body:JSON.stringify(body),headers:{"Content-Type":"application/json"},accountId:opts.ownerId,signal:AbortSignal.timeout(timeoutMs),bailOn429:!0})}catch(err){throw err instanceof Error&&(err.name==="TimeoutError"||err.name==="AbortError")?new ActivityTimeoutError(`Timed out after ${Math.round(timeoutMs/1e3)}s waiting for ${opts.timeoutSubject??"firewall traffic data"}.`):err}return{summary:response.summary??[],series:response.series??[],startTime:window.startTime,endTime:window.endTime}}function rowValue(row){let raw=row.values?.[VALUE_ALIAS],n=typeof raw=="number"?raw:Number(raw);return Number.isFinite(n)?n:0}function rowDimension(row,field){return String(row.dimensions?.[field]??"")}function isUnsupportedDimension(error){if(!isAPIError(error)||error.status!==400)return!1;let pattern=/does not support|is not supported|not publicly queryable/i,issues=error.issues;return Array.isArray(issues)?issues.some(issue=>typeof issue?.message=="string"&&pattern.test(issue.message)):pattern.test(error.serverMessage||error.message||"")}var ACTION_DIMENSION="wafAction";function actionFromRow(row){return rowDimension(row,ACTION_DIMENSION)||"unknown"}async function getFirewallMetrics(client,opts){let granularity=opts.granularity??{hours:1},result=await queryFirewallObservability(client,{ownerId:opts.ownerId,projectId:opts.projectId,startTime:opts.startTime,endTime:opts.endTime,granularity,groupBy:[ACTION_DIMENSION],filter:opts.filter,limit:100,timeoutMs:opts.timeoutMs,timeoutSubject:"firewall metrics"}),byAction=new Map,totalFromSummary=new Set;for(let row of result.summary){let action=actionFromRow(row);totalFromSummary.add(action),byAction.set(action,{action,total:rowValue(row),timeseries:[]})}for(let row of result.series){let action=actionFromRow(row),value=rowValue(row),series2=byAction.get(action);series2||(series2={action,total:0,timeseries:[]},byAction.set(action,series2)),series2.timeseries.push({timestamp:row.timestamp,value}),totalFromSummary.has(action)||(series2.total+=value)}let order=["allow","deny","challenge","log","rate_limit","bypass"],series=[...byAction.values()].sort((a,b)=>{let ai=order.indexOf(a.action),bi=order.indexOf(b.action);return ai===-1&&bi===-1?a.action.localeCompare(b.action):ai===-1?1:bi===-1?-1:ai-bi});for(let s of series)s.timeseries.sort((a,b)=>a.timestamp.localeCompare(b.timestamp));let totals={};for(let s of series)totals[s.action]=s.total;return{startTime:result.startTime.toISOString(),endTime:result.endTime.toISOString(),granularity,series,totals}}function quoteKqlValue(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function eqFilter(field,value){return`${field}:${quoteKqlValue(value)}`}function neFilter(field,value){return`${field}!=${quoteKqlValue(value)}`}function nonEmptyFilter(field){return neFilter(field,"")}var TRAFFIC_DIMENSIONS=[{alias:"ip",field:"clientIp",label:"IP Address",widgetTitle:"Top IPs",excludeFilter:neFilter("clientIp","127.0.0.1"),headerDetailFields:["asnName","asnId","clientIpCountry"],defaultGroupBy:"path"},{alias:"ja4",field:"clientJa4Digest",label:"JA4 Digest",widgetTitle:"Top JA4 Digests",excludeFilter:nonEmptyFilter("clientJa4Digest"),headerDetailFields:["clientUserAgent"],defaultGroupBy:"path"},{alias:"asn",field:"asnName",label:"AS Name",widgetTitle:"Top AS Names",excludeFilter:`(${nonEmptyFilter("asnId")}) AND (${nonEmptyFilter("asnName")})`,groupBy:["asnName","asnId"],labelFields:["asnId"],headerDetailFields:["asnId"],defaultGroupBy:"ip"},{alias:"user-agent",field:"clientUserAgent",label:"User Agent",widgetTitle:"Top User Agents",excludeFilter:nonEmptyFilter("clientUserAgent"),defaultGroupBy:"path"},{alias:"path",field:"requestPath",label:"Request Path",widgetTitle:"Top Request Paths",excludeFilter:nonEmptyFilter("requestPath"),defaultGroupBy:"ip"},{alias:"rule",field:"wafRuleId",label:"Firewall Rule",widgetTitle:"Rules",excludeFilter:`(${nonEmptyFilter("wafRuleId")}) AND (${nonEmptyFilter("wafAction")})`,defaultGroupBy:"ip"},{alias:"host",field:"requestHostname",label:"Hostname",widgetTitle:"Top Hosts",defaultGroupBy:"path"},{alias:"bot",field:"botName",label:"Bot",widgetTitle:"Verified Bots",excludeFilter:nonEmptyFilter("botName"),defaultGroupBy:"path"},{alias:"unknown-bot",field:"botCategory",label:"Unknown Bot Category",widgetTitle:"Unknown Bot Traffic",excludeFilter:nonEmptyFilter("botCategory"),metric:"vercel.request.count",extraFilter:neFilter("botVerified","pass"),defaultGroupBy:"path"},{alias:"country",field:"clientIpCountry",label:"Country",widgetTitle:"Top Countries",excludeFilter:nonEmptyFilter("clientIpCountry"),defaultGroupBy:"ip"},{alias:"action",field:"wafAction",label:"Firewall Action",widgetTitle:"Actions",excludeFilter:nonEmptyFilter("wafAction"),defaultGroupBy:"rule"}];function getDimension(alias){return TRAFFIC_DIMENSIONS.find(d=>d.alias===alias)}function dimensionAliases(){return TRAFFIC_DIMENSIONS.map(d=>d.alias)}function andFilters(...parts){let nonEmpty=parts.filter(p=>!!(p&&p.length>0));if(nonEmpty.length!==0)return nonEmpty.length===1?nonEmpty[0]:nonEmpty.map(p=>`(${p})`).join(" AND ")}var RULE_ID_DIMENSION="wafRuleId",RULE_TRAFFIC_FILTER=`(${nonEmptyFilter(RULE_ID_DIMENSION)}) AND (${nonEmptyFilter("wafAction")})`,GRANULARITY_LADDER=[[6e4,{minutes:1}],[5*6e4,{minutes:5}],[15*6e4,{minutes:15}],[30*6e4,{minutes:30}],[36e5,{hours:1}],[2*36e5,{hours:2}],[4*36e5,{hours:4}],[12*36e5,{hours:12}],[24*36e5,{hours:24}]],DEFAULT_MAX_BUCKETS=24;function pickGranularity(spanMs,maxBuckets=DEFAULT_MAX_BUCKETS){for(let[stepMs,granularity]of GRANULARITY_LADDER)if(spanMs/stepMs<=maxBuckets)return granularity;return{hours:24}}async function getTopList(client,opts){let{summary}=await queryFirewallObservability(client,{...opts,granularity:void 0,limit:Math.min(opts.top,500)}),rows=summary.map(row=>({values:Object.fromEntries(opts.groupBy.map(field=>[field,rowDimension(row,field)])),total:rowValue(row)}));return rows.sort((a,b)=>b.total-a.total),rows.slice(0,opts.top)}async function getGroupedTimeseries(client,opts){let spanMs=opts.endTime.getTime()-opts.startTime.getTime(),granularity=opts.granularity??pickGranularity(spanMs),groupBy=opts.groupBy??[],result=await queryFirewallObservability(client,{...opts,granularity,groupBy}),keyOf=row=>groupBy.map(f=>rowDimension(row,f)).join(" \xB7 "),groups=new Map,pointsByGroup=new Map,axisSet=new Set,hasSummary=result.summary.length>0,getOrCreate=row=>{let key=keyOf(row),group=groups.get(key);return group||(group={values:Object.fromEntries(groupBy.map(field=>[field,rowDimension(row,field)])),key,total:0,series:[]},groups.set(key,group)),group};for(let row of result.summary)getOrCreate(row).total=rowValue(row);for(let row of result.series){let timestamp=row.timestamp;if(!timestamp)continue;axisSet.add(timestamp);let group=getOrCreate(row),points=pointsByGroup.get(group.key);points||(points=new Map,pointsByGroup.set(group.key,points));let value=rowValue(row);points.set(timestamp,(points.get(timestamp)??0)+value),hasSummary||(group.total+=value)}let axis=[...axisSet].sort();for(let group of groups.values()){let points=pointsByGroup.get(group.key);group.series=axis.map(t=>points?.get(t)??0)}return{startTime:result.startTime.toISOString(),endTime:result.endTime.toISOString(),granularity,axis,groups:[...groups.values()].sort((a,b)=>b.total-a.total)}}var WELL_KNOWN_RULE_NAMES={sys_dos_mitigation:"DDoS Mitigation",ip_blocking:"IP Blocking",challenge_mode:"Attack Mode",default_web_traffic:"Allowed Requests",managed_bot_protection:"Bot Protection",managed_bot_filter:"Bot Protection",owasp_anomaly_detection:"OWASP Anomaly Detection",owasp_xss_detection:"OWASP XSS Detection",owasp_sqli_detection:"OWASP SQL Injection Detection",owasp_rfi_detection:"OWASP RFI Detection",owasp_lfi_detection:"OWASP LFI Detection",owasp_rce_detection:"OWASP RCE Detection",owasp_php_detection:"OWASP PHP Injection Detection",owasp_session_fixation_detection:"OWASP Session Fixation Detection",deployment_rules:"Deployment Rules",deployment_defined_rules:"Deployment Defined Rules"};function titleCaseManagedSuffix(ruleId){return ruleId.slice(8).split("_").filter(Boolean).map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function ipBlockName(ip){return!ip.hostname||ip.hostname==="*"?`IP Block ${ip.ip}`:`IP Block ${ip.hostname} ${ip.ip}`}function resolveRuleDisplayName(ruleId,config){if(!ruleId)return ruleId;let custom=config?.rules.find(r=>r.id===ruleId);if(custom?.name)return custom.name;let ip=config?.ips.find(r=>r.id===ruleId);if(ip)return ipBlockName(ip);let known=WELL_KNOWN_RULE_NAMES[ruleId];return known||(ruleId.startsWith("managed_")?titleCaseManagedSuffix(ruleId):ruleId)}var import_chalk3=__toESM(require_source(),1);var MAX_VALUE_WIDTH=60,MAX_TREND_LABEL_WIDTH=40,NOT_SET="(not set)",FIELD_LABELS={asnId:"AS Number",asnName:"AS Name",clientIp:"IP Address",clientIpCountry:"Country",clientJa4Digest:"JA4 Digest",clientUserAgent:"User Agent",requestHostname:"Hostname",requestPath:"Request Path",wafAction:"Action",wafRuleId:"Rule"};function fieldLabel(field){return FIELD_LABELS[field]??field}function windowLabel(opts){let range=`${formatUtcTime(opts.startMs,!0)} \u2013 ${formatUtcTime(opts.endMs,!0)} UTC`;if(opts.points===0)return range;let unit=opts.points===1?"point":"points";return`${range} \xB7 ${opts.points} ${unit} (${granularityLabel(opts.granularity)} each)`}function axisOf(series){let timestamps=new Set;for(let s of series)for(let point of s.timeseries)timestamps.add(point.timestamp);return[...timestamps].sort()}function peakOf(values,axis){let peak=0,peakTs="";for(let i=0;i<axis.length;i++)values[i]>peak&&(peak=values[i],peakTs=axis[i]);return{peak,peakTs}}function indent(rendered){return rendered.split(`
|
|
15
|
+
`),await client.input.confirm("This is the only draft change. Publish to production now?",!1)){let publishStamp=stamp_default();output_manager_default.spinner("Publishing to production");try{await activateFirewallConfig(client,scope,"draft"),output_manager_default.log(`${import_chalk2.default.cyan("Published")} to production ${import_chalk2.default.gray(publishStamp())}`)}catch(e){output_manager_default.error(`Failed to publish to production: ${mapFirewallApiError(e,scope,"Unknown error")}`)}}}else hadExistingDraft&&output_manager_default.warn(`There are other draft changes. Review with ${import_chalk2.default.cyan(withGlobalFlags(client,"firewall diff",scope))} before publishing.`)}function resolveIpRule(ips,identifier){if(!identifier)return[];let byId=ips.find(r=>r.id===identifier);if(byId)return[byId];let query=identifier.toLowerCase(),byIp=ips.filter(r=>r.ip.toLowerCase()===query);return byIp.length>0?byIp:ips.filter(r=>r.id.toLowerCase().includes(query))}function resolveRule(rules2,identifier){if(!identifier)return[];let byId=rules2.find(r=>r.id===identifier);if(byId)return[byId];let query=identifier.toLowerCase(),byName=rules2.filter(r=>r.name.toLowerCase()===query);if(byName.length>0)return byName;let byPartialName=rules2.filter(r=>r.name.toLowerCase().includes(query));return byPartialName.length>0?byPartialName:rules2.filter(r=>r.id.toLowerCase().includes(query))}function printActionImpactWarning(action){let actionType=action.mitigate?.action;if(actionType)switch(actionType){case"deny":output_manager_default.warn("This rule will deny matching requests. Legitimate traffic may be blocked if conditions are too broad.");break;case"challenge":output_manager_default.warn("This rule will challenge matching requests with a verification page. Some legitimate users or automated clients may be unable to complete the challenge.");break;case"rate_limit":output_manager_default.warn("This rule will rate limit matching requests. Legitimate traffic may be throttled if the limit is too low or keys are too broad.");break;default:break}}async function getBypass(client,projectId,options={}){let{teamId}=options,query=new URLSearchParams;query.set("projectId",projectId),teamId&&query.set("teamId",teamId);let url=`/v1/security/firewall/bypass?${query.toString()}`;return client.fetch(url)}import{isIP}from"node:net";var STRING_OPS=["eq","inc"],STRING_MATCH_OPS=["sub","pre","suf","re"],KEY_EXISTS_OPS=["ex"],STRING_ONLY=[...STRING_OPS],STRING_AND_MATCH=[...STRING_OPS,...STRING_MATCH_OPS],STRING_MATCH_AND_EXISTS=[...STRING_OPS,...STRING_MATCH_OPS,...KEY_EXISTS_OPS],CONDITION_TYPES=[{type:"path",displayName:"Request Path",description:"URL path of the request",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"route",displayName:"Route",description:"Route pattern (e.g., /blog/[slug])",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"raw_path",displayName:"Raw Path",description:"Pre-rewrite URL path",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"server_action",displayName:"Server Action Name",description:"Next.js Server Action name",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"method",displayName:"Method",description:"HTTP method (GET, POST, DELETE, etc.)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"GET",value:"GET"},{label:"HEAD",value:"HEAD"},{label:"POST",value:"POST"},{label:"DELETE",value:"DELETE"},{label:"PATCH",value:"PATCH"},{label:"PUT",value:"PUT"},{label:"CONNECT",value:"CONNECT"},{label:"OPTIONS",value:"OPTIONS"},{label:"TRACE",value:"TRACE"},{label:"DEBUG",value:"DEBUG"},{label:"QUERY",value:"QUERY"}]},{type:"host",displayName:"Hostname",description:"Request hostname",category:"request",requiresKey:!1,operators:STRING_AND_MATCH},{type:"protocol",displayName:"Protocol",description:"HTTP protocol version (HTTP/1.1, HTTP/2.0)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"HTTP/1.1",value:"HTTP/1.1"},{label:"HTTP/2.0",value:"HTTP/2.0"}]},{type:"environment",displayName:"Environment",description:"Deployment environment (preview, production)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"Preview",value:"preview"},{label:"Production",value:"production"}]},{type:"region",displayName:"Vercel Region",description:"Edge region serving the request",category:"request",requiresKey:!1,operators:STRING_ONLY},{type:"target_path",displayName:"Target Path",description:"Post-rewrite destination path",category:"request",requiresKey:!1,operators:STRING_AND_MATCH,valueValidation:"path"},{type:"scheme",displayName:"Scheme",description:"Request scheme (http, https)",category:"request",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"http",value:"http"},{label:"https",value:"https"}]},{type:"rate_limit_api_id",displayName:"Rate Limit API ID",description:"Identifier for rate-limit API grouping",category:"request",requiresKey:!1,operators:STRING_ONLY},{type:"ip_address",displayName:"IP Address",description:"Client IP address or CIDR range",category:"client",requiresKey:!1,operators:STRING_ONLY},{type:"user_agent",displayName:"User Agent",description:"Client User-Agent string",category:"client",requiresKey:!1,operators:STRING_AND_MATCH},{type:"geo_country",displayName:"Country",description:"Country code (ISO 3166-1 alpha-2)",category:"geo",requiresKey:!1,operators:STRING_ONLY},{type:"geo_continent",displayName:"Continent",description:"Continent code (AF, AN, AS, EU, NA, OC, SA)",category:"geo",requiresKey:!1,operators:STRING_ONLY,presetValues:[{label:"Africa (AF)",value:"AF"},{label:"Antarctica (AN)",value:"AN"},{label:"Asia (AS)",value:"AS"},{label:"Europe (EU)",value:"EU"},{label:"North America (NA)",value:"NA"},{label:"Oceania (OC)",value:"OC"},{label:"South America (SA)",value:"SA"}]},{type:"geo_city",displayName:"City",description:"City name",category:"geo",requiresKey:!1,operators:STRING_AND_MATCH},{type:"geo_country_region",displayName:"State / Region",description:"State or region code",category:"geo",requiresKey:!1,operators:STRING_AND_MATCH},{type:"geo_as_number",displayName:"AS Number",description:"Autonomous System Number",category:"geo",requiresKey:!1,operators:STRING_AND_MATCH,valueValidation:"digits"},{type:"header",displayName:"Request Header",description:"HTTP request header (requires key)",category:"key-value",requiresKey:!0,operators:STRING_MATCH_AND_EXISTS},{type:"query",displayName:"Query Parameter",description:"URL query parameter (requires key)",category:"key-value",requiresKey:!0,operators:STRING_MATCH_AND_EXISTS},{type:"cookie",displayName:"Cookie",description:"HTTP cookie (requires key)",category:"key-value",requiresKey:!0,operators:STRING_MATCH_AND_EXISTS},{type:"ja4_digest",displayName:"JA4 Digest",description:"JA4 TLS fingerprint",category:"security",requiresKey:!1,operators:STRING_AND_MATCH},{type:"ja3_digest",displayName:"JA3 Digest",description:"JA3 TLS fingerprint",category:"security",requiresKey:!1,operators:STRING_AND_MATCH,planRequirement:"enterprise"},{type:"bot_name",displayName:"Bot Name",description:"Verified bot name",category:"bot",requiresKey:!1,operators:STRING_AND_MATCH,planRequirement:"security-plus"},{type:"bot_category",displayName:"Bot Category",description:"Verified bot category",category:"bot",requiresKey:!1,operators:STRING_AND_MATCH,planRequirement:"security-plus"}],CONDITION_TYPE_MAP=Object.fromEntries(CONDITION_TYPES.map(ct=>[ct.type,ct])),ALL_OPERATORS=["eq","neq","inc","ninc","sub","pre","suf","re","ex","nex","gt","gte","lt","lte"],CATEGORY_LABELS={request:"Request",client:"Client",geo:"Geo / Location","key-value":"Key-Value (Header / Query / Cookie)",security:"Security / TLS",bot:"Bot Detection"},VALID_ACTIONS=["deny","challenge","log","bypass","rate_limit","redirect"],VALID_DURATIONS=["1m","5m","15m","30m","1h"],VALID_ALGORITHMS=["fixed_window","token_bucket"];async function fetchPlanInfo(client){try{let{team}=await getScope(client);if(team)return{isEnterprise:team.billing.plan==="enterprise",hasSecurityPlus:team.securityPlus?.enabled===!0,known:!0}}catch{}return{isEnterprise:!1,hasSecurityPlus:!1,known:!1}}function getAvailableConditionTypes(planInfo){return CONDITION_TYPES.filter(ct=>!(ct.deprecated||ct.planRequirement==="enterprise"&&!planInfo?.isEnterprise||ct.planRequirement==="security-plus"&&!planInfo?.hasSecurityPlus))}function getActionLabel(action){return{deny:"Deny \u2014 Block traffic (403)",challenge:"Challenge \u2014 Verify at security checkpoint",log:"Log \u2014 Monitor without blocking",bypass:"Bypass \u2014 Skip other custom rules",rate_limit:"Rate Limit \u2014 Enforce request limits",redirect:"Redirect \u2014 Send to a different URL"}[action]||action}function getOperatorDisplayName(op,neg){let pair={eq:["equals","does not equal"],inc:["is any of","is not any of"],sub:["contains","does not contain"],pre:["starts with","does not start with"],suf:["ends with","does not end with"],re:["matches regex","does not match regex"],ex:["exists","does not exist"]}[op];return pair?neg?pair[1]:pair[0]:neg?`NOT ${op}`:op}function validateConditionValue(val,meta){if(!meta?.valueValidation)return!0;switch(meta.valueValidation){case"path":return val.startsWith("/")?!0:"Path must start with /";case"ip":{if(isIP(val))return!0;let slashIdx=val.lastIndexOf("/");if(slashIdx!==-1){let ip=val.slice(0,slashIdx),prefix=Number.parseInt(val.slice(slashIdx+1),10);if(isIP(ip)&&!Number.isNaN(prefix)&&prefix>=0)return!0}return"Please enter a valid IP address or CIDR range."}case"hostname":return/^[A-Za-z0-9-]{1,63}(?:\.[A-Za-z0-9-]{1,63})*$/.test(val)?!0:"Please enter a valid hostname.";case"digits":return/^\d+$/.test(val)?!0:"Please enter digits only.";default:return!0}}var FIREWALL_ACTION_METRIC="vercel.firewall_action.count";var VALUE_ALIAS="value",DEFAULT_TIMEOUT_MS=45e3,ActivityTimeoutError=class extends Error{constructor(message){super(message),this.name="ActivityTimeoutError"}};function isRateLimited(error){return isAPIError(error)&&error.status===429}function rateLimitRetrySeconds(error){if(!isRateLimited(error))return;let ms9=error.retryAfterMs;if(!(typeof ms9!="number"||ms9<=0))return Math.ceil(ms9/1e3)}function isActivityTimeout(error){return isAPIError(error)&&error.status===408||error instanceof Error&&error.name==="ActivityTimeoutError"}function toBucketSeconds(granularity){return"minutes"in granularity?granularity.minutes*60:"hours"in granularity?granularity.hours*60*60:granularity.days*24*60*60}function alignQueryWindow(startTime,endTime,granularity){let stepMs=granularity?toBucketSeconds(granularity)*1e3:1e3;return{startTime:new Date(Math.floor(startTime.getTime()/stepMs)*stepMs),endTime:new Date(Math.ceil(endTime.getTime()/stepMs)*stepMs)}}async function queryFirewallObservability(client,opts){let groupBy=opts.groupBy??[],window=alignQueryWindow(opts.startTime,opts.endTime,opts.granularity),bucketed=opts.granularity!==void 0,ranked=groupBy.length>0&&opts.limit!==void 0,body={scope:{ownerId:opts.ownerId,projectIds:[opts.projectId]},timeRange:{start:window.startTime.toISOString(),end:window.endTime.toISOString()},metrics:{[VALUE_ALIAS]:{metric:opts.metric??FIREWALL_ACTION_METRIC,aggregation:"count"}},outputs:[VALUE_ALIAS],...opts.granularity?{bucketSeconds:toBucketSeconds(opts.granularity)}:{},...groupBy.length>0?{groupBy}:{},...opts.filter?{filter:opts.filter}:{},...ranked&&bucketed?{seriesSelection:{limit:opts.limit,mode:opts.approximateSelection?"approximate":"exact",rankBy:[{metric:VALUE_ALIAS,direction:"desc"}]}}:{},...ranked&&!bucketed?{rowLimit:opts.limit,orderBy:[{metric:VALUE_ALIAS,direction:"desc"}]}:{}},timeoutMs=opts.timeoutMs??DEFAULT_TIMEOUT_MS,response;try{response=await client.fetch(OBSERVABILITY_METRICS_PATH,{method:"POST",body:JSON.stringify(body),headers:{"Content-Type":"application/json"},accountId:opts.ownerId,signal:AbortSignal.timeout(timeoutMs),bailOn429:!0})}catch(err){throw err instanceof Error&&(err.name==="TimeoutError"||err.name==="AbortError")?new ActivityTimeoutError(`Timed out after ${Math.round(timeoutMs/1e3)}s waiting for ${opts.timeoutSubject??"firewall traffic data"}.`):err}return{summary:response.summary??[],series:response.series??[],startTime:window.startTime,endTime:window.endTime}}function rowValue(row){let raw=row.values?.[VALUE_ALIAS],n=typeof raw=="number"?raw:Number(raw);return Number.isFinite(n)?n:0}function rowDimension(row,field){return String(row.dimensions?.[field]??"")}function isUnsupportedDimension(error){if(!isAPIError(error)||error.status!==400)return!1;let pattern=/does not support|is not supported|not publicly queryable/i,issues=error.issues;return Array.isArray(issues)?issues.some(issue=>typeof issue?.message=="string"&&pattern.test(issue.message)):pattern.test(error.serverMessage||error.message||"")}var ACTION_DIMENSION="wafAction";function actionFromRow(row){return rowDimension(row,ACTION_DIMENSION)||"unknown"}async function getFirewallMetrics(client,opts){let granularity=opts.granularity??{hours:1},result=await queryFirewallObservability(client,{ownerId:opts.ownerId,projectId:opts.projectId,startTime:opts.startTime,endTime:opts.endTime,granularity,groupBy:[ACTION_DIMENSION],filter:opts.filter,limit:100,timeoutMs:opts.timeoutMs,timeoutSubject:"firewall metrics"}),byAction=new Map,totalFromSummary=new Set;for(let row of result.summary){let action=actionFromRow(row);totalFromSummary.add(action),byAction.set(action,{action,total:rowValue(row),timeseries:[]})}for(let row of result.series){let action=actionFromRow(row),value=rowValue(row),series2=byAction.get(action);series2||(series2={action,total:0,timeseries:[]},byAction.set(action,series2)),series2.timeseries.push({timestamp:row.timestamp,value}),totalFromSummary.has(action)||(series2.total+=value)}let order=["allow","deny","challenge","log","rate_limit","bypass"],series=[...byAction.values()].sort((a,b)=>{let ai=order.indexOf(a.action),bi=order.indexOf(b.action);return ai===-1&&bi===-1?a.action.localeCompare(b.action):ai===-1?1:bi===-1?-1:ai-bi});for(let s of series)s.timeseries.sort((a,b)=>a.timestamp.localeCompare(b.timestamp));let totals={};for(let s of series)totals[s.action]=s.total;return{startTime:result.startTime.toISOString(),endTime:result.endTime.toISOString(),granularity,series,totals}}function quoteKqlValue(value){return`"${value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function eqFilter(field,value){return`${field}:${quoteKqlValue(value)}`}function neFilter(field,value){return`${field}!=${quoteKqlValue(value)}`}function nonEmptyFilter(field){return neFilter(field,"")}var TRAFFIC_DIMENSIONS=[{alias:"ip",field:"clientIp",label:"IP Address",widgetTitle:"Top IPs",excludeFilter:neFilter("clientIp","127.0.0.1"),headerDetailFields:["asnName","asnId","clientIpCountry"],defaultGroupBy:"path"},{alias:"ja4",field:"clientJa4Digest",label:"JA4 Digest",widgetTitle:"Top JA4 Digests",excludeFilter:nonEmptyFilter("clientJa4Digest"),headerDetailFields:["clientUserAgent"],defaultGroupBy:"path"},{alias:"asn",field:"asnName",label:"AS Name",widgetTitle:"Top AS Names",excludeFilter:`(${nonEmptyFilter("asnId")}) AND (${nonEmptyFilter("asnName")})`,groupBy:["asnName","asnId"],labelFields:["asnId"],headerDetailFields:["asnId"],defaultGroupBy:"ip"},{alias:"user-agent",field:"clientUserAgent",label:"User Agent",widgetTitle:"Top User Agents",excludeFilter:nonEmptyFilter("clientUserAgent"),defaultGroupBy:"path"},{alias:"path",field:"requestPath",label:"Request Path",widgetTitle:"Top Request Paths",excludeFilter:nonEmptyFilter("requestPath"),defaultGroupBy:"ip"},{alias:"rule",field:"wafRuleId",label:"Firewall Rule",widgetTitle:"Rules",excludeFilter:`(${nonEmptyFilter("wafRuleId")}) AND (${nonEmptyFilter("wafAction")})`,defaultGroupBy:"ip"},{alias:"host",field:"requestHostname",label:"Hostname",widgetTitle:"Top Hosts",defaultGroupBy:"path"},{alias:"bot",field:"botName",label:"Bot",widgetTitle:"Verified Bots",excludeFilter:nonEmptyFilter("botName"),defaultGroupBy:"path"},{alias:"unknown-bot",field:"botCategory",label:"Unknown Bot Category",widgetTitle:"Unknown Bot Traffic",excludeFilter:nonEmptyFilter("botCategory"),metric:"vercel.request.count",extraFilter:neFilter("botVerified","pass"),defaultGroupBy:"path"},{alias:"country",field:"clientIpCountry",label:"Country",widgetTitle:"Top Countries",excludeFilter:nonEmptyFilter("clientIpCountry"),defaultGroupBy:"ip"},{alias:"action",field:"wafAction",label:"Firewall Action",widgetTitle:"Actions",excludeFilter:nonEmptyFilter("wafAction"),defaultGroupBy:"rule"}];function getDimension(alias){return TRAFFIC_DIMENSIONS.find(d=>d.alias===alias)}function dimensionAliases(){return TRAFFIC_DIMENSIONS.map(d=>d.alias)}function andFilters(...parts){let nonEmpty=parts.filter(p=>!!(p&&p.length>0));if(nonEmpty.length!==0)return nonEmpty.length===1?nonEmpty[0]:nonEmpty.map(p=>`(${p})`).join(" AND ")}var RULE_ID_DIMENSION="wafRuleId",RULE_TRAFFIC_FILTER=`(${nonEmptyFilter(RULE_ID_DIMENSION)}) AND (${nonEmptyFilter("wafAction")})`,GRANULARITY_LADDER=[[6e4,{minutes:1}],[5*6e4,{minutes:5}],[15*6e4,{minutes:15}],[30*6e4,{minutes:30}],[36e5,{hours:1}],[2*36e5,{hours:2}],[4*36e5,{hours:4}],[12*36e5,{hours:12}],[24*36e5,{hours:24}]],DEFAULT_MAX_BUCKETS=24;function pickGranularity(spanMs,maxBuckets=DEFAULT_MAX_BUCKETS){for(let[stepMs,granularity]of GRANULARITY_LADDER)if(spanMs/stepMs<=maxBuckets)return granularity;return{hours:24}}async function getTopList(client,opts){let{summary}=await queryFirewallObservability(client,{...opts,granularity:void 0,limit:Math.min(opts.top,500)}),rows=summary.map(row=>({values:Object.fromEntries(opts.groupBy.map(field=>[field,rowDimension(row,field)])),total:rowValue(row)}));return rows.sort((a,b)=>b.total-a.total),rows.slice(0,opts.top)}async function getGroupedTimeseries(client,opts){let spanMs=opts.endTime.getTime()-opts.startTime.getTime(),granularity=opts.granularity??pickGranularity(spanMs),groupBy=opts.groupBy??[],result=await queryFirewallObservability(client,{...opts,granularity,groupBy}),keyOf=row=>groupBy.map(f=>rowDimension(row,f)).join(" \xB7 "),groups=new Map,pointsByGroup=new Map,axisSet=new Set,hasSummary=result.summary.length>0,getOrCreate=row=>{let key=keyOf(row),group=groups.get(key);return group||(group={values:Object.fromEntries(groupBy.map(field=>[field,rowDimension(row,field)])),key,total:0,series:[]},groups.set(key,group)),group};for(let row of result.summary)getOrCreate(row).total=rowValue(row);for(let row of result.series){let timestamp=row.timestamp;if(!timestamp)continue;axisSet.add(timestamp);let group=getOrCreate(row),points=pointsByGroup.get(group.key);points||(points=new Map,pointsByGroup.set(group.key,points));let value=rowValue(row);points.set(timestamp,(points.get(timestamp)??0)+value),hasSummary||(group.total+=value)}let axis=[...axisSet].sort();for(let group of groups.values()){let points=pointsByGroup.get(group.key);group.series=axis.map(t=>points?.get(t)??0)}return{startTime:result.startTime.toISOString(),endTime:result.endTime.toISOString(),granularity,axis,groups:[...groups.values()].sort((a,b)=>b.total-a.total)}}var WELL_KNOWN_RULE_NAMES={sys_dos_mitigation:"DDoS Mitigation",ip_blocking:"IP Blocking",challenge_mode:"Attack Mode",default_web_traffic:"Allowed Requests",managed_bot_protection:"Bot Protection",managed_bot_filter:"Bot Protection",owasp_anomaly_detection:"OWASP Anomaly Detection",owasp_xss_detection:"OWASP XSS Detection",owasp_sqli_detection:"OWASP SQL Injection Detection",owasp_rfi_detection:"OWASP RFI Detection",owasp_lfi_detection:"OWASP LFI Detection",owasp_rce_detection:"OWASP RCE Detection",owasp_php_detection:"OWASP PHP Injection Detection",owasp_session_fixation_detection:"OWASP Session Fixation Detection",deployment_rules:"Deployment Rules",deployment_defined_rules:"Deployment Defined Rules"};function titleCaseManagedSuffix(ruleId){return ruleId.slice(8).split("_").filter(Boolean).map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function ipBlockName(ip){return!ip.hostname||ip.hostname==="*"?`IP Block ${ip.ip}`:`IP Block ${ip.hostname} ${ip.ip}`}function resolveRuleDisplayName(ruleId,config){if(!ruleId)return ruleId;let custom=config?.rules.find(r=>r.id===ruleId);if(custom?.name)return custom.name;let ip=config?.ips.find(r=>r.id===ruleId);if(ip)return ipBlockName(ip);let known=WELL_KNOWN_RULE_NAMES[ruleId];return known||(ruleId.startsWith("managed_")?titleCaseManagedSuffix(ruleId):ruleId)}var import_chalk3=__toESM(require_source(),1);var MAX_VALUE_WIDTH=60,MAX_TREND_LABEL_WIDTH=40,NOT_SET="(not set)",FIELD_LABELS={asnId:"AS Number",asnName:"AS Name",clientIp:"IP Address",clientIpCountry:"Country",clientJa4Digest:"JA4 Digest",clientUserAgent:"User Agent",requestHostname:"Hostname",requestPath:"Request Path",wafAction:"Action",wafRuleId:"Rule"};function fieldLabel(field){return FIELD_LABELS[field]??field}function windowLabel(opts){let range=`${formatUtcTime(opts.startMs,!0)} \u2013 ${formatUtcTime(opts.endMs,!0)} UTC`;if(opts.points===0)return range;let unit=opts.points===1?"point":"points";return`${range} \xB7 ${opts.points} ${unit} (${granularityLabel(opts.granularity)} each)`}function axisOf(series){let timestamps=new Set;for(let s of series)for(let point of s.timeseries)timestamps.add(point.timestamp);return[...timestamps].sort()}function peakOf(values,axis){let peak=0,peakTs="";for(let i=0;i<axis.length;i++)values[i]>peak&&(peak=values[i],peakTs=axis[i]);return{peak,peakTs}}function indent(rendered){return rendered.split(`
|
|
16
16
|
`).map(line2=>` ${line2}`.trimEnd())}function emptyLine(filtered){return import_chalk3.default.dim(filtered?" No requests match the current filters.":" No requests in this period.")}function retryLabel(seconds){if(seconds<90)return`${seconds}s`;let minutes=Math.round(seconds/60);if(minutes<90)return`${minutes} ${minutes===1?"minute":"minutes"}`;let hours=Math.round(seconds/3600);return`${hours} ${hours===1?"hour":"hours"}`}function unavailableLine(reason,retrySeconds){switch(reason){case"filter":return"Not reported alongside the filters in use.";case"plan":return"Needs Observability Plus.";case"rate-limit":return retrySeconds?`Rate limited by the Observability API. Retry in ${retryLabel(retrySeconds)}.`:"Rate limited by the Observability API.";case"timeout":return"Timed out. Narrow the window with `--since` and try again.";default:return"Couldn't load this table."}}function toTopListRows(rows,field,labelFields){return rows.filter(row=>row.values[field]).map(row=>{let extras=(labelFields??[]).map(f=>row.values[f]).filter(v=>!!v&&v!==row.values[field]);return{value:row.values[field],total:row.total,...extras.length>0?{label:`${row.values[field]} (${extras.join(", ")})`}:{}}})}function topListFetchCount(top,groupBy=[]){let extraFields=Math.max(0,groupBy.length-1);return top+1+extraFields*16}function formatTopList(list7,filtered){let lines=[` ${import_chalk3.default.bold(list7.title)}`];return list7.unavailable?(lines.push(import_chalk3.default.dim(` ${list7.message??unavailableLine(list7.unavailable,list7.retrySeconds)}`)),lines):list7.rows.length===0?(lines.push(emptyLine(filtered)),lines):(lines.push(...indent(table(list7.rows.map(row=>[ellipsizeMiddle(row.label??row.value,MAX_VALUE_WIDTH),formatCount(row.total)]),{align:["l","r"],hsep:3}))),lines)}function formatTrafficTopList(list7,filtered=!1){return formatTopList(list7,filtered).join(`
|
|
17
17
|
`)}function formatGroupedTrendTable(opts){let{axis}=opts.result,needsDate=windowNeedsDate(new Date(opts.result.startTime).getTime(),new Date(opts.result.endTime).getTime()),rows=[[opts.labelHeader,"Trend","Total","Peak","Peak at"].map(h=>import_chalk3.default.bold(import_chalk3.default.cyan(h)))];for(let group of opts.result.groups){let{peak,peakTs}=peakOf(group.series,axis);rows.push([ellipsizeMiddle(group.values[opts.field]||NOT_SET,MAX_TREND_LABEL_WIDTH),generateSparkline(group.series),formatCount(group.total),peak>0?formatCount(peak):"--",peak>0?formatUtcTime(new Date(peakTs).getTime(),needsDate):"--"])}return indent(table(rows,{align:["l","l","r","r","r"],hsep:3}))}function formatTrafficList(opts){let startMs=new Date(opts.startTime).getTime(),endMs=new Date(opts.endTime).getTime(),axis=axisOf(opts.series),lines=[` ${import_chalk3.default.bold("Firewall traffic")} ${import_chalk3.default.dim(windowLabel({startMs,endMs,points:axis.length,granularity:opts.granularity}))}`,"",` ${import_chalk3.default.bold("Requests by Action")}`,formatActionTrendTable(opts.series)],shared=sharedUnavailable(opts.topLists);if(shared)return lines.push(""),lines.push(` ${import_chalk3.default.dim(shared.message??unavailableLine(shared.reason,shared.retrySeconds))}`),lines.push(import_chalk3.default.dim(` No top lists: ${opts.topLists.map(l=>l.title).join(", ")}.`)),lines.push(""),lines.join(`
|
|
18
18
|
`);for(let list7 of opts.topLists)lines.push(""),lines.push(...formatTopList(list7,opts.filtered));return lines.push(""),lines.join(`
|
|
@@ -20,7 +20,7 @@ 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(
|
|
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(ms9){let hours=Math.floor(ms9/MS_PER_HOUR),minutes=Math.floor(ms9%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
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(`
|
|
@@ -166,7 +166,7 @@ ${formatRuleExpanded(modified)}
|
|
|
166
166
|
${formatAlertsList({...sections,from,to})}`),planIssue?output_manager_default.print(` ${FIREWALL_ACTIVITY_PLAN_MESSAGE}
|
|
167
167
|
`):sourceError&&output_manager_default.print(` ${FIREWALL_ALERTS_PARTIAL_ERROR_MESSAGE}
|
|
168
168
|
`),output_manager_default.print(`
|
|
169
|
-
`),0)}catch(e){return failFirewallApi(client,e,{fallback:"Failed to fetch firewall alerts",nextCommand:suggestedCommand,permissionAction:"read firewall alerts",projectName:project.name,timeoutJob:"firewall alerts"})}}var import_chalk35=__toESM(require_source(),1);var EVENTS_TIMEOUT_MS=2e4,TOP_N=5;function apiTimestampMs(apiTimestamp){let pinned=new Date(`${apiTimestamp.replace(" ","T")}Z`).getTime();return Number.isNaN(pinned)?new Date(apiTimestamp).getTime():pinned}function toIso(apiTimestamp){let
|
|
169
|
+
`),0)}catch(e){return failFirewallApi(client,e,{fallback:"Failed to fetch firewall alerts",nextCommand:suggestedCommand,permissionAction:"read firewall alerts",projectName:project.name,timeoutJob:"firewall alerts"})}}var import_chalk35=__toESM(require_source(),1);var EVENTS_TIMEOUT_MS=2e4,TOP_N=5;function apiTimestampMs(apiTimestamp){let pinned=new Date(`${apiTimestamp.replace(" ","T")}Z`).getTime();return Number.isNaN(pinned)?new Date(apiTimestamp).getTime():pinned}function toIso(apiTimestamp){let ms9=apiTimestampMs(apiTimestamp);return Number.isNaN(ms9)?apiTimestamp:new Date(ms9).toISOString()}function toPersistentAction(row){let redacted=isRedacted(row.action_type)||isRedacted(row.public_ip)||isRedacted(row.host);return{startTime:toIso(row.startTime),endTime:toIso(row.endTime),active:row.isActive,action:row.action,actionType:row.action_type,ruleType:isRedacted(row.action_type)?"hidden":row.action_type===SYSTEM_ACTION_TYPE?"system":"custom",...redacted?{redacted:!0}:{},host:row.host,ip:row.public_ip,requests:row.count,...row.ruleId?{ruleId:row.ruleId}:{},...row.ruleName?{ruleName:row.ruleName}:{}}}var SYSTEM_ACTION_TYPE="system-action",REDACTED_VALUE="***";function isRedacted(value){return value===REDACTED_VALUE}function ruleTypeLabel(actionType){return isRedacted(actionType)?"Hidden":actionType===SYSTEM_ACTION_TYPE?"System Rule":"Custom Rule"}var CLIENT_IP_DIMENSION="clientIp",HOST_DIMENSION="requestHostname",PATH_DIMENSION="requestPath";function persistentActionFilter(opts){return andFilters(isRedacted(opts.ip)?void 0:eqFilter(CLIENT_IP_DIMENSION,opts.ip),opts.host&&!isRedacted(opts.host)?eqFilter(HOST_DIMENSION,opts.host):void 0,opts.withPath?nonEmptyFilter(PATH_DIMENSION):void 0)}function aggregateTop(actions,key,top,mitigation){let totals=new Map;for(let action of actions){if(mitigation&&action.action!==mitigation)continue;let name=action[key];!name||isRedacted(name)||totals.set(name,(totals.get(name)??0)+action.count)}return[...totals.entries()].map(([name,count])=>({name,count})).sort((a,b)=>b.count-a.count).slice(0,top)}var PERSISTENT_ACTION_RETENTION_MS={enterprise:7*24*60*60*1e3,other:24*60*60*1e3};function clampPersistentActionWindow(opts){if(opts.planKnown===!1)return{from:opts.from,to:opts.to,empty:!1};let now=opts.now??Date.now(),retentionMs=opts.isEnterprise?PERSISTENT_ACTION_RETENTION_MS.enterprise:PERSISTENT_ACTION_RETENTION_MS.other,earliest=now-retentionMs;if(opts.from.getTime()>=earliest)return{from:opts.from,to:opts.to,empty:!1};let from=new Date(earliest);return{from,to:opts.to,requestedFrom:opts.from,empty:from.getTime()>=opts.to.getTime()}}function retentionLabel(isEnterprise){return isEnterprise?"7 days":"24 hours"}function startedAtMs(row){let ms9=apiTimestampMs(row.startTime);return Number.isNaN(ms9)?0:ms9}async function fetchFirewallPersistentActions(client,opts){let query=new URLSearchParams;query.set("projectId",opts.projectId),query.set("teamId",opts.teamId),query.set("startTimestamp",String(opts.startTime.getTime())),query.set("endTimestamp",String(opts.endTime.getTime())),opts.host&&query.set("hosts",opts.host);let timeoutMs=opts.timeoutMs??EVENTS_TIMEOUT_MS;try{return[...(await client.fetch(`/v1/security/firewall/events?${query.toString()}`,{accountId:opts.teamId,signal:AbortSignal.timeout(timeoutMs)})).actions??[]].sort((a,b)=>{let start=startedAtMs(b)-startedAtMs(a);return start!==0?start:b.count-a.count})}catch(err){throw err instanceof Error&&(err.name==="TimeoutError"||err.name==="AbortError")?new Error(`Timed out after ${Math.round(timeoutMs/1e3)}s waiting for firewall events. Re-run the command \u2014 the next try is usually faster.`):err}}async function getFirewallEvents(client,opts){let actions=await fetchFirewallPersistentActions(client,opts),top=opts.top??TOP_N;return{ips:aggregateTop(actions,"public_ip",top,opts.action),hosts:aggregateTop(actions,"host",top)}}function summarizePersistentActions(actions){let challenging=new Set,blocking=new Set,otherActions=0,withheldActions=0,activeTotal=0;for(let action of actions)if(action.isActive){if(activeTotal+=1,isRedacted(action.public_ip)){action.action==="challenge"||action.action==="deny"?withheldActions+=1:otherActions+=1;continue}action.action==="challenge"?challenging.add(action.public_ip):action.action==="deny"?blocking.add(action.public_ip):otherActions+=1}return activeTotal===0?null:{challengingIps:challenging.size,blockingIps:blocking.size,otherActions,withheldActions,activeTotal}}var PREVIOUS_WINDOW_MS=24*60*60*1e3,GRANULARITY_MINUTES=15,GRANULARITY_MS=GRANULARITY_MINUTES*60*1e3;function isActivityUnavailable2(error){return isAPIError(error)&&error.status===402}function floorToBucket(ms9){return Math.floor(ms9/GRANULARITY_MS)*GRANULARITY_MS}function sumInWindow(series,action,startMs,endMs){let total=0;for(let s of series)if(s.action===action)for(let point of s.timeseries){let ts=new Date(point.timestamp).getTime();ts>=startMs&&ts<endMs&&(total+=point.value)}return total}function reqPerMin(total,windowMs){let minutes=windowMs/6e4;return minutes>0?total/minutes:0}function axisBetween(startMs,endMs,stepMs){let axis=[];for(let t=startMs;t<endMs;t+=stepMs)axis.push(t);return axis}function valuesOnAxis(series,axis){let byTs=new Map;for(let point of series?.timeseries??[])byTs.set(new Date(point.timestamp).getTime(),point.value);return axis.map(t=>byTs.get(t)??0)}async function inspect2(client,argv){let parsed=await parseSubcommandArgs(argv,alertsInspectSubcommand,client,"alerts inspect");if(typeof parsed=="number")return parsed;let alertId=parsed.args[0];if(!alertId)return failFirewall(client,{message:`Alert id is required. Usage: ${withGlobalFlags(client,"firewall alerts inspect <alertid>")}`,nextCommand:"firewall alerts inspect <alertid>",reason:AGENT_REASON.MISSING_ARGUMENTS});let 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;if(!teamId)return failFirewall(client,{message:"Firewall alerts need a team. Run `vercel switch` to select a team or pass --scope <team>.",reason:AGENT_REASON.MISSING_SCOPE});let asJson=!!parsed.flags["--json"],suggestedCommand=`firewall alerts inspect ${alertId}${asJson?" --json":""}`;output_manager_default.spinner(`Fetching alert ${import_chalk35.default.bold(alertId)}`);try{let resolved=await findFirewallAlert(client,{projectId:project.id,teamId,alertId});if(!resolved)return failFirewall(client,{message:`No firewall alert found for "${alertId}". Run ${withGlobalFlags(client,"firewall alerts list")} to view recent alerts.`,nextCommand:"firewall alerts list",reason:AGENT_REASON.NOT_FOUND});let{alert}=resolved,action=alert.action??"deny",anomalyStart=floorToBucket(alert.startedAt),anomalyEnd=Math.max(alert.resolvedAt??Date.now(),anomalyStart+GRANULARITY_MS),chartStart=floorToBucket(anomalyStart-PREVIOUS_WINDOW_MS),chartEnd=anomalyEnd;output_manager_default.spinner(`Fetching traffic for ${import_chalk35.default.bold(alert.title)}`);let eventsIssue,[metrics,events]=await Promise.all([getFirewallMetrics(client,{projectId:project.id,ownerId:teamId,startTime:new Date(chartStart),endTime:new Date(chartEnd),granularity:{minutes:GRANULARITY_MINUTES}}).catch(err=>{if(isActivityUnavailable2(err))return null;throw err}),getFirewallEvents(client,{projectId:project.id,teamId,startTime:new Date(anomalyStart),endTime:new Date(anomalyEnd),action}).catch(err=>{if(isAPIError(err)&&(err.status===401||err.status===403))throw err;return isActivityUnavailable2(err)?(eventsIssue={reason:"plan",message:FIREWALL_ACTIVITY_PLAN_MESSAGE},null):(eventsIssue={reason:"error",message:apiServerMessage(err)||!isAPIError(err)&&err instanceof Error&&err.message||"Couldn't load denied IPs."},null)})]),rates,timeseries;if(metrics){let previousMs=anomalyStart-chartStart,anomalyMs=anomalyEnd-anomalyStart,previousTotal=sumInWindow(metrics.series,action,chartStart,anomalyStart),anomalyTotal=sumInWindow(metrics.series,action,anomalyStart,anomalyEnd),previousReqPerMin=reqPerMin(previousTotal,previousMs),anomalyReqPerMin=reqPerMin(anomalyTotal,anomalyMs);rates={previousReqPerMin,anomalyReqPerMin,multiplier:previousReqPerMin>0?anomalyReqPerMin/previousReqPerMin:null};let axis=axisBetween(chartStart,chartEnd,GRANULARITY_MS),series=metrics.series.find(s=>s.action===action);timeseries={action,startMs:chartStart,endMs:chartEnd,pointCount:axis.length,granularityMinutes:GRANULARITY_MINUTES,values:valuesOnAxis(series,axis)}}let hosts=events?.hosts&&events.hosts.length>0?events.hosts:resolved.hosts,ips=events?.ips;if(asJson)return outputJson(client,{alert,status:alert.resolvedAt?"resolved":"active",previous24h:rates?{reqPerMin:rates.previousReqPerMin}:null,anomaly:rates?{reqPerMin:rates.anomalyReqPerMin,multiplier:rates.multiplier}:null,timeseries:timeseries?{action:timeseries.action,startTime:new Date(timeseries.startMs).toISOString(),endTime:new Date(timeseries.endMs).toISOString(),granularity:{minutes:timeseries.granularityMinutes},points:timeseries.values.map((value,i)=>({timestamp:new Date(timeseries.startMs+i*GRANULARITY_MS).toISOString(),value}))}:null,deniedIps:ips?.map(row=>({ip:row.name,count:row.count}))??null,topHosts:hosts?.map(row=>({host:row.name,count:row.count}))??null,...metrics?{}:{activityUnavailable:{reason:"plan",message:FIREWALL_ACTIVITY_PLAN_MESSAGE}},...eventsIssue?{eventsUnavailable:eventsIssue}:{}}),0;if(output_manager_default.print(`
|
|
170
170
|
${formatAlertInspect({alert,rates,timeseries,ips,hosts})}`),!metrics)output_manager_default.print(` ${FIREWALL_ACTIVITY_PLAN_MESSAGE}
|
|
171
171
|
`);else if(eventsIssue?.reason==="plan")output_manager_default.print(` ${FIREWALL_ACTIVITY_PLAN_MESSAGE}
|
|
172
172
|
`);else if(eventsIssue){let haveHosts=!!(hosts&&hosts.length>0);output_manager_default.print(` Couldn't load denied IPs${haveHosts?"":" and hosts"}.
|
|
@@ -201,7 +201,7 @@ ${formatTrafficTopList(unknownBotTraffic)}
|
|
|
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 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})}trackCliSubcommandCleanup(actual){this.trackCliSubcommand({subcommand:"cleanup",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}
|
|
@@ -286,60 +286,78 @@ ${table2}
|
|
|
286
286
|
${import_chalk67.default.cyan(key.keyValue)}
|
|
287
287
|
`)),key.connectionString&&(output_manager_default.print(`
|
|
288
288
|
`),output_manager_default.log(`${import_chalk67.default.dim("Connection string:")}`),output_manager_default.print(` ${import_chalk67.default.cyan(key.connectionString)}
|
|
289
|
-
`))}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk68=__toESM(require_source(),1);async function sdkKeysRm(client,argv){let telemetryClient=new FlagsSdkKeysRmTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(sdkKeysRemoveSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[hashKey]=args,skipConfirmation=flags["--yes"],projectName=getProjectNameFromFlags(flags);telemetryClient.trackCliArgumentKey(hashKey),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliFlagYes(skipConfirmation);let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.NOT_LINKED,message:"Your codebase is not linked to a project. A user must run `vercel link` in a terminal to continue (this will prompt for login if needed).",next:[{command:buildCommandWithGlobalFlags(client.argv,"link"),when:"run in a terminal to log in if needed and link this codebase to a Vercel project, then retry this command"}]},1),1):(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}=link;try{if(!hashKey){if(client.nonInteractive)return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide the SDK key hash to delete. Run `vercel flags sdk-keys ls` to list keys.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags sdk-keys revoke <hashKey>"),when:"delete an SDK key by hash"},{command:buildCommandWithGlobalFlags(client.argv,"flags sdk-keys ls"),when:"list SDK keys to find the hash"}]},2),2;output_manager_default.spinner("Fetching SDK keys...");let keys=await getSdkKeys(client,project.id);if(output_manager_default.stopSpinner(),keys.length===0)return output_manager_default.log("No SDK keys found"),0;hashKey=await client.input.select({message:"Select an SDK key to delete:",choices:keys.map(key=>({name:`${key.hashKey.slice(0,12)}... (${key.type}, ${key.environment}${key.label?`, ${key.label}`:""})`,value:key.hashKey}))})}if(!skipConfirmation){if(client.nonInteractive)return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`Confirm revoking SDK key ${hashKey.slice(0,12)}... by adding --yes.`,next:[{command:buildCommandWithGlobalFlags(client.argv,`flags sdk-keys revoke ${hashKey} --yes`),when:"confirm and revoke the SDK key"}]},1),1;if(!await client.input.confirm(`Are you sure you want to revoke SDK key ${import_chalk68.default.bold(hashKey.slice(0,12)+"...")}?`,!1))return output_manager_default.log("Aborted"),0}output_manager_default.spinner("Revoking SDK key..."),await deleteSdkKey(client,project.id,hashKey),output_manager_default.stopSpinner(),output_manager_default.success(`SDK key ${import_chalk68.default.bold(hashKey.slice(0,12)+"...")} has been revoked`)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var COMMAND_CONFIG11={ls:getCommandAliases(sdkKeysListSubcommand),add:getCommandAliases(sdkKeysAddSubcommand),revoke:getCommandAliases(sdkKeysRemoveSubcommand)};async function sdkKeys(client){let telemetry=new FlagsSdkKeysTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(sdkKeysSubcommand.options),parsedArgs;try{parsedArgs=parseArguments(client.argv.slice(4),flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let subArgs=parsedArgs.args.slice(0),{subcommand,args,subcommandOriginal}=getSubcommand(subArgs,COMMAND_CONFIG11),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags sdk-keys",subcommand),output_manager_default.print(help(sdkKeysSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:sdkKeysSubcommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags sdk-keys",subcommandOriginal),printHelp(sdkKeysListSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),sdkKeysLs(client,args));case"add":return needHelp?(telemetry.trackCliFlagHelp("flags sdk-keys",subcommandOriginal),printHelp(sdkKeysAddSubcommand),0):(telemetry.trackCliSubcommandCreate(subcommandOriginal),subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags sdk-keys add","flags sdk-keys create"),sdkKeysAdd(client,args));case"revoke":return needHelp?(telemetry.trackCliFlagHelp("flags sdk-keys",subcommandOriginal),printHelp(sdkKeysRemoveSubcommand),0):(telemetry.trackCliSubcommandRevoke(subcommandOriginal),subcommandOriginal!=="revoke"&&warnDeprecatedSubcommand(client,`flags sdk-keys ${subcommandOriginal}`,"flags sdk-keys revoke"),sdkKeysRm(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG11)),output_manager_default.print(help(sdkKeysSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var FlagsConnectionsTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandAdd(actual){this.trackCliSubcommand({subcommand:"add",value:actual})}trackCliSubcommandRemove(actual){this.trackCliSubcommand({subcommand:"rm",value:actual})}},FlagsConnectionsLsTelemetryClient=class extends TelemetryClient{trackCliOptionRole(role){role&&this.trackCliOption({option:"role",value:role})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}},FlagsConnectionsAddTelemetryClient=class extends TelemetryClient{trackCliArgumentConsumerProject(project){project&&this.trackCliArgument({arg:"consumer-project",value:this.redactedValue})}},FlagsConnectionsRmTelemetryClient=class extends TelemetryClient{trackCliArgumentConsumerProject(project){project&&this.trackCliArgument({arg:"consumer-project",value:this.redactedValue})}trackCliFlagYes(yes){yes&&this.trackCliFlag("yes")}};var import_chalk69=__toESM(require_source(),1),import_ms5=__toESM(require_ms(),1);function connectionsUrl(projectId){return`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/connections`}async function getConnections(client,projectId,role){return output_manager_default.debug(`Fetching flags connections for project ${projectId} as ${role}`),(await client.fetch(`${connectionsUrl(projectId)}?role=${role}`)).data}async function createConnection(client,sourceProjectId,consumerProjectId){return output_manager_default.debug(`Connecting project ${consumerProjectId} to the flags of project ${sourceProjectId}`),client.fetch(connectionsUrl(sourceProjectId),{method:"PUT",body:{consumerProjectId}})}async function deleteConnection(client,sourceProjectId,consumerProjectId){output_manager_default.debug(`Disconnecting project ${consumerProjectId} from the flags of project ${sourceProjectId}`),await client.fetch(`${connectionsUrl(sourceProjectId)}/${encodeURIComponent(consumerProjectId)}`,{method:"DELETE",json:!1})}function connectionsCommand(client,template){return buildCommandWithGlobalFlags(client.argv,template,void 0,{preserveProject:!0,excludeFlags:["--yes"]})}function connectionsError(client,payload,exitCode=1){return outputAgentError(client,{...payload,status:AGENT_STATUS.ERROR,next:payload.next?.map(next=>({...next,command:connectionsCommand(client,next.command)}))},exitCode),client.nonInteractive||output_manager_default.fatal(payload.message),exitCode}async function resolveSourceProject(client,projectName){let link=await getLinkedFlagsProject(client,projectName);return link.status==="error"?link.exitCode:link.status==="not_linked"?connectionsError(client,{reason:AGENT_REASON.NOT_LINKED,message:`Your codebase isn't linked to a project on Vercel. Pass --project <name>, or run ${getCommandName("link")} to link it.`,next:[{command:"link",when:"link the project"}]}):(client.config.currentTeam=link.org.type==="team"?link.org.id:void 0,link)}async function resolveConsumerProject(client,link,consumerNameOrId,usage){if(!consumerNameOrId)return connectionsError(client,{reason:AGENT_REASON.MISSING_ARGUMENTS,message:`Please provide the name or ID of the consumer project: ${getCommandName(usage)}`,next:[{command:usage,when:"name the consumer project"}]},2);let consumer;try{consumer=await getProjectByNameOrId(client,consumerNameOrId,link.org.type==="team"?link.org.id:void 0)}catch(err){return printError(err),1}return consumer instanceof ProjectNotFound?connectionsError(client,{reason:AGENT_REASON.NOT_FOUND,message:`Project "${consumerNameOrId}" was not found in team ${link.org.slug}.`}):consumer.id===link.project.id?connectionsError(client,{reason:AGENT_REASON.INVALID_ARGUMENTS,message:"A project cannot be connected to its own flags."},2):consumer}var VALID_ROLES=["source","consumer"];async function connectionsLs(client,argv){let telemetryClient=new FlagsConnectionsLsTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(connectionsListSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{flags}=parsedArgs,json=flags["--json"],role=flags["--role"]??"source",projectName=getProjectNameFromFlags(flags);if(telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionRole(flags["--role"]),telemetryClient.trackCliFlagJson(json),!isRole(role))return connectionsError(client,{reason:AGENT_REASON.INVALID_ARGUMENTS,message:`Invalid role: ${role}. Must be one of: ${VALID_ROLES.join(", ")}`,next:[{command:"flags connections ls --role <source|consumer>",when:"list connections for a valid role"}]},2);let link=await resolveSourceProject(client,projectName);if(typeof link=="number")return link;let{project,org}=link,projectSlugLink=formatProject(org.slug,project.name),accountId=org.type==="team"?org.id:void 0;try{output_manager_default.spinner("Fetching flags connections...");let sorted=(await getConnections(client,project.id,role)).sort((a,b)=>b.createdAt-a.createdAt),names=json?new Map:await resolveProjectNames(client,sorted,role,accountId);if(output_manager_default.stopSpinner(),json)client.stdout.write(`${JSON.stringify({role,connections:sorted},null,2)}
|
|
289
|
+
`))}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk68=__toESM(require_source(),1);async function sdkKeysRm(client,argv){let telemetryClient=new FlagsSdkKeysRmTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(sdkKeysRemoveSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[hashKey]=args,skipConfirmation=flags["--yes"],projectName=getProjectNameFromFlags(flags);telemetryClient.trackCliArgumentKey(hashKey),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliFlagYes(skipConfirmation);let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.NOT_LINKED,message:"Your codebase is not linked to a project. A user must run `vercel link` in a terminal to continue (this will prompt for login if needed).",next:[{command:buildCommandWithGlobalFlags(client.argv,"link"),when:"run in a terminal to log in if needed and link this codebase to a Vercel project, then retry this command"}]},1),1):(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}=link;try{if(!hashKey){if(client.nonInteractive)return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide the SDK key hash to delete. Run `vercel flags sdk-keys ls` to list keys.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags sdk-keys revoke <hashKey>"),when:"delete an SDK key by hash"},{command:buildCommandWithGlobalFlags(client.argv,"flags sdk-keys ls"),when:"list SDK keys to find the hash"}]},2),2;output_manager_default.spinner("Fetching SDK keys...");let keys=await getSdkKeys(client,project.id);if(output_manager_default.stopSpinner(),keys.length===0)return output_manager_default.log("No SDK keys found"),0;hashKey=await client.input.select({message:"Select an SDK key to delete:",choices:keys.map(key=>({name:`${key.hashKey.slice(0,12)}... (${key.type}, ${key.environment}${key.label?`, ${key.label}`:""})`,value:key.hashKey}))})}if(!skipConfirmation){if(client.nonInteractive)return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`Confirm revoking SDK key ${hashKey.slice(0,12)}... by adding --yes.`,next:[{command:buildCommandWithGlobalFlags(client.argv,`flags sdk-keys revoke ${hashKey} --yes`),when:"confirm and revoke the SDK key"}]},1),1;if(!await client.input.confirm(`Are you sure you want to revoke SDK key ${import_chalk68.default.bold(hashKey.slice(0,12)+"...")}?`,!1))return output_manager_default.log("Aborted"),0}output_manager_default.spinner("Revoking SDK key..."),await deleteSdkKey(client,project.id,hashKey),output_manager_default.stopSpinner(),output_manager_default.success(`SDK key ${import_chalk68.default.bold(hashKey.slice(0,12)+"...")} has been revoked`)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var COMMAND_CONFIG11={ls:getCommandAliases(sdkKeysListSubcommand),add:getCommandAliases(sdkKeysAddSubcommand),revoke:getCommandAliases(sdkKeysRemoveSubcommand)};async function sdkKeys(client){let telemetry=new FlagsSdkKeysTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(sdkKeysSubcommand.options),parsedArgs;try{parsedArgs=parseArguments(client.argv.slice(4),flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let subArgs=parsedArgs.args.slice(0),{subcommand,args,subcommandOriginal}=getSubcommand(subArgs,COMMAND_CONFIG11),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags sdk-keys",subcommand),output_manager_default.print(help(sdkKeysSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:sdkKeysSubcommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags sdk-keys",subcommandOriginal),printHelp(sdkKeysListSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),sdkKeysLs(client,args));case"add":return needHelp?(telemetry.trackCliFlagHelp("flags sdk-keys",subcommandOriginal),printHelp(sdkKeysAddSubcommand),0):(telemetry.trackCliSubcommandCreate(subcommandOriginal),subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags sdk-keys add","flags sdk-keys create"),sdkKeysAdd(client,args));case"revoke":return needHelp?(telemetry.trackCliFlagHelp("flags sdk-keys",subcommandOriginal),printHelp(sdkKeysRemoveSubcommand),0):(telemetry.trackCliSubcommandRevoke(subcommandOriginal),subcommandOriginal!=="revoke"&&warnDeprecatedSubcommand(client,`flags sdk-keys ${subcommandOriginal}`,"flags sdk-keys revoke"),sdkKeysRm(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG11)),output_manager_default.print(help(sdkKeysSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var import_chalk69=__toESM(require_source(),1),import_ms5=__toESM(require_ms(),1),import_pluralize4=__toESM(require_pluralize(),1);var FLAG_SLUG_PATTERN=/^[A-Za-z0-9_.-]+$/,AFTER_PULL_REQUEST="After the pull request is merged and deployed to production";function hasPendingPullRequest(cleanup2){return!!(cleanup2.run?.result?.pullRequestUrl&&cleanup2.recommendations.some(recommendation=>recommendation.action==="review"&&!recommendation.checkId))}function getCleanupCommand(recommendation,{slug,state,checks,pendingPullRequest=!1}){let flag=FLAG_SLUG_PATTERN.test(slug)?slug:"<FLAG>",evaluationsArgs=["flags","evaluations",flag,"--since","3d","--group-by","variant"];switch(recommendation.action){case"remove_from_code":return{};case"start_agent_cleanup":return{args:["flags","cleanup",flag,"--vercel-agent"],...recommendation.requiresConfirmation?{when:"Only after a human confirms cleanup despite the checks that did not pass"}:{}};case"archive":return{args:["flags","archive",flag],...pendingPullRequest?{when:AFTER_PULL_REQUEST}:{}};case"delete":return{args:["flags","delete",flag],when:pendingPullRequest?`${AFTER_PULL_REQUEST}, and only after a human approves: deletion is permanent`:"Only after a human approves: deletion is permanent"};case"wait":return{args:["flags","cleanup",flag],...recommendation.after!==void 0?{when:`After ${new Date(recommendation.after).toISOString()}`}:{}};case"review":break}switch(recommendation.checkId){case"intent":return{args:["flags","inspect",flag]};case"configuration":return{args:["flags","set",flag,"--environment","production","--variant","<VARIANT>"],when:"Only after a human chooses the value production keeps. Replace <VARIANT> with that variant"};case"evaluations":return{args:evaluationsArgs};case"deployment":return checks.find(check=>check.id==="deployment")?.status==="unavailable"?{args:["flags","cleanup",flag]}:{args:state==="archived"?["flags","inspect",flag]:evaluationsArgs.concat("--group-by","client")};default:return{}}}function flagCleanupPath(projectId,flagId){return`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/flags/${encodeURIComponent(flagId)}/cleanup`}async function getFlagCleanup(client,projectId,flagId){return client.fetch(flagCleanupPath(projectId,flagId))}async function getFlagCleanupRun(client,projectId,flagId){let{run}=await client.fetch(`${flagCleanupPath(projectId,flagId)}/run`);return run}async function startFlagCleanup(client,projectId,flagId,{force=!1}={}){let{run}=await client.fetch(`${flagCleanupPath(projectId,flagId)}${force?"?force=true":""}`,{method:"POST",body:{},retry:{retries:0}});return run}var FlagsCleanupTelemetryClient=class extends TelemetryClient{trackCliArgumentFlag(flag){flag&&this.trackCliArgument({arg:"flag",value:this.redactedValue})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}trackCliFlagVercelAgent(vercelAgent){vercelAgent&&this.trackCliFlag("vercel-agent")}trackCliFlagForce(force){force&&this.trackCliFlag("force")}trackCliFlagWait(wait){wait&&this.trackCliFlag("wait")}trackCliOptionTimeout(timeout){timeout&&this.trackCliOption({option:"timeout",value:this.redactedValue})}};var DEFAULT_WAIT_TIMEOUT="15m",WAIT_POLL_INTERVAL_MS=5e3;async function cleanup(client,argv){let telemetryClient=new FlagsCleanupTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(cleanupSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg]=args,json=flags["--json"],useVercelAgent=flags["--vercel-agent"],force=flags["--force"],wait=flags["--wait"],timeoutArg=flags["--timeout"],projectName=getProjectNameFromFlags(flags);if(!flagArg)return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Missing required argument: flag.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags cleanup <FLAG>"),when:"Replace <FLAG> with a flag slug or ID from `flags list`"}]}),output_manager_default.error(`Missing required argument: flag. Usage: ${getCommandName("flags cleanup <flag>")}`),2;if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliFlagJson(json),telemetryClient.trackCliFlagVercelAgent(useVercelAgent),telemetryClient.trackCliFlagForce(force),telemetryClient.trackCliFlagWait(wait),telemetryClient.trackCliOptionTimeout(timeoutArg),timeoutArg!==void 0&&!wait)return output_manager_default.error("--timeout requires --wait."),2;let timeout=(0,import_ms5.default)(timeoutArg??DEFAULT_WAIT_TIMEOUT);if(typeof timeout!="number"||timeout<=0)return output_manager_default.error(`Invalid timeout "${timeoutArg}". Pass a duration such as 10m or 1h.`),2;let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.NOT_LINKED,message:"Your codebase isn't linked to a project on Vercel. Pass --project, or link it first.",next:[{command:buildCommandWithGlobalFlags(client.argv,"link"),when:"link the project"}]},1),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,checkStamp=stamp_default(),flag;try{flag=await getFlag(client,project.id,flagArg)}catch(err){return printError(err),1}json||output_manager_default.spinner(`Checking ${flag.slug} for cleanup`);let cleanup2;try{cleanup2=await getFlagCleanup(client,project.id,flag.id)}catch(err){return isAPIError(err)&&err.status===404?(output_manager_default.error("Flag cleanup isn't available for this team yet."),1):(printError(err),1)}finally{output_manager_default.stopSpinner()}let startedRun=null,existingRun=useVercelAgent&&!force&&cleanup2.run?.result?.pullRequestUrl?cleanup2.run:null;if(useVercelAgent&&!existingRun){let run=await startVercelAgentCleanup(client,project.id,flag,cleanup2.run,json);if(typeof run=="number")return run;startedRun=run,cleanup2=withStartedRun(cleanup2,run)}let exitCode=0;if(wait){let waited=await waitForRun(client,project.id,flag,cleanup2,{timeout,json});cleanup2=waited.cleanup,exitCode=waited.exitCode}if(json){let recommendations2=formatRecommendations(client,flag,cleanup2);return existingRun&&recommendations2.push(getRetryRecommendation(client,flag.slug)),client.stdout.write(`${JSON.stringify({flag:{id:flag.id,slug:flag.slug,kind:flag.kind,state:flag.state,permanent:flag.permanent??!1},project:{id:project.id,name:project.name},ready:cleanup2.ready,checks:cleanup2.checks,replacement:cleanup2.replacement,run:cleanup2.run,...startedRun?{outcome:"started"}:existingRun?{outcome:"unchanged"}:{},recommendations:recommendations2,next:recommendations2.flatMap(({command,when})=>command?[when?{command,when}:{command}]:[])},null,2)}
|
|
290
|
+
`),exitCode}output_manager_default.log(`Cleanup checks for ${import_chalk69.default.bold(flag.slug)} in ${formatProject(org.slug,project.name)} ${import_chalk69.default.gray(checkStamp())}`),client.stdout.write(`
|
|
291
|
+
${formatChecksTable(cleanup2.checks)}
|
|
292
|
+
`),printSummary(cleanup2),startedRun!==null&&cleanup2.run?.status==="running"||printVercelAgent(cleanup2.run,!1);let choice=null;if(existingRun&&canPromptOnTerminal(client)){output_manager_default.print(`
|
|
293
|
+
`);try{await client.withEscapePromptCancellation(()=>client.input.confirm("Vercel Agent already opened a pull request for this flag. Start a new cleanup?",!1))&&(choice="agent")}catch(err){if(isPromptCanceledError(err))return output_manager_default.print(` Canceled.
|
|
294
|
+
`),0;throw err}}else if(!useVercelAgent&&canPromptOnTerminal(client)&&cleanup2.recommendations.some(recommendation=>recommendation.action==="start_agent_cleanup")){output_manager_default.print(`
|
|
295
|
+
`);try{choice=await promptCleanupChoice(client,flag.slug,cleanup2.ready)}catch(err){if(isPromptCanceledError(err))return output_manager_default.print(` Canceled.
|
|
296
|
+
`),0;throw err}}if(choice==="agent"){let run=await startVercelAgentCleanup(client,project.id,flag,cleanup2.run,json);if(typeof run=="number")return run;if(startedRun=run,cleanup2=withStartedRun(cleanup2,run),wait){let waited=await waitForRun(client,project.id,flag,cleanup2,{timeout,json});cleanup2=waited.cleanup,exitCode=waited.exitCode,cleanup2.run?.status!=="running"&&printVercelAgent(cleanup2.run,!1)}}let recommendations=formatRecommendations(client,flag,cleanup2).filter(recommendation=>choice!=="manual"||recommendation.action!=="start_agent_cleanup");return existingRun&&!startedRun&&recommendations.push(getRetryRecommendation(client,flag.slug)),startedRun&&cleanup2.run?.status==="running"&&printVercelAgent(cleanup2.run,!0),printRecommendations(recommendations),startedRun&&(!client.stdout.isTTY||client.nonInteractive)&&client.stdout.write(`${startedRun.id}
|
|
297
|
+
`),exitCode}async function promptCleanupChoice(client,slug,ready){return client.withEscapePromptCancellation(()=>client.input.select({message:`How do you want to clean up ${slug}?`,choices:[{name:"Manually",value:"manual",description:ready?"Show the steps to remove the flag from code":"Show what to review before removing the flag"},{name:"With Vercel Agent",value:"agent",description:ready?"Vercel Agent removes the flag from code and opens a draft pull request":"Vercel Agent verifies the safe value, removes the flag from code, and opens a draft pull request"}]}))}async function startVercelAgentCleanup(client,projectId,flag,latestRun,json){if(latestRun?.status==="running")return output_manager_default.error(`A Vercel Agent cleanup is already running for this flag. Run ${getCommandName(`flags cleanup ${quoteArg(flag.slug)}`)} to check on it.`),1;try{return json||output_manager_default.spinner(`Starting Vercel Agent cleanup for ${flag.slug}`),await startFlagCleanup(client,projectId,flag.id,{force:latestRun?.status==="completed"})}catch(err){return printError(err),1}finally{output_manager_default.stopSpinner()}}function withStartedRun(cleanup2,run){return{...cleanup2,run,recommendations:[{action:"wait",message:"Vercel Agent cleanup is running. Check again later for its pull request."}]}}async function waitForRun(client,projectId,flag,cleanup2,{timeout,json}){let run=cleanup2.run;if(run?.status!=="running")return{cleanup:cleanup2,exitCode:run?.status==="failed"?1:0};let until=Date.now()+timeout;json||output_manager_default.spinner("Waiting for Vercel Agent cleanup to finish");try{for(;run?.status==="running";){if(Date.now()>=until)return output_manager_default.stopSpinner(),output_manager_default.warning(`Stopped waiting after ${(0,import_ms5.default)(timeout,{long:!0})}. Vercel Agent cleanup is still running. Run ${getCommandName(`flags cleanup ${quoteArg(flag.slug)} --wait`)} to keep waiting.`),{cleanup:{...cleanup2,run},exitCode:1};await sleep(WAIT_POLL_INTERVAL_MS),run=await getFlagCleanupRun(client,projectId,flag.id)}}catch(err){return output_manager_default.stopSpinner(),printError(err),{cleanup:{...cleanup2,run},exitCode:1}}finally{output_manager_default.stopSpinner()}let finished={...cleanup2,run};try{finished=await getFlagCleanup(client,projectId,flag.id)}catch(err){output_manager_default.debug(`Could not reload the flag cleanup: ${err instanceof Error?err.message:String(err)}`)}return{cleanup:finished,exitCode:run?.status==="failed"?1:0}}function getRetryRecommendation(client,slug){return{action:"start_agent_cleanup",message:"Start a new Vercel Agent cleanup instead.",command:buildCommandWithGlobalFlags(client.argv,`flags cleanup ${quoteArg(slug)} --vercel-agent --force`,packageName,{preserveProject:!0}),when:"Only if the existing pull request should be replaced"}}function formatRecommendations(client,flag,cleanup2){let pendingPullRequest=hasPendingPullRequest(cleanup2);return cleanup2.recommendations.map(recommendation=>{let{args:commandArgs,when}=getCleanupCommand(recommendation,{slug:flag.slug,state:flag.state,checks:cleanup2.checks,pendingPullRequest});return{...recommendation,command:commandArgs?buildCommandWithGlobalFlags(client.argv,commandArgs.map(quoteArg).join(" "),packageName,{preserveProject:!0}):null,when:when??null}})}function formatChecksTable(checks){return formatTable(["Check","Status","Result"],["l","l","l"],[{rows:checks.map(check=>[import_chalk69.default.bold(formatCheckName(check.id)),formatCheckStatus(check.status),check.message])}])}function printSummary(result){if(output_manager_default.print(`
|
|
298
|
+
`),result.ready){output_manager_default.print(` Ready for cleanup.${result.replacement?` Replace the flag with ${formatReplacement(result.replacement)}.`:""}
|
|
299
|
+
`);return}let pending=result.checks.filter(check=>check.status!=="passed");output_manager_default.warning(`Not ready for cleanup: ${(0,import_pluralize4.default)("check",pending.length,!0)} did not pass.`),result.replacement&&output_manager_default.print(` ${result.replacement.source==="production"?"Production serves":"Code defaults to"} ${formatReplacement(result.replacement)}.
|
|
300
|
+
`)}function printVercelAgent(run,started){if(!run)return;if(output_manager_default.print(`
|
|
301
|
+
`),started){output_manager_default.print(` Started Vercel Agent cleanup. It opens a draft pull request when it finishes.
|
|
302
|
+
`),printAlignedLabel("Run ID",run.id);return}let pullRequestUrl=run.result?.pullRequestUrl;printAlignedLabel("Vercel Agent",pullRequestUrl?`Opened ${remoteText(pullRequestUrl)}`:run.status==="running"?"Cleanup running":run.status==="failed"?"Last cleanup failed":"Last cleanup finished without a pull request")}function printRecommendations(recommendations){if(recommendations.length!==0){output_manager_default.print(`
|
|
303
|
+
Next steps:
|
|
304
|
+
`);for(let recommendation of recommendations){let when=recommendation.when?import_chalk69.default.gray(` (${recommendation.when})`):"";output_manager_default.print(` ${recommendation.message}${when}
|
|
305
|
+
`);for(let[index,step]of(recommendation.steps??[]).entries())output_manager_default.print(` ${index+1}. ${step}
|
|
306
|
+
`);recommendation.command&&output_manager_default.print(` ${import_chalk69.default.cyan(recommendation.command)}
|
|
307
|
+
`)}}}function formatReplacement(replacement){let value=remoteText(formatVariantValue(replacement.value));return replacement.label?`${value} (${remoteText(replacement.label)})`:value}function formatCheckName(id){switch(id){case"intent":return"Intent";case"configuration":return"Configuration";case"archived-state":return"State";case"deployment":return"Deployment";case"evaluations":return"Evaluations"}}function formatCheckStatus(status2){switch(status2){case"passed":return import_chalk69.default.green("passed");case"warning":return import_chalk69.default.yellow("warning");case"unavailable":return import_chalk69.default.gray("unavailable")}}var FlagsConnectionsTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandAdd(actual){this.trackCliSubcommand({subcommand:"add",value:actual})}trackCliSubcommandRemove(actual){this.trackCliSubcommand({subcommand:"rm",value:actual})}},FlagsConnectionsLsTelemetryClient=class extends TelemetryClient{trackCliOptionRole(role){role&&this.trackCliOption({option:"role",value:role})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}},FlagsConnectionsAddTelemetryClient=class extends TelemetryClient{trackCliArgumentConsumerProject(project){project&&this.trackCliArgument({arg:"consumer-project",value:this.redactedValue})}},FlagsConnectionsRmTelemetryClient=class extends TelemetryClient{trackCliArgumentConsumerProject(project){project&&this.trackCliArgument({arg:"consumer-project",value:this.redactedValue})}trackCliFlagYes(yes){yes&&this.trackCliFlag("yes")}};var import_chalk70=__toESM(require_source(),1),import_ms6=__toESM(require_ms(),1);function connectionsUrl(projectId){return`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/connections`}async function getConnections(client,projectId,role){return output_manager_default.debug(`Fetching flags connections for project ${projectId} as ${role}`),(await client.fetch(`${connectionsUrl(projectId)}?role=${role}`)).data}async function createConnection(client,sourceProjectId,consumerProjectId){return output_manager_default.debug(`Connecting project ${consumerProjectId} to the flags of project ${sourceProjectId}`),client.fetch(connectionsUrl(sourceProjectId),{method:"PUT",body:{consumerProjectId}})}async function deleteConnection(client,sourceProjectId,consumerProjectId){output_manager_default.debug(`Disconnecting project ${consumerProjectId} from the flags of project ${sourceProjectId}`),await client.fetch(`${connectionsUrl(sourceProjectId)}/${encodeURIComponent(consumerProjectId)}`,{method:"DELETE",json:!1})}function connectionsCommand(client,template){return buildCommandWithGlobalFlags(client.argv,template,void 0,{preserveProject:!0,excludeFlags:["--yes"]})}function connectionsError(client,payload,exitCode=1){return outputAgentError(client,{...payload,status:AGENT_STATUS.ERROR,next:payload.next?.map(next=>({...next,command:connectionsCommand(client,next.command)}))},exitCode),client.nonInteractive||output_manager_default.fatal(payload.message),exitCode}async function resolveSourceProject(client,projectName){let link=await getLinkedFlagsProject(client,projectName);return link.status==="error"?link.exitCode:link.status==="not_linked"?connectionsError(client,{reason:AGENT_REASON.NOT_LINKED,message:`Your codebase isn't linked to a project on Vercel. Pass --project <name>, or run ${getCommandName("link")} to link it.`,next:[{command:"link",when:"link the project"}]}):(client.config.currentTeam=link.org.type==="team"?link.org.id:void 0,link)}async function resolveConsumerProject(client,link,consumerNameOrId,usage){if(!consumerNameOrId)return connectionsError(client,{reason:AGENT_REASON.MISSING_ARGUMENTS,message:`Please provide the name or ID of the consumer project: ${getCommandName(usage)}`,next:[{command:usage,when:"name the consumer project"}]},2);let consumer;try{consumer=await getProjectByNameOrId(client,consumerNameOrId,link.org.type==="team"?link.org.id:void 0)}catch(err){return printError(err),1}return consumer instanceof ProjectNotFound?connectionsError(client,{reason:AGENT_REASON.NOT_FOUND,message:`Project "${consumerNameOrId}" was not found in team ${link.org.slug}.`}):consumer.id===link.project.id?connectionsError(client,{reason:AGENT_REASON.INVALID_ARGUMENTS,message:"A project cannot be connected to its own flags."},2):consumer}var VALID_ROLES=["source","consumer"];async function connectionsLs(client,argv){let telemetryClient=new FlagsConnectionsLsTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(connectionsListSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{flags}=parsedArgs,json=flags["--json"],role=flags["--role"]??"source",projectName=getProjectNameFromFlags(flags);if(telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionRole(flags["--role"]),telemetryClient.trackCliFlagJson(json),!isRole(role))return connectionsError(client,{reason:AGENT_REASON.INVALID_ARGUMENTS,message:`Invalid role: ${role}. Must be one of: ${VALID_ROLES.join(", ")}`,next:[{command:"flags connections ls --role <source|consumer>",when:"list connections for a valid role"}]},2);let link=await resolveSourceProject(client,projectName);if(typeof link=="number")return link;let{project,org}=link,projectSlugLink=formatProject(org.slug,project.name),accountId=org.type==="team"?org.id:void 0;try{output_manager_default.spinner("Fetching flags connections...");let sorted=(await getConnections(client,project.id,role)).sort((a,b)=>b.createdAt-a.createdAt),names=json?new Map:await resolveProjectNames(client,sorted,role,accountId);if(output_manager_default.stopSpinner(),json)client.stdout.write(`${JSON.stringify({role,connections:sorted},null,2)}
|
|
290
308
|
`);else if(sorted.length===0)role==="source"?(output_manager_default.log(`No project may read the flags of ${projectSlugLink}`),output_manager_default.log(`
|
|
291
|
-
Connect one with: ${
|
|
292
|
-
Ask an owner of the source project to run: ${getCommandName(`flags connections add ${quoteArg(project.name)} --project <source-project>`)}`));else{let count=`${
|
|
309
|
+
Connect one with: ${import_chalk70.default.cyan(connectionsCommand(client,"flags connections add <consumer-project>"))}`)):(output_manager_default.log(`${projectSlugLink} may not read the flags of any project`),output_manager_default.log(`
|
|
310
|
+
Ask an owner of the source project to run: ${getCommandName(`flags connections add ${quoteArg(project.name)} --project <source-project>`)}`));else{let count=`${import_chalk70.default.bold(sorted.length)} project${sorted.length===1?"":"s"}`;output_manager_default.log(role==="source"?`${count} may read the flags of ${projectSlugLink}`:`${projectSlugLink} may read the flags of ${count}`),printConnectionsTable(sorted,role,names)}}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function isRole(value){return VALID_ROLES.includes(value)}function otherProjectId(connection,role){return role==="source"?connection.consumerProjectId:connection.sourceProjectId}async function resolveProjectNames(client,connections2,role,accountId){let ids=[...new Set(connections2.map(c=>otherProjectId(c,role)))],entries=await Promise.all(ids.map(async id=>{try{let project=await getProjectByNameOrId(client,id,accountId);return[id,project instanceof Error?id:project.name]}catch{return[id,id]}}));return new Map(entries)}function printConnectionsTable(connections2,role,names){let now=Date.now(),header=role==="source"?"Consumer Project":"Source Project",rows=connections2.map(connection=>{let id=otherProjectId(connection,role),name=names.get(id)??id;return[name===id?id:`${name} ${import_chalk70.default.dim(id)}`,import_chalk70.default.dim(connection.createdBy),(0,import_ms6.default)(now-connection.createdAt)+" ago"]}),table2=formatTable([header,"Created By","Created"],["l","l","l"],[{name:"",rows}]);output_manager_default.print(`
|
|
293
311
|
${table2}
|
|
294
|
-
`)}var
|
|
295
|
-
`),output_manager_default.print(` ${
|
|
296
|
-
`),0}var
|
|
297
|
-
Create one with: ${getCommandName('flags segments create beta-users --label "Beta users" --add include:user.id=user_123')}`)):(output_manager_default.log(`${(0,
|
|
298
|
-
`)}function printSegmentsTable(segments2){let headers=["Slug","Label","Rules","Values","Used By","Updated"],now=Date.now(),rows=segments2.map(segment=>[
|
|
312
|
+
`)}var import_chalk71=__toESM(require_source(),1);async function connectionsAdd(client,argv){let telemetryClient=new FlagsConnectionsAddTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(connectionsAddSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[consumerNameOrId]=args,projectName=getProjectNameFromFlags(flags);telemetryClient.trackCliArgumentConsumerProject(consumerNameOrId),telemetryClient.trackCliOptionProject(projectName);let link=await resolveSourceProject(client,projectName);if(typeof link=="number")return link;let consumer=await resolveConsumerProject(client,link,consumerNameOrId,"flags connections add <consumer-project>");if(typeof consumer=="number")return consumer;let source=link.project;try{output_manager_default.spinner("Connecting project..."),await createConnection(client,source.id,consumer.id),output_manager_default.stopSpinner()}catch(err){return output_manager_default.stopSpinner(),isAPIError(err)&&err.code==="flags_project_connection_exists"?(output_manager_default.log(`${import_chalk71.default.bold(consumer.name)} already may read the flags of ${import_chalk71.default.bold(source.name)}`),0):(printError(err),1)}return output_manager_default.success(`${import_chalk71.default.bold(consumer.name)} may now read the flags of ${import_chalk71.default.bold(source.name)}`),output_manager_default.print(`
|
|
313
|
+
`),output_manager_default.print(` ${import_chalk71.default.dim("Source project ID:")} ${source.id}
|
|
314
|
+
`),0}var import_chalk72=__toESM(require_source(),1);async function connectionsRm(client,argv){let telemetryClient=new FlagsConnectionsRmTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(connectionsRemoveSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[consumerNameOrId]=args,skipConfirmation=flags["--yes"],projectName=getProjectNameFromFlags(flags);telemetryClient.trackCliArgumentConsumerProject(consumerNameOrId),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliFlagYes(skipConfirmation);let link=await resolveSourceProject(client,projectName);if(typeof link=="number")return link;let consumer=await resolveConsumerProject(client,link,consumerNameOrId,"flags connections remove <consumer-project>");if(typeof consumer=="number")return consumer;let source=link.project;if(!skipConfirmation){if(client.nonInteractive)return connectionsError(client,{reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`Confirm removing the connection of ${consumer.name} to the flags of ${source.name} by adding --yes.`,next:[{command:`flags connections remove ${quoteArg(consumerNameOrId)} --yes`,when:"confirm and remove the connection"}]});if(!await client.input.confirm(`Stop ${import_chalk72.default.bold(consumer.name)} from reading the flags of ${import_chalk72.default.bold(source.name)}? Its deployments lose access right away.`,!1))return output_manager_default.log("Aborted"),0}try{output_manager_default.spinner("Removing connection..."),await deleteConnection(client,source.id,consumer.id),output_manager_default.stopSpinner(),output_manager_default.success(`${import_chalk72.default.bold(consumer.name)} may no longer read the flags of ${import_chalk72.default.bold(source.name)}`)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var COMMAND_CONFIG12={ls:getCommandAliases(connectionsListSubcommand),add:getCommandAliases(connectionsAddSubcommand),rm:getCommandAliases(connectionsRemoveSubcommand)};async function connections(client){let telemetry=new FlagsConnectionsTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(connectionsSubcommand.options),parsedArgs;try{parsedArgs=parseArguments(client.argv.slice(4),flagsSpecification,{permissive:!0})}catch(err){return printError(err),1}let subArgs=parsedArgs.args.slice(0),{subcommand,args,subcommandOriginal}=getSubcommand(subArgs,COMMAND_CONFIG12),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags connections",subcommand),output_manager_default.print(help(connectionsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:connectionsSubcommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags connections",subcommandOriginal),printHelp(connectionsListSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),connectionsLs(client,args));case"add":return needHelp?(telemetry.trackCliFlagHelp("flags connections",subcommandOriginal),printHelp(connectionsAddSubcommand),0):(telemetry.trackCliSubcommandAdd(subcommandOriginal),connectionsAdd(client,args));case"rm":return needHelp?(telemetry.trackCliFlagHelp("flags connections",subcommandOriginal),printHelp(connectionsRemoveSubcommand),0):(telemetry.trackCliSubcommandRemove(subcommandOriginal),connectionsRm(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG12)),output_manager_default.print(help(connectionsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var FlagsSegmentsTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandInspect(actual){this.trackCliSubcommand({subcommand:"inspect",value:actual})}trackCliSubcommandCreate(actual){this.trackCliSubcommand({subcommand:"create",value:actual})}trackCliSubcommandUpdate(actual){this.trackCliSubcommand({subcommand:"update",value:actual})}trackCliSubcommandDelete(actual){this.trackCliSubcommand({subcommand:"delete",value:actual})}},FlagsSegmentsLsTelemetryClient=class extends TelemetryClient{trackCliFlagJson(json){json&&this.trackCliFlag("json")}},FlagsSegmentsInspectTelemetryClient=class extends TelemetryClient{trackCliArgumentSegment(segment){segment&&this.trackCliArgument({arg:"segment",value:this.redactedValue})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}},FlagsSegmentsCreateTelemetryClient=class extends TelemetryClient{trackCliArgumentSlug(slug){slug&&this.trackCliArgument({arg:"slug",value:this.redactedValue})}trackCliOptionLabel(label){label&&this.trackCliOption({option:"label",value:this.redactedValue})}trackCliOptionDescription(description){description&&this.trackCliOption({option:"description",value:this.redactedValue})}trackCliOptionHint(hint){hint&&this.trackCliOption({option:"hint",value:this.redactedValue})}trackCliOptionData(data){data&&this.trackCliOption({option:"data",value:this.redactedValue})}trackCliOptionAdd(add3){add3?.length&&this.trackCliOption({option:"add",value:this.redactedValue})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}},FlagsSegmentsUpdateTelemetryClient=class extends TelemetryClient{trackCliArgumentSegment(segment){segment&&this.trackCliArgument({arg:"segment",value:this.redactedValue})}trackCliOptionLabel(label){label&&this.trackCliOption({option:"label",value:this.redactedValue})}trackCliOptionDescription(description){description&&this.trackCliOption({option:"description",value:this.redactedValue})}trackCliOptionHint(hint){hint&&this.trackCliOption({option:"hint",value:this.redactedValue})}trackCliOptionData(data){data&&this.trackCliOption({option:"data",value:this.redactedValue})}trackCliOptionAdd(add3){add3?.length&&this.trackCliOption({option:"add",value:this.redactedValue})}trackCliOptionRemove(remove3){remove3?.length&&this.trackCliOption({option:"remove",value:this.redactedValue})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}},FlagsSegmentsRmTelemetryClient=class extends TelemetryClient{trackCliArgumentSegment(segment){segment&&this.trackCliArgument({arg:"segment",value:this.redactedValue})}trackCliFlagYes(yes){yes&&this.trackCliFlag("yes")}};var import_chalk73=__toESM(require_source(),1),import_ms7=__toESM(require_ms(),1),import_pluralize5=__toESM(require_pluralize(),1);function getSegmentsUrl(projectId,withMetadata=!1){let url=`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/segments`;return withMetadata?`${url}?withMetadata=true`:url}function getSegmentUrl(projectId,segmentIdOrSlug,withMetadata=!1){let url=`${getSegmentsUrl(projectId)}/${encodeURIComponent(segmentIdOrSlug)}`;return withMetadata?`${url}?withMetadata=true`:url}async function getSegments(client,projectId,withMetadata=!1){return output_manager_default.debug(`Fetching feature flag segments for project ${projectId}`),(await client.fetch(getSegmentsUrl(projectId,withMetadata))).data}async function getSegment(client,projectId,segmentIdOrSlug,withMetadata=!0){return output_manager_default.debug(`Fetching feature flag segment ${segmentIdOrSlug} for project ${projectId}`),client.fetch(getSegmentUrl(projectId,segmentIdOrSlug,withMetadata))}async function createSegment(client,projectId,request){let url=getSegmentsUrl(projectId);return output_manager_default.debug(`Creating feature flag segment ${request.slug} for project ${projectId}`),output_manager_default.debug(`API endpoint: PUT ${url}`),client.fetch(url,{method:"PUT",body:request})}async function updateSegment(client,projectId,segmentIdOrSlug,request){let url=getSegmentUrl(projectId,segmentIdOrSlug);return output_manager_default.debug(`Updating feature flag segment ${segmentIdOrSlug} for project ${projectId}`),client.fetch(url,{method:"PATCH",body:request})}async function deleteSegment(client,projectId,segmentIdOrSlug){let url=getSegmentUrl(projectId,segmentIdOrSlug);output_manager_default.debug(`Deleting feature flag segment ${segmentIdOrSlug} for project ${projectId}`),await client.fetch(url,{method:"DELETE"})}async function segmentsLs(client,argv){let telemetryClient=new FlagsSegmentsLsTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(segmentsListSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{flags}=parsedArgs,json=flags["--json"],projectName=getProjectNameFromFlags(flags);telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliFlagJson(json);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 feature flag segments for ${projectSlugLink}`);try{let segments2=await getSegments(client,project.id,!0);output_manager_default.stopSpinner();let sortedSegments=segments2.sort((a,b)=>b.updatedAt-a.updatedAt);json?outputJson5(client,sortedSegments):segments2.length===0?(output_manager_default.log(`No feature flag segments found for ${projectSlugLink} ${import_chalk73.default.gray(lsStamp())}`),output_manager_default.log(`
|
|
315
|
+
Create one with: ${getCommandName('flags segments create beta-users --label "Beta users" --add include:user.id=user_123')}`)):(output_manager_default.log(`${(0,import_pluralize5.default)("feature flag segment",segments2.length,!0)} found for ${projectSlugLink} ${import_chalk73.default.gray(lsStamp())}`),printSegmentsTable(sortedSegments))}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function outputJson5(client,segments2){let jsonOutput={segments:segments2.map(segment=>({id:segment.id,slug:segment.slug,label:segment.label,description:segment.description??null,data:segment.data,hint:segment.hint,usedByFlags:segment.usedByFlags??[],usedBySegments:segment.usedBySegments??[],createdAt:segment.createdAt,updatedAt:segment.updatedAt}))};client.stdout.write(`${JSON.stringify(jsonOutput,null,2)}
|
|
316
|
+
`)}function printSegmentsTable(segments2){let headers=["Slug","Label","Rules","Values","Used By","Updated"],now=Date.now(),rows=segments2.map(segment=>[import_chalk73.default.bold(segment.slug),segment.label,String(segment.data.rules?.length??0),String(countSegmentValues(segment)),String((segment.usedByFlags?.length??0)+(segment.usedBySegments?.length??0)),(0,import_ms7.default)(now-segment.updatedAt)+" ago"]),table2=formatTable(headers,["l","l","r","r","r","l"],[{name:"",rows}]);output_manager_default.print(`
|
|
299
317
|
${table2}
|
|
300
|
-
`)}function countSegmentValues(segment){return countMembershipValues(segment.data.include)+countMembershipValues(segment.data.exclude)}function countMembershipValues(map){return map?Object.values(map).reduce((sum,attributes)=>sum+Object.values(attributes).reduce((attributeSum,values)=>attributeSum+values.length,0),0):0}var
|
|
301
|
-
Feature flag segment ${
|
|
302
|
-
`),output_manager_default.print(` ${
|
|
303
|
-
`),output_manager_default.print(` ${
|
|
304
|
-
`),segment.description&&output_manager_default.print(` ${
|
|
305
|
-
`),segment.usedByFlags&&output_manager_default.print(` ${
|
|
306
|
-
`),segment.usedBySegments&&output_manager_default.print(` ${
|
|
307
|
-
`),showTimestamps&&(output_manager_default.print(` ${
|
|
308
|
-
`),output_manager_default.print(` ${
|
|
318
|
+
`)}function countSegmentValues(segment){return countMembershipValues(segment.data.include)+countMembershipValues(segment.data.exclude)}function countMembershipValues(map){return map?Object.values(map).reduce((sum,attributes)=>sum+Object.values(attributes).reduce((attributeSum,values)=>attributeSum+values.length,0),0):0}var import_chalk74=__toESM(require_source(),1);function printSegmentDetails({segment,projectSlugLink,showTimestamps=!0,settings}){output_manager_default.log(`
|
|
319
|
+
Feature flag segment ${import_chalk74.default.bold(segment.slug)} for ${projectSlugLink}
|
|
320
|
+
`),output_manager_default.print(` ${import_chalk74.default.dim("ID:")} ${segment.id}
|
|
321
|
+
`),output_manager_default.print(` ${import_chalk74.default.dim("Label:")} ${segment.label}
|
|
322
|
+
`),segment.description&&output_manager_default.print(` ${import_chalk74.default.dim("Description:")} ${segment.description}
|
|
323
|
+
`),segment.usedByFlags&&output_manager_default.print(` ${import_chalk74.default.dim("Used by flags:")} ${segment.usedByFlags.length}
|
|
324
|
+
`),segment.usedBySegments&&output_manager_default.print(` ${import_chalk74.default.dim("Used by segments:")} ${segment.usedBySegments.length}
|
|
325
|
+
`),showTimestamps&&(output_manager_default.print(` ${import_chalk74.default.dim("Created:")} ${formatDate(segment.createdAt)}
|
|
326
|
+
`),output_manager_default.print(` ${import_chalk74.default.dim("Updated:")} ${formatDate(segment.updatedAt)}
|
|
309
327
|
`)),printSegmentData(segment,settings)}function printSegmentData(segment,settings){let{rules:rules2=[],include={},exclude={}}=segment.data;if(output_manager_default.print(`
|
|
310
|
-
${
|
|
311
|
-
`),rules2.length===0)output_manager_default.print(` ${
|
|
312
|
-
`);else for(let rule of rules2){output_manager_default.print(` ${
|
|
313
|
-
`),output_manager_default.print(` ${
|
|
314
|
-
`);for(let condition of rule.conditions)output_manager_default.print(` ${
|
|
328
|
+
${import_chalk74.default.dim("Rules:")}
|
|
329
|
+
`),rules2.length===0)output_manager_default.print(` ${import_chalk74.default.dim("-")}
|
|
330
|
+
`);else for(let rule of rules2){output_manager_default.print(` ${import_chalk74.default.dim("Rule ID:")} ${rule.id}
|
|
331
|
+
`),output_manager_default.print(` ${import_chalk74.default.dim("\u2192")} ${formatOutcome2(rule.outcome)}
|
|
332
|
+
`);for(let condition of rule.conditions)output_manager_default.print(` ${import_chalk74.default.dim("if")} ${formatCondition(condition,settings)}
|
|
315
333
|
`)}printMembership("Include",include),printMembership("Exclude",exclude),output_manager_default.print(`
|
|
316
334
|
`)}function printMembership(label,map){output_manager_default.print(`
|
|
317
|
-
${
|
|
318
|
-
`);let entries=getMembershipEntries(map);if(entries.length===0){output_manager_default.print(` ${
|
|
319
|
-
`);return}for(let entry of entries){let note=entry.note?
|
|
335
|
+
${import_chalk74.default.dim(`${label}:`)}
|
|
336
|
+
`);let entries=getMembershipEntries(map);if(entries.length===0){output_manager_default.print(` ${import_chalk74.default.dim("-")}
|
|
337
|
+
`);return}for(let entry of entries){let note=entry.note?import_chalk74.default.gray(` (${entry.note})`):"";output_manager_default.print(` ${import_chalk74.default.dim(`${entry.entity}.${entry.attribute}:`)} ${entry.value}${note}
|
|
320
338
|
`)}}function getMembershipEntries(map){return Object.entries(map).flatMap(([entity,attributes])=>Object.entries(attributes).flatMap(([attribute,values])=>values.map(value=>({entity,attribute,value:value.value,note:value.note}))))}function formatOutcome2(outcome){return outcome.type==="all"?"match all conditions":`match ${outcome.passPromille/10}% by ${outcome.base.kind}.${outcome.base.attribute}`}function formatCondition(condition,settings){let lhs=condition.lhs.type==="entity"?`${condition.lhs.kind}.${condition.lhs.attribute}`:"segment",attributeType=condition.lhs.type==="entity"?getFlagAttributeType(settings,condition.lhs.kind,condition.lhs.attribute):void 0,rhs=condition.rhs===void 0?"":` ${formatValue(condition.rhs,attributeType)}`;return`${lhs} ${formatFlagConditionComparator(condition.cmp,{attributeType})}${rhs}`}function formatValue(value,attributeType){let timestampRhs=formatTimestampRhs(value,attributeType);return timestampRhs||(typeof value!="object"||value===null?JSON.stringify(value):value.type==="list"||value.type==="list/inline"?value.items.map(item=>JSON.stringify(item.value)).join(", "):value.type==="regex"?`/${value.pattern}/${value.flags}`:JSON.stringify(value))}async function segmentsInspect(client,argv){let telemetryClient=new FlagsSegmentsInspectTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(segmentsInspectSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[segmentArg]=args,json=flags["--json"],projectName=getProjectNameFromFlags(flags);if(!segmentArg)return output_manager_default.error("Please provide a segment slug or ID to inspect"),output_manager_default.log(`Example: ${getCommandName("flags segments inspect beta-users")}`),2;telemetryClient.trackCliArgumentSegment(segmentArg),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliFlagJson(json);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);try{output_manager_default.spinner("Fetching segment...");let[segment,settings]=await Promise.all([getSegment(client,project.id,segmentArg,!0),getFlagSettings(client,project.id)]);output_manager_default.stopSpinner(),json?client.stdout.write(`${JSON.stringify({segment},null,2)}
|
|
321
|
-
`):printSegmentDetails({segment,projectSlugLink,settings})}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk74=__toESM(require_source(),1);var import_fast_deep_equal7=__toESM(require_fast_deep_equal(),1);import{randomBytes as randomBytes2}from"node:crypto";function parseEntityAttributeSelector(input){let trimmed=input.trim(),separatorIndex=trimmed.indexOf(".");if(separatorIndex<=0||separatorIndex===trimmed.length-1)throw new Error(`Invalid entity attribute "${input}". Use ENTITY.ATTRIBUTE, for example user.signupAt.`);return{kind:trimmed.slice(0,separatorIndex),attribute:trimmed.slice(separatorIndex+1)}}var OPERATOR_ALIASES={"=":"eq","==":"eq",eq:"eq",equals:"eq",equal:"eq","does-not-equal":"!eq","not-equals":"!eq","not-equal":"!eq","!=":"!eq","!eq":"!eq",in:"oneOf",oneof:"oneOf","one-of":"oneOf",oneOf:"oneOf","not-in":"!oneOf","not-one-of":"!oneOf","!oneof":"!oneOf","!oneOf":"!oneOf",containsallof:"containsAllOf","contains-all-of":"containsAllOf",containsAllOf:"containsAllOf",containsanyof:"containsAnyOf","contains-any-of":"containsAnyOf",containsAnyOf:"containsAnyOf",containsnoneof:"containsNoneOf","contains-none-of":"containsNoneOf",containsNoneOf:"containsNoneOf",startswith:"startsWith","starts-with":"startsWith",startsWith:"startsWith",endswith:"endsWith","ends-with":"endsWith",endsWith:"endsWith",contains:"contains","!contains":"!contains","does-not-contain":"!contains",notcontains:"!contains","not-contains":"!contains",notContains:"!contains",exists:"ex",ex:"ex","!exists":"!ex","not-exists":"!ex","!ex":"!ex",gt:"gt",">":"gt",after:"gt",gte:"gte",">=":"gte","at-or-after":"gte","on-or-after":"gte",lt:"lt","<":"lt",before:"lt",lte:"lte","<=":"lte","at-or-before":"lte","on-or-before":"lte"},LIST_OPERATORS=new Set(FLAG_CONDITION_LIST_COMPARATORS),RHS_OPTIONAL_OPERATORS=new Set(FLAG_CONDITION_RHS_OPTIONAL_COMPARATORS);function shortId(prefix){let alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",bytes=randomBytes2(12),id=prefix;for(let i=0;i<bytes.length;i++)id+=alphabet[bytes[i]%alphabet.length];return id}function parseSegmentDataInput(input){let value=parseJson(input,"segment data");if(!isRecord(value))throw new Error("Segment data must be a JSON object");return value}function parseSegmentRuleInput(input,outcome={type:"all"}){let trimmed=input.trim();if(!trimmed)throw new Error("Segment rule cannot be empty");if(trimmed.startsWith("{")){let value=parseJson(trimmed,"segment rule");if(!isRecord(value))throw new Error("Segment rule JSON must be an object");return value}let conditions=trimmed.split(";").map(part=>part.trim()).filter(Boolean).map(parseSegmentConditionInput);if(conditions.length===0)throw new Error("Segment rule must include at least one condition");return{id:shortId("rule_"),conditions,outcome}}function parseSegmentConditionInput(input){let[field,operator,...valueParts]=input.split(":");if(!field||!operator)throw new Error(`Invalid segment rule "${input}". Use ENTITY.ATTRIBUTE:OPERATOR:VALUE, for example user.email:ends-with:@vercel.com.`);let lhs=parseEntityAttribute(field),cmp=parseComparator(operator),rawValue=valueParts.join(":");if(!rawValue&&!RHS_OPTIONAL_OPERATORS.has(cmp))throw new Error(`Segment rule "${input}" is missing a value`);return{lhs,cmp,...rawValue?{rhs:parseConditionValue(rawValue,cmp)}:{}}}function parseSegmentValueInput(input){let separatorIndex=input.indexOf("=");if(separatorIndex===-1)throw new Error(`Invalid segment value "${input}". Use ENTITY.ATTRIBUTE=VALUE.`);let lhs=input.slice(0,separatorIndex).trim(),rawValue=input.slice(separatorIndex+1).trim();if(!rawValue)throw new Error(`Invalid segment value "${input}". Value cannot be empty.`);let{kind:entity,attribute}=parseEntityAttribute(lhs),{value,note}=splitValueNote(rawValue);return{entity,attribute,value:note?{value,note}:{value}}}function addSegmentValue(data,field,input){let{entity,attribute,value}=parseSegmentValueInput(input),map=data[field]??{},entityValues=map[entity]??{},values=entityValues[attribute]??[];entityValues[attribute]=values.concat(value),map[entity]=entityValues,data[field]=map}function buildSegmentOperations(field,action,inputs){return inputs.map(input=>{let{entity,attribute,value}=parseSegmentValueInput(input);return{action,field,entity,attribute,value}})}function buildSegmentRuleOperations(action,inputs){return inputs.map(input=>buildSegmentRuleOperation(action,input))}function buildSegmentTargetOperations(action,inputs){return inputs.map(input=>parseSegmentTargetOperation(action,input))}function applySegmentOperations(data,operations){let next=normalizeSegmentData({rules:structuredClone(data.rules??[]),include:structuredClone(data.include??{}),exclude:structuredClone(data.exclude??{})});for(let operation of operations){if(operation.field==="rule"){if(operation.action==="add")next.rules=(next.rules??[]).concat(structuredClone(operation.rule));else if(operation.ruleId){let rules2=next.rules??[];if(!rules2.some(rule=>rule.id===operation.ruleId))throw new Error(`Segment rule "${operation.ruleId}" does not exist.`);next.rules=rules2.filter(rule=>rule.id!==operation.ruleId)}else if(operation.rule){let ruleToRemove=operation.rule,rules2=next.rules??[];if(!rules2.some(rule=>segmentRulesEqual(rule,ruleToRemove)))throw new Error("Segment rule does not exist.");next.rules=rules2.filter(rule=>!segmentRulesEqual(rule,ruleToRemove))}continue}if(operation.action==="add"){let map2=next[operation.field]??{},entityValues2=map2[operation.entity]??{},values2=entityValues2[operation.attribute]??[];entityValues2[operation.attribute]=values2.concat(operation.value),map2[operation.entity]=entityValues2,next[operation.field]=map2;continue}let entityValues=next[operation.field]?.[operation.entity],values=entityValues?.[operation.attribute],valueExists=values?.some(value=>value.value===operation.value.value);if(!values||!valueExists)throw new Error(`Segment ${operation.field} value "${operation.entity}.${operation.attribute}=${operation.value.value}" does not exist.`);entityValues[operation.attribute]=values.filter(value=>value.value!==operation.value.value)}return next}function parseSegmentTargetOperation(action,input){let separatorIndex=input.indexOf(":");if(separatorIndex===-1)throw new Error(`Invalid segment operation "${input}". Use include:ENTITY.ATTRIBUTE=VALUE, exclude:ENTITY.ATTRIBUTE=VALUE, or rule:ENTITY.ATTRIBUTE:OPERATOR:VALUE.`);let field=input.slice(0,separatorIndex).trim().toLowerCase(),valueInput=input.slice(separatorIndex+1).trim();if(!valueInput)throw new Error(`Invalid segment operation "${input}". Target is empty.`);if(field==="include"||field==="exclude"){let{entity,attribute,value}=parseSegmentValueInput(valueInput);return{action,field,entity,attribute,value}}if(field==="rule"||field==="rules")return buildSegmentRuleOperation(action,valueInput);throw new Error(`Invalid segment operation target "${field}". Use include, exclude, or rule.`)}function buildSegmentRuleOperation(action,input){if(action==="remove"&&isRuleIdInput(input))return{action,field:"rule",ruleId:input.trim()};let rule=parseSegmentRuleInput(input);return action==="add"?{action,field:"rule",rule}:{action,field:"rule",rule}}function normalizeSegmentData(data){return{rules:data.rules??[],include:data.include??{},exclude:data.exclude??{}}}function segmentRulesEqual(a,b){return(0,import_fast_deep_equal7.default)(getComparableRule(a),getComparableRule(b))}function getComparableRule(rule){return{conditions:rule.conditions,outcome:rule.outcome}}function isRuleIdInput(input){let trimmed=input.trim();return!trimmed.startsWith("{")&&!trimmed.includes(":")&&!trimmed.includes(".")}function parseComparator(input,ruleLabel="segment rule"){let normalized=input.trim(),lowercase=normalized.toLowerCase(),comparator=OPERATOR_ALIASES[normalized]??OPERATOR_ALIASES[lowercase];if(!comparator)throw new Error(`Invalid ${ruleLabel} operator "${input}". Valid operators: ${formatFlagConditionComparatorList()}.`);return comparator}function parseEntityAttribute(input){let{kind,attribute}=parseEntityAttributeSelector(input);return{type:"entity",kind,attribute}}function parseConditionValue(input,comparator){let trimmed=input.trim();return LIST_OPERATORS.has(comparator)?{type:"list",items:trimmed.split(",").map(value=>value.trim()).filter(Boolean).map(value=>({value:parseListItemValue(value)}))}:parseScalarValue(trimmed)}function parseScalarValue(value){return value==="true"?!0:value==="false"?!1:value!==""&&Number.isFinite(Number(value))?Number(value):value}function parseListItemValue(value){return value!==""&&Number.isFinite(Number(value))?Number(value):value}function splitValueNote(input){let separatorIndex=input.indexOf("|");if(separatorIndex===-1)return{value:input};let value=input.slice(0,separatorIndex).trim(),note=input.slice(separatorIndex+1).trim();return note?{value,note}:{value}}function parseJson(input,label){try{return JSON.parse(input)}catch{throw new Error(`Invalid JSON for ${label}`)}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}async function segmentsCreate(client,argv){let telemetryClient=new FlagsSegmentsCreateTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(segmentsCreateSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[slug]=args,label=flags["--label"],description=flags["--description"],hint=flags["--hint"],dataInput=flags["--data"],addInputs=flags["--add"]??[],json=flags["--json"],projectName=getProjectNameFromFlags(flags);if(telemetryClient.trackCliArgumentSlug(slug),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionLabel(label),telemetryClient.trackCliOptionDescription(description),telemetryClient.trackCliOptionHint(hint),telemetryClient.trackCliOptionData(dataInput),telemetryClient.trackCliOptionAdd(addInputs),telemetryClient.trackCliFlagJson(json),!slug)return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide a segment slug to create.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags segments create <slug> --label <label> --add include:user.id=<value>"),when:"create a segment with explicit values"}]},2),2):(output_manager_default.error("Please provide a slug for the segment"),output_manager_default.log(`Example: ${getCommandName('flags segments create beta-users --label "Beta users" --add include:user.id=user_123')}`),2);let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.NOT_LINKED,message:"Your codebase is not linked to a project. Run link first.",next:[{command:buildCommandWithGlobalFlags(client.argv,"link"),when:"link the project"}]},1),1):(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);label=await resolveSegmentLabel(client,label,slug),hint=await resolveSegmentHint(client,hint,description,label);let data,settings;try{settings=await getFlagSettings(client,project.id),data=coerceTimestampSegmentData(await collectSegmentData(client,{dataInput,addInputs}),settings,"input")}catch(err){return output_manager_default.error(err.message),1}let request={slug,label,description,data,hint};try{output_manager_default.spinner("Creating segment...");let segment=await createSegment(client,project.id,request);if(output_manager_default.stopSpinner(),json)return client.stdout.write(`${JSON.stringify({segment},null,2)}
|
|
322
|
-
`),0;output_manager_default.success(`Feature flag segment ${
|
|
323
|
-
`),0;output_manager_default.success(`Feature flag segment ${
|
|
339
|
+
`):printSegmentDetails({segment,projectSlugLink,settings})}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk75=__toESM(require_source(),1);var import_fast_deep_equal7=__toESM(require_fast_deep_equal(),1);import{randomBytes as randomBytes2}from"node:crypto";function parseEntityAttributeSelector(input){let trimmed=input.trim(),separatorIndex=trimmed.indexOf(".");if(separatorIndex<=0||separatorIndex===trimmed.length-1)throw new Error(`Invalid entity attribute "${input}". Use ENTITY.ATTRIBUTE, for example user.signupAt.`);return{kind:trimmed.slice(0,separatorIndex),attribute:trimmed.slice(separatorIndex+1)}}var OPERATOR_ALIASES={"=":"eq","==":"eq",eq:"eq",equals:"eq",equal:"eq","does-not-equal":"!eq","not-equals":"!eq","not-equal":"!eq","!=":"!eq","!eq":"!eq",in:"oneOf",oneof:"oneOf","one-of":"oneOf",oneOf:"oneOf","not-in":"!oneOf","not-one-of":"!oneOf","!oneof":"!oneOf","!oneOf":"!oneOf",containsallof:"containsAllOf","contains-all-of":"containsAllOf",containsAllOf:"containsAllOf",containsanyof:"containsAnyOf","contains-any-of":"containsAnyOf",containsAnyOf:"containsAnyOf",containsnoneof:"containsNoneOf","contains-none-of":"containsNoneOf",containsNoneOf:"containsNoneOf",startswith:"startsWith","starts-with":"startsWith",startsWith:"startsWith",endswith:"endsWith","ends-with":"endsWith",endsWith:"endsWith",contains:"contains","!contains":"!contains","does-not-contain":"!contains",notcontains:"!contains","not-contains":"!contains",notContains:"!contains",exists:"ex",ex:"ex","!exists":"!ex","not-exists":"!ex","!ex":"!ex",gt:"gt",">":"gt",after:"gt",gte:"gte",">=":"gte","at-or-after":"gte","on-or-after":"gte",lt:"lt","<":"lt",before:"lt",lte:"lte","<=":"lte","at-or-before":"lte","on-or-before":"lte"},LIST_OPERATORS=new Set(FLAG_CONDITION_LIST_COMPARATORS),RHS_OPTIONAL_OPERATORS=new Set(FLAG_CONDITION_RHS_OPTIONAL_COMPARATORS);function shortId(prefix){let alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",bytes=randomBytes2(12),id=prefix;for(let i=0;i<bytes.length;i++)id+=alphabet[bytes[i]%alphabet.length];return id}function parseSegmentDataInput(input){let value=parseJson(input,"segment data");if(!isRecord(value))throw new Error("Segment data must be a JSON object");return value}function parseSegmentRuleInput(input,outcome={type:"all"}){let trimmed=input.trim();if(!trimmed)throw new Error("Segment rule cannot be empty");if(trimmed.startsWith("{")){let value=parseJson(trimmed,"segment rule");if(!isRecord(value))throw new Error("Segment rule JSON must be an object");return value}let conditions=trimmed.split(";").map(part=>part.trim()).filter(Boolean).map(parseSegmentConditionInput);if(conditions.length===0)throw new Error("Segment rule must include at least one condition");return{id:shortId("rule_"),conditions,outcome}}function parseSegmentConditionInput(input){let[field,operator,...valueParts]=input.split(":");if(!field||!operator)throw new Error(`Invalid segment rule "${input}". Use ENTITY.ATTRIBUTE:OPERATOR:VALUE, for example user.email:ends-with:@vercel.com.`);let lhs=parseEntityAttribute(field),cmp=parseComparator(operator),rawValue=valueParts.join(":");if(!rawValue&&!RHS_OPTIONAL_OPERATORS.has(cmp))throw new Error(`Segment rule "${input}" is missing a value`);return{lhs,cmp,...rawValue?{rhs:parseConditionValue(rawValue,cmp)}:{}}}function parseSegmentValueInput(input){let separatorIndex=input.indexOf("=");if(separatorIndex===-1)throw new Error(`Invalid segment value "${input}". Use ENTITY.ATTRIBUTE=VALUE.`);let lhs=input.slice(0,separatorIndex).trim(),rawValue=input.slice(separatorIndex+1).trim();if(!rawValue)throw new Error(`Invalid segment value "${input}". Value cannot be empty.`);let{kind:entity,attribute}=parseEntityAttribute(lhs),{value,note}=splitValueNote(rawValue);return{entity,attribute,value:note?{value,note}:{value}}}function addSegmentValue(data,field,input){let{entity,attribute,value}=parseSegmentValueInput(input),map=data[field]??{},entityValues=map[entity]??{},values=entityValues[attribute]??[];entityValues[attribute]=values.concat(value),map[entity]=entityValues,data[field]=map}function buildSegmentOperations(field,action,inputs){return inputs.map(input=>{let{entity,attribute,value}=parseSegmentValueInput(input);return{action,field,entity,attribute,value}})}function buildSegmentRuleOperations(action,inputs){return inputs.map(input=>buildSegmentRuleOperation(action,input))}function buildSegmentTargetOperations(action,inputs){return inputs.map(input=>parseSegmentTargetOperation(action,input))}function applySegmentOperations(data,operations){let next=normalizeSegmentData({rules:structuredClone(data.rules??[]),include:structuredClone(data.include??{}),exclude:structuredClone(data.exclude??{})});for(let operation of operations){if(operation.field==="rule"){if(operation.action==="add")next.rules=(next.rules??[]).concat(structuredClone(operation.rule));else if(operation.ruleId){let rules2=next.rules??[];if(!rules2.some(rule=>rule.id===operation.ruleId))throw new Error(`Segment rule "${operation.ruleId}" does not exist.`);next.rules=rules2.filter(rule=>rule.id!==operation.ruleId)}else if(operation.rule){let ruleToRemove=operation.rule,rules2=next.rules??[];if(!rules2.some(rule=>segmentRulesEqual(rule,ruleToRemove)))throw new Error("Segment rule does not exist.");next.rules=rules2.filter(rule=>!segmentRulesEqual(rule,ruleToRemove))}continue}if(operation.action==="add"){let map2=next[operation.field]??{},entityValues2=map2[operation.entity]??{},values2=entityValues2[operation.attribute]??[];entityValues2[operation.attribute]=values2.concat(operation.value),map2[operation.entity]=entityValues2,next[operation.field]=map2;continue}let entityValues=next[operation.field]?.[operation.entity],values=entityValues?.[operation.attribute],valueExists=values?.some(value=>value.value===operation.value.value);if(!values||!valueExists)throw new Error(`Segment ${operation.field} value "${operation.entity}.${operation.attribute}=${operation.value.value}" does not exist.`);entityValues[operation.attribute]=values.filter(value=>value.value!==operation.value.value)}return next}function parseSegmentTargetOperation(action,input){let separatorIndex=input.indexOf(":");if(separatorIndex===-1)throw new Error(`Invalid segment operation "${input}". Use include:ENTITY.ATTRIBUTE=VALUE, exclude:ENTITY.ATTRIBUTE=VALUE, or rule:ENTITY.ATTRIBUTE:OPERATOR:VALUE.`);let field=input.slice(0,separatorIndex).trim().toLowerCase(),valueInput=input.slice(separatorIndex+1).trim();if(!valueInput)throw new Error(`Invalid segment operation "${input}". Target is empty.`);if(field==="include"||field==="exclude"){let{entity,attribute,value}=parseSegmentValueInput(valueInput);return{action,field,entity,attribute,value}}if(field==="rule"||field==="rules")return buildSegmentRuleOperation(action,valueInput);throw new Error(`Invalid segment operation target "${field}". Use include, exclude, or rule.`)}function buildSegmentRuleOperation(action,input){if(action==="remove"&&isRuleIdInput(input))return{action,field:"rule",ruleId:input.trim()};let rule=parseSegmentRuleInput(input);return action==="add"?{action,field:"rule",rule}:{action,field:"rule",rule}}function normalizeSegmentData(data){return{rules:data.rules??[],include:data.include??{},exclude:data.exclude??{}}}function segmentRulesEqual(a,b){return(0,import_fast_deep_equal7.default)(getComparableRule(a),getComparableRule(b))}function getComparableRule(rule){return{conditions:rule.conditions,outcome:rule.outcome}}function isRuleIdInput(input){let trimmed=input.trim();return!trimmed.startsWith("{")&&!trimmed.includes(":")&&!trimmed.includes(".")}function parseComparator(input,ruleLabel="segment rule"){let normalized=input.trim(),lowercase=normalized.toLowerCase(),comparator=OPERATOR_ALIASES[normalized]??OPERATOR_ALIASES[lowercase];if(!comparator)throw new Error(`Invalid ${ruleLabel} operator "${input}". Valid operators: ${formatFlagConditionComparatorList()}.`);return comparator}function parseEntityAttribute(input){let{kind,attribute}=parseEntityAttributeSelector(input);return{type:"entity",kind,attribute}}function parseConditionValue(input,comparator){let trimmed=input.trim();return LIST_OPERATORS.has(comparator)?{type:"list",items:trimmed.split(",").map(value=>value.trim()).filter(Boolean).map(value=>({value:parseListItemValue(value)}))}:parseScalarValue(trimmed)}function parseScalarValue(value){return value==="true"?!0:value==="false"?!1:value!==""&&Number.isFinite(Number(value))?Number(value):value}function parseListItemValue(value){return value!==""&&Number.isFinite(Number(value))?Number(value):value}function splitValueNote(input){let separatorIndex=input.indexOf("|");if(separatorIndex===-1)return{value:input};let value=input.slice(0,separatorIndex).trim(),note=input.slice(separatorIndex+1).trim();return note?{value,note}:{value}}function parseJson(input,label){try{return JSON.parse(input)}catch{throw new Error(`Invalid JSON for ${label}`)}}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}async function segmentsCreate(client,argv){let telemetryClient=new FlagsSegmentsCreateTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(segmentsCreateSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[slug]=args,label=flags["--label"],description=flags["--description"],hint=flags["--hint"],dataInput=flags["--data"],addInputs=flags["--add"]??[],json=flags["--json"],projectName=getProjectNameFromFlags(flags);if(telemetryClient.trackCliArgumentSlug(slug),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionLabel(label),telemetryClient.trackCliOptionDescription(description),telemetryClient.trackCliOptionHint(hint),telemetryClient.trackCliOptionData(dataInput),telemetryClient.trackCliOptionAdd(addInputs),telemetryClient.trackCliFlagJson(json),!slug)return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide a segment slug to create.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags segments create <slug> --label <label> --add include:user.id=<value>"),when:"create a segment with explicit values"}]},2),2):(output_manager_default.error("Please provide a slug for the segment"),output_manager_default.log(`Example: ${getCommandName('flags segments create beta-users --label "Beta users" --add include:user.id=user_123')}`),2);let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.NOT_LINKED,message:"Your codebase is not linked to a project. Run link first.",next:[{command:buildCommandWithGlobalFlags(client.argv,"link"),when:"link the project"}]},1),1):(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);label=await resolveSegmentLabel(client,label,slug),hint=await resolveSegmentHint(client,hint,description,label);let data,settings;try{settings=await getFlagSettings(client,project.id),data=coerceTimestampSegmentData(await collectSegmentData(client,{dataInput,addInputs}),settings,"input")}catch(err){return output_manager_default.error(err.message),1}let request={slug,label,description,data,hint};try{output_manager_default.spinner("Creating segment...");let segment=await createSegment(client,project.id,request);if(output_manager_default.stopSpinner(),json)return client.stdout.write(`${JSON.stringify({segment},null,2)}
|
|
340
|
+
`),0;output_manager_default.success(`Feature flag segment ${import_chalk75.default.bold(segment.slug)} created`),printSegmentDetails({segment,projectSlugLink,showTimestamps:!1,settings})}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}async function resolveSegmentLabel(client,label,slug){let defaultLabel=humanizeSlug(slug);return label||client.stdin.isTTY&&!client.nonInteractive&&(await client.input.text({message:`Enter a label for this segment (press Enter for "${defaultLabel}"):`})).trim()||defaultLabel}async function resolveSegmentHint(client,hint,description,label){return hint||(client.stdin.isTTY&&!client.nonInteractive?(await client.input.text({message:`Enter a hint for who belongs in this segment (press Enter for "${description||label}"):`})).trim()||description||label:description||label)}async function collectSegmentData(client,input){let hasExplicitData=!!input.dataInput,data=hasExplicitData?parseSegmentDataInput(input.dataInput):normalizeSegmentData({}),operations=buildSegmentTargetOperations("add",input.addInputs),nextData=operations.length>0?applySegmentOperations(data,operations):data;return!hasExplicitData&&input.addInputs.length===0&&client.stdin.isTTY&&!client.nonInteractive&&await collectSegmentDataInteractively(client,nextData),normalizeSegmentData(nextData)}async function collectSegmentDataInteractively(client,data){let addAnother=await client.input.confirm("Add segment criteria now?",!0);for(;addAnother;){let kind=await client.input.select({message:"What do you want to add?",choices:[{name:"Include an exact entity value",value:"include"},{name:"Exclude an exact entity value",value:"exclude"},{name:"Add a rule",value:"rule"}]});if(kind==="rule"){let rule=await client.input.text({message:"Enter rule as ENTITY.ATTRIBUTE:OPERATOR:VALUE (for example user.email:ends-with:@vercel.com):"});data.rules=(data.rules??[]).concat(parseSegmentRuleInput(rule))}else{let value=await client.input.text({message:`Enter ${kind} value as ENTITY.ATTRIBUTE=VALUE:`});addSegmentValue(data,kind,value)}addAnother=await client.input.confirm("Add another criterion?",!1)}}function humanizeSlug(slug){return slug.split(/[-_\s]+/).filter(Boolean).map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}var import_chalk76=__toESM(require_source(),1);async function segmentsUpdate(client,argv){let telemetryClient=new FlagsSegmentsUpdateTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(segmentsUpdateSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,segmentArg=args[0],label=flags["--label"],description=flags["--description"],hint=flags["--hint"],dataInput=flags["--data"],addInputs=flags["--add"]??[],removeInputs=flags["--remove"]??[],json=flags["--json"],projectName=getProjectNameFromFlags(flags);telemetryClient.trackCliArgumentSegment(segmentArg),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionLabel(label),telemetryClient.trackCliOptionDescription(description),telemetryClient.trackCliOptionHint(hint),telemetryClient.trackCliOptionData(dataInput),telemetryClient.trackCliOptionAdd(addInputs),telemetryClient.trackCliOptionRemove(removeInputs),telemetryClient.trackCliFlagJson(json);let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.NOT_LINKED,message:"Your codebase is not linked to a project. Run link first.",next:[{command:buildCommandWithGlobalFlags(client.argv,"link"),when:"link the project"}]},1),1):(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);try{if(!segmentArg&&(segmentArg=await resolveSegmentArg(client,project.id),!segmentArg))return 1;let settings=await getFlagSettings(client,project.id),operations=coerceTimestampOperations(buildOperations({addInputs,removeInputs}),settings),hasChanges=label!==void 0||description!==void 0||hint!==void 0||!!dataInput||operations.length>0,request;if(!hasChanges&&client.stdin.isTTY&&!client.nonInteractive){output_manager_default.spinner("Fetching segment...");let segment2=await getSegment(client,project.id,segmentArg,!0);output_manager_default.stopSpinner(),request=await collectUpdateInteractively(client,segment2,settings)}else request=await buildUpdateRequest(client,project.id,segmentArg,{label,description,hint,dataInput,operations,settings});if(request=coerceTimestampUpdateRequest(request,settings),!hasUpdateRequestChanges(request))return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide at least one segment update option, such as --label, --data, --add, or --remove.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags segments update <segment> --add include:user.id=<value>"),when:"add a value to a segment"},{command:buildCommandWithGlobalFlags(client.argv,"flags segments update <segment> --remove include:user.id=<value>"),when:"remove a value from a segment"},{command:buildCommandWithGlobalFlags(client.argv,"flags segments inspect <segment> --json"),when:"inspect the current segment data first"}]},2),2):(output_manager_default.warn("No segment changes were provided"),0);output_manager_default.spinner("Updating segment...");let segment=await updateSegment(client,project.id,segmentArg,request);if(output_manager_default.stopSpinner(),json)return client.stdout.write(`${JSON.stringify({segment},null,2)}
|
|
341
|
+
`),0;output_manager_default.success(`Feature flag segment ${import_chalk76.default.bold(segment.slug)} updated`),printSegmentDetails({segment,projectSlugLink,showTimestamps:!1,settings})}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}async function resolveSegmentArg(client,projectId){if(client.nonInteractive){outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide a segment slug or ID. Run `vercel flags segments ls` to list segments.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags segments update <segment> --add include:user.id=<value>"),when:"update a segment by slug or ID"},{command:buildCommandWithGlobalFlags(client.argv,"flags segments ls"),when:"list segments to find the slug or ID"}]},2);return}if(!client.stdin.isTTY){output_manager_default.error("Please provide a segment slug or ID to update"),output_manager_default.log(`Example: ${getCommandName("flags segments update beta-users --add include:user.id=user_123")}`);return}output_manager_default.spinner("Fetching segments...");let segments2=await getSegments(client,projectId,!0);if(output_manager_default.stopSpinner(),segments2.length===0){output_manager_default.error("No feature flag segments found"),output_manager_default.log(`Create one with: ${getCommandName('flags segments create beta-users --label "Beta users" --add include:user.id=user_123')}`);return}return client.input.select({message:"Select a segment to update:",choices:segments2.map(segment=>({name:`${segment.label} (${segment.slug})`,value:segment.slug}))})}async function buildUpdateRequest(client,projectId,segmentArg,input){let request={};if(input.label!==void 0&&(request.label=input.label),input.description!==void 0&&(request.description=input.description),input.hint!==void 0&&(request.hint=input.hint),input.dataInput&&(request.data=coerceTimestampSegmentData(parseSegmentDataInput(input.dataInput),input.settings,"input")),request.data)request.data=applySegmentOperations(request.data,input.operations);else if(hasRuleOperations(input.operations)){output_manager_default.spinner("Fetching segment...");let segment=await getSegment(client,projectId,segmentArg,!0);output_manager_default.stopSpinner(),request.data=applySegmentOperations(segment.data,input.operations)}else if(input.operations.length>0){if(hasRemoveOperations(input.operations)){output_manager_default.spinner("Fetching segment...");let segment=await getSegment(client,projectId,segmentArg,!0);output_manager_default.stopSpinner(),applySegmentOperations(segment.data,input.operations)}request.operations=input.operations.filter(isMembershipOperation)}return request}function buildOperations(input){return[...buildSegmentTargetOperations("add",input.addInputs),...buildSegmentTargetOperations("remove",input.removeInputs)]}function hasRuleOperations(operations){return operations.some(operation=>operation.field==="rule")}function hasRemoveOperations(operations){return operations.some(operation=>operation.action==="remove")}function isMembershipOperation(operation){return operation.field==="include"||operation.field==="exclude"}async function collectUpdateInteractively(client,segment,settings){let request={},data,replacingRules=!1,operations=[],keepEditing=!0;for(;keepEditing;){let action=await client.input.select({message:"What do you want to update?",choices:[{name:"Label",value:"label"},{name:"Description",value:"description"},{name:"Hint",value:"hint"},{name:"Add rule",value:"add-rule"},{name:"Remove rule",value:"remove-rule"},{name:"Replace all rules",value:"replace-rules"},{name:"Add include value",value:"include"},{name:"Add exclude value",value:"exclude"},{name:"Remove include value",value:"remove-include"},{name:"Remove exclude value",value:"remove-exclude"},{name:"Replace full data JSON",value:"data"},{name:"Done",value:"done"}]});switch(action){case"label":request.label=await client.input.text({message:`Enter a new label (current: ${segment.label}):`});break;case"description":request.description=await client.input.text({message:"Enter a new description:"});break;case"hint":request.hint=await client.input.text({message:`Enter a new hint (current: ${segment.hint}):`});break;case"add-rule":{let rule=await client.input.text({message:"Enter rule as ENTITY.ATTRIBUTE:OPERATOR:VALUE:"});operations.push(...buildSegmentRuleOperations("add",[rule]));break}case"remove-rule":{let rule=await client.input.text({message:"Enter rule as ENTITY.ATTRIBUTE:OPERATOR:VALUE or rule ID:"});operations.push(...buildSegmentRuleOperations("remove",[rule]));break}case"replace-rules":{let rule=await client.input.text({message:"Enter rule as ENTITY.ATTRIBUTE:OPERATOR:VALUE (repeat by choosing this again):"});replacingRules||(data=normalizeSegmentData({...segment.data,rules:[]}),replacingRules=!0),data=normalizeSegmentData(data??segment.data);let[coercedRule]=coerceTimestampSegmentData({rules:[parseSegmentRuleInput(rule)]},settings,"input").rules;data.rules=(data.rules??[]).concat(coercedRule);break}case"include":case"exclude":case"remove-include":case"remove-exclude":{let value=await client.input.text({message:"Enter value as ENTITY.ATTRIBUTE=VALUE:"});operations.push(...buildSegmentOperations(action.includes("include")?"include":"exclude",action.startsWith("remove")?"remove":"add",[value]));break}case"data":{let value=await client.input.text({message:"Enter full segment data JSON:"});data=coerceTimestampSegmentData(parseSegmentDataInput(value),settings,"input");break}case"done":keepEditing=!1;break}keepEditing&&(keepEditing=await client.input.confirm("Make another change?",!1))}let coercedOperations=coerceTimestampOperations(operations,settings,"input");return data?request.data=applySegmentOperations(data,coercedOperations):hasRuleOperations(coercedOperations)?request.data=applySegmentOperations(segment.data,coercedOperations):coercedOperations.length>0&&(request.operations=coercedOperations.filter(isMembershipOperation)),request}function hasUpdateRequestChanges(request){return request.label!==void 0||request.description!==void 0||request.hint!==void 0||request.data!==void 0||!!request.operations?.length}function coerceTimestampUpdateRequest(request,settings){return request.data?{...request,data:coerceTimestampSegmentData(request.data,settings)}:request}var import_chalk77=__toESM(require_source(),1);async function segmentsRm(client,argv){let telemetryClient=new FlagsSegmentsRmTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(segmentsRemoveSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,segmentArg=args[0],skipConfirmation=flags["--yes"],projectName=getProjectNameFromFlags(flags);telemetryClient.trackCliArgumentSegment(segmentArg),telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliFlagYes(skipConfirmation);let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return client.nonInteractive?(outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.NOT_LINKED,message:"Your codebase is not linked to a project. Run link first.",next:[{command:buildCommandWithGlobalFlags(client.argv,"link"),when:"link the project"}]},1),1):(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}=link;try{if(!segmentArg&&(segmentArg=await resolveSegmentArg2(client,project.id),!segmentArg))return 1;output_manager_default.spinner("Fetching segment...");let segment=await getSegment(client,project.id,segmentArg,!1);if(output_manager_default.stopSpinner(),!skipConfirmation){if(!client.stdin.isTTY)return output_manager_default.error("Missing required option --yes. Use --yes to skip the confirmation prompt in non-interactive mode."),2;if(client.nonInteractive)return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`Confirm deletion of segment ${segment.slug} by adding --yes.`,next:[{command:buildCommandWithGlobalFlags(client.argv,`flags segments delete ${segmentArg} --yes`),when:"confirm and delete the segment"}]},1),1;if(!await client.input.confirm(`Are you sure you want to delete segment ${import_chalk77.default.bold(segment.slug)}?`,!1))return output_manager_default.log("Aborted"),0}output_manager_default.spinner("Deleting segment..."),await deleteSegment(client,project.id,segmentArg),output_manager_default.stopSpinner(),output_manager_default.success(`Feature flag segment ${import_chalk77.default.bold(segment.slug)} deleted`)}catch(err){return output_manager_default.stopSpinner(),handleSegmentInUseError(client,err,segmentArg)||printError(err),1}return 0}function handleSegmentInUseError(client,error,segmentArg){if(!isAPIError(error)||error.code!=="SEGMENT_IN_USE")return!1;let usedBy=error.usedBy,flags=usedBy?.flags??[],segments2=usedBy?.segments??[],segment=segmentArg??"<segment>",formatReferences=references=>references.map(reference=>{let primary=reference.name??reference.label??reference.slug??reference.id;return primary&&reference.slug&&reference.slug!==primary?`${primary} (${reference.slug})`:primary??"Unknown reference"}).join(", "),firstFlag=flags.find(reference=>reference.slug||reference.id),firstSegment=segments2.find(reference=>reference.slug||reference.id),inspectSubcommand2=firstFlag!==void 0?`flags inspect ${firstFlag.slug??firstFlag.id}`:firstSegment!==void 0?`flags segments inspect ${firstSegment.slug??firstSegment.id}`:void 0,lines=[`Segment ${segment} is still in use and can't be deleted.`];flags.length>0&&lines.push(`Used by feature flags: ${formatReferences(flags)}`),segments2.length>0&&lines.push(`Used by segments: ${formatReferences(segments2)}`);let message=lines.join(`
|
|
324
342
|
`);return outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.SEGMENT_IN_USE,message,next:[...inspectSubcommand2?[{command:buildCommandWithGlobalFlags(client.argv,inspectSubcommand2),when:"inspect one reference that still uses the segment"}]:[],{command:buildCommandWithGlobalFlags(client.argv,`flags segments delete ${segment} --yes`),when:"retry after removing all references"}]},1),inspectSubcommand2?lines.push("",`Run ${getCommandName(inspectSubcommand2)} to inspect one reference, remove the segment from each rule, then try deleting the segment again.`):lines.push("","Remove every flag or segment rule that references it, then try deleting the segment again."),output_manager_default.error(lines.join(`
|
|
325
|
-
`)),!0}async function resolveSegmentArg2(client,projectId){if(client.nonInteractive){outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide a segment slug or ID. Run `vercel flags segments ls` to list segments.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags segments delete <segment> --yes"),when:"delete a segment by slug or ID"},{command:buildCommandWithGlobalFlags(client.argv,"flags segments ls"),when:"list segments to find the slug or ID"}]},2);return}if(!client.stdin.isTTY){output_manager_default.error("Please provide a segment slug or ID to delete"),output_manager_default.log(`Example: ${getCommandName("flags segments delete beta-users")}`);return}output_manager_default.spinner("Fetching segments...");let segments2=await getSegments(client,projectId);if(output_manager_default.stopSpinner(),segments2.length===0){output_manager_default.log("No feature flag segments found");return}return client.input.select({message:"Select a segment to delete:",choices:segments2.map(segment=>({name:`${segment.label} (${segment.slug})`,value:segment.slug}))})}var COMMAND_CONFIG13={ls:getCommandAliases(segmentsListSubcommand),inspect:getCommandAliases(segmentsInspectSubcommand),create:getCommandAliases(segmentsCreateSubcommand),update:getCommandAliases(segmentsUpdateSubcommand),delete:getCommandAliases(segmentsRemoveSubcommand)};async function segments(client){let telemetry=new FlagsSegmentsTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(segmentsSubcommand.options),argv=client.argv.slice(4),parsedArgs;try{parsedArgs=parseArguments(argv,flagsSpecification,{permissive:!0,commandShorthands:findCommandShorthands(segmentsSubcommand.subcommands,argv)})}catch(err){return printError(err),2}let{subcommand,args,subcommandOriginal}=getSubcommand(parsedArgs.args,COMMAND_CONFIG13),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags segments",subcommand),output_manager_default.print(help(segmentsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:segmentsSubcommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsListSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),segmentsLs(client,args));case"inspect":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsInspectSubcommand),0):(telemetry.trackCliSubcommandInspect(subcommandOriginal),segmentsInspect(client,args));case"create":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsCreateSubcommand),0):(telemetry.trackCliSubcommandCreate(subcommandOriginal),subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags segments add","flags segments create"),segmentsCreate(client,args));case"update":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsUpdateSubcommand),0):(telemetry.trackCliSubcommandUpdate(subcommandOriginal),segmentsUpdate(client,args));case"delete":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsRemoveSubcommand),0):(telemetry.trackCliSubcommandDelete(subcommandOriginal),subcommandOriginal==="remove"&&warnDeprecatedSubcommand(client,"flags segments remove","flags segments delete"),segmentsRm(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG13)),output_manager_default.print(help(segmentsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var FlagsEntitiesTelemetryClient=class extends TelemetryClient{trackSubcommand(subcommand,actual){this.trackCliSubcommand({subcommand,value:actual})}trackArguments(args,flags){args[0]&&this.trackCliArgument({arg:"kind",value:this.redactedValue}),this.trackCliOptionProject(flags["--project"]);for(let option of["label","attribute","add-attribute","remove-attribute","set-attribute-type"]){let value=flags[`--${option}`];(typeof value=="string"?value.trim():Array.isArray(value)&&value.length)&&this.trackCliOption({option,value:this.redactedValue})}for(let flag of["json","yes"])flags[`--${flag}`]&&this.trackCliFlag(flag)}};var
|
|
326
|
-
Feature flag entity ${
|
|
327
|
-
`),output_manager_default.print(` ${
|
|
328
|
-
`),output_manager_default.print(` ${
|
|
329
|
-
`),output_manager_default.print(` ${
|
|
330
|
-
`),entity.attributes.length===0&&output_manager_default.print(` ${
|
|
331
|
-
`);for(let attribute of entity.attributes)output_manager_default.print(` ${attribute.key} ${
|
|
343
|
+
`)),!0}async function resolveSegmentArg2(client,projectId){if(client.nonInteractive){outputAgentError(client,{status:AGENT_STATUS.ERROR,reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Please provide a segment slug or ID. Run `vercel flags segments ls` to list segments.",next:[{command:buildCommandWithGlobalFlags(client.argv,"flags segments delete <segment> --yes"),when:"delete a segment by slug or ID"},{command:buildCommandWithGlobalFlags(client.argv,"flags segments ls"),when:"list segments to find the slug or ID"}]},2);return}if(!client.stdin.isTTY){output_manager_default.error("Please provide a segment slug or ID to delete"),output_manager_default.log(`Example: ${getCommandName("flags segments delete beta-users")}`);return}output_manager_default.spinner("Fetching segments...");let segments2=await getSegments(client,projectId);if(output_manager_default.stopSpinner(),segments2.length===0){output_manager_default.log("No feature flag segments found");return}return client.input.select({message:"Select a segment to delete:",choices:segments2.map(segment=>({name:`${segment.label} (${segment.slug})`,value:segment.slug}))})}var COMMAND_CONFIG13={ls:getCommandAliases(segmentsListSubcommand),inspect:getCommandAliases(segmentsInspectSubcommand),create:getCommandAliases(segmentsCreateSubcommand),update:getCommandAliases(segmentsUpdateSubcommand),delete:getCommandAliases(segmentsRemoveSubcommand)};async function segments(client){let telemetry=new FlagsSegmentsTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(segmentsSubcommand.options),argv=client.argv.slice(4),parsedArgs;try{parsedArgs=parseArguments(argv,flagsSpecification,{permissive:!0,commandShorthands:findCommandShorthands(segmentsSubcommand.subcommands,argv)})}catch(err){return printError(err),2}let{subcommand,args,subcommandOriginal}=getSubcommand(parsedArgs.args,COMMAND_CONFIG13),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags segments",subcommand),output_manager_default.print(help(segmentsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:segmentsSubcommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsListSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),segmentsLs(client,args));case"inspect":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsInspectSubcommand),0):(telemetry.trackCliSubcommandInspect(subcommandOriginal),segmentsInspect(client,args));case"create":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsCreateSubcommand),0):(telemetry.trackCliSubcommandCreate(subcommandOriginal),subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags segments add","flags segments create"),segmentsCreate(client,args));case"update":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsUpdateSubcommand),0):(telemetry.trackCliSubcommandUpdate(subcommandOriginal),segmentsUpdate(client,args));case"delete":return needHelp?(telemetry.trackCliFlagHelp("flags segments",subcommandOriginal),printHelp(segmentsRemoveSubcommand),0):(telemetry.trackCliSubcommandDelete(subcommandOriginal),subcommandOriginal==="remove"&&warnDeprecatedSubcommand(client,"flags segments remove","flags segments delete"),segmentsRm(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG13)),output_manager_default.print(help(segmentsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var FlagsEntitiesTelemetryClient=class extends TelemetryClient{trackSubcommand(subcommand,actual){this.trackCliSubcommand({subcommand,value:actual})}trackArguments(args,flags){args[0]&&this.trackCliArgument({arg:"kind",value:this.redactedValue}),this.trackCliOptionProject(flags["--project"]);for(let option of["label","attribute","add-attribute","remove-attribute","set-attribute-type"]){let value=flags[`--${option}`];(typeof value=="string"?value.trim():Array.isArray(value)&&value.length)&&this.trackCliOption({option,value:this.redactedValue})}for(let flag of["json","yes"])flags[`--${flag}`]&&this.trackCliFlag(flag)}};var import_chalk79=__toESM(require_source(),1),import_pluralize6=__toESM(require_pluralize(),1);var import_chalk78=__toESM(require_source(),1);async function loadEntityUsageSources(client,projectId){let[active,archived,segments2]=await Promise.all([getFlagsFromDatabase(client,projectId,"active"),getFlagsFromDatabase(client,projectId,"archived"),getSegments(client,projectId)]);return{flags:[...active,...archived],segments:segments2}}async function getFlagsFromDatabase(client,projectId,state){let flags=[],query=new URLSearchParams({state,limit:String(MAX_FLAGS_PAGE_LIMIT)}),cursor;do{let response=await client.fetch(`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/flags?${query}`);flags.push(...response.data),cursor=response.pagination?.next??null,cursor&&query.set("cursor",cursor)}while(cursor);return flags}function collectEntityUsage(sources,kind,attribute){let matches=reference=>reference.kind===kind&&(attribute===void 0||reference.attribute===attribute);return{flags:sources.flags.filter(flag=>flagReferences(flag).some(matches)).map(flag=>flag.slug),segments:sources.segments.filter(segment=>segmentReferences(segment).some(matches)).map(segment=>segment.slug)}}function hasEntityUsage(usage){return usage.flags.length>0||usage.segments.length>0}function flagReferences(flag){let references=Object.values(flag.environments).flatMap(environmentReferences);return flag.experiment&&references.push(flag.experiment.base),references}function environmentReferences(environment){let references=[];(environment.fallthrough.type==="split"||environment.fallthrough.type==="rollout")&&references.push(environment.fallthrough.base);for(let rule of environment.rules){for(let condition of rule.conditions)condition.lhs.type==="entity"&&references.push(condition.lhs);(rule.outcome.type==="split"||rule.outcome.type==="rollout")&&references.push(rule.outcome.base)}for(let targets2 of Object.values(environment.targets??{}))references.push(...membershipReferences(targets2));return references}function segmentReferences(segment){let references=[];for(let rule of segment.data.rules??[]){for(let condition of rule.conditions)condition.lhs.type==="entity"&&references.push(condition.lhs);rule.outcome.type==="split"&&references.push(rule.outcome.base)}return references.push(...membershipReferences(segment.data.include)),references.push(...membershipReferences(segment.data.exclude)),references}function membershipReferences(map){return map?Object.entries(map).flatMap(([kind,attributes])=>Object.entries(attributes).filter(([,values])=>values.length>0).map(([attribute])=>({kind,attribute}))):[]}async function resolveEntitiesProject(client,projectName){let link=await getLinkedFlagsProject(client,projectName);return link.status==="error"?{exitCode:link.exitCode}:link.status==="not_linked"?client.nonInteractive?(entityAgentError(client,{reason:AGENT_REASON.NOT_LINKED,message:"Your codebase is not linked to a project. Run link first.",next:[{command:"link",when:"link the project"}]}),{exitCode:1}):(output_manager_default.fatal(`Your codebase isn't linked to a project on Vercel. Pass --project <name>, or run ${getCommandName("link")} to link it.`),{exitCode:1}):(client.config.currentTeam=link.org.type==="team"?link.org.id:void 0,{project:link.project,org:link.org,projectSlugLink:formatProject(link.org.slug,link.project.name)})}function isExitCodeResult(result){return"exitCode"in result}function formatAttributeList(entity){return entity.attributes.length===0?import_chalk78.default.dim("-"):entity.attributes.map(attribute=>`${attribute.key}:${import_chalk78.default.dim(attribute.type)}`).join(", ")}function printEntityDetails(entity,projectSlugLink){output_manager_default.log(`
|
|
344
|
+
Feature flag entity ${import_chalk78.default.bold(entity.kind)} for ${projectSlugLink}
|
|
345
|
+
`),output_manager_default.print(` ${import_chalk78.default.dim("Kind:")} ${entity.kind}
|
|
346
|
+
`),output_manager_default.print(` ${import_chalk78.default.dim("Label:")} ${entity.label}
|
|
347
|
+
`),output_manager_default.print(` ${import_chalk78.default.dim("Attributes:")}
|
|
348
|
+
`),entity.attributes.length===0&&output_manager_default.print(` ${import_chalk78.default.dim("-")}
|
|
349
|
+
`);for(let attribute of entity.attributes)output_manager_default.print(` ${attribute.key} ${import_chalk78.default.dim(attribute.type)}
|
|
332
350
|
`);output_manager_default.print(`
|
|
333
|
-
`)}function reportEntityNotFound(client,kind,retryCommand){entityAgentError(client,{reason:AGENT_REASON.NOT_FOUND,message:`Entity ${kind} was not found in this project.`,next:[{command:"flags entities ls",when:"list entities to find the kind"},{command:retryCommand,when:"replace <kind> with an existing entity kind and retry"}]}),output_manager_default.fatal(`Entity ${
|
|
351
|
+
`)}function reportEntityNotFound(client,kind,retryCommand){entityAgentError(client,{reason:AGENT_REASON.NOT_FOUND,message:`Entity ${kind} was not found in this project.`,next:[{command:"flags entities ls",when:"list entities to find the kind"},{command:retryCommand,when:"replace <kind> with an existing entity kind and retry"}]}),output_manager_default.fatal(`Entity ${import_chalk78.default.bold(kind)} was not found. Run ${cmd(buildCommandWithGlobalFlags(client.argv,"flags entities ls",void 0,{preserveProject:!0,excludeFlags:["--yes"]}))} to list entities.`)}function reportEntityInUse(client,options){let{kind,attribute,usage,retryCommand}=options;if(!hasEntityUsage(usage))return!1;let lines=[`${attribute?`Attribute ${kind}.${attribute}`:`Entity ${kind}`} is still in use and can't be changed.`];usage.flags.length>0&&lines.push(`Used by feature flags: ${usage.flags.join(", ")}`),usage.segments.length>0&&lines.push(`Used by segments: ${usage.segments.join(", ")}`);let inspectCommand=usage.flags.length>0?`flags inspect ${quoteArg(usage.flags[0])}`:`flags segments inspect ${quoteArg(usage.segments[0])}`;return entityAgentError(client,{reason:AGENT_REASON.ENTITY_IN_USE,message:lines.join(`
|
|
334
352
|
`),next:[{command:inspectCommand,when:"inspect one reference that still uses it"},{command:retryCommand,when:"retry after removing all references"}]}),lines.push("",`Run ${cmd(buildCommandWithGlobalFlags(client.argv,inspectCommand,void 0,{preserveProject:!0,excludeFlags:["--yes"]}))} to inspect one reference, remove all references to ${attribute?"the attribute":"the entity"}, then try again.`),output_manager_default.fatal(lines.join(`
|
|
335
353
|
`)),!0}async function selectEntityKind(client,entities2,action,retryCommand){if(client.nonInteractive){entityAgentError(client,{reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Provide an entity kind. Run `vercel flags entities ls` to list entities.",next:[{command:retryCommand,when:`replace <kind> with the entity kind to ${action}`},{command:"flags entities ls",when:"list entities to find the kind"}]});return}if(!client.stdin.isTTY){output_manager_default.fatal(`Provide an entity kind to ${action}`),output_manager_default.log(`Example: ${getCommandName(action==="delete"?"flags entities delete device":"flags entities update user --add-attribute email:string")}`);return}if(entities2.length===0){output_manager_default.log("No feature flag entities found");return}return client.input.select({message:`Select an entity to ${action}:`,choices:entities2.map(entity=>({name:`${entity.label} (${entity.kind})`,value:entity.kind}))})}function parseEntityArguments(client,argv,options){let parsed=parseArguments(argv,getFlagsSpecification(options));return new FlagsEntitiesTelemetryClient({opts:{store:client.telemetryEventStore}}).trackArguments(parsed.args,parsed.flags),parsed}function entityAgentError(client,payload){outputAgentError(client,{...payload,status:AGENT_STATUS.ERROR,next:payload.next?.map(next=>({...next,command:buildCommandWithGlobalFlags(client.argv,next.command,void 0,{preserveProject:next.command.startsWith("flags "),excludeFlags:["--yes"]})}))},1)}async function entitiesLs(client,argv){let parsedArgs=parseEntityArguments(client,argv,entitiesListSubcommand.options),{flags}=parsedArgs,json=flags["--json"],projectName=getProjectNameFromFlags(flags),context=await resolveEntitiesProject(client,projectName);if(isExitCodeResult(context))return context.exitCode;let{project,projectSlugLink}=context,lsStamp=stamp_default();output_manager_default.spinner(`Fetching feature flag entities for ${projectSlugLink}`);let settings=await getFlagSettings(client,project.id).catch(err=>{if(!(isAPIError(err)&&err.status===404&&err.code==="settings_not_found"))throw err});output_manager_default.stopSpinner();let entities2=settings?.entities??[];return json?client.stdout.write(`${JSON.stringify({entities:entities2},null,2)}
|
|
336
|
-
`):settings?entities2.length===0?(output_manager_default.log(`No feature flag entities found for ${projectSlugLink} ${
|
|
337
|
-
Create one with: ${getCommandName("flags entities create user --label User --attribute id:string")}`)):(output_manager_default.log(`${(0,
|
|
338
|
-
Create your first flag to set it up: ${cmd(buildCommandWithGlobalFlags(client.argv,"flags create my-feature",void 0,{preserveProject:!0}))}`)),0}function printEntitiesTable(entities2){let headers=["Kind","Label","Attributes"],rows=entities2.map(entity=>[
|
|
354
|
+
`):settings?entities2.length===0?(output_manager_default.log(`No feature flag entities found for ${projectSlugLink} ${import_chalk79.default.gray(lsStamp())}`),output_manager_default.log(`
|
|
355
|
+
Create one with: ${getCommandName("flags entities create user --label User --attribute id:string")}`)):(output_manager_default.log(`${(0,import_pluralize6.default)("feature flag entity",entities2.length,!0)} found for ${projectSlugLink} ${import_chalk79.default.gray(lsStamp())}`),printEntitiesTable(entities2)):(output_manager_default.log(`Flags is not set up for ${projectSlugLink} yet.`),output_manager_default.log(`
|
|
356
|
+
Create your first flag to set it up: ${cmd(buildCommandWithGlobalFlags(client.argv,"flags create my-feature",void 0,{preserveProject:!0}))}`)),0}function printEntitiesTable(entities2){let headers=["Kind","Label","Attributes"],rows=entities2.map(entity=>[import_chalk79.default.bold(entity.kind),entity.label,formatAttributeList(entity)]),table2=formatTable(headers,["l","l","l"],[{name:"",rows}]);output_manager_default.print(`
|
|
339
357
|
${table2}
|
|
340
|
-
`)}var
|
|
341
|
-
`),0):(output_manager_default.success(`Feature flag entity ${
|
|
342
|
-
`),0):(output_manager_default.success(`Feature flag entity ${import_chalk80.default.bold(result.kind)} updated`),printEntityDetails(result,projectSlugLink),0)}function parseChanges(input){input.label!==void 0&&validateEntityLabel(input.label);let addAttributes=parseAttributeInputs(input.addInputs),setAttributeTypes=parseAttributeInputs(input.setTypeInputs),removeAttributes=input.removeInputs.map(value=>value.trim());for(let key of removeAttributes)validateAttributeKey(key);let removed=new Set(removeAttributes);for(let attribute of[...addAttributes,...setAttributeTypes])if(removed.has(attribute.key))throw new Error(`Attribute "${attribute.key}" can not be removed and changed in the same command.`);let added=new Set(addAttributes.map(attribute=>attribute.key));for(let attribute of setAttributeTypes)if(added.has(attribute.key))throw new Error(`Attribute "${attribute.key}" can not be added and have its type changed in the same command.`);return{label:input.label,addAttributes,removeAttributes,setAttributeTypes}}function applyChanges(entity,changes){let removed=new Set(changes.removeAttributes),typeByKey=new Map(changes.setAttributeTypes.map(attribute=>[attribute.key,attribute.type]));return{...entity,label:changes.label??entity.label,attributes:[...entity.attributes.filter(attribute=>!removed.has(attribute.key)).map(attribute=>{let type=typeByKey.get(attribute.key);return type!==void 0&&type!==attribute.type?{key:attribute.key,type}:attribute}),...changes.addAttributes]}}function buildRetryCommand(kind,changes){let parts=[`flags entities update ${kind===void 0?"<kind>":quoteArg(kind)}`];changes.label!==void 0&&parts.push(`--label ${quoteArg(changes.label)}`);for(let attribute of changes.addAttributes)parts.push(`--add-attribute ${quoteArg(`${attribute.key}:${attribute.type}`)}`);for(let key of changes.removeAttributes)parts.push(`--remove-attribute ${quoteArg(key)}`);for(let attribute of changes.setAttributeTypes)parts.push(`--set-attribute-type ${quoteArg(`${attribute.key}:${attribute.type}`)}`);return parts.join(" ")}var import_chalk81=__toESM(require_source(),1),import_pluralize6=__toESM(require_pluralize(),1);async function entitiesRm(client,argv){let parsedArgs=parseEntityArguments(client,argv,entitiesRemoveSubcommand.options),{args,flags}=parsedArgs;if(args.length>1){let message="Provide only one entity kind to delete.";return entityAgentError(client,{reason:AGENT_REASON.INVALID_ARGUMENTS,message,next:[{command:"flags entities delete <kind> --yes",when:"replace <kind> with the single entity kind to delete"}]}),client.nonInteractive||output_manager_default.fatal(message),2}let kind=args[0],skipConfirmation=flags["--yes"],projectName=getProjectNameFromFlags(flags);if(client.nonInteractive||!client.stdin.isTTY){if(!kind)return await selectEntityKind(client,[],"delete","flags entities delete <kind> --yes"),2;if(!skipConfirmation)return reportMissingConfirmation(client,kind),1}let context=await resolveEntitiesProject(client,projectName);if(isExitCodeResult(context))return context.exitCode;let{project,projectSlugLink}=context;output_manager_default.spinner("Fetching feature flag settings\u2026");let settings=await getFlagSettings(client,project.id),prompted=!1;if(output_manager_default.stopSpinner(),!kind&&(printAlignedLabel("Project",projectSlugLink),kind=await selectEntityKind(client,settings.entities,"delete","flags entities delete <kind> --yes"),prompted=!0,!kind))return 1;let entity=findEntity(settings.entities,kind);if(!entity)return reportEntityNotFound(client,kind,"flags entities delete <kind> --yes"),1;if(!skipConfirmation){prompted||printAlignedLabel("Project",projectSlugLink);let confirmed=await client.input.confirm(`Delete entity ${import_chalk81.default.bold(entity.kind)} and its ${(0,import_pluralize6.default)("attribute",entity.attributes.length,!0)}?`,!1);if(prompted=!0,!confirmed)return output_manager_default.log("Aborted"),0}if(prompted&&(settings=await getFlagSettings(client,project.id),!findEntity(settings.entities,kind)))return reportEntityNotFound(client,kind,"flags entities delete <kind> --yes"),1;output_manager_default.spinner("Checking flags and segments for references\u2026");let sources=await loadEntityUsageSources(client,project.id);return output_manager_default.stopSpinner(),reportEntityInUse(client,{kind,usage:collectEntityUsage(sources,kind),retryCommand:`flags entities delete ${quoteArg(kind)} --yes`})?1:(output_manager_default.spinner("Deleting entity\u2026"),await updateFlagSettings(client,project.id,{entities:settings.entities.filter(candidate=>candidate.kind!==kind)}),output_manager_default.stopSpinner(),output_manager_default.success(`Feature flag entity ${import_chalk81.default.bold(entity.kind)} deleted`),0)}function reportMissingConfirmation(client,kind){entityAgentError(client,{reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`Add --yes to delete entity ${kind}.`,next:[{command:`flags entities delete ${quoteArg(kind)} --yes`,when:"delete the entity"}]}),client.nonInteractive||output_manager_default.fatal("Missing required option --yes. Add --yes to delete the entity without prompting.")}var commands={ls:{command:entitiesListSubcommand,run:entitiesLs},create:{command:entitiesCreateSubcommand,run:entitiesCreate},update:{command:entitiesUpdateSubcommand,run:entitiesUpdate},delete:{command:entitiesRemoveSubcommand,run:entitiesRm}},aliases=Object.fromEntries(Object.entries(commands).map(([name,{command}])=>[name,getCommandAliases(command)]));async function entities(client){let telemetry=new FlagsEntitiesTelemetryClient({opts:{store:client.telemetryEventStore}});try{let parsed=parseArguments(client.argv.slice(4),getFlagsSpecification(entitiesSubcommand.options),{permissive:!0}),{subcommand,args,subcommandOriginal}=getSubcommand(parsed.args,aliases),entry=typeof subcommand=="string"?commands[subcommand]:void 0;return parsed.flags["--help"]||!entry?(parsed.flags["--help"]?telemetry.trackCliFlagHelp("flags entities",entry?subcommandOriginal:void 0):output_manager_default.fatal(getInvalidSubcommand(aliases)),output_manager_default.print(help(entry?.command??entitiesSubcommand,{stream:client.stderr,parent:entry?{...entitiesSubcommand,name:"flags entities"}:flagsCommand,columns:client.stderr.columns})),parsed.flags["--help"]?0:2):(telemetry.trackSubcommand(subcommand,subcommandOriginal),subcommand==="create"&&subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags entities add","flags entities create"),subcommand==="delete"&&subcommandOriginal==="remove"&&warnDeprecatedSubcommand(client,"flags entities remove","flags entities delete"),await entry.run(client,args))}catch(err){return output_manager_default.stopSpinner(),printError(err),1}}var import_pluralize7=__toESM(require_pluralize(),1);function parseEntityLabelOperations(input){let operations;if(input.data!==void 0){if(input.set.length||input.remove.length)throw new Error("Can't combine --data with --set or --remove.");let data;try{data=JSON.parse(input.data)}catch{throw new Error("--data must be a JSON array of label operations.")}if(!Array.isArray(data)||data.length===0)throw new Error("--data must be a non-empty JSON array of label operations.");operations=data}else operations=[...input.remove.map(value=>({operation:"delete",value})),...input.set.map(valueLabel=>{let separator=valueLabel.indexOf("=");if(separator===-1)throw new Error('Use --set VALUE=LABEL, for example --set "pro=Pro Plan".');return{operation:"upsert",value:valueLabel.slice(0,separator),label:valueLabel.slice(separator+1)}})];return validateEntityLabelOperations(operations)}var MAX_LABEL_OPERATIONS=100;function validateEntityLabelOperations(operations){if(operations.length>MAX_LABEL_OPERATIONS)throw new Error(`Cannot update more than ${MAX_LABEL_OPERATIONS} labels at once. Split the operations into smaller batches.`);let values=new Set;return operations.map(item=>{if(!item||typeof item!="object")throw new Error("Each label operation must be an object.");let record=item,{operation,value,label}=record;if(operation!=="upsert"&&operation!=="delete")throw new Error('Label operations must use "upsert" or "delete".');let keys=operation==="upsert"?["operation","value","label"]:["operation","value"];if(Object.keys(record).some(key=>!keys.includes(key)))throw new Error(`Label ${operation} operations accept only ${keys.join(", ")}.`);if(validateLabelString(value,"value"),values.has(value))throw new Error("Each value can have only one label operation per command.");return values.add(value),operation==="delete"?{operation,value}:(validateLabelString(label,"label"),{operation,value,label})})}function validateLabelString(value,field){if(typeof value!="string"||Array.from(value).length>128)throw new Error(`Label ${field} must be a string of at most 128 characters.`)}function updateEntityLabelsBulk(client,projectId,items){return client.fetch(`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/labels/bulk`,{method:"PATCH",body:{items},retry:{retries:0},bailOn429:!0})}function parseLabelPagination(limit=20,next,attribute){if(!Number.isSafeInteger(limit)||limit<1)throw new Error("The --limit option must be a positive integer.");if(next===void 0)return{limit};try{if(!/^[A-Za-z0-9_-]+$/.test(next)||next.length>4096)throw new Error;let cursor=JSON.parse(Buffer.from(next,"base64url").toString("utf8"));if(!cursor||cursor.version!==1||typeof cursor.projectId!="string"||!cursor.projectId||cursor.attribute!==attribute||typeof cursor.after!="string")throw new Error;return{limit,cursor}}catch{throw new Error("Invalid or expired --next cursor for this list view. Omit --next to restart the list.")}}function paginateLabelItems(items,{limit,cursor},projectId,attribute,key){let remaining=items.filter(item=>cursor===void 0||key(item)>cursor.after).sort((a,b)=>key(a)<key(b)?-1:key(a)>key(b)?1:0),page=remaining.slice(0,limit),next=remaining.length>page.length?Buffer.from(JSON.stringify({version:1,projectId,attribute,after:key(page[page.length-1])})).toString("base64url"):null;return{items:page,pagination:{next}}}var FlagsLabelsTelemetryClient=class extends TelemetryClient{trackSubcommand(subcommand,actual){this.trackCliSubcommand({subcommand,value:actual})}trackArguments(args,flags){for(let[index,arg]of["attribute","value","label"].entries())index<args.length&&this.trackCliArgument({arg,value:this.redactedValue});this.trackCliOptionProject(flags["--project"]);for(let option of["set","remove","data","next"])flags[`--${option}`]!==void 0&&this.trackCliOption({option,value:this.redactedValue});flags["--limit"]!==void 0&&this.trackCliOption({option:"limit",value:String(flags["--limit"])}),flags["--json"]&&this.trackCliFlag("json")}};async function labels(client){let argv=client.argv.slice(4),telemetry=new FlagsLabelsTelemetryClient({opts:{store:client.telemetryEventStore}}),json=client.nonInteractive||argv.includes("--json"),inspectCommand="flags entities ls --json",reason=AGENT_REASON.INVALID_ARGUMENTS,recovery="Inspect entities and labels before retrying";function next(){return[{command:buildCommandWithGlobalFlags(client.argv,inspectCommand,void 0,{preserveProject:inspectCommand.startsWith("flags ")}),when:recovery}]}function printRecovery(){output_manager_default.print(` ${recovery}:
|
|
358
|
+
`)}var import_chalk80=__toESM(require_source(),1);var IDENTIFIER_PATTERN=/^[a-zA-Z0-9_-]+$/,MAX_ENTITIES=32,MAX_ATTRIBUTES=32,MAX_IDENTIFIER_LENGTH=128;function validateEntityKind(kind){if(!IDENTIFIER_PATTERN.test(kind)||kind.length>MAX_IDENTIFIER_LENGTH)throw new Error(`Invalid entity kind "${kind}". Use up to ${MAX_IDENTIFIER_LENGTH} letters, numbers, dashes, and underscores, for example user.`)}function validateEntityLabel(label){if(label.trim().length===0)throw new Error("Entity label can not be empty.");if(label.length>MAX_IDENTIFIER_LENGTH)throw new Error(`Entity label can not be longer than ${MAX_IDENTIFIER_LENGTH} characters.`)}function validateAttributeKey(key){if(!IDENTIFIER_PATTERN.test(key)||key.length>MAX_IDENTIFIER_LENGTH)throw new Error(`Invalid attribute key "${key}". Use up to ${MAX_IDENTIFIER_LENGTH} letters, numbers, dashes, and underscores, for example plan.`)}function parseAttributeType(type,key){if(!isFlagAttributeType(type))throw new Error(`Invalid type "${type}" for attribute "${key}". Valid types: ${formatFlagAttributeTypeList()}.`);return type}function parseAttributeInput(input){let parts=input.trim().split(":").map(part=>part.trim());if(parts.length!==2||!parts[0]||!parts[1])throw new Error(`Invalid attribute "${input}". Use KEY:TYPE, for example plan:string. Valid types: ${formatFlagAttributeTypeList()}.`);let[key,type]=parts;return validateAttributeKey(key),{key,type:parseAttributeType(type,key)}}function parseAttributeInputs(inputs){let attributes=inputs.map(parseAttributeInput),seen=new Set;for(let attribute of attributes){if(seen.has(attribute.key))throw new Error(`Attribute "${attribute.key}" is specified twice.`);seen.add(attribute.key)}return attributes}function defaultEntityLabel(kind){return kind.split(/[-_\s]+/).filter(Boolean).map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function findEntity(entities2,kind){return entities2.find(entity=>entity.kind===kind)}function findAttribute(entity,key){return entity.attributes.find(attribute=>attribute.key===key)}function validateEntities(entities2){if(entities2.length>MAX_ENTITIES)throw new Error(`A project can have at most ${MAX_ENTITIES} entities. Remove one before adding another.`);let kinds=new Set,labels2=new Set;for(let entity of entities2){if(kinds.has(entity.kind))throw new Error(`Entity kind "${entity.kind}" already exists.`);if(labels2.has(entity.label.trim()))throw new Error(`Entity label "${entity.label}" is already used by another entity.`);if(kinds.add(entity.kind),labels2.add(entity.label.trim()),entity.attributes.length>MAX_ATTRIBUTES)throw new Error(`Entity "${entity.kind}" can have at most ${MAX_ATTRIBUTES} attributes.`);let keys=new Set;for(let attribute of entity.attributes){if(keys.has(attribute.key))throw new Error(`Attribute "${attribute.key}" already exists on entity "${entity.kind}".`);keys.add(attribute.key)}}}async function entitiesCreate(client,argv){let parsedArgs=parseEntityArguments(client,argv,entitiesCreateSubcommand.options),{args,flags}=parsedArgs,[kind]=args,label=flags["--label"]?.trim(),attributeInputs=flags["--attribute"]??[],json=flags["--json"],projectName=getProjectNameFromFlags(flags);if(!kind)return client.nonInteractive?(entityAgentError(client,{reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Provide an entity kind to create.",next:[{command:"flags entities create <kind> --label <label> --attribute <key>:<type>",when:"create an entity with explicit attributes"}]}),2):(output_manager_default.fatal("Provide a kind for the entity"),output_manager_default.log(`Example: ${getCommandName("flags entities create user --label User --attribute id:string")}`),2);let attributes;try{validateEntityKind(kind),label!==void 0&&validateEntityLabel(label),attributes=parseAttributeInputs(attributeInputs)}catch(err){return output_manager_default.fatal(err.message),2}let context=await resolveEntitiesProject(client,projectName);if(isExitCodeResult(context))return context.exitCode;let{project,projectSlugLink}=context;output_manager_default.spinner("Fetching feature flag settings\u2026");let settings=await getFlagSettings(client,project.id);if(output_manager_default.stopSpinner(),findEntity(settings.entities,kind))return output_manager_default.fatal(`Entity ${import_chalk80.default.bold(kind)} already exists. Run ${getCommandName(`flags entities update ${kind}`)} to change it.`),1;let willPrompt=client.stdin.isTTY&&!client.nonInteractive&&(label===void 0||attributes.length===0);willPrompt&&printAlignedLabel("Project",projectSlugLink),label=await resolveEntityLabel(client,label,kind),attributes.length===0&&client.stdin.isTTY&&!client.nonInteractive&&(attributes=await collectAttributesInteractively(client)),willPrompt&&(settings=await getFlagSettings(client,project.id));let entity={kind,label,attributes},entities2=[...settings.entities,entity];try{validateEntityLabel(label),validateEntities(entities2)}catch(err){return output_manager_default.fatal(err.message),1}output_manager_default.spinner("Creating entity\u2026");let updated=await updateFlagSettings(client,project.id,{entities:entities2});output_manager_default.stopSpinner();let created=findEntity(updated.entities,kind)??entity;return json?(client.stdout.write(`${JSON.stringify({entity:created},null,2)}
|
|
359
|
+
`),0):(output_manager_default.success(`Feature flag entity ${import_chalk80.default.bold(created.kind)} created`),printEntityDetails(created,projectSlugLink),0)}async function resolveEntityLabel(client,label,kind){if(label)return label;let defaultLabel=defaultEntityLabel(kind);return client.stdin.isTTY&&!client.nonInteractive&&(await client.input.text({message:`Enter a label for this entity (press Enter for "${defaultLabel}"):`})).trim()||defaultLabel}async function collectAttributesInteractively(client){let attributes=[],addAnother=await client.input.confirm("Add attributes now?",!0);for(;addAnother;){let key=await client.input.text({message:"Attribute key (for example plan):",validate:value=>{try{validateAttributeKey(value.trim())}catch(err){return err.message}return attributes.some(attribute=>attribute.key===value.trim())?`Attribute "${value.trim()}" is already added.`:!0}}),type=await client.input.select({message:"Attribute type:",choices:FLAG_ATTRIBUTE_TYPES.map(value=>({name:value,value}))});attributes.push({key:key.trim(),type}),addAnother=await client.input.confirm("Add another attribute?",!1)}return attributes}var import_chalk81=__toESM(require_source(),1);async function entitiesUpdate(client,argv){let parsedArgs=parseEntityArguments(client,argv,entitiesUpdateSubcommand.options),{args,flags}=parsedArgs,kind=args[0],label=flags["--label"]?.trim(),addInputs=flags["--add-attribute"]??[],removeInputs=flags["--remove-attribute"]??[],setTypeInputs=flags["--set-attribute-type"]??[],json=flags["--json"],projectName=getProjectNameFromFlags(flags),changes;try{changes=parseChanges({label,addInputs,removeInputs,setTypeInputs})}catch(err){return output_manager_default.fatal(err.message),2}if(!(changes.label!==void 0||changes.addAttributes.length>0||changes.removeAttributes.length>0||changes.setAttributeTypes.length>0))return client.nonInteractive?(entityAgentError(client,{reason:AGENT_REASON.MISSING_ARGUMENTS,message:"Provide at least one entity update option, such as --label, --add-attribute, --remove-attribute, or --set-attribute-type.",next:[{command:"flags entities update <kind> --add-attribute <key>:<type>",when:"add an attribute to an entity"},{command:"flags entities update <kind> --remove-attribute <key>",when:"remove an attribute from an entity"},{command:"flags entities ls --json",when:"inspect the current entities first"}]}),2):(output_manager_default.fatal("Provide at least one change: --label, --add-attribute, --remove-attribute, or --set-attribute-type"),output_manager_default.log(`Example: ${getCommandName("flags entities update user --add-attribute email:string")}`),2);let context=await resolveEntitiesProject(client,projectName);if(isExitCodeResult(context))return context.exitCode;let{project,projectSlugLink}=context;output_manager_default.spinner("Fetching feature flag settings\u2026");let settings=await getFlagSettings(client,project.id);if(output_manager_default.stopSpinner(),!kind){if(client.stdin.isTTY&&!client.nonInteractive&&printAlignedLabel("Project",projectSlugLink),kind=await selectEntityKind(client,settings.entities,"update",buildRetryCommand(void 0,changes)),!kind)return client.nonInteractive||!client.stdin.isTTY?2:1;settings=await getFlagSettings(client,project.id)}let entity=findEntity(settings.entities,kind);if(!entity)return reportEntityNotFound(client,kind,buildRetryCommand(void 0,changes)),1;let retryCommand=buildRetryCommand(kind,changes);for(let attribute of changes.addAttributes)if(findAttribute(entity,attribute.key))return output_manager_default.fatal(`Attribute "${attribute.key}" already exists on entity "${entity.kind}". Use --set-attribute-type to change its type.`),1;for(let key of changes.removeAttributes)if(!findAttribute(entity,key))return output_manager_default.fatal(`Attribute ${import_chalk81.default.bold(`${kind}.${key}`)} does not exist.`),1;for(let attribute of changes.setAttributeTypes)if(!findAttribute(entity,attribute.key))return output_manager_default.fatal(`Attribute ${import_chalk81.default.bold(`${kind}.${attribute.key}`)} does not exist. Use --add-attribute to add it.`),1;let updatedEntity=applyChanges(entity,changes),entities2=settings.entities.map(candidate=>candidate.kind===kind?updatedEntity:candidate);try{validateEntities(entities2)}catch(err){return output_manager_default.fatal(err.message),1}let typeChanges=changes.setAttributeTypes.filter(attribute=>findAttribute(entity,attribute.key)?.type!==attribute.type),guardedKeys=[...changes.removeAttributes,...typeChanges.map(attribute=>attribute.key)];if(guardedKeys.length>0){output_manager_default.spinner("Checking flags and segments for references\u2026");let sources=await loadEntityUsageSources(client,project.id);output_manager_default.stopSpinner();for(let key of guardedKeys){let usage=collectEntityUsage(sources,kind,key);if(reportEntityInUse(client,{kind,attribute:key,usage,retryCommand}))return 1}}output_manager_default.spinner("Updating entity\u2026");let updated=await updateFlagSettings(client,project.id,{entities:entities2});output_manager_default.stopSpinner();let result=findEntity(updated.entities,kind)??updatedEntity;return json?(client.stdout.write(`${JSON.stringify({entity:result},null,2)}
|
|
360
|
+
`),0):(output_manager_default.success(`Feature flag entity ${import_chalk81.default.bold(result.kind)} updated`),printEntityDetails(result,projectSlugLink),0)}function parseChanges(input){input.label!==void 0&&validateEntityLabel(input.label);let addAttributes=parseAttributeInputs(input.addInputs),setAttributeTypes=parseAttributeInputs(input.setTypeInputs),removeAttributes=input.removeInputs.map(value=>value.trim());for(let key of removeAttributes)validateAttributeKey(key);let removed=new Set(removeAttributes);for(let attribute of[...addAttributes,...setAttributeTypes])if(removed.has(attribute.key))throw new Error(`Attribute "${attribute.key}" can not be removed and changed in the same command.`);let added=new Set(addAttributes.map(attribute=>attribute.key));for(let attribute of setAttributeTypes)if(added.has(attribute.key))throw new Error(`Attribute "${attribute.key}" can not be added and have its type changed in the same command.`);return{label:input.label,addAttributes,removeAttributes,setAttributeTypes}}function applyChanges(entity,changes){let removed=new Set(changes.removeAttributes),typeByKey=new Map(changes.setAttributeTypes.map(attribute=>[attribute.key,attribute.type]));return{...entity,label:changes.label??entity.label,attributes:[...entity.attributes.filter(attribute=>!removed.has(attribute.key)).map(attribute=>{let type=typeByKey.get(attribute.key);return type!==void 0&&type!==attribute.type?{key:attribute.key,type}:attribute}),...changes.addAttributes]}}function buildRetryCommand(kind,changes){let parts=[`flags entities update ${kind===void 0?"<kind>":quoteArg(kind)}`];changes.label!==void 0&&parts.push(`--label ${quoteArg(changes.label)}`);for(let attribute of changes.addAttributes)parts.push(`--add-attribute ${quoteArg(`${attribute.key}:${attribute.type}`)}`);for(let key of changes.removeAttributes)parts.push(`--remove-attribute ${quoteArg(key)}`);for(let attribute of changes.setAttributeTypes)parts.push(`--set-attribute-type ${quoteArg(`${attribute.key}:${attribute.type}`)}`);return parts.join(" ")}var import_chalk82=__toESM(require_source(),1),import_pluralize7=__toESM(require_pluralize(),1);async function entitiesRm(client,argv){let parsedArgs=parseEntityArguments(client,argv,entitiesRemoveSubcommand.options),{args,flags}=parsedArgs;if(args.length>1){let message="Provide only one entity kind to delete.";return entityAgentError(client,{reason:AGENT_REASON.INVALID_ARGUMENTS,message,next:[{command:"flags entities delete <kind> --yes",when:"replace <kind> with the single entity kind to delete"}]}),client.nonInteractive||output_manager_default.fatal(message),2}let kind=args[0],skipConfirmation=flags["--yes"],projectName=getProjectNameFromFlags(flags);if(client.nonInteractive||!client.stdin.isTTY){if(!kind)return await selectEntityKind(client,[],"delete","flags entities delete <kind> --yes"),2;if(!skipConfirmation)return reportMissingConfirmation(client,kind),1}let context=await resolveEntitiesProject(client,projectName);if(isExitCodeResult(context))return context.exitCode;let{project,projectSlugLink}=context;output_manager_default.spinner("Fetching feature flag settings\u2026");let settings=await getFlagSettings(client,project.id),prompted=!1;if(output_manager_default.stopSpinner(),!kind&&(printAlignedLabel("Project",projectSlugLink),kind=await selectEntityKind(client,settings.entities,"delete","flags entities delete <kind> --yes"),prompted=!0,!kind))return 1;let entity=findEntity(settings.entities,kind);if(!entity)return reportEntityNotFound(client,kind,"flags entities delete <kind> --yes"),1;if(!skipConfirmation){prompted||printAlignedLabel("Project",projectSlugLink);let confirmed=await client.input.confirm(`Delete entity ${import_chalk82.default.bold(entity.kind)} and its ${(0,import_pluralize7.default)("attribute",entity.attributes.length,!0)}?`,!1);if(prompted=!0,!confirmed)return output_manager_default.log("Aborted"),0}if(prompted&&(settings=await getFlagSettings(client,project.id),!findEntity(settings.entities,kind)))return reportEntityNotFound(client,kind,"flags entities delete <kind> --yes"),1;output_manager_default.spinner("Checking flags and segments for references\u2026");let sources=await loadEntityUsageSources(client,project.id);return output_manager_default.stopSpinner(),reportEntityInUse(client,{kind,usage:collectEntityUsage(sources,kind),retryCommand:`flags entities delete ${quoteArg(kind)} --yes`})?1:(output_manager_default.spinner("Deleting entity\u2026"),await updateFlagSettings(client,project.id,{entities:settings.entities.filter(candidate=>candidate.kind!==kind)}),output_manager_default.stopSpinner(),output_manager_default.success(`Feature flag entity ${import_chalk82.default.bold(entity.kind)} deleted`),0)}function reportMissingConfirmation(client,kind){entityAgentError(client,{reason:AGENT_REASON.CONFIRMATION_REQUIRED,message:`Add --yes to delete entity ${kind}.`,next:[{command:`flags entities delete ${quoteArg(kind)} --yes`,when:"delete the entity"}]}),client.nonInteractive||output_manager_default.fatal("Missing required option --yes. Add --yes to delete the entity without prompting.")}var commands={ls:{command:entitiesListSubcommand,run:entitiesLs},create:{command:entitiesCreateSubcommand,run:entitiesCreate},update:{command:entitiesUpdateSubcommand,run:entitiesUpdate},delete:{command:entitiesRemoveSubcommand,run:entitiesRm}},aliases=Object.fromEntries(Object.entries(commands).map(([name,{command}])=>[name,getCommandAliases(command)]));async function entities(client){let telemetry=new FlagsEntitiesTelemetryClient({opts:{store:client.telemetryEventStore}});try{let parsed=parseArguments(client.argv.slice(4),getFlagsSpecification(entitiesSubcommand.options),{permissive:!0}),{subcommand,args,subcommandOriginal}=getSubcommand(parsed.args,aliases),entry=typeof subcommand=="string"?commands[subcommand]:void 0;return parsed.flags["--help"]||!entry?(parsed.flags["--help"]?telemetry.trackCliFlagHelp("flags entities",entry?subcommandOriginal:void 0):output_manager_default.fatal(getInvalidSubcommand(aliases)),output_manager_default.print(help(entry?.command??entitiesSubcommand,{stream:client.stderr,parent:entry?{...entitiesSubcommand,name:"flags entities"}:flagsCommand,columns:client.stderr.columns})),parsed.flags["--help"]?0:2):(telemetry.trackSubcommand(subcommand,subcommandOriginal),subcommand==="create"&&subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags entities add","flags entities create"),subcommand==="delete"&&subcommandOriginal==="remove"&&warnDeprecatedSubcommand(client,"flags entities remove","flags entities delete"),await entry.run(client,args))}catch(err){return output_manager_default.stopSpinner(),printError(err),1}}var import_pluralize8=__toESM(require_pluralize(),1);function parseEntityLabelOperations(input){let operations;if(input.data!==void 0){if(input.set.length||input.remove.length)throw new Error("Can't combine --data with --set or --remove.");let data;try{data=JSON.parse(input.data)}catch{throw new Error("--data must be a JSON array of label operations.")}if(!Array.isArray(data)||data.length===0)throw new Error("--data must be a non-empty JSON array of label operations.");operations=data}else operations=[...input.remove.map(value=>({operation:"delete",value})),...input.set.map(valueLabel=>{let separator=valueLabel.indexOf("=");if(separator===-1)throw new Error('Use --set VALUE=LABEL, for example --set "pro=Pro Plan".');return{operation:"upsert",value:valueLabel.slice(0,separator),label:valueLabel.slice(separator+1)}})];return validateEntityLabelOperations(operations)}var MAX_LABEL_OPERATIONS=100;function validateEntityLabelOperations(operations){if(operations.length>MAX_LABEL_OPERATIONS)throw new Error(`Cannot update more than ${MAX_LABEL_OPERATIONS} labels at once. Split the operations into smaller batches.`);let values=new Set;return operations.map(item=>{if(!item||typeof item!="object")throw new Error("Each label operation must be an object.");let record=item,{operation,value,label}=record;if(operation!=="upsert"&&operation!=="delete")throw new Error('Label operations must use "upsert" or "delete".');let keys=operation==="upsert"?["operation","value","label"]:["operation","value"];if(Object.keys(record).some(key=>!keys.includes(key)))throw new Error(`Label ${operation} operations accept only ${keys.join(", ")}.`);if(validateLabelString(value,"value"),values.has(value))throw new Error("Each value can have only one label operation per command.");return values.add(value),operation==="delete"?{operation,value}:(validateLabelString(label,"label"),{operation,value,label})})}function validateLabelString(value,field){if(typeof value!="string"||Array.from(value).length>128)throw new Error(`Label ${field} must be a string of at most 128 characters.`)}function updateEntityLabelsBulk(client,projectId,items){return client.fetch(`/v1/projects/${encodeURIComponent(projectId)}/feature-flags/labels/bulk`,{method:"PATCH",body:{items},retry:{retries:0},bailOn429:!0})}function parseLabelPagination(limit=20,next,attribute){if(!Number.isSafeInteger(limit)||limit<1)throw new Error("The --limit option must be a positive integer.");if(next===void 0)return{limit};try{if(!/^[A-Za-z0-9_-]+$/.test(next)||next.length>4096)throw new Error;let cursor=JSON.parse(Buffer.from(next,"base64url").toString("utf8"));if(!cursor||cursor.version!==1||typeof cursor.projectId!="string"||!cursor.projectId||cursor.attribute!==attribute||typeof cursor.after!="string")throw new Error;return{limit,cursor}}catch{throw new Error("Invalid or expired --next cursor for this list view. Omit --next to restart the list.")}}function paginateLabelItems(items,{limit,cursor},projectId,attribute,key){let remaining=items.filter(item=>cursor===void 0||key(item)>cursor.after).sort((a,b)=>key(a)<key(b)?-1:key(a)>key(b)?1:0),page=remaining.slice(0,limit),next=remaining.length>page.length?Buffer.from(JSON.stringify({version:1,projectId,attribute,after:key(page[page.length-1])})).toString("base64url"):null;return{items:page,pagination:{next}}}var FlagsLabelsTelemetryClient=class extends TelemetryClient{trackSubcommand(subcommand,actual){this.trackCliSubcommand({subcommand,value:actual})}trackArguments(args,flags){for(let[index,arg]of["attribute","value","label"].entries())index<args.length&&this.trackCliArgument({arg,value:this.redactedValue});this.trackCliOptionProject(flags["--project"]);for(let option of["set","remove","data","next"])flags[`--${option}`]!==void 0&&this.trackCliOption({option,value:this.redactedValue});flags["--limit"]!==void 0&&this.trackCliOption({option:"limit",value:String(flags["--limit"])}),flags["--json"]&&this.trackCliFlag("json")}};async function labels(client){let argv=client.argv.slice(4),telemetry=new FlagsLabelsTelemetryClient({opts:{store:client.telemetryEventStore}}),json=client.nonInteractive||argv.includes("--json"),inspectCommand="flags entities ls --json",reason=AGENT_REASON.INVALID_ARGUMENTS,recovery="Inspect entities and labels before retrying";function next(){return[{command:buildCommandWithGlobalFlags(client.argv,inspectCommand,void 0,{preserveProject:inspectCommand.startsWith("flags ")}),when:recovery}]}function printRecovery(){output_manager_default.print(` ${recovery}:
|
|
343
361
|
${next()[0].command}
|
|
344
362
|
`)}function fail(message){if(json){let status2=reason===AGENT_REASON.MISSING_ARGUMENTS||reason===AGENT_REASON.NOT_LINKED?AGENT_STATUS.ACTION_REQUIRED:AGENT_STATUS.ERROR;client.stdout.write(`${JSON.stringify({status:status2,reason,message,next:next()},null,2)}
|
|
345
363
|
`)}else output_manager_default.fatal(message),printRecovery();return getExitCodeForReason(reason)}try{let printNextPage2=function(cursor){if(!json&&cursor&&pageOptions){let globalArgs=getGlobalFlagsFromArgs(client.argv.slice(2));globalArgs.some(arg=>arg==="--scope"||arg==="-S"||arg.startsWith("--scope="))||globalArgs.push("--scope",org.slug);let command2=getCommandNamePlain(["flags","labels","ls",...target===void 0?[]:[target],"--project",project.name,"--limit",String(pageOptions.limit),"--next",cursor,...globalArgs].map(quoteArg).join(" "));output_manager_default.print(`
|
|
@@ -349,29 +367,29 @@ ${formatTable(["Attribute","Labels"],["l","r"],[{name:"",rows}])}
|
|
|
349
367
|
`)}return printNextPage2(pagination.next),0}let entity=findEntity(settings.entities,kind),attribute=entity&&findAttribute(entity,attributeKey);if(!attribute)return reason=AGENT_REASON.NOT_FOUND,fail(entity?`Attribute ${kind}.${attributeKey} was not found in this project.`:`Entity ${kind} was not found in this project.`);if(inspectCommand=`flags labels ls ${quoteArg(`${kind}.${attributeKey}`)} --json`,pageOptions){let{items:labels2,pagination}=paginateLabelItems(attribute.labels??[],pageOptions,project.id,`${kind}.${attributeKey}`,label=>label.value);if(json)client.stdout.write(`${JSON.stringify({status:AGENT_STATUS.OK,entityKind:kind,attributeKey,labels:labels2,pagination},null,2)}
|
|
350
368
|
`);else if(printAlignedLabel("Project",projectSlugLink),printAlignedLabel("Attribute",`${kind}.${attributeKey}`),labels2.length===0)output_manager_default.log(pageOptions.cursor?"No more value labels found.":"No value labels found.");else{let rows=labels2.map(({value,label})=>[formatLabelCell(value),formatLabelCell(label)]);output_manager_default.print(`
|
|
351
369
|
${formatTable(["Value","Label"],["l","l"],[{name:"",rows}])}
|
|
352
|
-
`)}return printNextPage2(pagination.next),0}if(attribute.type!=="string"&&attribute.type!=="stringArray")return reason=AGENT_REASON.INVALID_ARGUMENTS,fail("Value labels are supported only for string and stringArray attributes.");json||(printAlignedLabel("Project",projectSlugLink),printAlignedLabel("Attribute",`${kind}.${attributeKey}`)),output_manager_default.spinner("Updating attribute labels\u2026");let result=await updateEntityLabelsBulk(client,project.id,operations.map(operation=>({...operation,entityKind:kind,attributeKey})));output_manager_default.stopSpinner();let failed=result.errors.length>0,message=`${(0,
|
|
370
|
+
`)}return printNextPage2(pagination.next),0}if(attribute.type!=="string"&&attribute.type!=="stringArray")return reason=AGENT_REASON.INVALID_ARGUMENTS,fail("Value labels are supported only for string and stringArray attributes.");json||(printAlignedLabel("Project",projectSlugLink),printAlignedLabel("Attribute",`${kind}.${attributeKey}`)),output_manager_default.spinner("Updating attribute labels\u2026");let result=await updateEntityLabelsBulk(client,project.id,operations.map(operation=>({...operation,entityKind:kind,attributeKey})));output_manager_default.stopSpinner();let failed=result.errors.length>0,message=`${(0,import_pluralize8.default)("label operation",result.labels.length,!0)} applied, ${result.errors.length} failed.`;if(json)client.stdout.write(`${JSON.stringify({status:failed?AGENT_STATUS.ERROR:AGENT_STATUS.OK,entityKind:kind,attributeKey,...result,...failed?{reason:AGENT_REASON.API_ERROR,message,next:next()}:{}},null,2)}
|
|
353
371
|
`);else if(failed){output_manager_default.fatal(message);for(let error of result.errors)output_manager_default.print(` ${JSON.stringify(error.value)}: ${error.code} \u2014 ${JSON.stringify(error.message)}
|
|
354
|
-
`);printRecovery()}else{let set2=result.labels.filter(item=>item.operation==="upsert").length,removed=result.labels.filter(item=>item.operation==="delete").length;output_manager_default.success(`Value labels updated for ${kind}.${attributeKey}: ${set2} set, ${removed} removed`)}return failed?1:0}catch(err){return output_manager_default.stopSpinner(),isAPIError(err)&&(reason=err.status===403?AGENT_REASON.PERMISSION_DENIED:AGENT_REASON.API_ERROR),fail(err instanceof Error?err.message:"Failed to manage attribute labels.")}}function formatLabelCell(value){let quoted=JSON.stringify(value);return value===""||value.trim()!==value||quoted.slice(1,-1)!==value?quoted:value}var FlagsRulesTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandAdd(actual){this.trackCliSubcommand({subcommand:"add",value:actual})}trackCliSubcommandUpdate(actual){this.trackCliSubcommand({subcommand:"update",value:actual})}trackCliSubcommandRemove(actual){this.trackCliSubcommand({subcommand:"rm",value:actual})}trackCliSubcommandMove(actual){this.trackCliSubcommand({subcommand:"move",value:actual})}},FlagsRulesCommandTelemetryClient=class extends TelemetryClient{trackCliArgumentFlag(flag){flag&&this.trackCliArgument({arg:"flag",value:this.redactedValue})}trackCliArgumentRule(rule){rule&&this.trackCliArgument({arg:"rule",value:this.redactedValue})}trackCliOptionEnvironment(environment){environment&&this.trackCliOption({option:"environment",value:STANDARD_ENVIRONMENTS.includes(environment)?environment:this.redactedValue})}trackCliOptionCondition(condition){condition?.length&&this.trackCliOption({option:"condition",value:this.redactedValue})}trackCliOptionVariant(variant){variant&&this.trackCliOption({option:"variant",value:this.redactedValue})}trackCliOptionBy(base){base&&this.trackCliOption({option:"by",value:this.redactedValue})}trackCliOptionWeight(weights){weights?.length&&this.trackCliOption({option:"weight",value:this.redactedValue})}trackCliOptionDefaultVariant(variant){variant&&this.trackCliOption({option:"default-variant",value:this.redactedValue})}trackCliOptionFromVariant(variant){variant&&this.trackCliOption({option:"from-variant",value:this.redactedValue})}trackCliOptionToVariant(variant){variant&&this.trackCliOption({option:"to-variant",value:this.redactedValue})}trackCliOptionStage(stages){stages?.length&&this.trackCliOption({option:"stage",value:this.redactedValue})}trackCliOptionFinalPercentage(percentage){percentage!==void 0&&this.trackCliOption({option:"final-percentage",value:this.redactedValue})}trackCliOptionStart(start){start&&this.trackCliOption({option:"start",value:this.redactedValue})}trackCliOptionPosition(position){position!==void 0&&this.trackCliOption({option:"position",value:String(position)})}trackCliOptionMessage(message){message&&this.trackCliOption({option:"message",value:this.redactedValue})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}};var import_chalk83=__toESM(require_source(),1),import_pluralize8=__toESM(require_pluralize(),1);import{randomBytes as randomBytes3}from"node:crypto";var RHS_OPTIONAL_OPERATORS2=new Set(FLAG_CONDITION_RHS_OPTIONAL_COMPARATORS);function parseFlagRuleConditions(inputs,settings){let conditionInputs=inputs.flatMap(input=>{let trimmed=input.trim();return!trimmed||trimmed.startsWith("{")?[trimmed]:trimmed.split(";").map(part=>part.trim()).filter(Boolean)});if(conditionInputs.length===0)throw new Error("At least one --condition is required. Use --condition <ENTITY.ATTRIBUTE:OPERATOR:VALUE>.");return conditionInputs.map(input=>coerceTimestampCondition(parseFlagRuleConditionInput(input),settings,"input"))}function parseFlagRuleConditionInput(input){let trimmed=input.trim();if(!trimmed)throw new Error("Flag rule condition cannot be empty");if(trimmed.startsWith("{")){let value=parseJson2(trimmed,"flag rule condition");if(!isRecord2(value))throw new Error("Flag rule condition JSON must be an object");return value}let[field,operator,...valueParts]=trimmed.split(":");if(!field||!operator)throw new Error(`Invalid flag rule condition "${input}". Use ENTITY.ATTRIBUTE:OPERATOR:VALUE or segment:OPERATOR:SEGMENT.`);let cmp=parseComparator(operator,"flag rule"),rawValue=valueParts.join(":");if(!rawValue&&!RHS_OPTIONAL_OPERATORS2.has(cmp))throw new Error(`Flag rule condition "${input}" is missing a value`);return{lhs:parseFlagConditionLhs(field),cmp,...rawValue?{rhs:parseConditionValue(rawValue,cmp)}:{}}}function hasFlagRuleOutcomeOptions(options){return!!(options.variantSelector||options.baseSelector||options.defaultVariantSelector||options.weightInputs.length>0||options.rollFromVariantSelector||options.rollToVariantSelector||options.stageInputs.length>0||options.start||options.finalPercentage!==void 0)}function needsFlagRuleOutcomeSettings(options){return options.variantSelector?!1:!!(options.baseSelector||options.defaultVariantSelector||options.weightInputs.length>0||options.rollFromVariantSelector||options.rollToVariantSelector||options.stageInputs.length>0||options.start||options.finalPercentage!==void 0)}function resolveFlagRuleOutcome(flag,settings,options){let hasVariant=!!options.variantSelector,hasRolloutOnlyOptions=!!(options.rollFromVariantSelector||options.rollToVariantSelector||options.stageInputs.length>0||options.start||options.finalPercentage!==void 0),hasSplitOnlyOptions=options.weightInputs.length>0,hasCommonOptions=!!(options.baseSelector||options.defaultVariantSelector);if(hasVariant&&(hasRolloutOnlyOptions||hasSplitOnlyOptions||hasCommonOptions))throw new Error("Cannot combine --variant with split or rollout outcome options.");if(hasRolloutOnlyOptions&&hasSplitOnlyOptions)throw new Error("Cannot combine --weight with rollout outcome options.");if(options.variantSelector)return{type:"variant",variantId:resolveVariantOrThrow(options.variantSelector,flag.variants,"--variant").id};if(hasRolloutOnlyOptions||hasCommonOptions&&options.currentOutcome?.type==="rollout")return resolveFlagRollout(flag,requireFlagSettings(settings),{stageInputs:options.stageInputs,finalPercentage:options.finalPercentage,baseSelector:options.baseSelector,rollFromVariantSelector:options.rollFromVariantSelector,rollToVariantSelector:options.rollToVariantSelector,defaultVariantSelector:options.defaultVariantSelector,start:options.start,currentOutcome:options.currentOutcome?.type==="experiment"?void 0:options.currentOutcome}).outcome;if(hasSplitOnlyOptions||hasCommonOptions)return resolveFlagSplit(flag,requireFlagSettings(settings),{weightInputs:options.weightInputs,baseSelector:options.baseSelector,defaultVariantSelector:options.defaultVariantSelector,currentOutcome:options.currentOutcome?.type==="experiment"?void 0:options.currentOutcome}).outcome;if(options.currentOutcome&&!options.requireOutcome)return options.currentOutcome;throw new Error("Missing rule outcome. Use --variant <VARIANT>, split options such as --weight, or rollout options such as --stage.")}function createFlagRule(conditions,outcome){return{id:shortId2("rule_"),conditions,outcome}}function addFlagRule(envConfig,rule,position){let rules2=structuredClone(envConfig.rules??[]),insertionIndex=resolvePosition(position,rules2.length+1)-1;return rules2.splice(insertionIndex,0,rule),buildRulesEnvironmentConfig(envConfig,rules2)}function removeFlagRule(envConfig,ruleId){let rules2=structuredClone(envConfig.rules??[]),ruleIndex=findFlagRuleIndex(rules2,ruleId);return rules2.splice(ruleIndex,1),buildRulesEnvironmentConfig(envConfig,rules2)}function updateFlagRule(envConfig,ruleId,updates){let rules2=structuredClone(envConfig.rules??[]),ruleIndex=findFlagRuleIndex(rules2,ruleId);return rules2[ruleIndex]={...rules2[ruleIndex],...updates.conditions?{conditions:updates.conditions}:{},...updates.outcome?{outcome:updates.outcome}:{}},buildRulesEnvironmentConfig(envConfig,rules2)}function moveFlagRule(envConfig,ruleId,position){let rules2=structuredClone(envConfig.rules??[]),targetPosition=resolvePosition(position,rules2.length),ruleIndex=findFlagRuleIndex(rules2,ruleId),[rule]=rules2.splice(ruleIndex,1);return rules2.splice(targetPosition-1,0,rule),buildRulesEnvironmentConfig(envConfig,rules2)}function resolveEffectiveFlagRulesEnvironment(flag,environment){let envConfig=flag.environments[environment],inheritedFrom=envConfig.reuse?.active?envConfig.reuse.environment:void 0;if(!inheritedFrom)return{environment,envConfig};let inheritedConfig=flag.environments[inheritedFrom];return inheritedConfig?{environment,envConfig:inheritedConfig,inheritedFrom}:{environment,envConfig}}function getFlagRulesEnvironmentConfig(flag,environment){let envConfig=flag.environments[environment],effectiveEnvironment=resolveEffectiveFlagRulesEnvironment(flag,environment);return{...envConfig,rules:structuredClone(effectiveEnvironment.envConfig.rules??[])}}function findFlagRule(rules2,ruleId){let rule=rules2.find(rule2=>rule2.id===ruleId);if(!rule)throw new Error(`Rule "${ruleId}" does not exist.`);return rule}function formatFlagRuleCondition(condition,settings){let lhs=condition.lhs.type==="segment"?"segment":`${condition.lhs.kind}.${condition.lhs.attribute}`,attributeType=condition.lhs.type==="entity"?getFlagAttributeType(settings,condition.lhs.kind,condition.lhs.attribute):void 0,comparator=formatFlagConditionComparator(condition.cmp,{...condition.cmpOptions,attributeType});if(condition.rhs===void 0||condition.rhs===null)return`${lhs} ${comparator}`;if(isRecord2(condition.rhs))return Array.isArray(condition.rhs.items)&&(condition.rhs.type==="list"||condition.rhs.type==="list/inline")?`${lhs} ${comparator} ${condition.rhs.items.map(formatListItem).join(", ")}`:`${lhs} ${comparator} ${JSON.stringify(condition.rhs)}`;let timestampRhs=formatTimestampRhs(condition.rhs,attributeType);return`${lhs} ${comparator} ${timestampRhs??String(condition.rhs)}`}function formatFlagRuleOutcome(outcome,variants){return formatFlagOutcome(outcome,variants)}function buildRulesEnvironmentConfig(envConfig,rules2){let nextConfig={...envConfig,rules:rules2};return envConfig.reuse&&(nextConfig.reuse={...envConfig.reuse,active:!1}),nextConfig}function parseFlagConditionLhs(input){let trimmed=input.trim();if(trimmed==="segment")return{type:"segment"};let[kind,...attributeParts]=trimmed.split("."),attribute=attributeParts.join(".");if(!kind||!attribute)throw new Error(`Invalid condition target "${input}". Use ENTITY.ATTRIBUTE or segment.`);return{type:"entity",kind,attribute}}function resolvePosition(position,max){if(position===void 0)return max;if(!Number.isInteger(position)||position<1||position>max)throw new Error(`Position must be an integer between 1 and ${max}.`);return position}function findFlagRuleIndex(rules2,ruleId){let ruleIndex=rules2.findIndex(rule=>rule.id===ruleId);if(ruleIndex===-1)throw new Error(`Rule "${ruleId}" does not exist.`);return ruleIndex}function shortId2(prefix){let alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",bytes=randomBytes3(12),id=prefix;for(let i=0;i<bytes.length;i++)id+=alphabet[bytes[i]%alphabet.length];return id}function requireFlagSettings(settings){if(!settings)throw new Error("Flag settings are required to resolve this rule outcome.");return settings}function formatListItem(item){return isRecord2(item)&&"value"in item?String(item.value):String(item)}function parseJson2(input,label){try{return JSON.parse(input)}catch{throw new Error(`Invalid JSON for ${label}`)}}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var import_chalk82=__toESM(require_source(),1);async function resolveRulesCommandContext(client,options){let link=await resolveProjectContext({client,projectNameOrId:options.projectName});if(link.status==="error")return{exitCode:link.exitCode};if(link.status==="not_linked")return output_manager_default.error(`Your codebase isn't linked to a project on Vercel. Run ${getCommandName("link")} to begin.`),{exitCode:1};client.config.currentTeam=link.org.type==="team"?link.org.id:void 0;let{project}=link;output_manager_default.spinner("Fetching flag...");let[flag,settings]=await Promise.all([getFlag(client,project.id,options.flagArg),options.fetchSettings?getFlagSettings(client,project.id):Promise.resolve(void 0)]);output_manager_default.stopSpinner();let environment=await resolveFlagEnvironment(client,flag,options.environment,options.promptMessage,{showEnvironmentDetails:!0,decorateChoices:!1});return{projectId:project.id,flag,settings,environment,envConfig:flag.environments[environment]}}function isExitCodeResult2(result){return"exitCode"in result}function warnIfRuleChangesAreBypassed(flag,environment,changeLabel="rule"){if(flag.state==="archived"){logArchivedFlagNotice(flag);return}let envConfig=flag.environments[environment];if(!envConfig)return;let mode=describeInactiveTargetingMode(flag,envConfig);mode&&(output_manager_default.print(`${import_chalk82.default.yellow("!")} This ${changeLabel} update was saved, but ${import_chalk82.default.bold(environment)} ${mode}. ${capitalize(changeLabel)} changes will not affect flag evaluation until targeting is active again.
|
|
372
|
+
`);printRecovery()}else{let set2=result.labels.filter(item=>item.operation==="upsert").length,removed=result.labels.filter(item=>item.operation==="delete").length;output_manager_default.success(`Value labels updated for ${kind}.${attributeKey}: ${set2} set, ${removed} removed`)}return failed?1:0}catch(err){return output_manager_default.stopSpinner(),isAPIError(err)&&(reason=err.status===403?AGENT_REASON.PERMISSION_DENIED:AGENT_REASON.API_ERROR),fail(err instanceof Error?err.message:"Failed to manage attribute labels.")}}function formatLabelCell(value){let quoted=JSON.stringify(value);return value===""||value.trim()!==value||quoted.slice(1,-1)!==value?quoted:value}var FlagsRulesTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandAdd(actual){this.trackCliSubcommand({subcommand:"add",value:actual})}trackCliSubcommandUpdate(actual){this.trackCliSubcommand({subcommand:"update",value:actual})}trackCliSubcommandRemove(actual){this.trackCliSubcommand({subcommand:"rm",value:actual})}trackCliSubcommandMove(actual){this.trackCliSubcommand({subcommand:"move",value:actual})}},FlagsRulesCommandTelemetryClient=class extends TelemetryClient{trackCliArgumentFlag(flag){flag&&this.trackCliArgument({arg:"flag",value:this.redactedValue})}trackCliArgumentRule(rule){rule&&this.trackCliArgument({arg:"rule",value:this.redactedValue})}trackCliOptionEnvironment(environment){environment&&this.trackCliOption({option:"environment",value:STANDARD_ENVIRONMENTS.includes(environment)?environment:this.redactedValue})}trackCliOptionCondition(condition){condition?.length&&this.trackCliOption({option:"condition",value:this.redactedValue})}trackCliOptionVariant(variant){variant&&this.trackCliOption({option:"variant",value:this.redactedValue})}trackCliOptionBy(base){base&&this.trackCliOption({option:"by",value:this.redactedValue})}trackCliOptionWeight(weights){weights?.length&&this.trackCliOption({option:"weight",value:this.redactedValue})}trackCliOptionDefaultVariant(variant){variant&&this.trackCliOption({option:"default-variant",value:this.redactedValue})}trackCliOptionFromVariant(variant){variant&&this.trackCliOption({option:"from-variant",value:this.redactedValue})}trackCliOptionToVariant(variant){variant&&this.trackCliOption({option:"to-variant",value:this.redactedValue})}trackCliOptionStage(stages){stages?.length&&this.trackCliOption({option:"stage",value:this.redactedValue})}trackCliOptionFinalPercentage(percentage){percentage!==void 0&&this.trackCliOption({option:"final-percentage",value:this.redactedValue})}trackCliOptionStart(start){start&&this.trackCliOption({option:"start",value:this.redactedValue})}trackCliOptionPosition(position){position!==void 0&&this.trackCliOption({option:"position",value:String(position)})}trackCliOptionMessage(message){message&&this.trackCliOption({option:"message",value:this.redactedValue})}trackCliFlagJson(json){json&&this.trackCliFlag("json")}};var import_chalk84=__toESM(require_source(),1),import_pluralize9=__toESM(require_pluralize(),1);import{randomBytes as randomBytes3}from"node:crypto";var RHS_OPTIONAL_OPERATORS2=new Set(FLAG_CONDITION_RHS_OPTIONAL_COMPARATORS);function parseFlagRuleConditions(inputs,settings){let conditionInputs=inputs.flatMap(input=>{let trimmed=input.trim();return!trimmed||trimmed.startsWith("{")?[trimmed]:trimmed.split(";").map(part=>part.trim()).filter(Boolean)});if(conditionInputs.length===0)throw new Error("At least one --condition is required. Use --condition <ENTITY.ATTRIBUTE:OPERATOR:VALUE>.");return conditionInputs.map(input=>coerceTimestampCondition(parseFlagRuleConditionInput(input),settings,"input"))}function parseFlagRuleConditionInput(input){let trimmed=input.trim();if(!trimmed)throw new Error("Flag rule condition cannot be empty");if(trimmed.startsWith("{")){let value=parseJson2(trimmed,"flag rule condition");if(!isRecord2(value))throw new Error("Flag rule condition JSON must be an object");return value}let[field,operator,...valueParts]=trimmed.split(":");if(!field||!operator)throw new Error(`Invalid flag rule condition "${input}". Use ENTITY.ATTRIBUTE:OPERATOR:VALUE or segment:OPERATOR:SEGMENT.`);let cmp=parseComparator(operator,"flag rule"),rawValue=valueParts.join(":");if(!rawValue&&!RHS_OPTIONAL_OPERATORS2.has(cmp))throw new Error(`Flag rule condition "${input}" is missing a value`);return{lhs:parseFlagConditionLhs(field),cmp,...rawValue?{rhs:parseConditionValue(rawValue,cmp)}:{}}}function hasFlagRuleOutcomeOptions(options){return!!(options.variantSelector||options.baseSelector||options.defaultVariantSelector||options.weightInputs.length>0||options.rollFromVariantSelector||options.rollToVariantSelector||options.stageInputs.length>0||options.start||options.finalPercentage!==void 0)}function needsFlagRuleOutcomeSettings(options){return options.variantSelector?!1:!!(options.baseSelector||options.defaultVariantSelector||options.weightInputs.length>0||options.rollFromVariantSelector||options.rollToVariantSelector||options.stageInputs.length>0||options.start||options.finalPercentage!==void 0)}function resolveFlagRuleOutcome(flag,settings,options){let hasVariant=!!options.variantSelector,hasRolloutOnlyOptions=!!(options.rollFromVariantSelector||options.rollToVariantSelector||options.stageInputs.length>0||options.start||options.finalPercentage!==void 0),hasSplitOnlyOptions=options.weightInputs.length>0,hasCommonOptions=!!(options.baseSelector||options.defaultVariantSelector);if(hasVariant&&(hasRolloutOnlyOptions||hasSplitOnlyOptions||hasCommonOptions))throw new Error("Cannot combine --variant with split or rollout outcome options.");if(hasRolloutOnlyOptions&&hasSplitOnlyOptions)throw new Error("Cannot combine --weight with rollout outcome options.");if(options.variantSelector)return{type:"variant",variantId:resolveVariantOrThrow(options.variantSelector,flag.variants,"--variant").id};if(hasRolloutOnlyOptions||hasCommonOptions&&options.currentOutcome?.type==="rollout")return resolveFlagRollout(flag,requireFlagSettings(settings),{stageInputs:options.stageInputs,finalPercentage:options.finalPercentage,baseSelector:options.baseSelector,rollFromVariantSelector:options.rollFromVariantSelector,rollToVariantSelector:options.rollToVariantSelector,defaultVariantSelector:options.defaultVariantSelector,start:options.start,currentOutcome:options.currentOutcome?.type==="experiment"?void 0:options.currentOutcome}).outcome;if(hasSplitOnlyOptions||hasCommonOptions)return resolveFlagSplit(flag,requireFlagSettings(settings),{weightInputs:options.weightInputs,baseSelector:options.baseSelector,defaultVariantSelector:options.defaultVariantSelector,currentOutcome:options.currentOutcome?.type==="experiment"?void 0:options.currentOutcome}).outcome;if(options.currentOutcome&&!options.requireOutcome)return options.currentOutcome;throw new Error("Missing rule outcome. Use --variant <VARIANT>, split options such as --weight, or rollout options such as --stage.")}function createFlagRule(conditions,outcome){return{id:shortId2("rule_"),conditions,outcome}}function addFlagRule(envConfig,rule,position){let rules2=structuredClone(envConfig.rules??[]),insertionIndex=resolvePosition(position,rules2.length+1)-1;return rules2.splice(insertionIndex,0,rule),buildRulesEnvironmentConfig(envConfig,rules2)}function removeFlagRule(envConfig,ruleId){let rules2=structuredClone(envConfig.rules??[]),ruleIndex=findFlagRuleIndex(rules2,ruleId);return rules2.splice(ruleIndex,1),buildRulesEnvironmentConfig(envConfig,rules2)}function updateFlagRule(envConfig,ruleId,updates){let rules2=structuredClone(envConfig.rules??[]),ruleIndex=findFlagRuleIndex(rules2,ruleId);return rules2[ruleIndex]={...rules2[ruleIndex],...updates.conditions?{conditions:updates.conditions}:{},...updates.outcome?{outcome:updates.outcome}:{}},buildRulesEnvironmentConfig(envConfig,rules2)}function moveFlagRule(envConfig,ruleId,position){let rules2=structuredClone(envConfig.rules??[]),targetPosition=resolvePosition(position,rules2.length),ruleIndex=findFlagRuleIndex(rules2,ruleId),[rule]=rules2.splice(ruleIndex,1);return rules2.splice(targetPosition-1,0,rule),buildRulesEnvironmentConfig(envConfig,rules2)}function resolveEffectiveFlagRulesEnvironment(flag,environment){let envConfig=flag.environments[environment],inheritedFrom=envConfig.reuse?.active?envConfig.reuse.environment:void 0;if(!inheritedFrom)return{environment,envConfig};let inheritedConfig=flag.environments[inheritedFrom];return inheritedConfig?{environment,envConfig:inheritedConfig,inheritedFrom}:{environment,envConfig}}function getFlagRulesEnvironmentConfig(flag,environment){let envConfig=flag.environments[environment],effectiveEnvironment=resolveEffectiveFlagRulesEnvironment(flag,environment);return{...envConfig,rules:structuredClone(effectiveEnvironment.envConfig.rules??[])}}function findFlagRule(rules2,ruleId){let rule=rules2.find(rule2=>rule2.id===ruleId);if(!rule)throw new Error(`Rule "${ruleId}" does not exist.`);return rule}function formatFlagRuleCondition(condition,settings){let lhs=condition.lhs.type==="segment"?"segment":`${condition.lhs.kind}.${condition.lhs.attribute}`,attributeType=condition.lhs.type==="entity"?getFlagAttributeType(settings,condition.lhs.kind,condition.lhs.attribute):void 0,comparator=formatFlagConditionComparator(condition.cmp,{...condition.cmpOptions,attributeType});if(condition.rhs===void 0||condition.rhs===null)return`${lhs} ${comparator}`;if(isRecord2(condition.rhs))return Array.isArray(condition.rhs.items)&&(condition.rhs.type==="list"||condition.rhs.type==="list/inline")?`${lhs} ${comparator} ${condition.rhs.items.map(formatListItem).join(", ")}`:`${lhs} ${comparator} ${JSON.stringify(condition.rhs)}`;let timestampRhs=formatTimestampRhs(condition.rhs,attributeType);return`${lhs} ${comparator} ${timestampRhs??String(condition.rhs)}`}function formatFlagRuleOutcome(outcome,variants){return formatFlagOutcome(outcome,variants)}function buildRulesEnvironmentConfig(envConfig,rules2){let nextConfig={...envConfig,rules:rules2};return envConfig.reuse&&(nextConfig.reuse={...envConfig.reuse,active:!1}),nextConfig}function parseFlagConditionLhs(input){let trimmed=input.trim();if(trimmed==="segment")return{type:"segment"};let[kind,...attributeParts]=trimmed.split("."),attribute=attributeParts.join(".");if(!kind||!attribute)throw new Error(`Invalid condition target "${input}". Use ENTITY.ATTRIBUTE or segment.`);return{type:"entity",kind,attribute}}function resolvePosition(position,max){if(position===void 0)return max;if(!Number.isInteger(position)||position<1||position>max)throw new Error(`Position must be an integer between 1 and ${max}.`);return position}function findFlagRuleIndex(rules2,ruleId){let ruleIndex=rules2.findIndex(rule=>rule.id===ruleId);if(ruleIndex===-1)throw new Error(`Rule "${ruleId}" does not exist.`);return ruleIndex}function shortId2(prefix){let alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",bytes=randomBytes3(12),id=prefix;for(let i=0;i<bytes.length;i++)id+=alphabet[bytes[i]%alphabet.length];return id}function requireFlagSettings(settings){if(!settings)throw new Error("Flag settings are required to resolve this rule outcome.");return settings}function formatListItem(item){return isRecord2(item)&&"value"in item?String(item.value):String(item)}function parseJson2(input,label){try{return JSON.parse(input)}catch{throw new Error(`Invalid JSON for ${label}`)}}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var import_chalk83=__toESM(require_source(),1);async function resolveRulesCommandContext(client,options){let link=await resolveProjectContext({client,projectNameOrId:options.projectName});if(link.status==="error")return{exitCode:link.exitCode};if(link.status==="not_linked")return output_manager_default.error(`Your codebase isn't linked to a project on Vercel. Run ${getCommandName("link")} to begin.`),{exitCode:1};client.config.currentTeam=link.org.type==="team"?link.org.id:void 0;let{project}=link;output_manager_default.spinner("Fetching flag...");let[flag,settings]=await Promise.all([getFlag(client,project.id,options.flagArg),options.fetchSettings?getFlagSettings(client,project.id):Promise.resolve(void 0)]);output_manager_default.stopSpinner();let environment=await resolveFlagEnvironment(client,flag,options.environment,options.promptMessage,{showEnvironmentDetails:!0,decorateChoices:!1});return{projectId:project.id,flag,settings,environment,envConfig:flag.environments[environment]}}function isExitCodeResult2(result){return"exitCode"in result}function warnIfRuleChangesAreBypassed(flag,environment,changeLabel="rule"){if(flag.state==="archived"){logArchivedFlagNotice(flag);return}let envConfig=flag.environments[environment];if(!envConfig)return;let mode=describeInactiveTargetingMode(flag,envConfig);mode&&(output_manager_default.print(`${import_chalk83.default.yellow("!")} This ${changeLabel} update was saved, but ${import_chalk83.default.bold(environment)} ${mode}. ${capitalize(changeLabel)} changes will not affect flag evaluation until targeting is active again.
|
|
355
373
|
`),output_manager_default.print(` Enable targeting (keeps the current fallthrough):
|
|
356
374
|
`),output_manager_default.print(` ${getCommandName(`flags targeting enable ${quoteArg(flag.slug)} --environment ${environment}`)}
|
|
357
|
-
`))}function describeInactiveTargetingMode(flag,envConfig){if(envConfig.reuse?.active)return`reuses ${
|
|
358
|
-
Add one with: ${getCommandName("flags rules add "+context.flag.slug+" --environment "+context.environment+" --condition user.plan:eq:pro --variant on"+projectFlag)}`),0}output_manager_default.log(`${(0,
|
|
359
|
-
`)}function printRulesTable(rules2,variants,settings){let headers=["Position","ID","Conditions","Outcome"],rows=rules2.map((rule,index)=>[String(index+1),
|
|
375
|
+
`))}function describeInactiveTargetingMode(flag,envConfig){if(envConfig.reuse?.active)return`reuses ${import_chalk83.default.bold(envConfig.reuse.environment)}`;if(envConfig.active)return;let variantId=envConfig.pausedOutcome?.variantId,variant=flag.variants.find(candidate=>candidate.id===variantId);return`is serving ${variant?formatVariantForDisplay(variant):variantId?import_chalk83.default.bold(variantId):"a fixed variant"}`}function capitalize(value){return value.charAt(0).toUpperCase()+value.slice(1)}async function rulesLs(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesListSubcommand2.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg]=args,environment=flags["--environment"],json=flags["--json"];if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliFlagJson(json),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg)return output_manager_default.error("Please provide a flag slug or ID to list rules for"),output_manager_default.log(`Example: ${getCommandName("flags rules ls my-feature --environment production")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment to list rules for:",fetchSettings:!json});if(isExitCodeResult2(context))return context.exitCode;let effectiveEnvironment=resolveEffectiveFlagRulesEnvironment(context.flag,context.environment),rules2=effectiveEnvironment.envConfig.rules??[];if(json)return outputJson6(client,{flag:context.flag.slug,environment:context.environment,inheritedFrom:effectiveEnvironment.inheritedFrom,rules:rules2}),0;let lsStamp=stamp_default(),environmentLabel=effectiveEnvironment.inheritedFrom?`${context.environment} (reuses ${effectiveEnvironment.inheritedFrom})`:context.environment;if(rules2.length===0){let projectFlag=flags["--project"]?` --project ${flags["--project"]}`:"";return output_manager_default.log(`No conditional rules found for ${import_chalk84.default.bold(context.flag.slug)} in ${environmentLabel} ${import_chalk84.default.gray(lsStamp())}`),output_manager_default.log(`
|
|
376
|
+
Add one with: ${getCommandName("flags rules add "+context.flag.slug+" --environment "+context.environment+" --condition user.plan:eq:pro --variant on"+projectFlag)}`),0}output_manager_default.log(`${(0,import_pluralize9.default)("conditional rule",rules2.length,!0)} found for ${import_chalk84.default.bold(context.flag.slug)} in ${environmentLabel} ${import_chalk84.default.gray(lsStamp())}`),printRulesTable(rules2,context.flag.variants,context.settings)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function outputJson6(client,data){client.stdout.write(`${JSON.stringify(data,null,2)}
|
|
377
|
+
`)}function printRulesTable(rules2,variants,settings){let headers=["Position","ID","Conditions","Outcome"],rows=rules2.map((rule,index)=>[String(index+1),import_chalk84.default.bold(rule.id),rule.conditions.map(condition=>formatFlagRuleCondition(condition,settings)).join("; "),formatFlagRuleOutcome(rule.outcome,variants)]),table2=formatTable(headers,["r","l","l","l"],[{name:"",rows}]);output_manager_default.print(`
|
|
360
378
|
${table2}
|
|
361
|
-
`)}var import_chalk84=__toESM(require_source(),1);async function rulesAdd(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesAddSubcommand2.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg]=args,environment=flags["--environment"],conditionInputs=flags["--condition"]??[],variantSelector=normalizeOptionalInput(flags["--variant"]),baseSelector=normalizeOptionalInput(flags["--by"]),defaultVariantSelector=normalizeOptionalInput(flags["--default-variant"]),weightInputs=flags["--weight"]??[],rollFromVariantSelector=normalizeOptionalInput(flags["--from-variant"]),rollToVariantSelector=normalizeOptionalInput(flags["--to-variant"]),stageInputs=(flags["--stage"]??[]).map(input=>input.trim()),finalPercentage=flags["--final-percentage"],start=normalizeOptionalInput(flags["--start"]),position=flags["--position"],message=normalizeOptionalInput(flags["--message"]);telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionCondition(conditionInputs),telemetryClient.trackCliOptionVariant(variantSelector),telemetryClient.trackCliOptionBy(baseSelector),telemetryClient.trackCliOptionWeight(weightInputs),telemetryClient.trackCliOptionDefaultVariant(defaultVariantSelector),telemetryClient.trackCliOptionFromVariant(rollFromVariantSelector),telemetryClient.trackCliOptionToVariant(rollToVariantSelector),telemetryClient.trackCliOptionStage(stageInputs),telemetryClient.trackCliOptionFinalPercentage(finalPercentage),telemetryClient.trackCliOptionStart(start),telemetryClient.trackCliOptionPosition(position),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]);let outcomeOptions={variantSelector,baseSelector,defaultVariantSelector,weightInputs,rollFromVariantSelector,rollToVariantSelector,stageInputs,finalPercentage,start};if(!flagArg)return output_manager_default.error("Please provide a flag slug or ID to add a rule to"),output_manager_default.log(`Example: ${getCommandName("flags rules add my-feature --environment production --condition user.plan:eq:pro --variant on")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment to add the rule to:",fetchSettings:needsFlagRuleOutcomeSettings(outcomeOptions)||conditionInputs.length>0});if(isExitCodeResult2(context))return context.exitCode;let conditions=parseFlagRuleConditions(conditionInputs,context.settings),outcome=resolveFlagRuleOutcome(context.flag,context.settings,{...outcomeOptions,requireOutcome:!0}),rule=createFlagRule(conditions,outcome),envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),nextEnvConfig=addFlagRule(envConfig,rule,position),nextPosition=nextEnvConfig.rules.findIndex(candidate=>candidate.id===rule.id)+1,updateMessage=await resolveFlagUpdateMessage(client,message,`Add rule ${rule.id} to ${context.environment}`);output_manager_default.spinner(`Adding rule to ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner(),output_manager_default.success(`Rule ${import_chalk84.default.bold(rule.id)} added to ${import_chalk84.default.bold(context.flag.slug)} in ${import_chalk84.default.bold(context.environment)}`),output_manager_default.log(` ${import_chalk84.default.dim("Position:")} ${nextPosition}`),output_manager_default.log(` ${import_chalk84.default.dim("Outcome:")} ${formatFlagRuleOutcome(rule.outcome,context.flag.variants)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk85=__toESM(require_source(),1),import_fast_deep_equal8=__toESM(require_fast_deep_equal(),1);async function rulesUpdate(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesUpdateSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,ruleId]=args,environment=flags["--environment"],conditionInputs=flags["--condition"]??[],variantSelector=normalizeOptionalInput(flags["--variant"]),baseSelector=normalizeOptionalInput(flags["--by"]),defaultVariantSelector=normalizeOptionalInput(flags["--default-variant"]),weightInputs=flags["--weight"]??[],rollFromVariantSelector=normalizeOptionalInput(flags["--from-variant"]),rollToVariantSelector=normalizeOptionalInput(flags["--to-variant"]),stageInputs=(flags["--stage"]??[]).map(input=>input.trim()),finalPercentage=flags["--final-percentage"],start=normalizeOptionalInput(flags["--start"]),message=normalizeOptionalInput(flags["--message"]);telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentRule(ruleId),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionCondition(conditionInputs),telemetryClient.trackCliOptionVariant(variantSelector),telemetryClient.trackCliOptionBy(baseSelector),telemetryClient.trackCliOptionWeight(weightInputs),telemetryClient.trackCliOptionDefaultVariant(defaultVariantSelector),telemetryClient.trackCliOptionFromVariant(rollFromVariantSelector),telemetryClient.trackCliOptionToVariant(rollToVariantSelector),telemetryClient.trackCliOptionStage(stageInputs),telemetryClient.trackCliOptionFinalPercentage(finalPercentage),telemetryClient.trackCliOptionStart(start),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]);let outcomeOptions={variantSelector,baseSelector,defaultVariantSelector,weightInputs,rollFromVariantSelector,rollToVariantSelector,stageInputs,finalPercentage,start};if(!flagArg||!ruleId)return output_manager_default.error("Please provide a flag slug or ID and rule ID to update"),output_manager_default.log(`Example: ${getCommandName("flags rules update my-feature rule_123 --environment production --variant on")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment containing the rule:",fetchSettings:needsFlagRuleOutcomeSettings(outcomeOptions)||conditionInputs.length>0});if(isExitCodeResult2(context))return context.exitCode;let envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),currentRule=findFlagRule(envConfig.rules??[],ruleId),hasOutcomeOptions=hasFlagRuleOutcomeOptions(outcomeOptions),nextConditions=conditionInputs.length>0?parseFlagRuleConditions(conditionInputs,context.settings):void 0,resolvedOutcome=hasOutcomeOptions?resolveFlagRuleOutcome(context.flag,context.settings,{...outcomeOptions,currentOutcome:currentRule.outcome}):void 0;if(!nextConditions&&!resolvedOutcome)return output_manager_default.warn("No rule changes were provided"),0;let nextEnvConfig=updateFlagRule(envConfig,ruleId,{conditions:nextConditions,outcome:resolvedOutcome});if((0,import_fast_deep_equal8.default)(context.envConfig,nextEnvConfig))return output_manager_default.warn("No rule changes were provided"),0;let updateMessage=await resolveFlagUpdateMessage(client,message,`Update rule ${ruleId} in ${context.environment}`);output_manager_default.spinner(`Updating rule in ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner();let nextRule=findFlagRule(nextEnvConfig.rules,ruleId);output_manager_default.success(`Rule ${import_chalk85.default.bold(ruleId)} updated for ${import_chalk85.default.bold(context.flag.slug)} in ${import_chalk85.default.bold(context.environment)}`),output_manager_default.log(` ${import_chalk85.default.dim("Conditions:")} ${nextRule.conditions.map(condition=>formatFlagRuleCondition(condition,context.settings)).join(", ")}`),output_manager_default.log(` ${import_chalk85.default.dim("Outcome:")} ${formatFlagRuleOutcome(nextRule.outcome,context.flag.variants)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk86=__toESM(require_source(),1);async function rulesRemove(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesRemoveSubcommand2.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,ruleId]=args,environment=flags["--environment"],message=normalizeOptionalInput(flags["--message"]);if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentRule(ruleId),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg||!ruleId)return output_manager_default.error("Please provide a flag slug or ID and rule ID to remove"),output_manager_default.log(`Example: ${getCommandName("flags rules remove my-feature rule_123 --environment production")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment containing the rule:"});if(isExitCodeResult2(context))return context.exitCode;let envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),nextEnvConfig=removeFlagRule(envConfig,ruleId),updateMessage=await resolveFlagUpdateMessage(client,message,`Remove rule ${ruleId} from ${context.environment}`);output_manager_default.spinner(`Removing rule from ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner(),output_manager_default.success(`Rule ${import_chalk86.default.bold(ruleId)} removed from ${import_chalk86.default.bold(context.flag.slug)} in ${import_chalk86.default.bold(context.environment)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk87=__toESM(require_source(),1),import_fast_deep_equal9=__toESM(require_fast_deep_equal(),1);async function rulesMove(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesMoveSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,ruleId]=args,environment=flags["--environment"],position=flags["--position"],message=normalizeOptionalInput(flags["--message"]);if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentRule(ruleId),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionPosition(position),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg||!ruleId||position===void 0)return output_manager_default.error("Please provide a flag slug or ID, rule ID, and destination position"),output_manager_default.log(`Example: ${getCommandName("flags rules move my-feature rule_123 --environment production --position 1")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment containing the rule:"});if(isExitCodeResult2(context))return context.exitCode;let envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),nextEnvConfig=moveFlagRule(envConfig,ruleId,position);if((0,import_fast_deep_equal9.default)(context.envConfig,nextEnvConfig))return output_manager_default.warn(`Rule ${import_chalk87.default.bold(ruleId)} is already at position ${position} in ${context.environment}`),0;let updateMessage=await resolveFlagUpdateMessage(client,message,`Move rule ${ruleId} to position ${position} in ${context.environment}`);output_manager_default.spinner(`Moving rule in ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner(),output_manager_default.success(`Rule ${import_chalk87.default.bold(ruleId)} moved to position ${position} for ${import_chalk87.default.bold(context.flag.slug)} in ${import_chalk87.default.bold(context.environment)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var COMMAND_CONFIG14={ls:getCommandAliases(rulesListSubcommand2),add:getCommandAliases(rulesAddSubcommand2),update:getCommandAliases(rulesUpdateSubcommand),rm:getCommandAliases(rulesRemoveSubcommand2),move:getCommandAliases(rulesMoveSubcommand)};async function rules(client){let telemetry=new FlagsRulesTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(rulesSubcommand2.options),parsedArgs;try{parsedArgs=parseArguments(client.argv.slice(4),flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let{subcommand,args,subcommandOriginal}=getSubcommand(parsedArgs.args,COMMAND_CONFIG14),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags rules",subcommand),output_manager_default.print(help(rulesSubcommand2,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:rulesSubcommand2,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesListSubcommand2),0):(telemetry.trackCliSubcommandList(subcommandOriginal),rulesLs(client,args));case"add":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesAddSubcommand2),0):(telemetry.trackCliSubcommandAdd(subcommandOriginal),rulesAdd(client,args));case"update":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesUpdateSubcommand),0):(telemetry.trackCliSubcommandUpdate(subcommandOriginal),rulesUpdate(client,args));case"rm":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesRemoveSubcommand2),0):(telemetry.trackCliSubcommandRemove(subcommandOriginal),rulesRemove(client,args));case"move":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesMoveSubcommand),0):(telemetry.trackCliSubcommandMove(subcommandOriginal),rulesMove(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG14)),output_manager_default.print(help(rulesSubcommand2,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var FlagsTargetsTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandAdd(actual){this.trackCliSubcommand({subcommand:"add",value:actual})}trackCliSubcommandRemove(actual){this.trackCliSubcommand({subcommand:"rm",value:actual})}},FlagsTargetsCommandTelemetryClient=class extends FlagsRulesCommandTelemetryClient{trackCliArgumentTarget(targets2){targets2?.length&&this.trackCliArgument({arg:"target",value:this.redactedValue})}};var import_chalk89=__toESM(require_source(),1),import_pluralize9=__toESM(require_pluralize(),1);function formatFlagTargetSelector(target){return`${target.entity}.${target.attribute}=${target.value}`}function parseFlagTargetInput(input,options={}){let separatorIndex=input.indexOf("=");if(separatorIndex===-1)throw new Error(`Invalid target "${input}". Use ENTITY.ATTRIBUTE=VALUE, for example user.id=user_123.`);let{kind:entity,attribute}=parseEntityAttributeSelector(input.slice(0,separatorIndex)),rawValue=input.slice(separatorIndex+1);if(!options.allowLabel){if(!rawValue)throw new Error(`Invalid target "${input}". Value cannot be empty.`);return{entity,attribute,value:rawValue}}let labelIndex=rawValue.indexOf("|"),value=(labelIndex===-1?rawValue:rawValue.slice(0,labelIndex)).trim();if(!value)throw new Error(`Invalid target "${input}". Value cannot be empty.`);if(labelIndex===-1)return{entity,attribute,value};let label=rawValue.slice(labelIndex+1).trim();if(!label)throw new Error(`Invalid target "${input}". Label cannot be empty; use ENTITY.ATTRIBUTE=VALUE|LABEL or omit the "|".`);return validateLabelString(label,"label"),{entity,attribute,value,label}}function parseFlagTargetInputs(inputs,settings){let seen=new Map;for(let input of inputs){let target=parseFlagTargetInput(input,{allowLabel:!0});assertTargetableAttribute(target,settings);let key=formatFlagTargetSelector(target),existing=seen.get(key);existing?target.label&&(existing.label=target.label):seen.set(key,target)}return[...seen.values()]}function assertTargetableAttribute(target,settings){let entity=settings.entities.find(candidate=>candidate.kind===target.entity);if(!entity){let available=settings.entities.map(candidate=>candidate.kind);throw new Error(available.length>0?`Entity "${target.entity}" does not exist. Available entities: ${available.join(", ")}.`:`Entity "${target.entity}" does not exist. Define entities before adding targets.`)}let attribute=entity.attributes.find(candidate=>candidate.key===target.attribute);if(!attribute){let available=entity.attributes.map(candidate=>`${entity.kind}.${candidate.key}`);throw new Error(available.length>0?`Attribute "${target.entity}.${target.attribute}" does not exist. Available attributes: ${available.join(", ")}.`:`Attribute "${target.entity}.${target.attribute}" does not exist.`)}if(attribute.type!=="string")throw new Error(`Only string attributes can be targeted directly. ${target.entity}.${target.attribute} is a ${attribute.type} attribute.`)}function listFlagTargets(targets2){let entries=[];for(let[variantId,entities2]of Object.entries(targets2??{}))for(let[entity,attributes]of Object.entries(entities2))for(let[attribute,values]of Object.entries(attributes))for(let item of values)entries.push({variantId,entity,attribute,value:item.value,...item.note?{note:item.note}:{}});return entries}function findFlagTargetVariantId(targets2,target){for(let[variantId,entities2]of Object.entries(targets2??{}))if(entities2[target.entity]?.[target.attribute]?.some(item=>item.value===target.value))return variantId}function addFlagTargets(targets2,selectors,variantId){let next=structuredClone(targets2??{}),results=[];for(let selector of selectors){let previousVariantId=findFlagTargetVariantId(next,selector);if(previousVariantId===variantId){results.push({...selector,status:"unchanged"});continue}let previous=previousVariantId?deleteTargetValue(next,previousVariantId,selector):void 0,entities2=next[variantId]??={},attributes=entities2[selector.entity]??={};(attributes[selector.attribute]??=[]).push(previous?.note?{value:selector.value,note:previous.note}:{value:selector.value}),results.push(previousVariantId?{...selector,status:"moved",previousVariantId}:{...selector,status:"added"})}return{targets:next,results}}function removeFlagTargets(targets2,selectors){let next=structuredClone(targets2??{}),results=[],seen=new Set;for(let selector of selectors){let key=formatFlagTargetSelector(selector);if(seen.has(key))continue;seen.add(key);let variantId=findFlagTargetVariantId(next,selector);if(!variantId)throw new Error(`Target "${formatFlagTargetSelector(selector)}" does not exist.`);deleteTargetValue(next,variantId,selector),results.push({...selector,variantId})}return{targets:next,results}}function deleteTargetValue(targets2,variantId,selector){let entities2=targets2[variantId],attributes=entities2?.[selector.entity],values=attributes?.[selector.attribute];if(!entities2||!attributes||!values)return;let removed=values.find(item=>item.value===selector.value),remaining=values.filter(item=>item.value!==selector.value);return remaining.length>0?(attributes[selector.attribute]=remaining,removed):(delete attributes[selector.attribute],Object.keys(attributes).length===0&&delete entities2[selector.entity],Object.keys(entities2).length===0&&delete targets2[variantId],removed)}function buildTargetsEnvironmentConfig(flag,environment,targets2){return{...flag.environments[environment],targets:targets2}}var import_chalk88=__toESM(require_source(),1);function formatTargetValue2(target,settings){let label=target.label??resolveTargetingLabel(settings,target.entity,target.attribute,target.value),selector=formatFlagTargetSelector(target);return label?`${selector} ${import_chalk88.default.gray(label)}`:selector}function formatTargetVariant(flag,variantId){let variant=flag.variants.find(candidate=>candidate.id===variantId);return formatFlagVariantSummary(variant,variantId)}async function targetsLs(client,argv){let telemetryClient=new FlagsTargetsCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(targetsListSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg]=args,environment=flags["--environment"],json=flags["--json"];if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliFlagJson(json),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg)return output_manager_default.error("Please provide a flag slug or ID to list targets for"),output_manager_default.log(`Example: ${getCommandName("flags targets list my-feature --environment production")}`),2;if(json&&!environment)return output_manager_default.error("Missing required option --environment when using --json"),output_manager_default.log(`Example: ${getCommandName("flags targets list my-feature --environment production --json")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:flags["--project"],flagArg,environment,promptMessage:"Select an environment to list targets for:",fetchSettings:!json});if(isExitCodeResult2(context))return context.exitCode;let{envConfig}=context,targets2=envConfig.targets??{};if(json)return client.stdout.write(`${JSON.stringify({flag:context.flag.slug,environment:context.environment,active:envConfig.active,...envConfig.reuse?{reuse:envConfig.reuse}:{},targets:targets2},null,2)}
|
|
362
|
-
`),0;let entries=listFlagTargets(targets2),lsStamp=stamp_default(),inactiveMode=describeInactiveTargetingMode(context.flag,envConfig);if(entries.length===0){let projectFlag=flags["--project"]?` --project ${flags["--project"]}`:"";return output_manager_default.log(`No targets found for ${
|
|
363
|
-
Add one with: ${getCommandName(`flags targets add ${context.flag.slug} --environment ${context.environment} user.id=user_123${projectFlag}`)}`),0}output_manager_default.log(`${(0,
|
|
364
|
-
`)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function printTargetsTable(entries,flag,settings){let headers=["Attribute","Value","Label","Variant"],rows=entries.map(entry=>[`${entry.entity}.${entry.attribute}`,
|
|
379
|
+
`)}var import_chalk85=__toESM(require_source(),1);async function rulesAdd(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesAddSubcommand2.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg]=args,environment=flags["--environment"],conditionInputs=flags["--condition"]??[],variantSelector=normalizeOptionalInput(flags["--variant"]),baseSelector=normalizeOptionalInput(flags["--by"]),defaultVariantSelector=normalizeOptionalInput(flags["--default-variant"]),weightInputs=flags["--weight"]??[],rollFromVariantSelector=normalizeOptionalInput(flags["--from-variant"]),rollToVariantSelector=normalizeOptionalInput(flags["--to-variant"]),stageInputs=(flags["--stage"]??[]).map(input=>input.trim()),finalPercentage=flags["--final-percentage"],start=normalizeOptionalInput(flags["--start"]),position=flags["--position"],message=normalizeOptionalInput(flags["--message"]);telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionCondition(conditionInputs),telemetryClient.trackCliOptionVariant(variantSelector),telemetryClient.trackCliOptionBy(baseSelector),telemetryClient.trackCliOptionWeight(weightInputs),telemetryClient.trackCliOptionDefaultVariant(defaultVariantSelector),telemetryClient.trackCliOptionFromVariant(rollFromVariantSelector),telemetryClient.trackCliOptionToVariant(rollToVariantSelector),telemetryClient.trackCliOptionStage(stageInputs),telemetryClient.trackCliOptionFinalPercentage(finalPercentage),telemetryClient.trackCliOptionStart(start),telemetryClient.trackCliOptionPosition(position),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]);let outcomeOptions={variantSelector,baseSelector,defaultVariantSelector,weightInputs,rollFromVariantSelector,rollToVariantSelector,stageInputs,finalPercentage,start};if(!flagArg)return output_manager_default.error("Please provide a flag slug or ID to add a rule to"),output_manager_default.log(`Example: ${getCommandName("flags rules add my-feature --environment production --condition user.plan:eq:pro --variant on")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment to add the rule to:",fetchSettings:needsFlagRuleOutcomeSettings(outcomeOptions)||conditionInputs.length>0});if(isExitCodeResult2(context))return context.exitCode;let conditions=parseFlagRuleConditions(conditionInputs,context.settings),outcome=resolveFlagRuleOutcome(context.flag,context.settings,{...outcomeOptions,requireOutcome:!0}),rule=createFlagRule(conditions,outcome),envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),nextEnvConfig=addFlagRule(envConfig,rule,position),nextPosition=nextEnvConfig.rules.findIndex(candidate=>candidate.id===rule.id)+1,updateMessage=await resolveFlagUpdateMessage(client,message,`Add rule ${rule.id} to ${context.environment}`);output_manager_default.spinner(`Adding rule to ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner(),output_manager_default.success(`Rule ${import_chalk85.default.bold(rule.id)} added to ${import_chalk85.default.bold(context.flag.slug)} in ${import_chalk85.default.bold(context.environment)}`),output_manager_default.log(` ${import_chalk85.default.dim("Position:")} ${nextPosition}`),output_manager_default.log(` ${import_chalk85.default.dim("Outcome:")} ${formatFlagRuleOutcome(rule.outcome,context.flag.variants)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk86=__toESM(require_source(),1),import_fast_deep_equal8=__toESM(require_fast_deep_equal(),1);async function rulesUpdate(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesUpdateSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,ruleId]=args,environment=flags["--environment"],conditionInputs=flags["--condition"]??[],variantSelector=normalizeOptionalInput(flags["--variant"]),baseSelector=normalizeOptionalInput(flags["--by"]),defaultVariantSelector=normalizeOptionalInput(flags["--default-variant"]),weightInputs=flags["--weight"]??[],rollFromVariantSelector=normalizeOptionalInput(flags["--from-variant"]),rollToVariantSelector=normalizeOptionalInput(flags["--to-variant"]),stageInputs=(flags["--stage"]??[]).map(input=>input.trim()),finalPercentage=flags["--final-percentage"],start=normalizeOptionalInput(flags["--start"]),message=normalizeOptionalInput(flags["--message"]);telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentRule(ruleId),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionCondition(conditionInputs),telemetryClient.trackCliOptionVariant(variantSelector),telemetryClient.trackCliOptionBy(baseSelector),telemetryClient.trackCliOptionWeight(weightInputs),telemetryClient.trackCliOptionDefaultVariant(defaultVariantSelector),telemetryClient.trackCliOptionFromVariant(rollFromVariantSelector),telemetryClient.trackCliOptionToVariant(rollToVariantSelector),telemetryClient.trackCliOptionStage(stageInputs),telemetryClient.trackCliOptionFinalPercentage(finalPercentage),telemetryClient.trackCliOptionStart(start),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]);let outcomeOptions={variantSelector,baseSelector,defaultVariantSelector,weightInputs,rollFromVariantSelector,rollToVariantSelector,stageInputs,finalPercentage,start};if(!flagArg||!ruleId)return output_manager_default.error("Please provide a flag slug or ID and rule ID to update"),output_manager_default.log(`Example: ${getCommandName("flags rules update my-feature rule_123 --environment production --variant on")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment containing the rule:",fetchSettings:needsFlagRuleOutcomeSettings(outcomeOptions)||conditionInputs.length>0});if(isExitCodeResult2(context))return context.exitCode;let envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),currentRule=findFlagRule(envConfig.rules??[],ruleId),hasOutcomeOptions=hasFlagRuleOutcomeOptions(outcomeOptions),nextConditions=conditionInputs.length>0?parseFlagRuleConditions(conditionInputs,context.settings):void 0,resolvedOutcome=hasOutcomeOptions?resolveFlagRuleOutcome(context.flag,context.settings,{...outcomeOptions,currentOutcome:currentRule.outcome}):void 0;if(!nextConditions&&!resolvedOutcome)return output_manager_default.warn("No rule changes were provided"),0;let nextEnvConfig=updateFlagRule(envConfig,ruleId,{conditions:nextConditions,outcome:resolvedOutcome});if((0,import_fast_deep_equal8.default)(context.envConfig,nextEnvConfig))return output_manager_default.warn("No rule changes were provided"),0;let updateMessage=await resolveFlagUpdateMessage(client,message,`Update rule ${ruleId} in ${context.environment}`);output_manager_default.spinner(`Updating rule in ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner();let nextRule=findFlagRule(nextEnvConfig.rules,ruleId);output_manager_default.success(`Rule ${import_chalk86.default.bold(ruleId)} updated for ${import_chalk86.default.bold(context.flag.slug)} in ${import_chalk86.default.bold(context.environment)}`),output_manager_default.log(` ${import_chalk86.default.dim("Conditions:")} ${nextRule.conditions.map(condition=>formatFlagRuleCondition(condition,context.settings)).join(", ")}`),output_manager_default.log(` ${import_chalk86.default.dim("Outcome:")} ${formatFlagRuleOutcome(nextRule.outcome,context.flag.variants)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk87=__toESM(require_source(),1);async function rulesRemove(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesRemoveSubcommand2.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,ruleId]=args,environment=flags["--environment"],message=normalizeOptionalInput(flags["--message"]);if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentRule(ruleId),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg||!ruleId)return output_manager_default.error("Please provide a flag slug or ID and rule ID to remove"),output_manager_default.log(`Example: ${getCommandName("flags rules remove my-feature rule_123 --environment production")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment containing the rule:"});if(isExitCodeResult2(context))return context.exitCode;let envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),nextEnvConfig=removeFlagRule(envConfig,ruleId),updateMessage=await resolveFlagUpdateMessage(client,message,`Remove rule ${ruleId} from ${context.environment}`);output_manager_default.spinner(`Removing rule from ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner(),output_manager_default.success(`Rule ${import_chalk87.default.bold(ruleId)} removed from ${import_chalk87.default.bold(context.flag.slug)} in ${import_chalk87.default.bold(context.environment)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var import_chalk88=__toESM(require_source(),1),import_fast_deep_equal9=__toESM(require_fast_deep_equal(),1);async function rulesMove(client,argv){let telemetryClient=new FlagsRulesCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(rulesMoveSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,ruleId]=args,environment=flags["--environment"],position=flags["--position"],message=normalizeOptionalInput(flags["--message"]);if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentRule(ruleId),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionPosition(position),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg||!ruleId||position===void 0)return output_manager_default.error("Please provide a flag slug or ID, rule ID, and destination position"),output_manager_default.log(`Example: ${getCommandName("flags rules move my-feature rule_123 --environment production --position 1")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:parsedArgs.flags["--project"],flagArg,environment,promptMessage:"Select an environment containing the rule:"});if(isExitCodeResult2(context))return context.exitCode;let envConfig=getFlagRulesEnvironmentConfig(context.flag,context.environment),nextEnvConfig=moveFlagRule(envConfig,ruleId,position);if((0,import_fast_deep_equal9.default)(context.envConfig,nextEnvConfig))return output_manager_default.warn(`Rule ${import_chalk88.default.bold(ruleId)} is already at position ${position} in ${context.environment}`),0;let updateMessage=await resolveFlagUpdateMessage(client,message,`Move rule ${ruleId} to position ${position} in ${context.environment}`);output_manager_default.spinner(`Moving rule in ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:nextEnvConfig},message:updateMessage});output_manager_default.stopSpinner(),output_manager_default.success(`Rule ${import_chalk88.default.bold(ruleId)} moved to position ${position} for ${import_chalk88.default.bold(context.flag.slug)} in ${import_chalk88.default.bold(context.environment)}`),warnIfRuleChangesAreBypassed(updatedFlag,context.environment)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var COMMAND_CONFIG14={ls:getCommandAliases(rulesListSubcommand2),add:getCommandAliases(rulesAddSubcommand2),update:getCommandAliases(rulesUpdateSubcommand),rm:getCommandAliases(rulesRemoveSubcommand2),move:getCommandAliases(rulesMoveSubcommand)};async function rules(client){let telemetry=new FlagsRulesTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(rulesSubcommand2.options),parsedArgs;try{parsedArgs=parseArguments(client.argv.slice(4),flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let{subcommand,args,subcommandOriginal}=getSubcommand(parsedArgs.args,COMMAND_CONFIG14),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags rules",subcommand),output_manager_default.print(help(rulesSubcommand2,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:rulesSubcommand2,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesListSubcommand2),0):(telemetry.trackCliSubcommandList(subcommandOriginal),rulesLs(client,args));case"add":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesAddSubcommand2),0):(telemetry.trackCliSubcommandAdd(subcommandOriginal),rulesAdd(client,args));case"update":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesUpdateSubcommand),0):(telemetry.trackCliSubcommandUpdate(subcommandOriginal),rulesUpdate(client,args));case"rm":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesRemoveSubcommand2),0):(telemetry.trackCliSubcommandRemove(subcommandOriginal),rulesRemove(client,args));case"move":return needHelp?(telemetry.trackCliFlagHelp("flags rules",subcommandOriginal),printHelp(rulesMoveSubcommand),0):(telemetry.trackCliSubcommandMove(subcommandOriginal),rulesMove(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG14)),output_manager_default.print(help(rulesSubcommand2,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var FlagsTargetsTelemetryClient=class extends TelemetryClient{trackCliSubcommandList(actual){this.trackCliSubcommand({subcommand:"ls",value:actual})}trackCliSubcommandAdd(actual){this.trackCliSubcommand({subcommand:"add",value:actual})}trackCliSubcommandRemove(actual){this.trackCliSubcommand({subcommand:"rm",value:actual})}},FlagsTargetsCommandTelemetryClient=class extends FlagsRulesCommandTelemetryClient{trackCliArgumentTarget(targets2){targets2?.length&&this.trackCliArgument({arg:"target",value:this.redactedValue})}};var import_chalk90=__toESM(require_source(),1),import_pluralize10=__toESM(require_pluralize(),1);function formatFlagTargetSelector(target){return`${target.entity}.${target.attribute}=${target.value}`}function parseFlagTargetInput(input,options={}){let separatorIndex=input.indexOf("=");if(separatorIndex===-1)throw new Error(`Invalid target "${input}". Use ENTITY.ATTRIBUTE=VALUE, for example user.id=user_123.`);let{kind:entity,attribute}=parseEntityAttributeSelector(input.slice(0,separatorIndex)),rawValue=input.slice(separatorIndex+1);if(!options.allowLabel){if(!rawValue)throw new Error(`Invalid target "${input}". Value cannot be empty.`);return{entity,attribute,value:rawValue}}let labelIndex=rawValue.indexOf("|"),value=(labelIndex===-1?rawValue:rawValue.slice(0,labelIndex)).trim();if(!value)throw new Error(`Invalid target "${input}". Value cannot be empty.`);if(labelIndex===-1)return{entity,attribute,value};let label=rawValue.slice(labelIndex+1).trim();if(!label)throw new Error(`Invalid target "${input}". Label cannot be empty; use ENTITY.ATTRIBUTE=VALUE|LABEL or omit the "|".`);return validateLabelString(label,"label"),{entity,attribute,value,label}}function parseFlagTargetInputs(inputs,settings){let seen=new Map;for(let input of inputs){let target=parseFlagTargetInput(input,{allowLabel:!0});assertTargetableAttribute(target,settings);let key=formatFlagTargetSelector(target),existing=seen.get(key);existing?target.label&&(existing.label=target.label):seen.set(key,target)}return[...seen.values()]}function assertTargetableAttribute(target,settings){let entity=settings.entities.find(candidate=>candidate.kind===target.entity);if(!entity){let available=settings.entities.map(candidate=>candidate.kind);throw new Error(available.length>0?`Entity "${target.entity}" does not exist. Available entities: ${available.join(", ")}.`:`Entity "${target.entity}" does not exist. Define entities before adding targets.`)}let attribute=entity.attributes.find(candidate=>candidate.key===target.attribute);if(!attribute){let available=entity.attributes.map(candidate=>`${entity.kind}.${candidate.key}`);throw new Error(available.length>0?`Attribute "${target.entity}.${target.attribute}" does not exist. Available attributes: ${available.join(", ")}.`:`Attribute "${target.entity}.${target.attribute}" does not exist.`)}if(attribute.type!=="string")throw new Error(`Only string attributes can be targeted directly. ${target.entity}.${target.attribute} is a ${attribute.type} attribute.`)}function listFlagTargets(targets2){let entries=[];for(let[variantId,entities2]of Object.entries(targets2??{}))for(let[entity,attributes]of Object.entries(entities2))for(let[attribute,values]of Object.entries(attributes))for(let item of values)entries.push({variantId,entity,attribute,value:item.value,...item.note?{note:item.note}:{}});return entries}function findFlagTargetVariantId(targets2,target){for(let[variantId,entities2]of Object.entries(targets2??{}))if(entities2[target.entity]?.[target.attribute]?.some(item=>item.value===target.value))return variantId}function addFlagTargets(targets2,selectors,variantId){let next=structuredClone(targets2??{}),results=[];for(let selector of selectors){let previousVariantId=findFlagTargetVariantId(next,selector);if(previousVariantId===variantId){results.push({...selector,status:"unchanged"});continue}let previous=previousVariantId?deleteTargetValue(next,previousVariantId,selector):void 0,entities2=next[variantId]??={},attributes=entities2[selector.entity]??={};(attributes[selector.attribute]??=[]).push(previous?.note?{value:selector.value,note:previous.note}:{value:selector.value}),results.push(previousVariantId?{...selector,status:"moved",previousVariantId}:{...selector,status:"added"})}return{targets:next,results}}function removeFlagTargets(targets2,selectors){let next=structuredClone(targets2??{}),results=[],seen=new Set;for(let selector of selectors){let key=formatFlagTargetSelector(selector);if(seen.has(key))continue;seen.add(key);let variantId=findFlagTargetVariantId(next,selector);if(!variantId)throw new Error(`Target "${formatFlagTargetSelector(selector)}" does not exist.`);deleteTargetValue(next,variantId,selector),results.push({...selector,variantId})}return{targets:next,results}}function deleteTargetValue(targets2,variantId,selector){let entities2=targets2[variantId],attributes=entities2?.[selector.entity],values=attributes?.[selector.attribute];if(!entities2||!attributes||!values)return;let removed=values.find(item=>item.value===selector.value),remaining=values.filter(item=>item.value!==selector.value);return remaining.length>0?(attributes[selector.attribute]=remaining,removed):(delete attributes[selector.attribute],Object.keys(attributes).length===0&&delete entities2[selector.entity],Object.keys(entities2).length===0&&delete targets2[variantId],removed)}function buildTargetsEnvironmentConfig(flag,environment,targets2){return{...flag.environments[environment],targets:targets2}}var import_chalk89=__toESM(require_source(),1);function formatTargetValue2(target,settings){let label=target.label??resolveTargetingLabel(settings,target.entity,target.attribute,target.value),selector=formatFlagTargetSelector(target);return label?`${selector} ${import_chalk89.default.gray(label)}`:selector}function formatTargetVariant(flag,variantId){let variant=flag.variants.find(candidate=>candidate.id===variantId);return formatFlagVariantSummary(variant,variantId)}async function targetsLs(client,argv){let telemetryClient=new FlagsTargetsCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(targetsListSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg]=args,environment=flags["--environment"],json=flags["--json"];if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliFlagJson(json),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg)return output_manager_default.error("Please provide a flag slug or ID to list targets for"),output_manager_default.log(`Example: ${getCommandName("flags targets list my-feature --environment production")}`),2;if(json&&!environment)return output_manager_default.error("Missing required option --environment when using --json"),output_manager_default.log(`Example: ${getCommandName("flags targets list my-feature --environment production --json")}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:flags["--project"],flagArg,environment,promptMessage:"Select an environment to list targets for:",fetchSettings:!json});if(isExitCodeResult2(context))return context.exitCode;let{envConfig}=context,targets2=envConfig.targets??{};if(json)return client.stdout.write(`${JSON.stringify({flag:context.flag.slug,environment:context.environment,active:envConfig.active,...envConfig.reuse?{reuse:envConfig.reuse}:{},targets:targets2},null,2)}
|
|
380
|
+
`),0;let entries=listFlagTargets(targets2),lsStamp=stamp_default(),inactiveMode=describeInactiveTargetingMode(context.flag,envConfig);if(entries.length===0){let projectFlag=flags["--project"]?` --project ${flags["--project"]}`:"";return output_manager_default.log(`No targets found for ${import_chalk90.default.bold(context.flag.slug)} in ${context.environment} ${import_chalk90.default.gray(lsStamp())}`),output_manager_default.log(`
|
|
381
|
+
Add one with: ${getCommandName(`flags targets add ${context.flag.slug} --environment ${context.environment} user.id=user_123${projectFlag}`)}`),0}output_manager_default.log(`${(0,import_pluralize10.default)("target",entries.length,!0)} found for ${import_chalk90.default.bold(context.flag.slug)} in ${context.environment} ${import_chalk90.default.gray(lsStamp())}`),printTargetsTable(entries,context.flag,context.settings),inactiveMode&&output_manager_default.print(`${import_chalk90.default.yellow("!")} ${import_chalk90.default.bold(context.environment)} ${inactiveMode}; these targets are not evaluated until targeting is active again.
|
|
382
|
+
`)}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function printTargetsTable(entries,flag,settings){let headers=["Attribute","Value","Label","Variant"],rows=entries.map(entry=>[`${entry.entity}.${entry.attribute}`,import_chalk90.default.bold(entry.value),resolveTargetingLabel(settings,entry.entity,entry.attribute,entry.value)??entry.note??"",formatTargetVariant(flag,entry.variantId)]),table2=formatTable(headers,["l","l","l","l"],[{name:"",rows}]);output_manager_default.print(`
|
|
365
383
|
${table2}
|
|
366
|
-
`)}var
|
|
384
|
+
`)}var import_chalk91=__toESM(require_source(),1),import_pluralize11=__toESM(require_pluralize(),1);var EXAMPLE="flags targets add my-feature --environment production user.id=user_123";async function targetsAdd(client,argv){let telemetryClient=new FlagsTargetsCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(targetsAddSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,...targetInputs]=args,environment=flags["--environment"],variantSelector=normalizeOptionalInput(flags["--variant"]),message=normalizeOptionalInput(flags["--message"]),json=flags["--json"];if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentTarget(targetInputs),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionVariant(variantSelector),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliFlagJson(json),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg||targetInputs.length===0)return output_manager_default.error("Please provide a flag slug or ID and at least one target as ENTITY.ATTRIBUTE=VALUE"),output_manager_default.log(`Example: ${getCommandName(EXAMPLE)}`),2;if(json&&!environment)return output_manager_default.error("Missing required option --environment when using --json"),output_manager_default.log(`Example: ${getCommandName(`${EXAMPLE} --json`)}`),2;try{let context=await resolveRulesCommandContext(client,{projectName:flags["--project"],flagArg,environment,promptMessage:"Select an environment to add targets to:",fetchSettings:!0});if(isExitCodeResult2(context))return context.exitCode;if(!context.settings)throw new Error("Flag settings are required to add targets.");let selectors=parseFlagTargetInputs(targetInputs,context.settings),variant=resolveTargetVariant(context.flag,variantSelector);if(!variant)return 2;let{targets:targets2,results}=addFlagTargets(context.envConfig.targets,selectors,variant.id),changed=results.filter(result=>result.status!=="unchanged"),variantSummary=formatTargetVariant(context.flag,variant.id),labelItems=buildLabelItems(selectors,context.settings);if(changed.length===0&&labelItems.length===0)return json?(writeJson(client,context.flag.slug,context.environment,targets2),0):(output_manager_default.warn(`${(0,import_pluralize11.default)("target",results.length,!0)} already ${results.length===1?"serves":"serve"} ${variantSummary} in ${import_chalk91.default.bold(context.environment)}; nothing to change`),0);let updatedFlag=context.flag;if(changed.length>0){let defaultMessage=`Add ${(0,import_pluralize11.default)("target",changed.length,!0)} to ${context.environment}`,updateMessage=json?message??defaultMessage:await resolveFlagUpdateMessage(client,message,defaultMessage);output_manager_default.spinner(`Adding targets to ${context.environment}...`),updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:buildTargetsEnvironmentConfig(context.flag,context.environment,targets2)},message:updateMessage}),output_manager_default.stopSpinner()}let labels2=await saveLabels(client,context.projectId,labelItems),finalTargets=updatedFlag.environments[context.environment]?.targets??targets2;if(json)return writeJson(client,updatedFlag.slug,context.environment,finalTargets,labels2),labels2&&labels2.errors.length>0?1:0;let labelSummary=labels2&&labels2.labels.length>0?` ${import_chalk91.default.dim(`(${(0,import_pluralize11.default)("label",labels2.labels.length,!0)} set)`)}`:"";changed.length>0?output_manager_default.success(`${(0,import_pluralize11.default)("target",changed.length,!0)} added to ${import_chalk91.default.bold(context.flag.slug)} in ${import_chalk91.default.bold(context.environment)}${labelSummary}`):output_manager_default.success(`Targets of ${import_chalk91.default.bold(context.flag.slug)} in ${import_chalk91.default.bold(context.environment)} unchanged${labelSummary}`);let failedLabelKeys=new Set((labels2?.errors??[]).map(error=>`${error.entityKind}.${error.attributeKey}=${error.value}`));for(let result of results){let selector=failedLabelKeys.has(formatFlagTargetSelector(result))?{...result,label:void 0}:result,value=formatTargetValue2(selector,context.settings);result.status==="moved"&&result.previousVariantId?output_manager_default.log(` ${value} ${import_chalk91.default.dim("\u2192")} ${variantSummary} ${import_chalk91.default.dim(`(moved from ${formatTargetVariant(context.flag,result.previousVariantId)})`)}`):result.status==="unchanged"?output_manager_default.log(` ${value} ${import_chalk91.default.dim("\u2192")} ${variantSummary} ${import_chalk91.default.dim("(unchanged)")}`):output_manager_default.log(` ${value} ${import_chalk91.default.dim("\u2192")} ${variantSummary}`)}if(warnIfRuleChangesAreBypassed(updatedFlag,context.environment,"target"),labels2&&labels2.errors.length>0){output_manager_default.warn(`${(0,import_pluralize11.default)("label",labels2.errors.length,!0)} ${labels2.errors.length===1?"was":"were"} not saved. The targets above are in place; set the labels again with:`);for(let error of labels2.errors){let item=labelItems.find(candidate=>candidate.entityKind===error.entityKind&&candidate.attributeKey===error.attributeKey&&candidate.value===error.value);output_manager_default.print(` ${import_chalk91.default.dim(`${error.code}: ${error.message}`)}
|
|
367
385
|
`),output_manager_default.print(` ${getCommandName(["flags labels set",quoteArg(`${error.entityKind}.${error.attributeKey}`),quoteArg(error.value),quoteArg(item&&"label"in item?item.label:"")].join(" "))}
|
|
368
|
-
`)}return 1}}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function resolveTargetVariant(flag,variantSelector){if(variantSelector)return resolveVariantOrThrow(variantSelector,flag.variants,"--variant");if(flag.kind==="boolean")return getBooleanVariant(flag,!0);output_manager_default.error(`Missing required option --variant. Flag ${
|
|
369
|
-
`)}var
|
|
370
|
-
`),0;output_manager_default.success(`${(0,
|
|
386
|
+
`)}return 1}}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}function resolveTargetVariant(flag,variantSelector){if(variantSelector)return resolveVariantOrThrow(variantSelector,flag.variants,"--variant");if(flag.kind==="boolean")return getBooleanVariant(flag,!0);output_manager_default.error(`Missing required option --variant. Flag ${import_chalk91.default.bold(flag.slug)} is a ${flag.kind} flag, so choose which variant the targets receive.`),output_manager_default.log(`Example: ${getCommandName(`flags targets add ${flag.slug} --environment production --variant <VARIANT> user.id=user_123`)}`)}function buildLabelItems(selectors,settings){let items=selectors.filter(selector=>selector.label!==void 0&&selector.label!==resolveTargetingLabel(settings,selector.entity,selector.attribute,selector.value)).map(selector=>({operation:"upsert",entityKind:selector.entity,attributeKey:selector.attribute,value:selector.value,label:selector.label}));if(items.length>MAX_LABEL_OPERATIONS)throw new Error(`Cannot set more than ${MAX_LABEL_OPERATIONS} labels at once. Split the targets into smaller batches.`);return items}async function saveLabels(client,projectId,items){if(items.length!==0){output_manager_default.spinner("Saving labels...");try{return await updateEntityLabelsBulk(client,projectId,items)}catch(err){let message=err instanceof Error?err.message:String(err);return{labels:[],errors:items.map(item=>({entityKind:item.entityKind,attributeKey:item.attributeKey,value:item.value,code:isAPIError(err)?err.code??"api_error":"error",message}))}}finally{output_manager_default.stopSpinner()}}}function writeJson(client,flag,environment,targets2,labels2){client.stdout.write(`${JSON.stringify({flag,environment,targets:targets2,...labels2?{labels:labels2}:{}},null,2)}
|
|
387
|
+
`)}var import_chalk92=__toESM(require_source(),1),import_pluralize12=__toESM(require_pluralize(),1);var EXAMPLE2="flags targets remove my-feature --environment production user.id=user_123";async function targetsRemove(client,argv){let telemetryClient=new FlagsTargetsCommandTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(targetsRemoveSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,[flagArg,...targetInputs]=args,environment=flags["--environment"],message=normalizeOptionalInput(flags["--message"]),json=flags["--json"];if(telemetryClient.trackCliArgumentFlag(flagArg),telemetryClient.trackCliArgumentTarget(targetInputs),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliOptionMessage(message),telemetryClient.trackCliFlagJson(json),telemetryClient.trackCliOptionProject(flags["--project"]),!flagArg||targetInputs.length===0)return output_manager_default.error("Please provide a flag slug or ID and at least one target as ENTITY.ATTRIBUTE=VALUE"),output_manager_default.log(`Example: ${getCommandName(EXAMPLE2)}`),2;if(json&&!environment)return output_manager_default.error("Missing required option --environment when using --json"),output_manager_default.log(`Example: ${getCommandName(`${EXAMPLE2} --json`)}`),2;try{let selectors=targetInputs.map(input=>parseFlagTargetInput(input)),context=await resolveRulesCommandContext(client,{projectName:flags["--project"],flagArg,environment,promptMessage:"Select an environment to remove targets from:",fetchSettings:!json});if(isExitCodeResult2(context))return context.exitCode;let{targets:targets2,results}=removeFlagTargets(context.envConfig.targets,selectors),defaultMessage=`Remove ${(0,import_pluralize12.default)("target",results.length,!0)} from ${context.environment}`,updateMessage=json?message??defaultMessage:await resolveFlagUpdateMessage(client,message,defaultMessage);output_manager_default.spinner(`Removing targets from ${context.environment}...`);let updatedFlag=await updateFlag(client,context.projectId,flagArg,{environments:{[context.environment]:buildTargetsEnvironmentConfig(context.flag,context.environment,targets2)},message:updateMessage});if(output_manager_default.stopSpinner(),json)return client.stdout.write(`${JSON.stringify({flag:updatedFlag.slug,environment:context.environment,targets:updatedFlag.environments[context.environment]?.targets??targets2},null,2)}
|
|
388
|
+
`),0;output_manager_default.success(`${(0,import_pluralize12.default)("target",results.length,!0)} removed from ${import_chalk92.default.bold(context.flag.slug)} in ${import_chalk92.default.bold(context.environment)}`);for(let result of results)output_manager_default.log(` ${formatTargetValue2(result,context.settings)} ${import_chalk92.default.dim("(was")} ${formatTargetVariant(context.flag,result.variantId)}${import_chalk92.default.dim(")")}`);warnIfRuleChangesAreBypassed(updatedFlag,context.environment,"target")}catch(err){return output_manager_default.stopSpinner(),printError(err),1}return 0}var COMMAND_CONFIG15={ls:getCommandAliases(targetsListSubcommand),add:getCommandAliases(targetsAddSubcommand),rm:getCommandAliases(targetsRemoveSubcommand)};async function targets(client){let telemetry=new FlagsTargetsTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(targetsSubcommand.options),parsedArgs;try{parsedArgs=parseArguments(client.argv.slice(4),flagsSpecification,{permissive:!0})}catch(err){return printError(err),2}let{subcommand,args,subcommandOriginal}=getSubcommand(parsedArgs.args,COMMAND_CONFIG15),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags targets",subcommand),output_manager_default.print(help(targetsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:targetsSubcommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags targets",subcommandOriginal),printHelp(targetsListSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),targetsLs(client,args));case"add":return needHelp?(telemetry.trackCliFlagHelp("flags targets",subcommandOriginal),printHelp(targetsAddSubcommand),0):(telemetry.trackCliSubcommandAdd(subcommandOriginal),targetsAdd(client,args));case"rm":return needHelp?(telemetry.trackCliFlagHelp("flags targets",subcommandOriginal),printHelp(targetsRemoveSubcommand),0):(telemetry.trackCliSubcommandRemove(subcommandOriginal),targetsRemove(client,args));default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG15)),output_manager_default.print(help(targetsSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var FlagsTargetingTelemetryClient=class extends TelemetryClient{trackCliSubcommandEnable(actual){this.trackCliSubcommand({subcommand:"enable",value:actual})}};var COMMAND_CONFIG16={enable:getCommandAliases(targetingEnableSubcommand)};async function targeting(client,args){let telemetry=new FlagsTargetingTelemetryClient({opts:{store:client.telemetryEventStore}}),{subcommand,args:subArgs,subcommandOriginal}=getSubcommand(args,COMMAND_CONFIG16);switch(subcommand){case"enable":return telemetry.trackCliSubcommandEnable(subcommandOriginal),useTargeting(client,subArgs);default:return output_manager_default.error(getInvalidSubcommand(COMMAND_CONFIG16)),output_manager_default.print(help(targetingSubcommand,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns})),2}}var import_env=__toESM(require_dist(),1);init_dist();async function emitDatafiles(client){try{parseArguments(client.argv.slice(4),getFlagsSpecification(prepareSubcommand.options))}catch(err){return printError(err),2}try{let localEnv={};try{localEnv=(0,import_env.loadEnvConfig)(client.cwd,!0).combinedEnv}catch(err){output_manager_default.debug(`Failed to load local env files: ${err}`)}return await prepareFlagsDefinitions({cwd:client.cwd,env:{...localEnv,...process.env},userAgentSuffix:ua_default,output:output_manager_default}),0}catch(err){return printError(err),1}}var import_env2=__toESM(require_dist(),1);async function override(client,argv){let parsedArgs,flagsSpecification=getFlagsSpecification(overrideSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,decryptToken=flags["--decrypt"];return decryptToken?handleDecrypt(client,decryptToken):handleEncrypt(client,args,flags)}async function handleEncrypt(client,args,flags){let expiration=flags["--expiration"]??"1y";if(args.length===0)return output_manager_default.error(`Please provide at least one flag override as flag=value.
|
|
371
389
|
Example: vercel flags override my-flag=true`),2;let overrides={};for(let arg of args){let eqIndex=arg.indexOf("=");if(eqIndex===-1)return output_manager_default.error(`Invalid override format: "${arg}". Expected flag=value.`),1;let key=arg.slice(0,eqIndex),rawValue=arg.slice(eqIndex+1);overrides[key]=parseValue(rawValue)}let secret=resolveSecret(client);if(!secret)return output_manager_default.error("FLAGS_SECRET not found. Set it in the environment, .env.local, or .env file."),1;try{let encrypted=await encryptOverrides(overrides,secret,expiration);return client.stdout.write(encrypted+`
|
|
372
390
|
`),0}catch(err){return printError(err),1}}async function handleDecrypt(client,token){let secret=resolveSecret(client);if(!secret)return output_manager_default.error("FLAGS_SECRET not found. Set it in the environment, .env.local, or .env file."),1;try{let overrides=await decryptOverrides(token,secret);return overrides===void 0?(output_manager_default.error("Invalid token: not a valid flag overrides token."),2):(client.stdout.write(JSON.stringify(overrides,null,2)+`
|
|
373
|
-
`),0)}catch(err){return printError(err),1}}function parseValue(raw){if(raw==="true")return!0;if(raw==="false")return!1;let num=Number(raw);return!Number.isNaN(num)&&raw.trim()!==""?num:raw}function resolveSecret(client){let{combinedEnv}=(0,import_env2.loadEnvConfig)(client.cwd,!0);return combinedEnv.FLAGS_SECRET}async function encryptOverrides(overrides,secret,expirationTime){let encodedSecret=base64url_exports.decode(secret);if(encodedSecret.length!==32)throw new Error("Invalid FLAGS_SECRET: must be a 256-bit base64url-encoded key (32 bytes).");return new EncryptJWT({o:overrides,pur:"overrides"}).setExpirationTime(expirationTime).setProtectedHeader({alg:"dir",enc:"A256GCM"}).encrypt(encodedSecret)}async function decryptOverrides(encryptedData,secret){let encodedSecret=base64url_exports.decode(secret);if(encodedSecret.length!==32)throw new Error("Invalid FLAGS_SECRET: must be a 256-bit base64url-encoded key (32 bytes).");let{payload}=await jwtDecrypt(encryptedData,encodedSecret);if(!(payload.pur!=="overrides"||!payload.o))return payload.o}var
|
|
391
|
+
`),0)}catch(err){return printError(err),1}}function parseValue(raw){if(raw==="true")return!0;if(raw==="false")return!1;let num=Number(raw);return!Number.isNaN(num)&&raw.trim()!==""?num:raw}function resolveSecret(client){let{combinedEnv}=(0,import_env2.loadEnvConfig)(client.cwd,!0);return combinedEnv.FLAGS_SECRET}async function encryptOverrides(overrides,secret,expirationTime){let encodedSecret=base64url_exports.decode(secret);if(encodedSecret.length!==32)throw new Error("Invalid FLAGS_SECRET: must be a 256-bit base64url-encoded key (32 bytes).");return new EncryptJWT({o:overrides,pur:"overrides"}).setExpirationTime(expirationTime).setProtectedHeader({alg:"dir",enc:"A256GCM"}).encrypt(encodedSecret)}async function decryptOverrides(encryptedData,secret){let encodedSecret=base64url_exports.decode(secret);if(encodedSecret.length!==32)throw new Error("Invalid FLAGS_SECRET: must be a 256-bit base64url-encoded key (32 bytes).");let{payload}=await jwtDecrypt(encryptedData,encodedSecret);if(!(payload.pur!=="overrides"||!payload.o))return payload.o}var import_chalk93=__toESM(require_source(),1),import_ms8=__toESM(require_ms(),1),import_pluralize13=__toESM(require_pluralize(),1);var MAX_LISTED_VARIANTS=3,MAX_VARIANT_LENGTH=30;function isPackedDatafile(data){return typeof data=="object"&&data!==null&&typeof data.definitions=="object"&&data.definitions!==null}function printDatafileSummary(datafile2,{projectLabel,environment,jsonCommand}){let envName=datafile2.environment??environment,slugs=Object.keys(datafile2.definitions).sort(),segmentCount=Object.keys(datafile2.segments??{}).length,source=[envName?`the ${envName} datafile`:"the datafile",projectLabel??datafile2.projectId].filter(Boolean).join(" for "),details=[datafile2.revision!==void 0?`revision ${datafile2.revision}`:null,datafile2.configUpdatedAt!==void 0?`updated ${(0,import_ms8.default)(Math.max(0,Date.now()-datafile2.configUpdatedAt))} ago`:null].filter(Boolean),detailsSuffix=details.length>0?` ${import_chalk93.default.gray(`(${details.join(", ")})`)}`:"",segmentsSuffix=segmentCount>0?` and ${(0,import_pluralize13.default)("segment",segmentCount,!0)}`:"";if(slugs.length===0)output_manager_default.log(`No feature flags in ${source}${detailsSuffix}`);else{output_manager_default.log(`${(0,import_pluralize13.default)("feature flag",slugs.length,!0)}${segmentsSuffix} in ${source}${detailsSuffix}`);let rows=slugs.map(slug=>formatFlagRow(slug,datafile2.definitions[slug],envName)),table2=formatTable(["Name","Serves","Rules","Targets","Reuses"],["l","l","r","r","l"],[{name:"",rows}]);output_manager_default.print(`
|
|
374
392
|
${table2}
|
|
375
|
-
`)}output_manager_default.log(`To see the full datafile including rules, run ${jsonCommand}`)}function formatFlagRow(slug,definition,envName){let{config,reusedEnvironment}=resolveEnvironmentConfig(definition,envName),reuses=reusedEnvironment??"";return config===void 0||typeof config=="object"&&"reuse"in config?[
|
|
393
|
+
`)}output_manager_default.log(`To see the full datafile including rules, run ${jsonCommand}`)}function formatFlagRow(slug,definition,envName){let{config,reusedEnvironment}=resolveEnvironmentConfig(definition,envName),reuses=reusedEnvironment??"";return config===void 0||typeof config=="object"&&"reuse"in config?[import_chalk93.default.bold(slug),import_chalk93.default.gray("unknown"),"","",reuses]:typeof config=="number"?[import_chalk93.default.bold(slug),formatServes(definition,new Set([config])),"","",reuses]:[import_chalk93.default.bold(slug),formatServes(definition,collectServedVariants(definition,config)),String(config.rules?.length??0),String(countTargets(config.targets)),reuses]}function resolveEnvironmentConfig(definition,envName){let environments=definition.environments??{},name=envName??Object.keys(environments)[0],config=name!==void 0?environments[name]:void 0,reusedEnvironment,visited=new Set([name]);for(;typeof config=="object"&&config!==null&&"reuse"in config;){if(reusedEnvironment??=config.reuse,visited.has(config.reuse))return{config:void 0,reusedEnvironment};visited.add(config.reuse),config=environments[config.reuse]}return{config,reusedEnvironment}}function collectServedVariants(definition,config){let served=new Set,addOutcome=outcome=>{if(typeof outcome=="number"){served.add(outcome);return}switch(outcome?.type){case"split":outcome.weights.forEach((weight,index)=>{weight>0&&served.add(index)}),served.add(outcome.defaultVariant);return;case"rollout":served.add(outcome.rollFromVariant),served.add(outcome.rollToVariant),served.add(outcome.defaultVariant);return;case"experiment":if(definition.experiment){addOutcome({type:"split",...definition.experiment});return}break}definition.variants.forEach((_,index)=>served.add(index))};addOutcome(config.fallthrough);for(let rule of config.rules??[])addOutcome(rule?.outcome);return config.targets?.forEach((targetList,index)=>{countTargets([targetList])>0&&served.add(index)}),served}function formatServes(definition,served){let values=[...served].sort((a,b)=>a-b).map(index=>definition.variants[index]);return values.length===1?values[0]===void 0?import_chalk93.default.gray("unknown"):truncateEnd(formatVariantValue(values[0]),MAX_VARIANT_LENGTH,{omission:"\u2026"}):values.length<=MAX_LISTED_VARIANTS&&values.every(value=>typeof value=="boolean"||typeof value=="number")?values.map(value=>formatVariantValue(value)).join(", "):(0,import_pluralize13.default)("variant",values.length,!0)}function countTargets(targets2){let count=0;for(let targetList of targets2??[])for(let attributes of Object.values(targetList))for(let values of Object.values(attributes))count+=Array.isArray(values)?values.length:0;return count}var FlagsDatafileTelemetryClient=class extends TelemetryClient{trackCliFlagJson(json){json&&this.trackCliFlag("json")}trackCliOptionProject(project){project&&this.trackCliOption({option:"project",value:this.redactedValue})}trackCliOptionEnvironment(environment){environment&&this.trackCliOption({option:"environment",value:environment})}trackCliFlagSdkKey(sdkKey){sdkKey&&this.trackCliFlag("sdk-key")}};var DATAFILE_URL="https://flags.vercel.com/v1/datafile",ENVIRONMENTS=["production","preview","development"],MAX_SDK_KEY_BYTES=4096,SDK_KEY_FORMAT=/^vf_(?:server|client)_[\x21-\x7E]+$/;function commandName(json,subcommands){return json?getCommandNamePlain(subcommands):getCommandName(subcommands)}function sdkKeyInputHint(json){return`Pipe it to stdin instead, for example ${commandName(json,"flags datafile --sdk-key < sdk-key.txt")}.`}async function datafile(client,argv){let telemetryClient=new FlagsDatafileTelemetryClient({opts:{store:client.telemetryEventStore}}),parsedArgs,flagsSpecification=getFlagsSpecification(datafileSubcommand.options);try{parsedArgs=parseArguments(argv,flagsSpecification)}catch(err){return printError(err),2}let{args,flags}=parsedArgs,projectName=getProjectNameFromFlags(flags),environment=flags["--environment"],useSdkKey=!!flags["--sdk-key"],json=!!flags["--json"];if(telemetryClient.trackCliOptionProject(projectName),telemetryClient.trackCliOptionEnvironment(environment),telemetryClient.trackCliFlagSdkKey(useSdkKey),telemetryClient.trackCliFlagJson(json),argv.some(arg=>arg.startsWith("--sdk-key="))||args.some(arg=>SDK_KEY_PATTERN.test(arg)))return outputError(client,json,"INVALID_ARGUMENTS",`SDK keys can't be passed as arguments. ${sdkKeyInputHint(json)}`);if(args.length>0)return outputError(client,json,"INVALID_ARGUMENTS",`${commandName(json,"flags datafile")} doesn't take arguments.`);if(environment!==void 0&&!ENVIRONMENTS.includes(environment))return outputError(client,json,"INVALID_ARGUMENTS",`Invalid environment "${environment}". Must be one of: ${ENVIRONMENTS.join(", ")}.`);if(useSdkKey){if(environment)return outputError(client,json,"MUTUAL_EXCLUSIVITY","The --environment option cannot be used with --sdk-key, as SDK keys are already bound to an environment.");if(projectName)return outputError(client,json,"MUTUAL_EXCLUSIVITY","The --project option cannot be used with --sdk-key, as SDK keys are already bound to a project.");let sdkKey=await readSdkKey(client,json);return typeof sdkKey=="number"?sdkKey:(json||output_manager_default.spinner("Fetching datafile"),fetchAndPrintDatafile(client,json,sdkKey,{},"Bearer",{jsonCommand:getJsonCommand(["--sdk-key"])}))}let link=await getLinkedFlagsProject(client,projectName);if(link.status==="error")return link.exitCode;if(link.status==="not_linked")return outputError(client,json,"NOT_LINKED",`Your codebase isn't linked to a project on Vercel. Pass --project <name>, or run ${commandName(json,"link")} to link it.`);let{project,org}=link;json||output_manager_default.spinner(`Fetching ${environment?`${environment} `:""}datafile for ${formatProject(org.slug,project.name)}`);let token,authScheme="Bearer",targetEnvironment=environment??"development",headers={"x-vercel-flags-project-id":project.id};try{let oidcToken=targetEnvironment==="development"?await getDevelopmentOidcToken(client,project.id,org.id):void 0;if(oidcToken)token=oidcToken;else{if(await client.ensureAuthorized(),!client.authConfig.token)return output_manager_default.stopSpinner(),outputError(client,json,"NOT_AUTHORIZED",`No user token is available. Run ${commandName(json,"login")} and retry the datafile command.`);token=client.authConfig.token,authScheme="VercelUser",headers["x-vercel-flags-team-id"]=org.id,headers["x-vercel-env"]=targetEnvironment}}catch(err){return output_manager_default.stopSpinner(),printUnexpectedError(client,json,err)}return fetchAndPrintDatafile(client,json,token,headers,authScheme,{projectLabel:formatProject(org.slug,project.name),environment:targetEnvironment,jsonCommand:getJsonCommand([...projectName?["--project",quoteArg(projectName)]:[],...environment?["--environment",environment]:[]])})}function getJsonCommand(args){return getCommandName(["flags datafile",...args,"--json"].join(" "))}async function readSdkKey(client,json){let sdkKey;if(!client.stdin.isTTY)sdkKey=(await readStdinText(client.stdin,MAX_SDK_KEY_BYTES)).trim();else if(!client.nonInteractive&&!json)sdkKey=(await client.input.password({message:"SDK key",mask:!0,validate:value=>value.trim().length>0?!0:"Enter an SDK key."})).trim();else return missingSdkKey(client,json,"Missing SDK key.");return sdkKey?SDK_KEY_PATTERN.test(sdkKey)?SDK_KEY_FORMAT.test(sdkKey)?sdkKey:outputError(client,json,"INVALID_ARGUMENTS","The SDK key can't contain spaces, line breaks, or other control characters."):outputError(client,json,"INVALID_ARGUMENTS","The SDK key must start with vf_server_ or vf_client_."):missingSdkKey(client,json,"No SDK key was read from stdin.")}function missingSdkKey(client,json,problem){let reason=AGENT_REASON.MISSING_KEY,machine=json||shouldEmitNonInteractiveCommandError(client),message=`${problem} ${sdkKeyInputHint(machine)}`;return machine?writeActionRequired(client,{status:AGENT_STATUS.ACTION_REQUIRED,reason,message,next:[{command:`${buildCommandWithGlobalFlags(client.argv,`flags datafile --sdk-key${json?" --json":""}`)} < <SDK_KEY_FILE>`,when:"Replace <SDK_KEY_FILE> with a file that contains the SDK key"}]}):output_manager_default.error(message),getExitCodeForReason(reason)}async function getDevelopmentOidcToken(client,projectId,accountId){try{let result=await client.fetch(`/projects/${projectId}/token`,{method:"POST",accountId,retry:{retries:0},bailOn429:!0,body:JSON.stringify({source:"vercel-cli"}),headers:{"Content-Type":"application/json"}});return typeof result.token=="string"&&result.token.trim()?result.token:void 0}catch{output_manager_default.debug("Development OIDC token unavailable; using user authentication.");return}}async function fetchAndPrintDatafile(client,json,token,extraHeaders,authScheme,summary){try{let res=await fetch(DATAFILE_URL,{redirect:"error",headers:{accept:"application/json",authorization:`${authScheme} ${token}`,"user-agent":ua_default,...extraHeaders}});if(output_manager_default.stopSpinner(),!res.ok){let body=await res.text().catch(()=>"");return outputError(client,json,"DATAFILE_FETCH_FAILED",redactSecret(`Failed to fetch datafile (${res.status} ${res.statusText})${body?`: ${body}`:""}`,token))}let data=await res.json();return json?client.stdout.write(`${JSON.stringify({datafile:data},null,2)}
|
|
376
394
|
`):isPackedDatafile(data)?printDatafileSummary(data,summary):client.stdout.write(`${JSON.stringify(data,null,2)}
|
|
377
|
-
`),0}catch(err){return output_manager_default.stopSpinner(),printUnexpectedError(client,json,err,token)}}function redactSecret(text,secret){return secret?text.split(secret).join("[REDACTED]"):text}function printUnexpectedError(client,json,err,secret=""){let message=err instanceof Error?err.message:String(err),redacted=redactSecret(message,secret);return json?outputError(client,json,"UNEXPECTED_ERROR",redacted):(printError(redacted===message?err:new Error(redacted)),1)}var COMMAND_CONFIG17={ls:getCommandAliases(listSubcommand),stale:getCommandAliases(staleSubcommand),inspect:getCommandAliases(inspectSubcommand),versions:getCommandAliases(versionsSubcommand),evaluations:getCommandAliases(evaluationsSubcommand),create:getCommandAliases(createSubcommand),open:getCommandAliases(openSubcommand),update:getCommandAliases(updateSubcommand),set:getCommandAliases(setSubcommand),targeting:getCommandAliases(targetingSubcommand),"use-targeting":getCommandAliases(useTargetingSubcommand),split:getCommandAliases(splitSubcommand),rollout:getCommandAliases(rolloutSubcommand),delete:getCommandAliases(removeSubcommand),archive:getCommandAliases(archiveSubcommand),unarchive:getCommandAliases(unarchiveSubcommand),disable:getCommandAliases(disableSubcommand),enable:getCommandAliases(enableSubcommand),rules:getCommandAliases(rulesSubcommand2),targets:getCommandAliases(targetsSubcommand),segments:getCommandAliases(segmentsSubcommand),entities:getCommandAliases(entitiesSubcommand),labels:getCommandAliases(labelsSubcommand),"sdk-keys":getCommandAliases(sdkKeysSubcommand),connections:getCommandAliases(connectionsSubcommand),prepare:getCommandAliases(prepareSubcommand),datafile:getCommandAliases(datafileSubcommand),override:getCommandAliases(overrideSubcommand)};async function main10(client){let telemetry=new FlagsTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(flagsCommand.options),argv=client.argv.slice(2),parsedArgs;try{parsedArgs=parseArguments(argv,flagsSpecification,{permissive:!0,commandShorthands:findCommandShorthands(commandsStructs,argv)})}catch(err){return printError(err),2}let subArgs=parsedArgs.args.slice(1),{subcommand,args,subcommandOriginal}=getSubcommand(subArgs,COMMAND_CONFIG17),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags",subcommand),output_manager_default.print(help(flagsCommand,{stream:client.stderr,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(listSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),ls(client,args));case"inspect":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(inspectSubcommand),0):(telemetry.trackCliSubcommandInspect(subcommandOriginal),inspect5(client,args));case"versions":return telemetry.trackCliSubcommandVersions(subcommandOriginal),versions(client,needHelp?[...args,"--help"]:args);case"evaluations":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(evaluationsSubcommand),0):(telemetry.trackCliSubcommandEvaluations(subcommandOriginal),evaluations(client,args));case"stale":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(staleSubcommand),0):(telemetry.trackCliSubcommandStale(subcommandOriginal),stale(client,args));case"open":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(openSubcommand),0):(telemetry.trackCliSubcommandOpen(subcommandOriginal),openFlag(client,args));case"create":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(createSubcommand),0):(telemetry.trackCliSubcommandCreate(subcommandOriginal),subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags add","flags create"),create(client,args));case"update":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(updateSubcommand),0):(telemetry.trackCliSubcommandUpdate(subcommandOriginal),update(client,args));case"set":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(setSubcommand),0):(telemetry.trackCliSubcommandSet(subcommandOriginal),set(client,args));case"use-targeting":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(useTargetingSubcommand),0):(telemetry.trackCliSubcommandUseTargeting(subcommandOriginal),warnDeprecatedSubcommand(client,"flags use-targeting","flags targeting enable"),useTargeting(client,args));case"targeting":return telemetry.trackCliSubcommandTargeting(subcommandOriginal),targeting(client,args);case"split":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(splitSubcommand),0):(telemetry.trackCliSubcommandSplit(subcommandOriginal),split(client,args));case"rollout":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(rolloutSubcommand),0):(telemetry.trackCliSubcommandRollout(subcommandOriginal),rollout(client,args));case"delete":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(removeSubcommand),0):(telemetry.trackCliSubcommandDelete(subcommandOriginal),subcommandOriginal==="remove"&&warnDeprecatedSubcommand(client,"flags remove","flags delete"),rm(client,args));case"archive":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(archiveSubcommand),0):(telemetry.trackCliSubcommandArchive(subcommandOriginal),archive(client,args));case"unarchive":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(unarchiveSubcommand),0):(telemetry.trackCliSubcommandUnarchive(subcommandOriginal),unarchive(client,args));case"disable":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(disableSubcommand),0):(telemetry.trackCliSubcommandDisable(subcommandOriginal),disable3(client,args));case"enable":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(enableSubcommand),0):(telemetry.trackCliSubcommandEnable(subcommandOriginal),enable3(client,args));case"rules":return telemetry.trackCliSubcommandRules(subcommandOriginal),rules(client);case"targets":return telemetry.trackCliSubcommandTargets(subcommandOriginal),targets(client);case"sdk-keys":return telemetry.trackCliSubcommandSdkKeys(subcommandOriginal),sdkKeys(client);case"connections":return telemetry.trackCliSubcommandConnections(subcommandOriginal),connections(client);case"segments":return telemetry.trackCliSubcommandSegments(subcommandOriginal),segments(client);case"entities":return telemetry.trackCliSubcommandEntities(subcommandOriginal),entities(client);case"labels":return telemetry.trackCliSubcommandLabels(subcommandOriginal),labels(client);case"prepare":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(prepareSubcommand),0):(telemetry.trackCliSubcommandPrepare(subcommandOriginal),emitDatafiles(client));case"datafile":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(datafileSubcommand),0):(telemetry.trackCliSubcommandDatafile(subcommandOriginal),datafile(client,args));case"override":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(overrideSubcommand),0):(telemetry.trackCliSubcommandOverride(subcommandOriginal),override(client,args));default:return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(listSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),ls(client,args))}}export{feedback,main9 as firewall,main10 as flags};
|
|
395
|
+
`),0}catch(err){return output_manager_default.stopSpinner(),printUnexpectedError(client,json,err,token)}}function redactSecret(text,secret){return secret?text.split(secret).join("[REDACTED]"):text}function printUnexpectedError(client,json,err,secret=""){let message=err instanceof Error?err.message:String(err),redacted=redactSecret(message,secret);return json?outputError(client,json,"UNEXPECTED_ERROR",redacted):(printError(redacted===message?err:new Error(redacted)),1)}var COMMAND_CONFIG17={ls:getCommandAliases(listSubcommand),stale:getCommandAliases(staleSubcommand),cleanup:getCommandAliases(cleanupSubcommand),inspect:getCommandAliases(inspectSubcommand),versions:getCommandAliases(versionsSubcommand),evaluations:getCommandAliases(evaluationsSubcommand),create:getCommandAliases(createSubcommand),open:getCommandAliases(openSubcommand),update:getCommandAliases(updateSubcommand),set:getCommandAliases(setSubcommand),targeting:getCommandAliases(targetingSubcommand),"use-targeting":getCommandAliases(useTargetingSubcommand),split:getCommandAliases(splitSubcommand),rollout:getCommandAliases(rolloutSubcommand),delete:getCommandAliases(removeSubcommand),archive:getCommandAliases(archiveSubcommand),unarchive:getCommandAliases(unarchiveSubcommand),disable:getCommandAliases(disableSubcommand),enable:getCommandAliases(enableSubcommand),rules:getCommandAliases(rulesSubcommand2),targets:getCommandAliases(targetsSubcommand),segments:getCommandAliases(segmentsSubcommand),entities:getCommandAliases(entitiesSubcommand),labels:getCommandAliases(labelsSubcommand),"sdk-keys":getCommandAliases(sdkKeysSubcommand),connections:getCommandAliases(connectionsSubcommand),prepare:getCommandAliases(prepareSubcommand),datafile:getCommandAliases(datafileSubcommand),override:getCommandAliases(overrideSubcommand)};async function main10(client){let telemetry=new FlagsTelemetryClient({opts:{store:client.telemetryEventStore}}),flagsSpecification=getFlagsSpecification(flagsCommand.options),argv=client.argv.slice(2),parsedArgs;try{parsedArgs=parseArguments(argv,flagsSpecification,{permissive:!0,commandShorthands:findCommandShorthands(commandsStructs,argv)})}catch(err){return printError(err),2}let subArgs=parsedArgs.args.slice(1),{subcommand,args,subcommandOriginal}=getSubcommand(subArgs,COMMAND_CONFIG17),needHelp=parsedArgs.flags["--help"];if(!subcommand&&needHelp)return telemetry.trackCliFlagHelp("flags",subcommand),output_manager_default.print(help(flagsCommand,{stream:client.stderr,columns:client.stderr.columns})),0;function printHelp(command){output_manager_default.print(help(command,{stream:client.stderr,parent:flagsCommand,columns:client.stderr.columns}))}switch(subcommand){case"ls":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(listSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),ls(client,args));case"inspect":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(inspectSubcommand),0):(telemetry.trackCliSubcommandInspect(subcommandOriginal),inspect5(client,args));case"versions":return telemetry.trackCliSubcommandVersions(subcommandOriginal),versions(client,needHelp?[...args,"--help"]:args);case"evaluations":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(evaluationsSubcommand),0):(telemetry.trackCliSubcommandEvaluations(subcommandOriginal),evaluations(client,args));case"stale":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(staleSubcommand),0):(telemetry.trackCliSubcommandStale(subcommandOriginal),stale(client,args));case"open":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(openSubcommand),0):(telemetry.trackCliSubcommandOpen(subcommandOriginal),openFlag(client,args));case"create":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(createSubcommand),0):(telemetry.trackCliSubcommandCreate(subcommandOriginal),subcommandOriginal==="add"&&warnDeprecatedSubcommand(client,"flags add","flags create"),create(client,args));case"update":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(updateSubcommand),0):(telemetry.trackCliSubcommandUpdate(subcommandOriginal),update(client,args));case"set":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(setSubcommand),0):(telemetry.trackCliSubcommandSet(subcommandOriginal),set(client,args));case"use-targeting":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(useTargetingSubcommand),0):(telemetry.trackCliSubcommandUseTargeting(subcommandOriginal),warnDeprecatedSubcommand(client,"flags use-targeting","flags targeting enable"),useTargeting(client,args));case"targeting":return telemetry.trackCliSubcommandTargeting(subcommandOriginal),targeting(client,args);case"split":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(splitSubcommand),0):(telemetry.trackCliSubcommandSplit(subcommandOriginal),split(client,args));case"rollout":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(rolloutSubcommand),0):(telemetry.trackCliSubcommandRollout(subcommandOriginal),rollout(client,args));case"delete":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(removeSubcommand),0):(telemetry.trackCliSubcommandDelete(subcommandOriginal),subcommandOriginal==="remove"&&warnDeprecatedSubcommand(client,"flags remove","flags delete"),rm(client,args));case"archive":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(archiveSubcommand),0):(telemetry.trackCliSubcommandArchive(subcommandOriginal),archive(client,args));case"unarchive":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(unarchiveSubcommand),0):(telemetry.trackCliSubcommandUnarchive(subcommandOriginal),unarchive(client,args));case"disable":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(disableSubcommand),0):(telemetry.trackCliSubcommandDisable(subcommandOriginal),disable3(client,args));case"enable":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(enableSubcommand),0):(telemetry.trackCliSubcommandEnable(subcommandOriginal),enable3(client,args));case"rules":return telemetry.trackCliSubcommandRules(subcommandOriginal),rules(client);case"targets":return telemetry.trackCliSubcommandTargets(subcommandOriginal),targets(client);case"cleanup":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(cleanupSubcommand),0):(telemetry.trackCliSubcommandCleanup(subcommandOriginal),cleanup(client,args));case"sdk-keys":return telemetry.trackCliSubcommandSdkKeys(subcommandOriginal),sdkKeys(client);case"connections":return telemetry.trackCliSubcommandConnections(subcommandOriginal),connections(client);case"segments":return telemetry.trackCliSubcommandSegments(subcommandOriginal),segments(client);case"entities":return telemetry.trackCliSubcommandEntities(subcommandOriginal),entities(client);case"labels":return telemetry.trackCliSubcommandLabels(subcommandOriginal),labels(client);case"prepare":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(prepareSubcommand),0):(telemetry.trackCliSubcommandPrepare(subcommandOriginal),emitDatafiles(client));case"datafile":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(datafileSubcommand),0):(telemetry.trackCliSubcommandDatafile(subcommandOriginal),datafile(client,args));case"override":return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(overrideSubcommand),0):(telemetry.trackCliSubcommandOverride(subcommandOriginal),override(client,args));default:return needHelp?(telemetry.trackCliFlagHelp("flags",subcommandOriginal),printHelp(listSubcommand),0):(telemetry.trackCliSubcommandList(subcommandOriginal),ls(client,args))}}export{feedback,main9 as firewall,main10 as flags};
|