apify-cli 1.10.1-beta.54 → 1.10.1-beta.55

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.
@@ -1,4 +1,4 @@
1
- import e from"node:process";import t from"chalk";import n from"indent-string";import r from"widest-line";import i from"wrap-ansi";import a,{basename as s,dirname as c,isAbsolute as l,join as u,relative as f,resolve as p,sep as m}from"node:path";import{inspect as h,parseArgs as g,promisify as _}from"node:util";import{gt as v,gte as y,minVersion as b,satisfies as x}from"semver";import{appendFileSync as S,chmodSync as C,closeSync as w,constants as T,copyFileSync as E,createWriteStream as D,existsSync as O,fstat as k,mkdirSync as A,openSync as j,readFileSync as M,readdirSync as N,realpathSync as ee,renameSync as P,rmSync as F,statSync as te,unlinkSync as ne,writeFileSync as I,writeSync as re}from"node:fs";import ie from"string-width";import ae from"strip-ansi";import{once as oe}from"node:events";import{homedir as se,platform as ce}from"node:os";import le,{isCI as ue}from"ci-info";import{ACTOR_ENV_VARS as L,ACTOR_JOB_STATUSES as R,ACTOR_JOB_TERMINAL_STATUSES as de,ACTOR_JOB_TYPES as z,ACTOR_NAME as fe,ACTOR_SOURCE_TYPES as pe,APIFY_ENV_VARS as B,KEY_VALUE_STORE_KEYS as me,LOCAL_ACTOR_ENV_VARS as he,LOCAL_STORAGE_SUBDIRS as ge,MAX_MULTIFILE_BYTES as _e,META_ORIGINS as ve,SOURCE_FILE_FORMATS as ye}from"@apify/consts";import{jaroWinkler as be}from"@skyra/jaro-winkler";import xe from"js-levenshtein";import{ApifyApiError as Se,ApifyClient as Ce,DownloadItemsFormat as V}from"apify-client";import we,{AxiosHeaders as Te}from"axios";import{createHmacSignature as Ee,cryptoRandomObjectId as De}from"@apify/utilities";import{access as Oe,appendFile as ke,mkdir as H,readFile as U,readdir as Ae,rename as je,rm as Me,stat as W,symlink as Ne,unlink as Pe,writeFile as G}from"node:fs/promises";import{setTimeout as Fe}from"node:timers/promises";import{Result as Ie,err as Le,none as Re,ok as ze,some as Be}from"@sapphire/result";import{execa as Ve}from"execa";import He from"configparser";import Ue from"@inquirer/input";import We from"which";import{execSync as Ge,spawn as Ke}from"node:child_process";import{DurationFormatter as qe,Time as Je,TimeTypes as Ye}from"@sapphire/duration";import{Timestamp as Xe}from"@sapphire/timestamp";import Ze from"adm-zip";import Qe from"ajv/dist/2019.js";import{ZipArchive as $e}from"archiver";import et from"escape-string-regexp";import tt from"ignore";import{getEncoding as nt}from"istextorbinary";import rt,{Mime as it}from"mime";import at from"mime/types/other.js";import ot from"mime/types/standard.js";import{glob as st}from"tinyglobby";import{calculateRunDynamicMemory as ct}from"@apify/actor-memory-expression";import{Separator as lt,createPrompt as ut,isEnterKey as dt,makeTheme as ft,useKeypress as pt,usePrefix as mt,useState as ht}from"@inquirer/core";import{compile as gt}from"json-schema-to-typescript";import{validateInputSchema as _t,validateInputUsingValidator as vt}from"@apify/input_schema";import{getDatasetSchemaValidator as yt,getKeyValueStoreSchemaValidator as bt,getOutputSchemaValidator as xt}from"@apify/json_schemas";import{pipeline as St}from"node:stream/promises";import{MemoryStorage as Ct}from"@crawlee/memory-storage";import wt from"cli-table3";import{downloadTemplate as Tt}from"giget";import Et from"jju";import Dt from"open";import{fetchManifest as Ot,manifestUrl as kt,wrapperManifestUrl as At}from"@apify/actor-templates";import jt from"computer-name";import Mt from"@inquirer/password";import{createServer as Nt}from"node:http";import{createHash as Pt,randomBytes as Ft}from"node:crypto";import It from"@inquirer/select";import Lt from"node:assert";import{ReadStream as Rt}from"node:tty";import zt from"detect-indent";import{fileURLToPath as Bt}from"node:url";import Vt from"@root/walk";import Ht from"handlebars";function internalLog(e){e.stdoutOutput&&console.log(...e.stdoutOutput),e.stderrOutput&&console.error(...e.stderrOutput)}function simpleLog(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[e.message]})}function error(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.red(`Error:`),e.message]})}function warning(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.yellow.bold(`Warning:`),e.message]})}function success(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.green(`Success:`),e.message]})}function run(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.gray(`Run:`),e.message]})}function info(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.white(`Info:`),e.message]})}function detectInstallMethod(){if(process.env.APIFY_CLI_BUNDLE)return`bundle`;let e=process.argv[1];if(!e)return warning({message:`Failed to detect install method of CLI, assuming npm`}),`npm`;let t=ee(e);return process.env.VOLTA_HOME&&t.includes(process.env.VOLTA_HOME)?`volta`:t.includes(`homebrew/Cellar`)||t.includes(`linuxbrew/Cellar`)?`homebrew`:process.env.PNPM_HOME&&t.includes(process.env.PNPM_HOME)?`pnpm`:process.env.BUN_INSTALL&&t.includes(process.env.BUN_INSTALL)?`bun`:`npm`}function getRuntimeInfo(){return process.versions.bun?{runtime:`bun`,version:process.versions.bun,nodeVersion:process.versions.node}:process.versions.deno?{runtime:`deno`,version:process.versions.deno,nodeVersion:process.versions.node}:{runtime:`node`,version:process.versions.node}}let Ut=null;function useCLIMetadata(){if(Ut)return Ut;let e=detectInstallMethod(),t=getRuntimeInfo();return Ut={version:`1.10.1-beta.54`,hash:`6a5425998e7150344e07647a412328481ab83103`,arch:process.env.APIFY_BUNDLE_ARCH??process.arch,platform:process.platform===`win32`?`windows`:process.platform,runtime:t,extraRuntimeData:t.nodeVersion?`(emulating node ${t.nodeVersion})`:``,installMethod:e,get fullVersionString(){return`apify-cli/${this.version} (${this.hash.slice(0,7)}) running on ${this.platform}-${this.arch} with ${this.runtime.runtime}-${t.version}${this.extraRuntimeData?` ${this.extraRuntimeData}`:``}, installed via ${this.installMethod}`},get isBeta(){return this.version.includes(`beta`)||this.version===`0.0.0`}},e===`bundle`&&(Ut.installPath=c(process.execPath)),Ut}function cliDebugPrint(e,...n){process.env.APIFY_CLI_DEBUG&&console.error(t.gray(`[${e}]`),...n)}const Wt=[`apify`,`actor`];function unixWrapperScript(e){return[`#!/bin/sh`,`DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"`,`APIFY_CLI_ENTRYPOINT=${e} exec "$DIR/apify-cli" "$@"`,``].join(`
1
+ import e from"node:process";import t from"chalk";import n from"indent-string";import r from"widest-line";import i from"wrap-ansi";import a,{basename as s,dirname as c,isAbsolute as l,join as u,relative as f,resolve as p,sep as m}from"node:path";import{inspect as h,parseArgs as g,promisify as _}from"node:util";import{gt as v,gte as y,minVersion as b,satisfies as x}from"semver";import{appendFileSync as S,chmodSync as C,closeSync as w,constants as T,copyFileSync as E,createWriteStream as D,existsSync as O,fstat as k,mkdirSync as A,openSync as j,readFileSync as M,readdirSync as N,realpathSync as ee,renameSync as P,rmSync as F,statSync as te,unlinkSync as ne,writeFileSync as I,writeSync as re}from"node:fs";import ie from"string-width";import ae from"strip-ansi";import{once as oe}from"node:events";import{homedir as se,platform as ce}from"node:os";import le,{isCI as ue}from"ci-info";import{ACTOR_ENV_VARS as L,ACTOR_JOB_STATUSES as R,ACTOR_JOB_TERMINAL_STATUSES as de,ACTOR_JOB_TYPES as z,ACTOR_NAME as fe,ACTOR_SOURCE_TYPES as pe,APIFY_ENV_VARS as B,KEY_VALUE_STORE_KEYS as me,LOCAL_ACTOR_ENV_VARS as he,LOCAL_STORAGE_SUBDIRS as ge,MAX_MULTIFILE_BYTES as _e,META_ORIGINS as ve,SOURCE_FILE_FORMATS as ye}from"@apify/consts";import{jaroWinkler as be}from"@skyra/jaro-winkler";import xe from"js-levenshtein";import{ApifyApiError as Se,ApifyClient as Ce,DownloadItemsFormat as V}from"apify-client";import we,{AxiosHeaders as Te}from"axios";import{createHmacSignature as Ee,cryptoRandomObjectId as De}from"@apify/utilities";import{access as Oe,appendFile as ke,mkdir as H,readFile as U,readdir as Ae,rename as je,rm as Me,stat as W,symlink as Ne,unlink as Pe,writeFile as G}from"node:fs/promises";import{setTimeout as Fe}from"node:timers/promises";import{Result as Ie,err as Le,none as Re,ok as ze,some as Be}from"@sapphire/result";import{execa as Ve}from"execa";import He from"configparser";import Ue from"@inquirer/input";import We from"which";import{execSync as Ge,spawn as Ke}from"node:child_process";import{DurationFormatter as qe,Time as Je,TimeTypes as Ye}from"@sapphire/duration";import{Timestamp as Xe}from"@sapphire/timestamp";import Ze from"adm-zip";import Qe from"ajv/dist/2019.js";import{ZipArchive as $e}from"archiver";import et from"escape-string-regexp";import tt from"ignore";import{getEncoding as nt}from"istextorbinary";import rt,{Mime as it}from"mime";import at from"mime/types/other.js";import ot from"mime/types/standard.js";import{glob as st}from"tinyglobby";import{calculateRunDynamicMemory as ct}from"@apify/actor-memory-expression";import{Separator as lt,createPrompt as ut,isEnterKey as dt,makeTheme as ft,useKeypress as pt,usePrefix as mt,useState as ht}from"@inquirer/core";import{compile as gt}from"json-schema-to-typescript";import{validateInputSchema as _t,validateInputUsingValidator as vt}from"@apify/input_schema";import{getDatasetSchemaValidator as yt,getKeyValueStoreSchemaValidator as bt,getOutputSchemaValidator as xt}from"@apify/json_schemas";import{pipeline as St}from"node:stream/promises";import{MemoryStorage as Ct}from"@crawlee/memory-storage";import wt from"cli-table3";import{downloadTemplate as Tt}from"giget";import Et from"jju";import Dt from"open";import{fetchManifest as Ot,manifestUrl as kt,wrapperManifestUrl as At}from"@apify/actor-templates";import jt from"computer-name";import Mt from"@inquirer/password";import{createServer as Nt}from"node:http";import{createHash as Pt,randomBytes as Ft}from"node:crypto";import It from"@inquirer/select";import Lt from"node:assert";import{ReadStream as Rt}from"node:tty";import zt from"detect-indent";import{fileURLToPath as Bt}from"node:url";import Vt from"@root/walk";import Ht from"handlebars";function internalLog(e){e.stdoutOutput&&console.log(...e.stdoutOutput),e.stderrOutput&&console.error(...e.stderrOutput)}function simpleLog(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[e.message]})}function error(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.red(`Error:`),e.message]})}function warning(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.yellow.bold(`Warning:`),e.message]})}function success(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.green(`Success:`),e.message]})}function run(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.gray(`Run:`),e.message]})}function info(e){internalLog({[e.stdout?`stdoutOutput`:`stderrOutput`]:[t.white(`Info:`),e.message]})}function detectInstallMethod(){if(process.env.APIFY_CLI_BUNDLE)return`bundle`;let e=process.argv[1];if(!e)return warning({message:`Failed to detect install method of CLI, assuming npm`}),`npm`;let t=ee(e);return process.env.VOLTA_HOME&&t.includes(process.env.VOLTA_HOME)?`volta`:t.includes(`homebrew/Cellar`)||t.includes(`linuxbrew/Cellar`)?`homebrew`:process.env.PNPM_HOME&&t.includes(process.env.PNPM_HOME)?`pnpm`:process.env.BUN_INSTALL&&t.includes(process.env.BUN_INSTALL)?`bun`:`npm`}function getRuntimeInfo(){return process.versions.bun?{runtime:`bun`,version:process.versions.bun,nodeVersion:process.versions.node}:process.versions.deno?{runtime:`deno`,version:process.versions.deno,nodeVersion:process.versions.node}:{runtime:`node`,version:process.versions.node}}let Ut=null;function useCLIMetadata(){if(Ut)return Ut;let e=detectInstallMethod(),t=getRuntimeInfo();return Ut={version:`1.10.1-beta.55`,hash:`9667ede414802eef2f8e10846d919c7b07527b27`,arch:process.env.APIFY_BUNDLE_ARCH??process.arch,platform:process.platform===`win32`?`windows`:process.platform,runtime:t,extraRuntimeData:t.nodeVersion?`(emulating node ${t.nodeVersion})`:``,installMethod:e,get fullVersionString(){return`apify-cli/${this.version} (${this.hash.slice(0,7)}) running on ${this.platform}-${this.arch} with ${this.runtime.runtime}-${t.version}${this.extraRuntimeData?` ${this.extraRuntimeData}`:``}, installed via ${this.installMethod}`},get isBeta(){return this.version.includes(`beta`)||this.version===`0.0.0`}},e===`bundle`&&(Ut.installPath=c(process.execPath)),Ut}function cliDebugPrint(e,...n){process.env.APIFY_CLI_DEBUG&&console.error(t.gray(`[${e}]`),...n)}const Wt=[`apify`,`actor`];function unixWrapperScript(e){return[`#!/bin/sh`,`DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"`,`APIFY_CLI_ENTRYPOINT=${e} exec "$DIR/apify-cli" "$@"`,``].join(`
2
2
  `)}function windowsCmdWrapperScript(e){return[`@echo off`,`setlocal`,`set "APIFY_CLI_ENTRYPOINT=${e}"`,`"%~dp0apify-cli.exe" %*`,``].join(`\r
3
3
  `)}function windowsPowershellWrapperScript(e){return[`#!/usr/bin/env pwsh`,`$prev = $env:APIFY_CLI_ENTRYPOINT`,`$env:APIFY_CLI_ENTRYPOINT = "${e}"`,`try {`,` & "$PSScriptRoot\\apify-cli.exe" @args`,`} finally {`,` $env:APIFY_CLI_ENTRYPOINT = $prev`,`}`,`exit $LASTEXITCODE`,``].join(`\r
4
4
  `)}function atomicWriteSync(t,n,r){let i=`${t}.${e.pid}.tmp`;try{I(i,n),r!==void 0&&C(i,r),P(i,t)}catch(e){try{F(i,{force:!0})}catch{}throw e}}function atomicCopySync(t,n,r){let i=`${n}.${e.pid}.tmp`;try{E(t,i),r!==void 0&&C(i,r),P(i,n)}catch(e){try{F(i,{force:!0})}catch{}throw e}}function writeEntrypointShims(e,t){for(let n of Wt)atomicWriteSync(u(e,n),unixWrapperScript(n),493),t&&(atomicWriteSync(u(e,`${n}.cmd`),windowsCmdWrapperScript(n)),atomicWriteSync(u(e,`${n}.ps1`),windowsPowershellWrapperScript(n)))}function migrateLegacyBundleInstallIfNeeded(){let t=useCLIMetadata();if(t.installMethod!==`bundle`)return;let n=t.platform===`windows`,r=c(e.execPath),i=s(e.execPath).replace(/\.exe$/i,``).toLowerCase();if(n)for(let e of Wt){let t=u(r,`${e}.exe.old`);if(O(t))try{F(t,{force:!0}),cliDebugPrint(`[migration] removed stale legacy binary`,t)}catch(e){cliDebugPrint(`[migration] failed to remove stale legacy binary`,{stalePath:t,err:e})}}if(i===`apify-cli`||!Wt.includes(i))return;cliDebugPrint(`[migration] legacy multi-bundle install detected, migrating to single bundle`,{binDir:r,selfName:i});let a=u(r,`apify-cli${n?`.exe`:``}`);try{atomicCopySync(e.execPath,a,n?void 0:493),cliDebugPrint(`[migration] copied current bundle to`,a)}catch(e){cliDebugPrint(`[migration] failed to copy current bundle, will retry on next run`,{err:e});return}try{writeEntrypointShims(r,n),cliDebugPrint(`[migration] wrote entrypoint shims`)}catch(e){cliDebugPrint(`[migration] failed to write entrypoint shims, will retry on next run`,{err:e})}if(n){for(let t of Wt){let n=u(r,`${t}.exe`);if(O(n))try{p(n)===p(e.execPath)?(P(n,`${n}.old`),cliDebugPrint(`[migration] renamed running legacy binary`,n)):F(n,{force:!0})}catch(e){try{P(n,`${n}.old`)}catch{}cliDebugPrint(`[migration] failed to remove legacy binary`,{legacyBinaryPath:n,err:e})}}let t=u(r,`upgrade.ps1`);try{F(t,{force:!0}),cliDebugPrint(`[migration] removed upgrade script, it will be re-downloaded on the next upgrade`)}catch(e){cliDebugPrint(`[migration] failed to remove upgrade script`,{upgradeScriptPath:t,err:e})}}cliDebugPrint(`[migration] migration to single bundle complete`)}let Gt;function getMaxLineWidth(){if(Gt)return Gt;let e=Number(process.env.APIFY_CLI_MAX_LINE_WIDTH);if(!Number.isNaN(e))Gt=e;else if(!process.stdout.isTTY)Gt=80;else{let e=process.stdout.getWindowSize?.()[0]??-1;Gt=e<1?80:e<40?40:e}return Gt}var BaseCommandRenderer=class{command;entrypoint;constructor(e,t){this.entrypoint=e,this.command=t}pushShortDescription(e){let n=this.command.interactive?`${t.yellow(`[INTERACTIVE]`)} `:``;this.command.shortDescription?e.push(`${n}${this.command.shortDescription}`,``):this.command.description&&e.push(`${n}${this.command.description.split(`
@@ -16,7 +16,7 @@ import e from"node:process";import t from"chalk";import n from"indent-string";im
16
16
  `).trim()}selectiveRender(e){let t=[];return e.showShortDescription&&this.pushShortDescription(t),e.showDescription&&this.command.description&&this.pushDescription(t),e.showSubcommands&&this.pushSubcommands(t),e.showExamples&&this.pushExamples(t),e.showLearnMore&&this.pushLearnMore(t),t.join(`
17
17
  `).trim()}pushSubcommands(e){if(!this.command.subcommands?.length)return;e.push(t.bold(`SUBCOMMANDS`));let a=r(this.command.subcommands.map(e=>`${this.command.name} ${e.name}`).join(`
18
18
  `));for(let t of this.command.subcommands){let r=t.shortDescription||t.description?.split(`
19
- `)[0]||``,s=`${this.command.name} ${t.name.padEnd(a-this.command.name.length-1)} ${r}`,c=i(s,getMaxLineWidth()-a-2),l=n(c,a+2+2).trim();e.push(` ${l}`)}e.push(``)}};const Kt=/* @__PURE__ */ new Map;function registerCommandForHelpGeneration(e,t){if(t.name.toLowerCase()!==t.name){error({message:`Command name "${t.name}" is not correctly set up internally. Make sure you fill out the "name" field in the command class extension.`});return}if(t.subcommands?.length){Kt.set(t,new CommandWithSubcommandsHelp(e,t));for(let n of t.subcommands)registerCommandForHelpGeneration(`${e} ${t.name}`,n)}else Kt.set(t,new CommandHelp(e,t))}function renderHelpForCommand(e){let t=Kt.get(e);if(!t)throw Error(`No help renderer found for command ${e.name}`);return t.render()}function selectiveRenderHelpForCommand(e,t){let n=Kt.get(e);if(!n)throw Error(`No help renderer found for command ${e.name}`);return n.selectiveRender(t)}function sortByName(e,t){return e[0].name.localeCompare(t[0].name)}const qt=[`Local Actor Development`,`Apify Console`,`Authentication`,`Utilities`],Jt=`Other`,Yt=[{command:`apify login`},{description:`Walks you interactively through the Actor creation flow.`,command:`apify create`},{command:`apify run`},{command:`apify push`},{command:`apify actors search "web scraper"`}],Xt=[{command:`actor get-input`},{command:`actor push-data '{"url":"https://example.com"}'`},{command:`actor set-value OUTPUT '{"done":true}'`}];function renderMainHelpMenu(e){let a=useCLIMetadata(),s=[];e===`actor`?s.push(`'actor' is the runtime CLI baked into Apify Actor Docker images. It exposes a reduced command set intended for use from inside a running Actor. When available, these commands are equivalent to 'apify actor <subcommand>'.`,``):s.push(`Apify command-line interface (CLI) helps you manage the Apify cloud platform and develop, build, and deploy Apify Actors.`,``),s.push(t.bold(`VERSION`)),s.push(` ${a.fullVersionString}`),s.push(``),s.push(t.bold(`USAGE`)),s.push(` $ ${e} <command> [options]`),s.push(``);let c=[];for(let[e,t]of Kt)t.entrypoint.includes(` `)||e.hidden||c.push([e,t]);let l=/* @__PURE__ */ new Map;for(let e of c){let[t]=e,n=t.group||Jt;l.has(n)||l.set(n,[]),l.get(n).push(e)}for(let e of l.values())e.sort(sortByName);let u=[];for(let e of qt)l.has(e)&&u.push(e);let f=[...l.keys()].filter(e=>!qt.includes(e)&&e!==Jt).sort();u.push(...f),l.has(Jt)&&u.push(Jt);let p=c.map(([e])=>e.name).join(`
19
+ `)[0]||``,s=`${this.command.name} ${t.name.padEnd(a-this.command.name.length-1)} ${r}`,c=i(s,getMaxLineWidth()-a-2),l=n(c,a+2+2).trim();e.push(` ${l}`)}e.push(``)}};const Kt=/* @__PURE__ */ new Map;function registerCommandForHelpGeneration(e,t){if(t.name.toLowerCase()!==t.name)error({message:`Command name "${t.name}" is not correctly set up internally. Make sure you fill out the "name" field in the command class extension.`});else if(t.subcommands?.length){Kt.set(t,new CommandWithSubcommandsHelp(e,t));for(let n of t.subcommands)registerCommandForHelpGeneration(`${e} ${t.name}`,n)}else Kt.set(t,new CommandHelp(e,t))}function renderHelpForCommand(e){let t=Kt.get(e);if(!t)throw Error(`No help renderer found for command ${e.name}`);return t.render()}function selectiveRenderHelpForCommand(e,t){let n=Kt.get(e);if(!n)throw Error(`No help renderer found for command ${e.name}`);return n.selectiveRender(t)}function sortByName(e,t){return e[0].name.localeCompare(t[0].name)}const qt=[`Local Actor Development`,`Apify Console`,`Authentication`,`Utilities`],Jt=`Other`,Yt=[{command:`apify login`},{description:`Walks you interactively through the Actor creation flow.`,command:`apify create`},{command:`apify run`},{command:`apify push`},{command:`apify actors search "web scraper"`}],Xt=[{command:`actor get-input`},{command:`actor push-data '{"url":"https://example.com"}'`},{command:`actor set-value OUTPUT '{"done":true}'`}];function renderMainHelpMenu(e){let a=useCLIMetadata(),s=[];e===`actor`?s.push(`'actor' is the runtime CLI baked into Apify Actor Docker images. It exposes a reduced command set intended for use from inside a running Actor. When available, these commands are equivalent to 'apify actor <subcommand>'.`,``):s.push(`Apify command-line interface (CLI) helps you manage the Apify cloud platform and develop, build, and deploy Apify Actors.`,``),s.push(t.bold(`VERSION`)),s.push(` ${a.fullVersionString}`),s.push(``),s.push(t.bold(`USAGE`)),s.push(` $ ${e} <command> [options]`),s.push(``);let c=[];for(let[e,t]of Kt)t.entrypoint.includes(` `)||e.hidden||c.push([e,t]);let l=/* @__PURE__ */ new Map;for(let e of c){let[t]=e,n=t.group||Jt;l.has(n)||l.set(n,[]),l.get(n).push(e)}for(let e of l.values())e.sort(sortByName);let u=[];for(let e of qt)l.has(e)&&u.push(e);let f=[...l.keys()].filter(e=>!qt.includes(e)&&e!==Jt).sort();u.push(...f),l.has(Jt)&&u.push(Jt);let p=c.map(([e])=>e.name).join(`
20
20
  `),m=r(p)||1,renderEntry=([e])=>{let t=e.shortDescription||e.description?.split(`
21
21
  `)[0]||``,r=`${e.name.padEnd(m)} ${t}`,a=i(r,getMaxLineWidth()-m-4);return` ${n(a,m+2+2).trim()}`};for(let e of u){let n=l.get(e);n.length&&(s.push(t.bold(e.toUpperCase())),s.push(...n.map(renderEntry),``))}let h=e===`actor`?Xt:Yt;if(h.length){s.push(t.bold(`EXAMPLES`));for(let e=0;e<h.length;e++){let r=h[e];if(r.description){e>0&&s.push(``);let a=i(r.description,getMaxLineWidth()-4,{trim:!1}).split(`
22
22
  `).map(e=>`# ${e}`).join(`
@@ -27,8 +27,8 @@ import e from"node:process";import t from"chalk";import n from"indent-string";im
27
27
  `)}}}static buildMessageFromFlagData(e){let n=[`Flag ${t.white.bold(e.shortForm?`-${e.name}`:`--${e.name}`)}`];return e.ambiguousFlag?(n.push(`is ambiguous (meaning the provided value could be interpreted as a flag too).`),e.ambiguousMessage?n.push(`\n${e.ambiguousMessage.split(`
28
28
  `).map(e=>` ${e}`).join(`
29
29
  `)}`):n.push(`To solve this, provide the flag like this: --${e.name}=<value>`)):e.expectsValue?n.push(`expects a value`):n.push(`does not take an argument`),n.map(e=>t.gray(e)).join(` `)}static into(e,t){if(e instanceof CommandError)return e;if(e instanceof Error&&`code`in e){let n=e;switch(n.code){case`ERR_PARSE_ARGS_INVALID_OPTION_VALUE`:return new CommandError({code:0,message:n.message,command:t});case`ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL`:return new CommandError({code:1,message:n.message,command:t});case`ERR_PARSE_ARGS_UNKNOWN_OPTION`:return new CommandError({code:2,message:n.message,command:t});default:return new CommandError({code:9,message:`Unknown error: ${e instanceof Error?e.message:String(e)}`,command:t})}}return new CommandError({code:9,message:`Unknown error: ${e instanceof Error?e.message:String(e)}`,command:t})}};const $t=_(k);let en;async function useStdin(){if(en)return en;let t=e.stdin,n={isTTY:t.isTTY,hasData:!1,waitDelay:0,stream:t},r=await $t(0).then(t=>{if(cliDebugPrint(`useStdin`,{stat:t,isRegularFile:t.isFile(),isDirectory:t.isDirectory(),isBlockDevice:t.isBlockDevice(),isCharDevice:t.isCharacterDevice(),isSymbolicLink:t.isSymbolicLink(),isFIFO:t.isFIFO(),isSocket:t.isSocket()}),e.platform===`win32`){if((t.mode&T.S_IFIFO)===T.S_IFIFO)return 100;if(t.isFile())return 50}return t.isFIFO()||t.isFile()||(t.isSocket()?50:!1)}).catch(()=>!1);return cliDebugPrint(`useStdin`,{hasData:n.hasData,waitDelay:n.waitDelay,isTTY:n.isTTY,pipedIn:r,readableEnded:t.readableEnded}),(!t.isTTY||r!==!1&&(t.isTTY!==void 0||!t.readableEnded))&&(n.hasData=!0),typeof r==`number`&&(n.waitDelay=r),en=n,n}async function readStdin(){let e=await useStdin(),{hasData:t,waitDelay:n,stream:r}=e;if(!t)return;let i=[],a=new AbortController,s=null;n&&(s=setTimeout(()=>{a.abort()},n).unref());let onData=e=>{i.push(e),s&&=(clearTimeout(s),null)};r.on(`data`,onData);try{await oe(r,`end`,{signal:a.signal})}catch(e){if(e.name===`AbortError`)return}finally{r.off(`data`,onData),r.pause()}s&&clearTimeout(s),e.hasData=!1;let c=Buffer.concat(i);if(c.length)return c}var tn={node:`>=22`};const nn=`storage`,rn={$schema:`https://apify.com/schemas/v1/actor.ide.json`,actorSpecification:1,name:null,version:`0.0`,buildTag:`latest`,environmentVariables:{}},an=Date.UTC(2026,9,1),on=[`SIGINT`,`SIGTERM`,`SIGHUP`],GLOBAL_CONFIGS_FOLDER=()=>{let t=u(se(),`.apify`);return e.env.__APIFY_INTERNAL_TEST_AUTH_PATH__?u(t,e.env.__APIFY_INTERNAL_TEST_AUTH_PATH__):t},AUTH_FILE_PATH=()=>u(GLOBAL_CONFIGS_FOLDER(),`auth.json`),SECRETS_FILE_PATH=()=>u(GLOBAL_CONFIGS_FOLDER(),`secrets.json`),STATE_FILE_PATH=()=>u(GLOBAL_CONFIGS_FOLDER(),`state.json`),TELEMETRY_FILE_PATH=()=>u(GLOBAL_CONFIGS_FOLDER(),`telemetry.json`),sn=`.actor`,K=u(sn,`actor.json`),cn=tn.node,ln=le.GITHUB_ACTIONS?`${e.env.GITHUB_SERVER_URL}/${e.env.GITHUB_REPOSITORY}/actions/runs/${e.env.GITHUB_RUN_ID}`:void 0,un={"X-Apify-Request-Origin":le.isCI?ve.CI:ve.CLI,...ln&&{"X-Apify-Github-Actions-Run-Url":ln}},dn=`3.11.0`;function migrateStateV0ToV1$1(e){if(e.version&&e.version>=1)return!1;let t=e;if(t.latestNpmVersionCheckedAt){let n=new Date(t.latestNpmVersionCheckedAt).getTime(),r=t.latestNpmVersion;cliDebugPrint(`LocalStateV0ToV1`,`Migrating state from v0 to v1`,{oldState:e,newState:{versionCheck:{lastChecked:n,lastVersion:r}}}),updateLocalState({version:1},e=>{e.versionCheck={lastChecked:n,lastVersion:r}})}return!0}const fn={version:1};function useLocalState(){let e=STATE_FILE_PATH();if(!O(e))return fn;let t=JSON.parse(M(e,`utf-8`));return migrateStateV0ToV1$1(t)?useLocalState():t}function updateLocalState(e,t){let n={...e};t(n);let r=STATE_FILE_PATH(),i=c(r);A(i,{recursive:!0}),I(STATE_FILE_PATH(),JSON.stringify(n,null,` `))}const pn=useCLIMetadata(),mn=`Apify CLI/${pn.version} (https://github.com/apify/apify-cli)`,hn=[`https://1.1.1.1`,`https://8.8.8.8`];async function isOnline(e=500){let t=new AbortController,n=setTimeout(()=>{t.abort()},e),r=await Promise.any(hn.map(async e=>fetch(e,{signal:t.signal,headers:{"User-Agent":mn},keepalive:!1}))).catch(()=>null);return clearTimeout(n),r?r.ok?(cliDebugPrint(`isOnline`,{state:`online`,site:r.url}),!0):(cliDebugPrint(`isOnline`,{state:`offline`}),!1):(cliDebugPrint(`isOnline`,{state:`timeout`}),!1)}async function getLatestVersion(e){let t=await fetch(`https://api.github.com/repos/apify/apify-cli/releases/latest`,{headers:{"User-Agent":mn}});if(!t.ok)return cliDebugPrint(`useCLIVersionCheck`,`Failed to fetch latest version`,{statusCode:t.status,body:await t.text()}),warning({message:`Failed to fetch latest version of Apify CLI, using the cached version instead.`}),null;let n=(await t.json()).tag_name.replace(/^v/,``);return cliDebugPrint(`useCLIVersionCheck`,`Fetched latest version`,{version:n}),updateLocalState(e,e=>{e.versionCheck={lastChecked:Date.now(),lastVersion:n}}),n}function shouldSkipVersionCheck(){return!(!process.env.APIFY_CLI_SKIP_UPDATE_CHECK||[`0`,`false`].includes(process.env.APIFY_CLI_SKIP_UPDATE_CHECK))}async function useCLIVersionCheck(e=!1){let t=useLocalState(),n=!t.versionCheck||Date.now()-t.versionCheck.lastChecked>864e5,r=e||n&&await isOnline(),i=r?await getLatestVersion(t):t.versionCheck?.lastVersion;if(!i)return{currentVersion:pn.version,latestVersion:`unknown`,shouldUpdate:!1,cacheHit:!1};let a=v(i,pn.version);return{currentVersion:pn.version,latestVersion:i,shouldUpdate:a,cacheHit:!r}}function useCommandSuggestions(e){let t=[...J.entries()].sort(([e],[t])=>e.localeCompare(t)),n=e.toLowerCase();return t.map(([e,t])=>{let r=e.toLowerCase(),i=e.split(` `),a=i[i.length-1].toLowerCase(),s=t.aliases?.includes(a)||t.hiddenAliases?.includes(a)||!1,c=xe(n,r),l=be(n,r),u=c<=2||l>=.975;return u?(cliDebugPrint(`useCommandSuggestions`,{inputString:n,lowercased:r,matches:u,levenshtein:c,jaroWinkler:l}),s?{string:`${r} (alias for ${t.name})`,distance:l}:{string:`${r}`,distance:l}):null}).filter(e=>e!==null).sort((e,t)=>t.distance-e.distance).map(e=>e.string)}const gn=await readStdin(),_n=useCLIMetadata(),vn=`Apify CLI/${_n.version} (https://github.com/apify/apify-cli)`;function processVersionCheck(t){_n.installMethod!==`bundle`&&(x(e.version,cn)||(error({message:`${t} CLI requires Node.js version ${cn}. Your current version is ${e.version}.`}),e.exit(1)))}function printCLIVersionAndExitIfFlagUsed(t){t.values.version===!0&&t.positionals.length===0&&(console.log(_n.fullVersionString),e.exit(0))}function printHelpAndExitIfFlagUsedOrNoCommandPassed(t,n){(t.values.help===!0&&t.positionals.length===0||t.positionals.length===0)&&(console.log(renderMainHelpMenu(n)),e.exit(0))}function handleCommandNotFound(n){let r=useCommandSuggestions(String(n)),i=t.gray(`Command ${t.whiteBright(n)} not found`);r.length&&(i+=`
30
- `,i+=t.gray(`Did you mean: ${r.map(e=>t.whiteBright(e)).join(`, `)}?`)),error({message:i}),e.exit(1)}async function runVersionCheck(e,t){let n=J.get(`upgrade`);if([n.name,...n.aliases??[]].some(e=>t===e)){cliDebugPrint(`[VersionCheckMiddleware]`,`upgrade command detected, skipping version check`);return}if(shouldSkipVersionCheck()){cliDebugPrint(`[VersionCheckMiddleware]`,`skipping version check because APIFY_CLI_SKIP_UPDATE_CHECK is set`);return}await internalRunCommand(e,n,{flags_internalAutomaticCall:!0})}async function runCLI(t){migrateLegacyBundleInstallIfNeeded(),cliDebugPrint(`CLIMetadata`,{..._n,fullVersionString:_n.fullVersionString,argv:e.argv,cwd:e.cwd(),execPath:e.execPath});let n=e.argv.slice(2);cliDebugPrint(`ProcessArgv`,n);let r=g({allowPositionals:!0,strict:!1,options:{help:{type:`boolean`,short:`h`},version:{type:`boolean`,short:`v`}},args:n});printCLIVersionAndExitIfFlagUsed(r),printHelpAndExitIfFlagUsedOrNoCommandPassed(r,t),await runVersionCheck(t,r.positionals[0]),cliDebugPrint(`TopLevelOptions`,r);let i=r.positionals[0],a=-1;if(J.get(i)?.subcommands?.length){if(r.positionals[1]?.toLowerCase()===`help`)a=1;else if(r.positionals[2]?.toLowerCase()===`help`){let e=J.get(`${i} ${r.positionals[1]}`);e&&!e.args&&(a=2)}}if(a!==-1){let e=r.positionals[a],t=n.indexOf(e);t!==-1&&n.splice(t,1),!n.includes(`--help`)&&!n.includes(`-h`)&&n.push(`--help`),r.positionals.splice(a,1),r.values.help=!0}let s=r.positionals[1],c=!1,l=J.get(i);if(!l)return handleCommandNotFound(i);let u=l;if(l.subcommands?.length){if(!s)return l.printHelp();c=!0,u=J.get(`${i} ${s}`)}if(!u)return handleCommandNotFound(`${i} ${s}`);let f=[...n],p=f.indexOf(i);if(cliDebugPrint(`CommandNameIndex`,p),f.splice(p,1),c){let e=f.indexOf(s);cliDebugPrint(`SubcommandNameIndex`,e),f.splice(e,1)}cliDebugPrint(`RebuiltArgs`,f),cliDebugPrint(`CommandToRun`,u);let m=new u(t,c?`${l.name} ${s}`:l.name,i,c?s:void 0),h=m._buildParseArgsOption();cliDebugPrint(`ParserOptionsForCommand`,h);try{let e=g({...h,args:f});await m._run(e),cliDebugPrint(`CommandArgsResult`,e)}catch(t){error({message:Qt.into(t,u).getPrettyMessage()}),e.exit(1)}}const updateLocalJson=async(e,t={},n=null)=>{let r=await U(e,`utf-8`),i=JSON.parse(r),a;n?(a=i,a[n]={...i[n],...t}):a={...i,...t},await G(e,JSON.stringify(a,null,` `))},ensureFolderExistsSync=(e,t)=>{t||(t=e,e=`.`),t.split(m).reduce((e,t)=>(e=u(e,t),O(e)||A(e),e),e)},rimrafPromised=async e=>{let t=Array.isArray(e)?e:[e];await Promise.all(t.map(async e=>Me(e,{recursive:!0,force:!0,maxRetries:10,retryDelay:100})))},deleteFile=async e=>{(await W(e)).isFile()&&await Pe(e)};function ensureApifyDirectory(e){let t=c(e);A(t,{recursive:!0})}const sumFilesSizeInBytes=async(e,t)=>(await Promise.all(e.map(async e=>W(u(t,e))))).map(e=>e.size).reduce((e,t)=>e+t,0);let yn;function parseAuthFile(){if(!O(AUTH_FILE_PATH()))return{};try{let e=JSON.parse(M(AUTH_FILE_PATH(),`utf-8`));return typeof e!=`object`||!e||Array.isArray(e)?null:e}catch{return null}}function readAuthFile(){return parseAuthFile()??{}}function writeAuthFile(e){atomicWriteJson(AUTH_FILE_PATH(),e)}function atomicWriteJson(e,t){ensureApifyDirectory(e);let n=`${e}.tmp-${De(8)}`;try{I(n,JSON.stringify(t,null,` `),{mode:384}),P(n,e)}catch(e){throw F(n,{force:!0}),e}}function v1Profile(e){return{...typeof e.username==`string`?{username:e.username}:{},name:null,...typeof e.organizationOwnerUserId==`string`?{organizationOwnerUserId:e.organizationOwnerUserId}:{},authMethod:`token`,expiresAt:null,hasRefreshToken:!1,loggedInAt:null}}function toV2(e){let t={version:2,profiles:{}};return typeof e.id==`string`&&(t.activeProfile=e.id,t.profiles[e.id]=v1Profile(e)),typeof e.token==`string`&&(t.token=e.token),typeof e.proxy?.password==`string`&&(t.proxy={password:e.proxy.password}),t}const bn={1:toV2};async function migrateAuthFile(){return yn??=(async()=>{try{let e=parseAuthFile();if(!e||Object.keys(e).length===0)return;let t=typeof e.version==`number`?e.version:1;if(t>=2)return;let n=e;for(let e=t;e<2;e++){let t=bn[e];if(!t)throw Error(`No migration step from auth file version ${e}.`);n=t(n)}writeAuthFile(n)}catch(e){cliDebugPrint(`auth-file`,`auth file migration failed`,e),warning({message:`Your stored login cannot be read until ${AUTH_FILE_PATH()} is updated to the current format, and the update failed. Make the directory it is in writable, then run the command again. Set APIFY_CLI_DEBUG=1 to see why.`})}})(),yn}function assertSupportedAuthFileVersion(){let{version:e}=readAuthFile();if(typeof e==`number`&&e>2)throw Error(`Your credentials in ${AUTH_FILE_PATH()} were written by a newer Apify CLI. It uses auth file version ${e} and this one reads 2. Upgrade the CLI, or run "apify logout" to discard them.`)}async function ensureAuthFileCurrent(){await migrateAuthFile(),assertSupportedAuthFileVersion()}function lookUpActiveProfile(){let e=readAuthFile();if(e.version!==2){let t=e;return typeof t.id==`string`?{profile:{id:t.id,...v1Profile(t)}}:{}}if(!e.activeProfile)return{};let t=e.profiles?.[e.activeProfile];return t?{profile:{id:e.activeProfile,...t}}:{missingProfile:e.activeProfile}}function profileLabel(e){return e.name??e.username??e.id}function listProfiles(){let e=readAuthFile();if(e.version!==2){let{profile:e}=lookUpActiveProfile();return e?[e]:[]}return Object.entries(e.profiles??{}).map(([e,t])=>({id:e,...t}))}function matchProfiles(e){let t=listProfiles(),n=t.find(({id:t})=>t===e);return n?[n]:t.filter(t=>profileLabel(t)===e)}function lookUpProfile(e){let t=listProfiles().find(({id:t})=>t===e);return t?{profile:t}:{missingProfile:e}}function setActiveProfile(e){let t=readAuthFile();t.profiles?.[e]&&(t.activeProfile=e,writeAuthFile(t))}function getActiveProfile(){return lookUpActiveProfile().profile}function getActiveProfileId(){let e=readAuthFile();if(e.version!==2){let t=e;return typeof t.id==`string`?t.id:void 0}return e.activeProfile}function readProfileSecret(e,t){let n=readAuthFile().profiles?.[e];if(n)switch(t){case`token`:return n.token;case`refresh-token`:return n.refreshToken;default:return n.proxy?.password}}function writeProfileSecret(e,t,n){updateProfile(e,e=>setProfileSecret(e,t,n))}function clearProfileFileSecrets(e){let t=readAuthFile().profiles?.[e];(t?.token!==void 0||t?.proxy!==void 0||t?.refreshToken!==void 0)&&updateProfile(e,e=>{delete e.token,delete e.proxy,delete e.refreshToken})}function setProfileSecret(e,t,n){t===`token`?e.token=n:t===`refresh-token`?e.refreshToken=n:e.proxy={...e.proxy,password:n}}function deleteProfileSecret(e,t){readProfileSecret(e,t)!==void 0&&updateProfile(e,e=>{t===`token`?delete e.token:t===`refresh-token`?delete e.refreshToken:delete e.proxy})}function updateProfile(e,t){let n=readAuthFile(),r=n.profiles?.[e];r&&(t(r),writeAuthFile(n))}function updateProfileAuth(e,t){updateProfile(e,e=>{e.authMethod=t.authMethod,e.expiresAt=t.expiresAt,e.hasRefreshToken=t.hasRefreshToken,t.oauth?e.oauth=t.oauth:delete e.oauth})}function upsertProfile(e,t){assertSupportedAuthFileVersion();let n=readAuthFile(),r=n.version===2?n:{version:2};r.profiles??={},delete r.token,delete r.proxy;let i=r.profiles[e];r.profiles[e]={...t,...i?.token?{token:i.token}:{},...i?.proxy?{proxy:i.proxy}:{},...i?.refreshToken?{refreshToken:i.refreshToken}:{}},r.activeProfile=e,writeAuthFile(r)}function removeProfile(e){let t=readAuthFile();if(t.version!==2)return discardAuthFile(),{};let n=e??t.activeProfile,r=n?t.profiles?.[n]:void 0,i=n&&r?{id:n,...r}:void 0;if(n&&t.profiles&&delete t.profiles[n],n!==t.activeProfile){writeAuthFile(t);let e=t.activeProfile?t.profiles?.[t.activeProfile]:void 0;return{removed:i,active:e&&{id:t.activeProfile,...e}}}delete t.activeProfile,delete t.token,delete t.proxy;let[a]=Object.entries(t.profiles??{}).sort(([,e],[,t])=>(t.loggedInAt??``).localeCompare(e.loggedInAt??``)).map(([e])=>e);return a?(t.activeProfile=a,writeAuthFile(t),{removed:i,active:{id:a,...t.profiles[a]}}):(discardAuthFile(),{removed:i})}function removeAllProfiles(){discardAuthFile()}function discardAuthFile(){F(AUTH_FILE_PATH(),{force:!0,maxRetries:10,retryDelay:100})}const xn=`com.apify.cli`,Sn=[`token`,`proxy-password`,`refresh-token`];function keyringKey(e,t){return{service:`${xn}.${t}`,account:e}}function legacyKeyringKey(e){return{service:xn,account:e}}let Cn,wn,Tn,En;async function loadKeyringModule(){return Cn===void 0&&(Cn=await importKeyringModule()),Cn}async function importKeyringModule(){if(useCLIMetadata().installMethod===`bundle`)try{let e=await import(`__APIFY_KEYRING_NATIVE_SUBPACKAGE__`),t=e.Entry??e.default?.Entry;return t?{Entry:t}:null}catch(e){return cliDebugPrint(`credentials`,`failed to load bundled keyring`,e),null}try{return await import(`@napi-rs/keyring`)}catch(e){return cliDebugPrint(`credentials`,`failed to load @napi-rs/keyring`,e),null}}async function getBackend(){return wn||(wn=(async()=>e.env.APIFY_DISABLE_KEYRING===`1`?`file`:await loadKeyringModule()?`keyring`:`file`)(),wn)}function stripProxyPassword(e){e.proxy&&(delete e.proxy.password,Object.keys(e.proxy).length===0&&delete e.proxy)}async function getKeyringEntry({service:e,account:t}){let n=await loadKeyringModule();return n?new n.Entry(e,t):null}async function readKeyring(e){try{let t=await getKeyringEntry(e);return t?t.getPassword()??void 0:void 0}catch(t){cliDebugPrint(`credentials`,`failed to read ${e.service}/${e.account} from keyring`,t);return}}async function writeKeyring(e,t){let n=await getKeyringEntry(e);if(!n)throw Error(`OS keyring is not available.`);n.setPassword(t)}async function deleteKeyring(e){try{let t=await getKeyringEntry(e);return t&&t.deletePassword(),null}catch(t){return cliDebugPrint(`credentials`,`failed to delete ${e.service}/${e.account} from keyring`,t),await readKeyring(e)===void 0?null:{key:e,error:t}}}async function backendFor(e){return readProfileSecret(e,`token`)===void 0?getBackend():`file`}async function getSecret(e,t){return await backendFor(e)===`keyring`?await readKeyring(keyringKey(e,t))??readProfileSecret(e,t):readProfileSecret(e,t)}async function setSecret(e,t,n,r={}){let i=await backendFor(e),a=t===`token`?await getBackend():i;if(!(r.skipIfUnchanged&&i===a&&await getSecret(e,t)===n)){if(a===`keyring`)try{await writeKeyring(keyringKey(e,t),n),t===`token`&&clearProfileFileSecrets(e);return}catch(n){cliDebugPrint(`credentials`,`keyring write failed; falling back to file`,n),t===`token`&&await moveKeyringSecretsToFile(e)}writeProfileSecret(e,t,n)}}async function moveKeyringSecretsToFile(e){for(let t of Sn){if(t===`token`)continue;let n=await readKeyring(keyringKey(e,t));n!==void 0&&(writeProfileSecret(e,t,n),readProfileSecret(e,t)===n&&await deleteKeyring(keyringKey(e,t)))}}async function deleteSecret(e,t){let n=await backendFor(e)===`keyring`?await deleteKeyring(keyringKey(e,t)):null;return deleteProfileSecret(e,t),n}async function clearKeyringSecrets(e,{keepLegacy:t=!1}={}){let n=[];for(let r of Sn)e&&n.push(await deleteKeyring(keyringKey(e,r))),t||n.push(await deleteKeyring(legacyKeyringKey(r)));return n.filter(e=>e!==null)}function describeLeftovers(e){return e.map(({key:e})=>`${e.service}/${e.account}`).join(`, `)}function leftoverReasons(e){let t=e.map(({error:e})=>e instanceof Error?e.message:String(e));return[...new Set(t)].join(` `)}async function ensureMigrated(){return Tn||(Tn=(async()=>{try{let e=readAuthFile();if(typeof e.version==`number`&&e.version>2||!e.token&&!e.proxy?.password||await getBackend()===`file`)return;try{e.token&&await writeKeyring(legacyKeyringKey(`token`),e.token),e.proxy?.password&&await writeKeyring(legacyKeyringKey(`proxy-password`),e.proxy.password)}catch(e){cliDebugPrint(`credentials`,`keyring write failed during migration; keeping secrets in the file`,e);return}delete e.token,stripProxyPassword(e),writeAuthFile(e)}catch(e){cliDebugPrint(`credentials`,`migration failed`,e)}})(),Tn)}async function dropUnkeyedSecrets(e){for(let e of Sn)await deleteKeyring(legacyKeyringKey(e));(e.token!==void 0||e.proxy!==void 0)&&(delete e.token,delete e.proxy,writeAuthFile(e))}async function keyKeyringSecrets(e){let t;for(let n of Sn){let r=legacyKeyringKey(n),i=await readKeyring(r);if(i!==void 0){if(t??=await readKeyring(keyringKey(e,`token`))===void 0,!t||await getSecret(e,n)!==void 0){await deleteKeyring(r);continue}if(await backendFor(e)===`keyring`){let t=keyringKey(e,n);try{await writeKeyring(t,i),await readKeyring(t)===i&&await deleteKeyring(r);continue}catch(e){cliDebugPrint(`credentials`,`keyring write failed while keying secrets by user`,e)}}writeProfileSecret(e,n,i),readProfileSecret(e,n)===i&&await deleteKeyring(r)}}}function keyFileSecrets(e,t){let n=t.profiles?.[e];if(!n)return;let{token:r}=t,i=t.proxy?.password;(r!==void 0||i!==void 0)&&(r!==void 0&&(n.token=r),i!==void 0&&(n.proxy={password:i}),delete t.token,delete t.proxy,writeAuthFile(t))}async function ensureSecretsKeyed(){return En??=(async()=>{try{let e=readAuthFile();if(e.version!==2)return;let t=e.activeProfile;if(!t){await dropUnkeyedSecrets(e);return}keyFileSecrets(t,e),await backendFor(t)===`keyring`&&await keyKeyringSecrets(t)}catch(e){cliDebugPrint(`credentials`,`keying secrets by user failed`,e)}})(),En}async function ensureCredentialsCurrent(){await ensureMigrated(),await ensureAuthFileCurrent(),await ensureSecretsKeyed()}const Dn=`full_api_access`,On=3e5,kn=3e4;function readUrlEnv(t,n){let r=e.env[t];if(!r)return n;let i=r.replace(/\/+$/,``);if(!URL.canParse(i))throw Error(`Invalid ${t} environment variable: "${r}" is not a valid URL.`);return i}function getOAuthIssuerUrl(){return readUrlEnv(`APIFY_CLI_OAUTH_ISSUER_URL`,`https://console-backend.apify.com`)}function getOAuthClientId(){let t=e.env.APIFY_CLI_OAUTH_CLIENT_ID;if(!t)return`https://apify.com/.well-known/oauth-clients/apify-cli.json`;if(!URL.canParse(t))throw Error(`Invalid APIFY_CLI_OAUTH_CLIENT_ID environment variable: "${t}" is not a valid URL.`);return t}var OAuthError=class extends Error{code;status;description;name=`OAuthError`;constructor(e,t,n){super(n?`${e}: ${n}`:e),this.code=e,this.status=t,this.description=n}};async function postTokenRequest(e,t){let n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,Accept:`application/json`,...un},body:new URLSearchParams(t),signal:AbortSignal.timeout(kn)}),r=await n.text(),i={};try{i=r?JSON.parse(r):{}}catch{}if(n.ok&&typeof i.access_token==`string`)return{ok:!0,tokens:i};let a=typeof i.error==`string`?i.error:`http_${n.status}`,s=typeof i.error_description==`string`?i.error_description:void 0;return{ok:!1,error:new OAuthError(a,n.status,s)}}async function refreshAccessToken(e){let t=await postTokenRequest(e.tokenEndpoint,{grant_type:`refresh_token`,refresh_token:e.refreshToken,client_id:e.clientId});if(!t.ok)throw t.error;return t.tokens}var OAuthSessionError=class extends Error{name=`OAuthSessionError`},OAuthSessionExpiredError=class extends OAuthSessionError{name=`OAuthSessionExpiredError`;constructor(){super(`Your Apify login session has expired. Run "apify login" to sign in again.`)}};const An=/* @__PURE__ */ new Map;function sessionOf(e){let t=An.get(e);return t||(t={refreshAttempted:!1},An.set(e,t)),t}function readMetadata(e){let{profile:t}=lookUpProfile(e);if(t?.authMethod!==`oauth2`||!t.oauth||!t.expiresAt)return;let n=Date.parse(t.expiresAt);if(!Number.isFinite(n))return;let r=t.oauth.refreshTokenExpiresAt?Date.parse(t.oauth.refreshTokenExpiresAt):void 0;return{...t.oauth,expiresAt:n,...Number.isFinite(r)?{refreshTokenExpiresAtMs:r}:{}}}async function getAccessToken(e,{minRemainingMs:t=6e4}={}){let n=readMetadata(e);if(!n)return getSecret(e,`token`);let r=sessionOf(e),i=Date.now();if(!needsRefresh(n,i,t)){if(r.cached&&r.cached.expiresAt===n.expiresAt)return r.cached.token;let t=await getSecret(e,`token`);return t&&(r.cached={token:t,expiresAt:n.expiresAt}),t}if(n.refreshTokenExpiresAtMs!==void 0&&n.refreshTokenExpiresAtMs<=i)throw new OAuthSessionExpiredError;if(r.refreshAttempted){if(r.refreshFailure)throw r.refreshFailure;return r.cached?.token??getSecret(e,`token`)}return r.inflightRefresh??=refreshSession(e,r,n,t).catch(e=>{throw r.refreshFailure=e,e}).finally(()=>{r.inflightRefresh=void 0}),r.inflightRefresh}async function saveOAuthSession(e,t,n){await persistTokens(e,t,{...n,refreshTokenExpiresAt:null})}async function clearOAuthSession(e){An.delete(e);let t=await deleteSecret(e,`refresh-token`);t&&cliDebugPrint(`oauth`,`the keyring kept the refresh token`,t.error),lookUpProfile(e).profile?.authMethod===`oauth2`&&updateProfileAuth(e,{authMethod:`token`,expiresAt:null,hasRefreshToken:!1})}function needsRefresh(e,t,n){return e.expiresAt-t<n||e.refreshTokenExpiresAtMs!==void 0&&e.refreshTokenExpiresAtMs-t<18e5}async function refreshSession(e,t,n,r){let i=await acquireRefreshLock(e);try{let i=readMetadata(e)??n;if(!needsRefresh(i,Date.now(),r)){let n=await getSecret(e,`token`);return n&&(t.cached={token:n,expiresAt:i.expiresAt}),n}let a=await getSecret(e,`refresh-token`);if(!a)throw new OAuthSessionExpiredError;t.refreshAttempted=!0;let s;try{s=await refreshAccessToken({tokenEndpoint:i.tokenEndpoint,clientId:i.clientId,refreshToken:a})}catch(n){return handleRefreshFailure(e,t,n,i,a)}return await persistTokens(e,s,i),s.access_token}finally{i()}}async function handleRefreshFailure(e,t,n,r,i){cliDebugPrint(`oauth`,`refresh failed`,n);let a=n instanceof OAuthError&&(n.code===`invalid_grant`||n.code===`expired_token`);if(a){let n=await getSecret(e,`refresh-token`);if(n&&n!==i){let n=await getSecret(e,`token`),r=readMetadata(e);return n&&r&&(t.cached={token:n,expiresAt:r.expiresAt}),n}}if(Date.now()<r.expiresAt)return getSecret(e,`token`);throw a?(await clearOAuthSession(e),new OAuthSessionExpiredError):new OAuthSessionError(`Could not refresh your Apify session. Check your connection or run "apify login".`)}async function persistTokens(e,t,n){let r=Date.now(),i=r+(t.expires_in??3600)*1e3,a=t.refresh_token_expires_in===void 0?n.refreshTokenExpiresAt:new Date(r+t.refresh_token_expires_in*1e3).toISOString();t.refresh_token&&await setSecret(e,`refresh-token`,t.refresh_token,{skipIfUnchanged:!0}),await setSecret(e,`token`,t.access_token,{skipIfUnchanged:!0}),updateProfileAuth(e,{authMethod:`oauth2`,expiresAt:new Date(i).toISOString(),hasRefreshToken:!!t.refresh_token||await getSecret(e,`refresh-token`)!==void 0,oauth:{issuer:n.issuer,clientId:n.clientId,tokenEndpoint:n.tokenEndpoint,refreshTokenExpiresAt:a}}),sessionOf(e).cached={token:t.access_token,expiresAt:i}}async function acquireRefreshLock(t){let n=u(GLOBAL_CONFIGS_FOLDER(),`oauth-refresh-${t}.lock`),release=()=>{try{ne(n)}catch{}},noop=()=>{};try{ensureApifyDirectory(AUTH_FILE_PATH())}catch{return noop}for(let t=0;t<50;t++){try{let t=j(n,`wx`);return re(t,`${e.pid}`),w(t),release}catch(e){if(e.code!==`EEXIST`)return noop}try{if(Date.now()-te(n).mtimeMs>3e4){ne(n);continue}}catch{continue}await Fe(100)}return cliDebugPrint(`oauth`,`refresh lock wait timed out; continuing without it`),noop}const jn=/* @__PURE__ */ new Set([`undefined`,`null`,`nil`,`none`,`nan`,`false`,`0`,`-`]);function readEnvToken(){let t=e.env[B.TOKEN]?.trim();return t?jn.has(t.toLowerCase())?{kind:`invalid`,raw:t}:{kind:`token`,token:t}:{kind:`unset`}}function invalidEnvTokenMessage(e){return`${B.TOKEN} is set to "${e}", which is not an API token. Unset ${B.TOKEN} and try again.`}const Mn={env:`${B.TOKEN} environment variable`,stored:`apify login`,profile:`--profile flag`};let Nn,Pn;const Fn=`No accounts are stored. Run "apify login" to add one.`;function envTokenOverridesProfileMessage(e){return`${B.TOKEN} is set, so commands ignore ${e}. Unset ${B.TOKEN} and try again.`}async function requireProfile(t){await ensureCredentialsCurrent();let n=matchProfiles(t);if(n.length===1)return n[0];if(e.exitCode=5,n.length>1)throw Error(`More than one stored account is called "${t}": ${n.map(({id:e})=>e).join(`, `)}. Use the user ID instead.`);let r=listProfiles().map(profileLabel);throw Error(r.length?`No stored account is called "${t}". Stored accounts: ${r.join(`, `)}.`:`No stored account is called "${t}". Run "apify login" to add one.`)}function getCurrentProfile(){return Pn??getActiveProfile()}async function selectProfile(t){if(readEnvToken().kind!==`unset`)throw e.exitCode=5,Error(envTokenOverridesProfileMessage(`--profile`));Pn=await requireProfile(t),Nn=void 0}const resolveAuth=async()=>{Nn??=(async()=>{await ensureMigrated();let t=readEnvToken();if(t.kind===`invalid`)throw e.exitCode=5,Error(invalidEnvTokenMessage(t.raw));if(t.kind===`token`)return O(AUTH_FILE_PATH())&&warning({message:`Using the API token from ${B.TOKEN}.`}),{token:t.token,source:`env`};if(await ensureCredentialsCurrent(),Pn){let t=await getAccessToken(Pn.id);if(!t)throw e.exitCode=1,Error(missingProfileTokenMessage(Pn));return{token:t,source:`profile`,profile:profileRef(Pn)}}let n=getActiveProfileId(),r=n?await getAccessToken(n):void 0;if(!r)return;let i=getActiveProfile();return{token:r,source:`stored`,...i?{profile:profileRef(i)}:{}}})();try{return await Nn}catch(e){throw Nn=void 0,e}};function profileRef(e){return{id:e.id,label:profileLabel(e)}}function missingProfileTokenMessage(e){return`No API token is stored for ${profileLabel(e)}. Run "apify login" to log in to ${profileLabel(e)} again.`}function describeAuthFailure(e,t){if(!e)return`You are not logged in with your Apify account. Call "apify login" to fix that.`;let n=t instanceof Se?t.statusCode:void 0;if(t&&n!==401&&n!==403)return`Could not verify your API token. The Apify API request failed: ${t instanceof Error?t.message:String(t)}`;switch(e.source){case`env`:return`The API token in ${B.TOKEN} was rejected. Unset it to use your stored login instead.`;default:return e.profile?`The stored API token for ${e.profile.label} was rejected. Run "apify login" to log in to ${e.profile.label} again.`:`Your stored API token was rejected. Call "apify login" to log in again.`}}const getAnonymousApifyClientOptions=t=>({baseUrl:t||e.env.APIFY_CLIENT_BASE_URL,requestInterceptors:[e=>{e.headers??=new Te;for(let[t,n]of Object.entries(un))e.headers[t]=n;return e}]}),getApifyClientOptionsForToken=(e,t)=>({...getAnonymousApifyClientOptions(t),token:e});async function loginWithToken(e,t){let n=new Ce(getApifyClientOptionsForToken(e,t)),r;try{r=await n.user(`me`).get()}catch(e){return cliDebugPrint(`[loginWithToken] error getting user info`,{error:e,apiBaseUrl:t}),null}if(!r.id)throw Error(`The Apify API returned no user ID for this token, so the login cannot be stored.`);let i=r.proxy?.password;await ensureCredentialsCurrent();let{organizationOwnerUserId:a}=r;upsertProfile(r.id,{username:r.username,name:r.username||r.id,...a?{organizationOwnerUserId:a}:{},authMethod:`token`,expiresAt:null,hasRefreshToken:!1,loggedInAt:(/* @__PURE__ */ new Date()).toISOString()});let s=await clearKeyringSecrets();if(await clearOAuthSession(r.id),await setSecret(r.id,`token`,e,{skipIfUnchanged:!0}),i)await setSecret(r.id,`proxy-password`,i,{skipIfUnchanged:!0});else{let e=await deleteSecret(r.id,`proxy-password`);e&&s.push(e)}return s.length&&warning({message:`Secrets this login could not remove are still in the OS keyring at ${describeLeftovers(s)}; delete them with your OS keyring app.`}),{client:n,userInfo:r}}const In={output:e.stderr},Ln=`confirm`,Rn=`no-${Ln}`;function stdinCheckWrapper(e,{errorMessageForStdin:t=`Please use the --${Ln}/--${Rn} flags to confirm the action.`}={}){return async(n,...r)=>{let{isTTY:i,hasData:a}=await useStdin(),s=n;if(ue||!i&&!a){if(s.providedConfirmFromStdin===void 0)throw Error(s.errorMessageForStdin??t);return s.providedConfirmFromStdin}return await e(n,...r)}}const zn=stdinCheckWrapper(async({message:e,validate:t,default:n})=>await Ue({message:e,validate:t,default:n},In),{errorMessageForStdin:`Please provide a valid input based on the command options.`});var Spider=class{name;class_name;start_urls;pathname;constructor(e){this.name=e.name,this.class_name=e.class_name,this.start_urls=e.start_urls,this.pathname=e.pathname}},SpiderFileAnalyzer=class{pathname;constructor(e){this.pathname=e}getSpiders(){let e=M(this.pathname,`utf8`),t=/class\s+(\w+)/g,n=[],r=t.exec(e);for(;r;)n.push(new Spider({class_name:r[1],pathname:this.pathname})),r=t.exec(e);return n}},ScrapyProjectAnalyzer=class{pathname;configuration=null;settings=null;constructor(e){this.pathname=e,this.settings=null,this.loadScrapyCfg()}static isApplicable(e){return O(u(e,`scrapy.cfg`))}async init(){await this.loadSettings()}loadScrapyCfg(){let e=new He,t=p(u(this.pathname,`scrapy.cfg`));if(!O(t))throw Error(`scrapy.cfg not found in "${t}".
31
- Are you sure there is a Scrapy project there?`);e.read(t),this.configuration=e}async loadSettings(){let e=this.configuration.get(`settings`,`default`).split(`.`)[0],t=await zn({message:`Enter the Scrapy BOT_NAME (see settings.py):`,default:e}),n=await zn({message:`What folder are the Scrapy spider modules stored in? (see SPIDER_MODULES in settings.py):`,default:`${e}.spiders`});this.settings={BOT_NAME:t,SPIDER_MODULES:typeof n==`string`?[n]:n}}getName(){return this.settings?.BOT_NAME}getAvailableSpiders(){let e=this.settings?.SPIDER_MODULES;if(!e)throw Error(`SPIDER_MODULES path not found in settings.`);let t=[];for(let n of e){let e=u(this.pathname,n.replaceAll(`.`,`/`)),r=N(e,{withFileTypes:!0});for(let n of r)n.isFile()&&n.name.endsWith(`.py`)&&n.name!==`__init__.py`&&t.push(...new SpiderFileAnalyzer(u(e,n.name)).getSpiders())}return t}};const Bn=/* @__PURE__ */ new Map,Vn={node:[`--version`],deno:[`eval`,`"console.log(process.versions.node)"`],bun:[`--eval`,`"console.log(process.versions.node)"`]};async function getRuntimeVersion(t,n){try{let r=await Ve(t,n,{shell:!0,windowsHide:!0,verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0});return r.stdout?r.stdout.trim().replace(/^v/,``):null}catch{return null}}async function getNpmVersion(t){let n=await Ve(t,[`--version`],{shell:!0,windowsHide:!0,verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0});return n.stdout?n.stdout.trim().replace(/^v/,``):null}async function useJavaScriptRuntime(t=e.cwd()){let n=Bn.get(t);if(n)return cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!0,cwd:t,runtime:n.unwrapOr(null)}),n;for(let[e,n]of Object.entries(Vn))try{let r=normalizeExecutablePath(await We(e)),i=await getRuntimeVersion(r,n);if(i){let n={executablePath:r,version:i};if(e===`node`){let e=normalizeExecutablePath(await We(`npm`).catch(()=>null));e&&(n.pmPath=e,n.pmVersion=await getNpmVersion(e),n.pmName=`npm`)}else n.runtimeShorthand=e,n.pmPath=r,n.pmVersion=i,n.pmName=e;return Bn.set(t,Be(n)),cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!1,cwd:t,runtime:Bn.get(t)?.unwrap()}),Be(n)}}catch{}return Bn.set(t,Re),cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!1,cwd:t,runtime:null}),Re}const Hn=/* @__PURE__ */ new Map;async function getPythonVersion(t){try{let n=await Ve(t,[`-c`,`"import platform; print(platform.python_version())"`],{shell:!0,windowsHide:!0,verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0});return n.stdout?n.stdout.trim():null}catch{return null}}async function usePythonRuntime({cwd:t=e.cwd(),force:n=!1}={}){let r=Hn.get(t);if(r&&!n)return cliDebugPrint(`usePythonRuntime`,{cacheHit:!0,cwd:t,runtime:r.unwrapOr(null)}),r;let i=ce()===`win32`,a=i?[`Scripts`,`python.exe`]:[`bin`,`python3`],s;s=e.env.VIRTUAL_ENV?u(e.env.VIRTUAL_ENV,...a):u(t,`.venv`,...a),s=normalizeExecutablePath(s);try{let e=await getPythonVersion(s);if(e)return Hn.set(t,Be({executablePath:s,version:e})),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:Hn.get(t)?.unwrap()}),Hn.get(t)}catch{}let c=[`python3`,`python`,...i?[`python3.exe`,`python.exe`]:[]];for(let e of c)try{let n=normalizeExecutablePath(await We(e)),r=await getPythonVersion(n);if(r)return Hn.set(t,Be({executablePath:n,version:r})),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:Hn.get(t)?.unwrap()}),Hn.get(t)}catch{}return Hn.set(t,Re),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:null}),Re}const Un=/* @__PURE__ */ new Map;async function useCwdProject({cwd:t=e.cwd()}={}){let n=Un.get(t);if(n)return cliDebugPrint(`useCwdProject`,{cacheHit:!0,project:n}),ze(n);let r={type:3},check=async()=>{if(await checkScrapyProject(t)){r.type=2;let e=await usePythonRuntime({cwd:t});r.runtime=e.unwrapOr(void 0),await fileExists(u(t,`uv.lock`))&&(r.packageManager=`uv`);let n=new ScrapyProjectAnalyzer(t);if(n.loadScrapyCfg(),n.configuration.hasKey(`apify`,`mainpy_location`))r.entrypoint={path:n.configuration.get(`apify`,`mainpy_location`)};else try{let e=await checkPythonProject(t);e&&(r.entrypoint={path:e})}catch{}return}let e=await checkNodeProject(t);if(!e){let e=null;try{e=await checkPythonProject(t)}catch(e){return Le({message:e instanceof Error?e.message:String(e)})}if(e){r.type=1;let n=await usePythonRuntime({cwd:t});r.entrypoint={path:e},r.runtime=n.unwrapOr(void 0),await fileExists(u(t,`uv.lock`))&&(r.packageManager=`uv`);let i=u(t,e.replace(/\./g,`/`));await fileExists(u(i,`__main__.py`))||(r.warnings=[`The detected Python package "${e}" is missing __main__.py. Running with "python -m" will fail without it.`]);return}}if(e){r.type=0;let t=await useJavaScriptRuntime();r.runtime=t.unwrapOr(void 0),e.type===`file`?r.entrypoint={path:e.path}:e.type===`script`&&(r.entrypoint={script:e.script});return}return ze(r)},i=await check();return i?.isErr()?(cliDebugPrint(`useCwdProject`,{cacheHit:!1,error:i}),i):(cliDebugPrint(`useCwdProject`,{cacheHit:!1,project:r}),Un.set(t,r),ze(r))}async function checkNodeProject(e){let t=u(e,`package.json`);try{let n=await U(t,`utf-8`),r=JSON.parse(n);if(r.scripts?.start)return{type:`script`,script:`start`};if(r.main)try{return await Oe(p(e,r.main)),{path:p(e,r.main),type:`file`}}catch{}return{type:`unknown-entrypoint`}}catch{}let n=[u(e,`index.js`),u(e,`index.mjs`),u(e,`index.cjs`),u(e,`main.js`),u(e,`main.mjs`),u(e,`main.cjs`),u(e,`src`,`index.js`),u(e,`src`,`index.mjs`),u(e,`src`,`index.cjs`),u(e,`src`,`main.js`),u(e,`src`,`main.mjs`),u(e,`src`,`main.cjs`),u(e,`dist`,`index.js`),u(e,`dist`,`index.mjs`),u(e,`dist`,`index.cjs`),u(e,`dist`,`main.js`),u(e,`dist`,`main.mjs`),u(e,`dist`,`main.cjs`)];for(let e of n)try{return await Oe(e),{path:e,type:`file`}}catch{}return null}async function fileExists(e){try{return await Oe(e),!0}catch{return!1}}async function dirExists(e){try{return(await W(e)).isDirectory()}catch{return!1}}function isValidPythonIdentifier(e){return/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e)}async function hasPythonFilesInDirOrSubdirs(e){try{let t=await Ae(e,{withFileTypes:!0});if(t.some(e=>e.isFile()&&e.name.endsWith(`.py`)))return!0;for(let n of t){if(!n.isDirectory()||n.name.startsWith(`.`)||n.name.startsWith(`_`))continue;let t=u(e,n.name);try{let e=await Ae(t,{withFileTypes:!0});if(e.some(e=>e.isFile()&&e.name.endsWith(`.py`)))return!0;if(n.name===`src`){for(let n of e)if(n.isDirectory()&&!(n.name.startsWith(`.`)||n.name.startsWith(`_`)))try{if((await Ae(u(t,n.name),{withFileTypes:!0})).some(e=>e.isFile()&&e.name.endsWith(`.py`)))return!0}catch{}}}catch{}}return!1}catch{return!1}}async function dirHasPyFiles(e){try{return(await Ae(e,{withFileTypes:!0})).some(e=>e.isFile()&&e.name.endsWith(`.py`)&&e.name!==`__init__.py`)}catch{return!1}}async function findNearMissPackagesInDir(e){try{let t=await Ae(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory()||r.name.startsWith(`.`)||r.name.startsWith(`_`))continue;let t=isValidPythonIdentifier(r.name),i=await fileExists(u(e,r.name,`__init__.py`)),a=i||await dirHasPyFiles(u(e,r.name));t&&i||a&&n.push({name:r.name,needsRename:!t,needsInit:!i})}return n}catch{return[]}}async function findPackagesInDir(e){try{let t=await Ae(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory())continue;let{name:t}=r;t.startsWith(`.`)||t.startsWith(`_`)||!isValidPythonIdentifier(t)||await fileExists(u(e,t,`__init__.py`))&&n.push({name:t,path:u(e,t)})}return n}catch{return[]}}async function discoverPythonPackages(e){let t=[],n=await findPackagesInDir(e);t.push(...n.map(e=>e.name));let r=u(e,`src`),i=await fileExists(u(r,`__init__.py`));if(await dirExists(r)&&!i){let e=await findPackagesInDir(r);t.push(...e.map(e=>`src.${e.name}`))}return t}async function checkPythonProject(e){let t=await discoverPythonPackages(e);if(t.length===1)return t[0];if(t.length>1){let e=t.map(e=>` - ${e}`).join(`
30
+ `,i+=t.gray(`Did you mean: ${r.map(e=>t.whiteBright(e)).join(`, `)}?`)),error({message:i}),e.exit(1)}async function runVersionCheck(e,t){let n=J.get(`upgrade`);[n.name,...n.aliases??[]].some(e=>t===e)?cliDebugPrint(`[VersionCheckMiddleware]`,`upgrade command detected, skipping version check`):shouldSkipVersionCheck()?cliDebugPrint(`[VersionCheckMiddleware]`,`skipping version check because APIFY_CLI_SKIP_UPDATE_CHECK is set`):await internalRunCommand(e,n,{flags_internalAutomaticCall:!0})}async function runCLI(t){migrateLegacyBundleInstallIfNeeded(),cliDebugPrint(`CLIMetadata`,{..._n,fullVersionString:_n.fullVersionString,argv:e.argv,cwd:e.cwd(),execPath:e.execPath});let n=e.argv.slice(2);cliDebugPrint(`ProcessArgv`,n);let r=g({allowPositionals:!0,strict:!1,options:{help:{type:`boolean`,short:`h`},version:{type:`boolean`,short:`v`}},args:n});printCLIVersionAndExitIfFlagUsed(r),printHelpAndExitIfFlagUsedOrNoCommandPassed(r,t),await runVersionCheck(t,r.positionals[0]),cliDebugPrint(`TopLevelOptions`,r);let i=r.positionals[0],a=-1;if(J.get(i)?.subcommands?.length){if(r.positionals[1]?.toLowerCase()===`help`)a=1;else if(r.positionals[2]?.toLowerCase()===`help`){let e=J.get(`${i} ${r.positionals[1]}`);e&&!e.args&&(a=2)}}if(a!==-1){let e=r.positionals[a],t=n.indexOf(e);t!==-1&&n.splice(t,1),!n.includes(`--help`)&&!n.includes(`-h`)&&n.push(`--help`),r.positionals.splice(a,1),r.values.help=!0}let s=r.positionals[1],c=!1,l=J.get(i);if(!l)return handleCommandNotFound(i);let u=l;if(l.subcommands?.length){if(!s)return l.printHelp();c=!0,u=J.get(`${i} ${s}`)}if(!u)return handleCommandNotFound(`${i} ${s}`);let f=[...n],p=f.indexOf(i);if(cliDebugPrint(`CommandNameIndex`,p),f.splice(p,1),c){let e=f.indexOf(s);cliDebugPrint(`SubcommandNameIndex`,e),f.splice(e,1)}cliDebugPrint(`RebuiltArgs`,f),cliDebugPrint(`CommandToRun`,u);let m=new u(t,c?`${l.name} ${s}`:l.name,i,c?s:void 0),h=m._buildParseArgsOption();cliDebugPrint(`ParserOptionsForCommand`,h);try{let e=g({...h,args:f});await m._run(e),cliDebugPrint(`CommandArgsResult`,e)}catch(t){error({message:Qt.into(t,u).getPrettyMessage()}),e.exit(1)}}const updateLocalJson=async(e,t={},n=null)=>{let r=await U(e,`utf-8`),i=JSON.parse(r),a;n?(a=i,a[n]={...i[n],...t}):a={...i,...t},await G(e,JSON.stringify(a,null,` `))},ensureFolderExistsSync=(e,t)=>{t||(t=e,e=`.`),t.split(m).reduce((e,t)=>(e=u(e,t),O(e)||A(e),e),e)},rimrafPromised=async e=>{let t=Array.isArray(e)?e:[e];await Promise.all(t.map(async e=>Me(e,{recursive:!0,force:!0,maxRetries:10,retryDelay:100})))},deleteFile=async e=>{(await W(e)).isFile()&&await Pe(e)};function ensureApifyDirectory(e){let t=c(e);A(t,{recursive:!0})}const sumFilesSizeInBytes=async(e,t)=>(await Promise.all(e.map(async e=>W(u(t,e))))).map(e=>e.size).reduce((e,t)=>e+t,0);let yn;function parseAuthFile(){if(!O(AUTH_FILE_PATH()))return{};try{let e=JSON.parse(M(AUTH_FILE_PATH(),`utf-8`));return typeof e!=`object`||!e||Array.isArray(e)?null:e}catch{return null}}function readAuthFile(){return parseAuthFile()??{}}function writeAuthFile(e){atomicWriteJson(AUTH_FILE_PATH(),e)}function atomicWriteJson(e,t){ensureApifyDirectory(e);let n=`${e}.tmp-${De(8)}`;try{I(n,JSON.stringify(t,null,` `),{mode:384}),P(n,e)}catch(e){throw F(n,{force:!0}),e}}function v1Profile(e){return{...typeof e.username==`string`?{username:e.username}:{},name:null,...typeof e.organizationOwnerUserId==`string`?{organizationOwnerUserId:e.organizationOwnerUserId}:{},authMethod:`token`,expiresAt:null,hasRefreshToken:!1,loggedInAt:null}}function toV2(e){let t={version:2,profiles:{}};return typeof e.id==`string`&&(t.activeProfile=e.id,t.profiles[e.id]=v1Profile(e)),typeof e.token==`string`&&(t.token=e.token),typeof e.proxy?.password==`string`&&(t.proxy={password:e.proxy.password}),t}const bn={1:toV2};async function migrateAuthFile(){return yn??=(async()=>{try{let e=parseAuthFile();if(!e||Object.keys(e).length===0)return;let t=typeof e.version==`number`?e.version:1;if(t>=2)return;let n=e;for(let e=t;e<2;e++){let t=bn[e];if(!t)throw Error(`No migration step from auth file version ${e}.`);n=t(n)}writeAuthFile(n)}catch(e){cliDebugPrint(`auth-file`,`auth file migration failed`,e),warning({message:`Your stored login cannot be read until ${AUTH_FILE_PATH()} is updated to the current format, and the update failed. Make the directory it is in writable, then run the command again. Set APIFY_CLI_DEBUG=1 to see why.`})}})(),yn}function assertSupportedAuthFileVersion(){let{version:e}=readAuthFile();if(typeof e==`number`&&e>2)throw Error(`Your credentials in ${AUTH_FILE_PATH()} were written by a newer Apify CLI. It uses auth file version ${e} and this one reads 2. Upgrade the CLI, or run "apify logout" to discard them.`)}async function ensureAuthFileCurrent(){await migrateAuthFile(),assertSupportedAuthFileVersion()}function lookUpActiveProfile(){let e=readAuthFile();if(e.version!==2){let t=e;return typeof t.id==`string`?{profile:{id:t.id,...v1Profile(t)}}:{}}if(!e.activeProfile)return{};let t=e.profiles?.[e.activeProfile];return t?{profile:{id:e.activeProfile,...t}}:{missingProfile:e.activeProfile}}function profileLabel(e){return e.name??e.username??e.id}function listProfiles(){let e=readAuthFile();if(e.version!==2){let{profile:e}=lookUpActiveProfile();return e?[e]:[]}return Object.entries(e.profiles??{}).map(([e,t])=>({id:e,...t}))}function matchProfiles(e){let t=listProfiles(),n=t.find(({id:t})=>t===e);return n?[n]:t.filter(t=>profileLabel(t)===e)}function lookUpProfile(e){let t=listProfiles().find(({id:t})=>t===e);return t?{profile:t}:{missingProfile:e}}function setActiveProfile(e){let t=readAuthFile();t.profiles?.[e]&&(t.activeProfile=e,writeAuthFile(t))}function getActiveProfile(){return lookUpActiveProfile().profile}function getActiveProfileId(){let e=readAuthFile();if(e.version!==2){let t=e;return typeof t.id==`string`?t.id:void 0}return e.activeProfile}function readProfileSecret(e,t){let n=readAuthFile().profiles?.[e];if(n)switch(t){case`token`:return n.token;case`refresh-token`:return n.refreshToken;default:return n.proxy?.password}}function writeProfileSecret(e,t,n){updateProfile(e,e=>setProfileSecret(e,t,n))}function clearProfileFileSecrets(e){let t=readAuthFile().profiles?.[e];(t?.token!==void 0||t?.proxy!==void 0||t?.refreshToken!==void 0)&&updateProfile(e,e=>{delete e.token,delete e.proxy,delete e.refreshToken})}function setProfileSecret(e,t,n){t===`token`?e.token=n:t===`refresh-token`?e.refreshToken=n:e.proxy={...e.proxy,password:n}}function deleteProfileSecret(e,t){readProfileSecret(e,t)!==void 0&&updateProfile(e,e=>{t===`token`?delete e.token:t===`refresh-token`?delete e.refreshToken:delete e.proxy})}function updateProfile(e,t){let n=readAuthFile(),r=n.profiles?.[e];r&&(t(r),writeAuthFile(n))}function updateProfileAuth(e,t){updateProfile(e,e=>{e.authMethod=t.authMethod,e.expiresAt=t.expiresAt,e.hasRefreshToken=t.hasRefreshToken,t.oauth?e.oauth=t.oauth:delete e.oauth})}function upsertProfile(e,t){assertSupportedAuthFileVersion();let n=readAuthFile(),r=n.version===2?n:{version:2};r.profiles??={},delete r.token,delete r.proxy;let i=r.profiles[e];r.profiles[e]={...t,...i?.token?{token:i.token}:{},...i?.proxy?{proxy:i.proxy}:{},...i?.refreshToken?{refreshToken:i.refreshToken}:{}},r.activeProfile=e,writeAuthFile(r)}function removeProfile(e){let t=readAuthFile();if(t.version!==2)return discardAuthFile(),{};let n=e??t.activeProfile,r=n?t.profiles?.[n]:void 0,i=n&&r?{id:n,...r}:void 0;if(n&&t.profiles&&delete t.profiles[n],n!==t.activeProfile){writeAuthFile(t);let e=t.activeProfile?t.profiles?.[t.activeProfile]:void 0;return{removed:i,active:e&&{id:t.activeProfile,...e}}}delete t.activeProfile,delete t.token,delete t.proxy;let[a]=Object.entries(t.profiles??{}).sort(([,e],[,t])=>(t.loggedInAt??``).localeCompare(e.loggedInAt??``)).map(([e])=>e);return a?(t.activeProfile=a,writeAuthFile(t),{removed:i,active:{id:a,...t.profiles[a]}}):(discardAuthFile(),{removed:i})}function removeAllProfiles(){discardAuthFile()}function discardAuthFile(){F(AUTH_FILE_PATH(),{force:!0,maxRetries:10,retryDelay:100})}const xn=`com.apify.cli`,Sn=[`token`,`proxy-password`,`refresh-token`];function keyringKey(e,t){return{service:`${xn}.${t}`,account:e}}function legacyKeyringKey(e){return{service:xn,account:e}}let Cn,wn,Tn,En;async function loadKeyringModule(){return Cn===void 0&&(Cn=await importKeyringModule()),Cn}async function importKeyringModule(){if(useCLIMetadata().installMethod===`bundle`)try{let e=await import(`__APIFY_KEYRING_NATIVE_SUBPACKAGE__`),t=e.Entry??e.default?.Entry;return t?{Entry:t}:null}catch(e){return cliDebugPrint(`credentials`,`failed to load bundled keyring`,e),null}try{return await import(`@napi-rs/keyring`)}catch(e){return cliDebugPrint(`credentials`,`failed to load @napi-rs/keyring`,e),null}}async function getBackend(){return wn||(wn=(async()=>e.env.APIFY_DISABLE_KEYRING===`1`?`file`:await loadKeyringModule()?`keyring`:`file`)(),wn)}function stripProxyPassword(e){e.proxy&&(delete e.proxy.password,Object.keys(e.proxy).length===0&&delete e.proxy)}async function getKeyringEntry({service:e,account:t}){let n=await loadKeyringModule();return n?new n.Entry(e,t):null}async function readKeyring(e){try{let t=await getKeyringEntry(e);return t?t.getPassword()??void 0:void 0}catch(t){cliDebugPrint(`credentials`,`failed to read ${e.service}/${e.account} from keyring`,t);return}}async function writeKeyring(e,t){let n=await getKeyringEntry(e);if(!n)throw Error(`OS keyring is not available.`);n.setPassword(t)}async function deleteKeyring(e){try{let t=await getKeyringEntry(e);return t&&t.deletePassword(),null}catch(t){return cliDebugPrint(`credentials`,`failed to delete ${e.service}/${e.account} from keyring`,t),await readKeyring(e)===void 0?null:{key:e,error:t}}}async function backendFor(e){return readProfileSecret(e,`token`)===void 0?getBackend():`file`}async function getSecret(e,t){return await backendFor(e)===`keyring`?await readKeyring(keyringKey(e,t))??readProfileSecret(e,t):readProfileSecret(e,t)}async function setSecret(e,t,n,r={}){let i=await backendFor(e),a=t===`token`?await getBackend():i;if(!(r.skipIfUnchanged&&i===a&&await getSecret(e,t)===n)){if(a===`keyring`)try{await writeKeyring(keyringKey(e,t),n),t===`token`&&clearProfileFileSecrets(e);return}catch(n){cliDebugPrint(`credentials`,`keyring write failed; falling back to file`,n),t===`token`&&await moveKeyringSecretsToFile(e)}writeProfileSecret(e,t,n)}}async function moveKeyringSecretsToFile(e){for(let t of Sn){if(t===`token`)continue;let n=await readKeyring(keyringKey(e,t));n!==void 0&&(writeProfileSecret(e,t,n),readProfileSecret(e,t)===n&&await deleteKeyring(keyringKey(e,t)))}}async function deleteSecret(e,t){let n=await backendFor(e)===`keyring`?await deleteKeyring(keyringKey(e,t)):null;return deleteProfileSecret(e,t),n}async function clearKeyringSecrets(e,{keepLegacy:t=!1}={}){let n=[];for(let r of Sn)e&&n.push(await deleteKeyring(keyringKey(e,r))),t||n.push(await deleteKeyring(legacyKeyringKey(r)));return n.filter(e=>e!==null)}function describeLeftovers(e){return e.map(({key:e})=>`${e.service}/${e.account}`).join(`, `)}function leftoverReasons(e){let t=e.map(({error:e})=>e instanceof Error?e.message:String(e));return[...new Set(t)].join(` `)}async function ensureMigrated(){return Tn||(Tn=(async()=>{try{let e=readAuthFile();if(typeof e.version==`number`&&e.version>2||!e.token&&!e.proxy?.password||await getBackend()===`file`)return;try{e.token&&await writeKeyring(legacyKeyringKey(`token`),e.token),e.proxy?.password&&await writeKeyring(legacyKeyringKey(`proxy-password`),e.proxy.password)}catch(e){cliDebugPrint(`credentials`,`keyring write failed during migration; keeping secrets in the file`,e);return}delete e.token,stripProxyPassword(e),writeAuthFile(e)}catch(e){cliDebugPrint(`credentials`,`migration failed`,e)}})(),Tn)}async function dropUnkeyedSecrets(e){for(let e of Sn)await deleteKeyring(legacyKeyringKey(e));(e.token!==void 0||e.proxy!==void 0)&&(delete e.token,delete e.proxy,writeAuthFile(e))}async function keyKeyringSecrets(e){let t;for(let n of Sn){let r=legacyKeyringKey(n),i=await readKeyring(r);if(i!==void 0){if(t??=await readKeyring(keyringKey(e,`token`))===void 0,!t||await getSecret(e,n)!==void 0)await deleteKeyring(r);else{if(await backendFor(e)===`keyring`){let t=keyringKey(e,n);try{await writeKeyring(t,i),await readKeyring(t)===i&&await deleteKeyring(r);continue}catch(e){cliDebugPrint(`credentials`,`keyring write failed while keying secrets by user`,e)}}writeProfileSecret(e,n,i),readProfileSecret(e,n)===i&&await deleteKeyring(r)}}}}function keyFileSecrets(e,t){let n=t.profiles?.[e];if(!n)return;let{token:r}=t,i=t.proxy?.password;(r!==void 0||i!==void 0)&&(r!==void 0&&(n.token=r),i!==void 0&&(n.proxy={password:i}),delete t.token,delete t.proxy,writeAuthFile(t))}async function ensureSecretsKeyed(){return En??=(async()=>{try{let e=readAuthFile();if(e.version!==2)return;let t=e.activeProfile;if(!t){await dropUnkeyedSecrets(e);return}keyFileSecrets(t,e),await backendFor(t)===`keyring`&&await keyKeyringSecrets(t)}catch(e){cliDebugPrint(`credentials`,`keying secrets by user failed`,e)}})(),En}async function ensureCredentialsCurrent(){await ensureMigrated(),await ensureAuthFileCurrent(),await ensureSecretsKeyed()}const Dn=`full_api_access`,On=3e5,kn=3e4;function readUrlEnv(t,n){let r=e.env[t];if(!r)return n;let i=r.replace(/\/+$/,``);if(!URL.canParse(i))throw Error(`Invalid ${t} environment variable: "${r}" is not a valid URL.`);return i}function getOAuthIssuerUrl(){return readUrlEnv(`APIFY_CLI_OAUTH_ISSUER_URL`,`https://console-backend.apify.com`)}function getOAuthClientId(){let t=e.env.APIFY_CLI_OAUTH_CLIENT_ID;if(!t)return`https://apify.com/.well-known/oauth-clients/apify-cli.json`;if(!URL.canParse(t))throw Error(`Invalid APIFY_CLI_OAUTH_CLIENT_ID environment variable: "${t}" is not a valid URL.`);return t}var OAuthError=class extends Error{code;status;description;name=`OAuthError`;constructor(e,t,n){super(n?`${e}: ${n}`:e),this.code=e,this.status=t,this.description=n}};async function postTokenRequest(e,t){let n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,Accept:`application/json`,...un},body:new URLSearchParams(t),signal:AbortSignal.timeout(kn)}),r=await n.text(),i={};try{i=r?JSON.parse(r):{}}catch{}if(n.ok&&typeof i.access_token==`string`)return{ok:!0,tokens:i};let a=typeof i.error==`string`?i.error:`http_${n.status}`,s=typeof i.error_description==`string`?i.error_description:void 0;return{ok:!1,error:new OAuthError(a,n.status,s)}}async function refreshAccessToken(e){let t=await postTokenRequest(e.tokenEndpoint,{grant_type:`refresh_token`,refresh_token:e.refreshToken,client_id:e.clientId});if(!t.ok)throw t.error;return t.tokens}var OAuthSessionError=class extends Error{name=`OAuthSessionError`},OAuthSessionExpiredError=class extends OAuthSessionError{name=`OAuthSessionExpiredError`;constructor(){super(`Your Apify login session has expired. Run "apify login" to sign in again.`)}};const An=/* @__PURE__ */ new Map;function sessionOf(e){let t=An.get(e);return t||(t={refreshAttempted:!1},An.set(e,t)),t}function readMetadata(e){let{profile:t}=lookUpProfile(e);if(t?.authMethod!==`oauth2`||!t.oauth||!t.expiresAt)return;let n=Date.parse(t.expiresAt);if(!Number.isFinite(n))return;let r=t.oauth.refreshTokenExpiresAt?Date.parse(t.oauth.refreshTokenExpiresAt):void 0;return{...t.oauth,expiresAt:n,...Number.isFinite(r)?{refreshTokenExpiresAtMs:r}:{}}}async function getAccessToken(e,{minRemainingMs:t=6e4}={}){let n=readMetadata(e);if(!n)return getSecret(e,`token`);let r=sessionOf(e),i=Date.now();if(!needsRefresh(n,i,t)){if(r.cached&&r.cached.expiresAt===n.expiresAt)return r.cached.token;let t=await getSecret(e,`token`);return t&&(r.cached={token:t,expiresAt:n.expiresAt}),t}if(n.refreshTokenExpiresAtMs!==void 0&&n.refreshTokenExpiresAtMs<=i)throw new OAuthSessionExpiredError;if(r.refreshAttempted){if(r.refreshFailure)throw r.refreshFailure;return r.cached?.token??getSecret(e,`token`)}return r.inflightRefresh??=refreshSession(e,r,n,t).catch(e=>{throw r.refreshFailure=e,e}).finally(()=>{r.inflightRefresh=void 0}),r.inflightRefresh}async function saveOAuthSession(e,t,n){await persistTokens(e,t,{...n,refreshTokenExpiresAt:null})}async function clearOAuthSession(e){An.delete(e);let t=await deleteSecret(e,`refresh-token`);t&&cliDebugPrint(`oauth`,`the keyring kept the refresh token`,t.error),lookUpProfile(e).profile?.authMethod===`oauth2`&&updateProfileAuth(e,{authMethod:`token`,expiresAt:null,hasRefreshToken:!1})}function needsRefresh(e,t,n){return e.expiresAt-t<n||e.refreshTokenExpiresAtMs!==void 0&&e.refreshTokenExpiresAtMs-t<18e5}async function refreshSession(e,t,n,r){let i=await acquireRefreshLock(e);try{let i=readMetadata(e)??n;if(!needsRefresh(i,Date.now(),r)){let n=await getSecret(e,`token`);return n&&(t.cached={token:n,expiresAt:i.expiresAt}),n}let a=await getSecret(e,`refresh-token`);if(!a)throw new OAuthSessionExpiredError;t.refreshAttempted=!0;let s;try{s=await refreshAccessToken({tokenEndpoint:i.tokenEndpoint,clientId:i.clientId,refreshToken:a})}catch(n){return handleRefreshFailure(e,t,n,i,a)}return await persistTokens(e,s,i),s.access_token}finally{i()}}async function handleRefreshFailure(e,t,n,r,i){cliDebugPrint(`oauth`,`refresh failed`,n);let a=n instanceof OAuthError&&(n.code===`invalid_grant`||n.code===`expired_token`);if(a){let n=await getSecret(e,`refresh-token`);if(n&&n!==i){let n=await getSecret(e,`token`),r=readMetadata(e);return n&&r&&(t.cached={token:n,expiresAt:r.expiresAt}),n}}if(Date.now()<r.expiresAt)return getSecret(e,`token`);throw a?(await clearOAuthSession(e),new OAuthSessionExpiredError):new OAuthSessionError(`Could not refresh your Apify session. Check your connection or run "apify login".`)}async function persistTokens(e,t,n){let r=Date.now(),i=r+(t.expires_in??3600)*1e3,a=t.refresh_token_expires_in===void 0?n.refreshTokenExpiresAt:new Date(r+t.refresh_token_expires_in*1e3).toISOString();t.refresh_token&&await setSecret(e,`refresh-token`,t.refresh_token,{skipIfUnchanged:!0}),await setSecret(e,`token`,t.access_token,{skipIfUnchanged:!0}),updateProfileAuth(e,{authMethod:`oauth2`,expiresAt:new Date(i).toISOString(),hasRefreshToken:!!t.refresh_token||await getSecret(e,`refresh-token`)!==void 0,oauth:{issuer:n.issuer,clientId:n.clientId,tokenEndpoint:n.tokenEndpoint,refreshTokenExpiresAt:a}}),sessionOf(e).cached={token:t.access_token,expiresAt:i}}async function acquireRefreshLock(t){let n=u(GLOBAL_CONFIGS_FOLDER(),`oauth-refresh-${t}.lock`),release=()=>{try{ne(n)}catch{}},noop=()=>{};try{ensureApifyDirectory(AUTH_FILE_PATH())}catch{return noop}for(let t=0;t<50;t++){try{let t=j(n,`wx`);return re(t,`${e.pid}`),w(t),release}catch(e){if(e.code!==`EEXIST`)return noop}try{if(Date.now()-te(n).mtimeMs>3e4){ne(n);continue}}catch{continue}await Fe(100)}return cliDebugPrint(`oauth`,`refresh lock wait timed out; continuing without it`),noop}const jn=/* @__PURE__ */ new Set([`undefined`,`null`,`nil`,`none`,`nan`,`false`,`0`,`-`]);function readEnvToken(){let t=e.env[B.TOKEN]?.trim();return t?jn.has(t.toLowerCase())?{kind:`invalid`,raw:t}:{kind:`token`,token:t}:{kind:`unset`}}function invalidEnvTokenMessage(e){return`${B.TOKEN} is set to "${e}", which is not an API token. Unset ${B.TOKEN} and try again.`}const Mn={env:`${B.TOKEN} environment variable`,stored:`apify login`,profile:`--profile flag`};let Nn,Pn;const Fn=`No accounts are stored. Run "apify login" to add one.`;function envTokenOverridesProfileMessage(e){return`${B.TOKEN} is set, so commands ignore ${e}. Unset ${B.TOKEN} and try again.`}async function requireProfile(t){await ensureCredentialsCurrent();let n=matchProfiles(t);if(n.length===1)return n[0];if(e.exitCode=5,n.length>1)throw Error(`More than one stored account is called "${t}": ${n.map(({id:e})=>e).join(`, `)}. Use the user ID instead.`);let r=listProfiles().map(profileLabel);throw Error(r.length?`No stored account is called "${t}". Stored accounts: ${r.join(`, `)}.`:`No stored account is called "${t}". Run "apify login" to add one.`)}function getCurrentProfile(){return Pn??getActiveProfile()}async function selectProfile(t){if(readEnvToken().kind!==`unset`)throw e.exitCode=5,Error(envTokenOverridesProfileMessage(`--profile`));Pn=await requireProfile(t),Nn=void 0}const resolveAuth=async()=>{Nn??=(async()=>{await ensureMigrated();let t=readEnvToken();if(t.kind===`invalid`)throw e.exitCode=5,Error(invalidEnvTokenMessage(t.raw));if(t.kind===`token`)return O(AUTH_FILE_PATH())&&warning({message:`Using the API token from ${B.TOKEN}.`}),{token:t.token,source:`env`};if(await ensureCredentialsCurrent(),Pn){let t=await getAccessToken(Pn.id);if(!t)throw e.exitCode=1,Error(missingProfileTokenMessage(Pn));return{token:t,source:`profile`,profile:profileRef(Pn)}}let n=getActiveProfileId(),r=n?await getAccessToken(n):void 0;if(!r)return;let i=getActiveProfile();return{token:r,source:`stored`,...i?{profile:profileRef(i)}:{}}})();try{return await Nn}catch(e){throw Nn=void 0,e}};function profileRef(e){return{id:e.id,label:profileLabel(e)}}function missingProfileTokenMessage(e){return`No API token is stored for ${profileLabel(e)}. Run "apify login" to log in to ${profileLabel(e)} again.`}function describeAuthFailure(e,t){if(!e)return`You are not logged in with your Apify account. Call "apify login" to fix that.`;let n=t instanceof Se?t.statusCode:void 0;if(t&&n!==401&&n!==403)return`Could not verify your API token. The Apify API request failed: ${t instanceof Error?t.message:String(t)}`;switch(e.source){case`env`:return`The API token in ${B.TOKEN} was rejected. Unset it to use your stored login instead.`;default:return e.profile?`The stored API token for ${e.profile.label} was rejected. Run "apify login" to log in to ${e.profile.label} again.`:`Your stored API token was rejected. Call "apify login" to log in again.`}}const getAnonymousApifyClientOptions=t=>({baseUrl:t||e.env.APIFY_CLIENT_BASE_URL,requestInterceptors:[e=>{e.headers??=new Te;for(let[t,n]of Object.entries(un))e.headers[t]=n;return e}]}),getApifyClientOptionsForToken=(e,t)=>({...getAnonymousApifyClientOptions(t),token:e});async function loginWithToken(e,t){let n=new Ce(getApifyClientOptionsForToken(e,t)),r;try{r=await n.user(`me`).get()}catch(e){return cliDebugPrint(`[loginWithToken] error getting user info`,{error:e,apiBaseUrl:t}),null}if(!r.id)throw Error(`The Apify API returned no user ID for this token, so the login cannot be stored.`);let i=r.proxy?.password;await ensureCredentialsCurrent();let{organizationOwnerUserId:a}=r;upsertProfile(r.id,{username:r.username,name:r.username||r.id,...a?{organizationOwnerUserId:a}:{},authMethod:`token`,expiresAt:null,hasRefreshToken:!1,loggedInAt:(/* @__PURE__ */ new Date()).toISOString()});let s=await clearKeyringSecrets();if(await clearOAuthSession(r.id),await setSecret(r.id,`token`,e,{skipIfUnchanged:!0}),i)await setSecret(r.id,`proxy-password`,i,{skipIfUnchanged:!0});else{let e=await deleteSecret(r.id,`proxy-password`);e&&s.push(e)}return s.length&&warning({message:`Secrets this login could not remove are still in the OS keyring at ${describeLeftovers(s)}; delete them with your OS keyring app.`}),{client:n,userInfo:r}}const In={output:e.stderr},Ln=`confirm`,Rn=`no-${Ln}`;function stdinCheckWrapper(e,{errorMessageForStdin:t=`Please use the --${Ln}/--${Rn} flags to confirm the action.`}={}){return async(n,...r)=>{let{isTTY:i,hasData:a}=await useStdin(),s=n;if(ue||!i&&!a){if(s.providedConfirmFromStdin===void 0)throw Error(s.errorMessageForStdin??t);return s.providedConfirmFromStdin}return await e(n,...r)}}const zn=stdinCheckWrapper(async({message:e,validate:t,default:n})=>await Ue({message:e,validate:t,default:n},In),{errorMessageForStdin:`Please provide a valid input based on the command options.`});var Spider=class{name;class_name;start_urls;pathname;constructor(e){this.name=e.name,this.class_name=e.class_name,this.start_urls=e.start_urls,this.pathname=e.pathname}},SpiderFileAnalyzer=class{pathname;constructor(e){this.pathname=e}getSpiders(){let e=M(this.pathname,`utf8`),t=/class\s+(\w+)/g,n=[],r=t.exec(e);for(;r;)n.push(new Spider({class_name:r[1],pathname:this.pathname})),r=t.exec(e);return n}},ScrapyProjectAnalyzer=class{pathname;configuration=null;settings=null;constructor(e){this.pathname=e,this.settings=null,this.loadScrapyCfg()}static isApplicable(e){return O(u(e,`scrapy.cfg`))}async init(){await this.loadSettings()}loadScrapyCfg(){let e=new He,t=p(u(this.pathname,`scrapy.cfg`));if(!O(t))throw Error(`scrapy.cfg not found in "${t}".
31
+ Are you sure there is a Scrapy project there?`);e.read(t),this.configuration=e}async loadSettings(){let e=this.configuration.get(`settings`,`default`).split(`.`)[0],t=await zn({message:`Enter the Scrapy BOT_NAME (see settings.py):`,default:e}),n=await zn({message:`What folder are the Scrapy spider modules stored in? (see SPIDER_MODULES in settings.py):`,default:`${e}.spiders`});this.settings={BOT_NAME:t,SPIDER_MODULES:typeof n==`string`?[n]:n}}getName(){return this.settings?.BOT_NAME}getAvailableSpiders(){let e=this.settings?.SPIDER_MODULES;if(!e)throw Error(`SPIDER_MODULES path not found in settings.`);let t=[];for(let n of e){let e=u(this.pathname,n.replaceAll(`.`,`/`)),r=N(e,{withFileTypes:!0});for(let n of r)n.isFile()&&n.name.endsWith(`.py`)&&n.name!==`__init__.py`&&t.push(...new SpiderFileAnalyzer(u(e,n.name)).getSpiders())}return t}};const Bn=/* @__PURE__ */ new Map,Vn={node:[`--version`],deno:[`eval`,`"console.log(process.versions.node)"`],bun:[`--eval`,`"console.log(process.versions.node)"`]};async function getRuntimeVersion(t,n){try{let r=await Ve(t,n,{shell:!0,windowsHide:!0,verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0});return r.stdout?r.stdout.trim().replace(/^v/,``):null}catch{return null}}async function getNpmVersion(t){let n=await Ve(t,[`--version`],{shell:!0,windowsHide:!0,verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0});return n.stdout?n.stdout.trim().replace(/^v/,``):null}async function useJavaScriptRuntime(t=e.cwd()){let n=Bn.get(t);if(n)return cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!0,cwd:t,runtime:n.unwrapOr(null)}),n;for(let[e,n]of Object.entries(Vn))try{let r=normalizeExecutablePath(await We(e)),i=await getRuntimeVersion(r,n);if(i){let n={executablePath:r,version:i};if(e===`node`){let e=normalizeExecutablePath(await We(`npm`).catch(()=>null));e&&(n.pmPath=e,n.pmVersion=await getNpmVersion(e),n.pmName=`npm`)}else n.runtimeShorthand=e,n.pmPath=r,n.pmVersion=i,n.pmName=e;return Bn.set(t,Be(n)),cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!1,cwd:t,runtime:Bn.get(t)?.unwrap()}),Be(n)}}catch{}return Bn.set(t,Re),cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!1,cwd:t,runtime:null}),Re}const Hn=/* @__PURE__ */ new Map;async function getPythonVersion(t){try{let n=await Ve(t,[`-c`,`"import platform; print(platform.python_version())"`],{shell:!0,windowsHide:!0,verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0});return n.stdout?n.stdout.trim():null}catch{return null}}async function usePythonRuntime({cwd:t=e.cwd(),force:n=!1}={}){let r=Hn.get(t);if(r&&!n)return cliDebugPrint(`usePythonRuntime`,{cacheHit:!0,cwd:t,runtime:r.unwrapOr(null)}),r;let i=ce()===`win32`,a=i?[`Scripts`,`python.exe`]:[`bin`,`python3`],s;s=e.env.VIRTUAL_ENV?u(e.env.VIRTUAL_ENV,...a):u(t,`.venv`,...a),s=normalizeExecutablePath(s);try{let e=await getPythonVersion(s);if(e)return Hn.set(t,Be({executablePath:s,version:e})),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:Hn.get(t)?.unwrap()}),Hn.get(t)}catch{}let c=[`python3`,`python`,...i?[`python3.exe`,`python.exe`]:[]];for(let e of c)try{let n=normalizeExecutablePath(await We(e)),r=await getPythonVersion(n);if(r)return Hn.set(t,Be({executablePath:n,version:r})),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:Hn.get(t)?.unwrap()}),Hn.get(t)}catch{}return Hn.set(t,Re),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:null}),Re}const Un=/* @__PURE__ */ new Map;async function useCwdProject({cwd:t=e.cwd()}={}){let n=Un.get(t);if(n)return cliDebugPrint(`useCwdProject`,{cacheHit:!0,project:n}),ze(n);let r={type:3},check=async()=>{if(await checkScrapyProject(t)){r.type=2;let e=await usePythonRuntime({cwd:t});r.runtime=e.unwrapOr(void 0),await fileExists(u(t,`uv.lock`))&&(r.packageManager=`uv`);let n=new ScrapyProjectAnalyzer(t);if(n.loadScrapyCfg(),n.configuration.hasKey(`apify`,`mainpy_location`))r.entrypoint={path:n.configuration.get(`apify`,`mainpy_location`)};else try{let e=await checkPythonProject(t);e&&(r.entrypoint={path:e})}catch{}return}let e=await checkNodeProject(t);if(!e){let e=null;try{e=await checkPythonProject(t)}catch(e){return Le({message:e instanceof Error?e.message:String(e)})}if(e){r.type=1;let n=await usePythonRuntime({cwd:t});r.entrypoint={path:e},r.runtime=n.unwrapOr(void 0),await fileExists(u(t,`uv.lock`))&&(r.packageManager=`uv`);let i=u(t,e.replace(/\./g,`/`));await fileExists(u(i,`__main__.py`))||(r.warnings=[`The detected Python package "${e}" is missing __main__.py. Running with "python -m" will fail without it.`]);return}}if(e){r.type=0;let t=await useJavaScriptRuntime();r.runtime=t.unwrapOr(void 0),e.type===`file`?r.entrypoint={path:e.path}:e.type===`script`&&(r.entrypoint={script:e.script})}else return ze(r)},i=await check();return i?.isErr()?(cliDebugPrint(`useCwdProject`,{cacheHit:!1,error:i}),i):(cliDebugPrint(`useCwdProject`,{cacheHit:!1,project:r}),Un.set(t,r),ze(r))}async function checkNodeProject(e){let t=u(e,`package.json`);try{let n=await U(t,`utf-8`),r=JSON.parse(n);if(r.scripts?.start)return{type:`script`,script:`start`};if(r.main)try{return await Oe(p(e,r.main)),{path:p(e,r.main),type:`file`}}catch{}return{type:`unknown-entrypoint`}}catch{}let n=[u(e,`index.js`),u(e,`index.mjs`),u(e,`index.cjs`),u(e,`main.js`),u(e,`main.mjs`),u(e,`main.cjs`),u(e,`src`,`index.js`),u(e,`src`,`index.mjs`),u(e,`src`,`index.cjs`),u(e,`src`,`main.js`),u(e,`src`,`main.mjs`),u(e,`src`,`main.cjs`),u(e,`dist`,`index.js`),u(e,`dist`,`index.mjs`),u(e,`dist`,`index.cjs`),u(e,`dist`,`main.js`),u(e,`dist`,`main.mjs`),u(e,`dist`,`main.cjs`)];for(let e of n)try{return await Oe(e),{path:e,type:`file`}}catch{}return null}async function fileExists(e){try{return await Oe(e),!0}catch{return!1}}async function dirExists(e){try{return(await W(e)).isDirectory()}catch{return!1}}function isValidPythonIdentifier(e){return/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e)}async function hasPythonFilesInDirOrSubdirs(e){try{let t=await Ae(e,{withFileTypes:!0});if(t.some(e=>e.isFile()&&e.name.endsWith(`.py`)))return!0;for(let n of t){if(!n.isDirectory()||n.name.startsWith(`.`)||n.name.startsWith(`_`))continue;let t=u(e,n.name);try{let e=await Ae(t,{withFileTypes:!0});if(e.some(e=>e.isFile()&&e.name.endsWith(`.py`)))return!0;if(n.name===`src`){for(let n of e)if(n.isDirectory()&&!(n.name.startsWith(`.`)||n.name.startsWith(`_`)))try{if((await Ae(u(t,n.name),{withFileTypes:!0})).some(e=>e.isFile()&&e.name.endsWith(`.py`)))return!0}catch{}}}catch{}}return!1}catch{return!1}}async function dirHasPyFiles(e){try{return(await Ae(e,{withFileTypes:!0})).some(e=>e.isFile()&&e.name.endsWith(`.py`)&&e.name!==`__init__.py`)}catch{return!1}}async function findNearMissPackagesInDir(e){try{let t=await Ae(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory()||r.name.startsWith(`.`)||r.name.startsWith(`_`))continue;let t=isValidPythonIdentifier(r.name),i=await fileExists(u(e,r.name,`__init__.py`)),a=i||await dirHasPyFiles(u(e,r.name));t&&i||a&&n.push({name:r.name,needsRename:!t,needsInit:!i})}return n}catch{return[]}}async function findPackagesInDir(e){try{let t=await Ae(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory())continue;let{name:t}=r;t.startsWith(`.`)||t.startsWith(`_`)||!isValidPythonIdentifier(t)||await fileExists(u(e,t,`__init__.py`))&&n.push({name:t,path:u(e,t)})}return n}catch{return[]}}async function discoverPythonPackages(e){let t=[],n=await findPackagesInDir(e);t.push(...n.map(e=>e.name));let r=u(e,`src`),i=await fileExists(u(r,`__init__.py`));if(await dirExists(r)&&!i){let e=await findPackagesInDir(r);t.push(...e.map(e=>`src.${e.name}`))}return t}async function checkPythonProject(e){let t=await discoverPythonPackages(e);if(t.length===1)return t[0];if(t.length>1){let e=t.map(e=>` - ${e}`).join(`
32
32
  `);throw Error(`Multiple Python packages found:\n${e}\n\nApify CLI cannot determine which package to run.
33
33
  Please specify the package using the --entrypoint flag, e.g.:
34
34
  apify run --entrypoint <package_name>`)}let n=await findNearMissPackagesInDir(e),r=u(e,`src`),i=!await fileExists(u(r,`__init__.py`))&&await dirExists(r)?await findNearMissPackagesInDir(r):[],a=[...n.map(e=>({...e,prefix:``})),...i.map(e=>({...e,prefix:`src/`}))];if(a.length>0){let e=a.map(({name:e,prefix:t,needsRename:n,needsInit:r})=>{let i=[];return n&&i.push(`rename to "${t}${e.replace(/[^a-zA-Z0-9_]/g,`_`)}/"`),r&&i.push(`add __init__.py`),` - "${t}${e}/" → ${i.join(` and `)}`}).join(`
@@ -49,12 +49,12 @@ Common package structures:
49
49
  `)}\n`,{flag:`a`})):I(n,`${i.join(`
50
50
  `)}\n`,{flag:`w`}))},$n=new it(ot,at).define({"application/gzip":[`tgz`],"text/typescript":[`ts`,`tsx`,`mts`]},!0),getSourceFileFormat=(e,t)=>{let n=$n.getType(e);return n?n.startsWith(`text/`)||n.includes(`javascript`)||n.includes(`json`)||n.includes(`xml`)||n.includes(`application/node`)||n.includes(`application/toml`)||n.includes(`application/x-sh`)||n.includes(`application/x-httpd-php`)?ye.TEXT:ye.BASE64:nt(t)===`binary`?ye.BASE64:ye.TEXT},createSourceFiles=async(e,t)=>e.map(e=>{let n=M(u(t,e)),r=getSourceFileFormat(e,n);return{name:e,format:r,content:r===ye.TEXT?n.toString(`utf8`):n.toString(`base64`)}}),getGitignoreFallbackFilter=async e=>{let t=await st(`**/.gitignore`,{dot:!0,cwd:e,ignore:[`.git/**`],expandDirectories:!1}),n=[];for(let r of t){let t=c(r),i=await U(u(e,r),`utf-8`);n.push({dir:t===`.`?``:t,ig:Yn().add(i)})}let r=c(e);for(;r!==c(r)&&!O(u(r,`.git`));){let t=u(r,`.gitignore`);if(O(t))try{let i=await U(t,`utf-8`),a=f(r,e);n.push({dir:``,ig:Yn().add(i),ancestorPrefix:a})}catch{}r=c(r)}return n.length===0?e=>e:e=>e.filter(e=>{for(let{dir:t,ig:r,ancestorPrefix:i}of n){let n;if(n=t?e.startsWith(`${t}/`)?e.slice(t.length+1):null:i?`${i}/${e}`:e,n!==null&&r.ignores(n))return!1}return!0})},parseActorIgnore=async e=>{let t=u(e,`.actorignore`);if(!O(t))return{excludeFilter:null,forceIncludePatterns:[]};let n=(await U(t,`utf-8`)).split(`
51
51
  `),r=[],i=[];for(let e of n){let t=e.trim();t&&!t.startsWith(`#`)&&(t.startsWith(`!`)?i.push(t.slice(1)):r.push(t))}return{excludeFilter:r.length>0?e=>{let t=Yn().add(r);return e.filter(e=>!t.ignores(e))}:null,forceIncludePatterns:i}},getActorLocalFilePaths=async t=>{let n=t??e.cwd(),r=[`.git/**`,`apify_storage`,`node_modules`,`storage`,`crawlee_storage`],{excludeFilter:i,forceIncludePatterns:a}=await parseActorIgnore(n),gitIgnoreFilter=null;try{let e=Ge(`git ls-files --others --ignored --exclude-standard --directory`,{cwd:n,encoding:`utf-8`,stdio:[`ignore`,`pipe`,`ignore`]}).split(`
52
- `).filter(Boolean);if(e.length>0){let t=Yn().add(e);gitIgnoreFilter=e=>e.filter(e=>!t.ignores(e))}}catch{gitIgnoreFilter=await getGitignoreFallbackFilter(n)}let s=await st([`*`,`**/**`],{ignore:r,dot:!0,expandDirectories:!1,cwd:n}),c=gitIgnoreFilter?gitIgnoreFilter(s):s;if(i&&(c=i(c)),a.length>0){let e=Yn().add(a),t=s.filter(t=>e.ignores(t)),n=new Set(c);for(let e of t)n.add(e);c=[...n]}let l=s.filter(e=>e===`.actor`||e.startsWith(`.actor/`));if(l.length>0){let e=new Set(c);for(let t of l)e.add(t);c=[...e]}return c},createActZip=async(e,t,n)=>{O(e)&&await deleteFile(e);let r=D(e),i=new $e({zlib:{level:6}});i.pipe(r),t.forEach(e=>i.file(u(n,e),{name:e})),await i.finalize()},getLocalInput=(e,t)=>{let n=t??me.INPUT,r=p(e,getLocalKeyValueStorePath());if(!O(r))return;let i=readKvsRecordMetadata(r,n);if(i){let e=i.filename??encodeRecordKey(n);if(O(u(r,e)))return{body:M(u(r,e)),contentType:i.contentType,fileName:e}}let a=N(r).find(e=>!!e.match(inputFileRegExp(n)));return a?{body:M(u(r,a)),contentType:$n.getType(a),fileName:a}:void 0},purgeDefaultQueue=async()=>{await rimrafPromised(p(e.cwd(),getLocalRequestQueuePath()))},purgeDefaultDataset=async()=>{await rimrafPromised(p(e.cwd(),getLocalDatasetPath()))},purgeDefaultKeyValueStore=async(...t)=>{let n=p(e.cwd(),getLocalKeyValueStorePath());if(!O(n))return;let r=N(n),i=t.length>0?t:[me.INPUT],a=i.map(inputFileRegExp),s=new Set(i.flatMap(e=>[recordMetadataFileName(e),readKvsRecordMetadata(n,e)?.filename])),c=[];r.forEach(e=>{!s.has(e)&&!a.some(t=>t.test(e))&&c.push(deleteFile(u(n,e)))}),await Promise.all(c)},outputJobLog=async({job:t,timeoutMillis:n,apifyClient:r})=>{let{id:i,status:a}=t,s=r||new Ce({baseUrl:e.env.APIFY_CLIENT_BASE_URL});if(de.includes(a)){if(e.env.APIFY_NO_LOGS_IN_TESTS)return;let t=await s.log(i).get();e.stderr.write(t);return}return new Promise(async t=>{let r=await s.log(i).stream();if(!r){t(`no-logs`);return}let a=null;r.on(`data`,t=>{e.env.APIFY_NO_LOGS_IN_TESTS||e.stderr.write(t.toString())}),r.once(`end`,()=>{t(`finished`),a&&clearTimeout(a)}),n!==void 0&&(a=setTimeout(()=>{r.destroy(),t(`timeouts`)},n))})},checkIfStorageIsEmpty=async t=>{let n=t||me.INPUT,r=getLocalStorageDir().replaceAll(`\\`,`/`),i=getLocalKeyValueStorePath().replaceAll(`\\`,`/`);return(await st([`${r}/**`,...[n,`${Kn}${n}`].flatMap(e=>[`!${i}/${e}`,`!${i}/${e}.*`])],{cwd:e.cwd()})).length===0},validateActorName=e=>{if(!fe.REGEX.test(e))throw Error(`The Actor name must be a DNS hostname-friendly string (e.g. my-newest-actor).`);if(e.length<fe.MIN_LENGTH)throw Error(`The Actor name must be at least ${fe.MIN_LENGTH} characters long.`);if(e.length>fe.MAX_LENGTH)throw Error(`The Actor name must be at most ${fe.MAX_LENGTH} characters long.`)},validateActorNameForPrompt=e=>{try{validateActorName(e)}catch(e){return e.message}return!0},sanitizeActorName=e=>{let t=e.replaceAll(/[^a-zA-Z0-9-]/g,`-`);return t.length<fe.MIN_LENGTH&&(t=`${t}-apify-actor`),t=t.replaceAll(/^-+/g,``).replaceAll(/-+$/g,``),t.slice(0,fe.MAX_LENGTH)},isPythonVersionSupported=e=>x(e,`^${dn}`),isNodeVersionSupported=e=>{let t=b(cn);return y(e,t)},downloadZip=async e=>{let t=await we.get(e,{responseType:`arraybuffer`,validateStatus:()=>!0,headers:{"User-Agent":`Apify CLI/${useCLIMetadata().version} (https://github.com/apify/apify-cli)`}});if(t.status<200||t.status>=300){let n=Buffer.from(t.data).toString(`utf8`).trim().slice(0,500);throw Error(`Failed to download the archive from ${e} (HTTP ${t.status}).${n?`\nServer response: ${n}`:``}`)}let n=Buffer.from(t.data);if(n.subarray(0,2).toString()!==`PK`)throw Error(`The file downloaded from ${e} is not a valid zip archive - a proxy or firewall likely intercepted the download. Check your network or try a different one.`);return new Ze(n)},downloadAndUnzip=async({url:e,pathTo:t})=>{(await downloadZip(e)).extractAllTo(t,!0)},q=new Xe(`YYYY-MM-DD [at] HH:mm:ss`),er=new Xe(`YYYY-MM-DD[
52
+ `).filter(Boolean);if(e.length>0){let t=Yn().add(e);gitIgnoreFilter=e=>e.filter(e=>!t.ignores(e))}}catch{gitIgnoreFilter=await getGitignoreFallbackFilter(n)}let s=await st([`*`,`**/**`],{ignore:r,dot:!0,expandDirectories:!1,cwd:n}),c=gitIgnoreFilter?gitIgnoreFilter(s):s;if(i&&(c=i(c)),a.length>0){let e=Yn().add(a),t=s.filter(t=>e.ignores(t)),n=new Set(c);for(let e of t)n.add(e);c=[...n]}let l=s.filter(e=>e===`.actor`||e.startsWith(`.actor/`));if(l.length>0){let e=new Set(c);for(let t of l)e.add(t);c=[...e]}return c},createActZip=async(e,t,n)=>{O(e)&&await deleteFile(e);let r=D(e),i=new $e({zlib:{level:6}});i.pipe(r),t.forEach(e=>i.file(u(n,e),{name:e})),await i.finalize()},getLocalInput=(e,t)=>{let n=t??me.INPUT,r=p(e,getLocalKeyValueStorePath());if(!O(r))return;let i=readKvsRecordMetadata(r,n);if(i){let e=i.filename??encodeRecordKey(n);if(O(u(r,e)))return{body:M(u(r,e)),contentType:i.contentType,fileName:e}}let a=N(r).find(e=>!!e.match(inputFileRegExp(n)));return a?{body:M(u(r,a)),contentType:$n.getType(a),fileName:a}:void 0},purgeDefaultQueue=async()=>{await rimrafPromised(p(e.cwd(),getLocalRequestQueuePath()))},purgeDefaultDataset=async()=>{await rimrafPromised(p(e.cwd(),getLocalDatasetPath()))},purgeDefaultKeyValueStore=async(...t)=>{let n=p(e.cwd(),getLocalKeyValueStorePath());if(!O(n))return;let r=N(n),i=t.length>0?t:[me.INPUT],a=i.map(inputFileRegExp),s=new Set(i.flatMap(e=>[recordMetadataFileName(e),readKvsRecordMetadata(n,e)?.filename])),c=[];r.forEach(e=>{!s.has(e)&&!a.some(t=>t.test(e))&&c.push(deleteFile(u(n,e)))}),await Promise.all(c)},outputJobLog=async({job:t,timeoutMillis:n,apifyClient:r})=>{let{id:i,status:a}=t,s=r||new Ce({baseUrl:e.env.APIFY_CLIENT_BASE_URL});if(de.includes(a)){if(e.env.APIFY_NO_LOGS_IN_TESTS)return;let t=await s.log(i).get();e.stderr.write(t)}else return new Promise(async t=>{let r=await s.log(i).stream();if(!r){t(`no-logs`);return}let a=null;r.on(`data`,t=>{e.env.APIFY_NO_LOGS_IN_TESTS||e.stderr.write(t.toString())}),r.once(`end`,()=>{t(`finished`),a&&clearTimeout(a)}),n!==void 0&&(a=setTimeout(()=>{r.destroy(),t(`timeouts`)},n))})},checkIfStorageIsEmpty=async t=>{let n=t||me.INPUT,r=getLocalStorageDir().replaceAll(`\\`,`/`),i=getLocalKeyValueStorePath().replaceAll(`\\`,`/`);return(await st([`${r}/**`,...[n,`${Kn}${n}`].flatMap(e=>[`!${i}/${e}`,`!${i}/${e}.*`])],{cwd:e.cwd()})).length===0},validateActorName=e=>{if(!fe.REGEX.test(e))throw Error(`The Actor name must be a DNS hostname-friendly string (e.g. my-newest-actor).`);if(e.length<fe.MIN_LENGTH)throw Error(`The Actor name must be at least ${fe.MIN_LENGTH} characters long.`);if(e.length>fe.MAX_LENGTH)throw Error(`The Actor name must be at most ${fe.MAX_LENGTH} characters long.`)},validateActorNameForPrompt=e=>{try{validateActorName(e)}catch(e){return e.message}return!0},sanitizeActorName=e=>{let t=e.replaceAll(/[^a-zA-Z0-9-]/g,`-`);return t.length<fe.MIN_LENGTH&&(t=`${t}-apify-actor`),t=t.replaceAll(/^-+/g,``).replaceAll(/-+$/g,``),t.slice(0,fe.MAX_LENGTH)},isPythonVersionSupported=e=>x(e,`^${dn}`),isNodeVersionSupported=e=>{let t=b(cn);return y(e,t)},downloadZip=async e=>{let t=await we.get(e,{responseType:`arraybuffer`,validateStatus:()=>!0,headers:{"User-Agent":`Apify CLI/${useCLIMetadata().version} (https://github.com/apify/apify-cli)`}});if(t.status<200||t.status>=300){let n=Buffer.from(t.data).toString(`utf8`).trim().slice(0,500);throw Error(`Failed to download the archive from ${e} (HTTP ${t.status}).${n?`\nServer response: ${n}`:``}`)}let n=Buffer.from(t.data);if(n.subarray(0,2).toString()!==`PK`)throw Error(`The file downloaded from ${e} is not a valid zip archive - a proxy or firewall likely intercepted the download. Check your network or try a different one.`);return new Ze(n)},downloadAndUnzip=async({url:e,pathTo:t})=>{(await downloadZip(e)).extractAllTo(t,!0)},q=new Xe(`YYYY-MM-DD [at] HH:mm:ss`),er=new Xe(`YYYY-MM-DD[
53
53
  ]HH:mm:ss`),tr=new Xe(`YYYY-MM-DD`),nr=new qe,rr=new qe({[Ye.Day]:{DEFAULT:`d`},[Ye.Hour]:{DEFAULT:`h`},[Ye.Minute]:{DEFAULT:`m`},[Ye.Month]:{DEFAULT:`M`},[Ye.Second]:{DEFAULT:`s`},[Ye.Week]:{DEFAULT:`w`},[Ye.Year]:{DEFAULT:`y`}});function objectGroupBy(e,t){if(`groupBy`in Object)return Object.groupBy(e,t);let n={},r=0;for(let i of e){let e=t(i,r++);n[e]||(n[e]=[]),n[e].push(i)}return n}function printJsonToStdout(e){console.log(JSON.stringify(e,null,2))}const userHomeDir=()=>e.env.HOME??se(),tildify=e=>{let t=userHomeDir();return t&&e.startsWith(t)?e.replace(t,`~`):e};function detectShell(){let t=e.env.SHELL??``;return t.includes(`zsh`)?`zsh`:t.includes(`bash`)?`bash`:t.includes(`fish`)?`fish`:`unknown`}function shellConfigFile(t,n){switch(n){case`bash`:{let n=[u(t,`.bashrc`),u(t,`.bash_profile`)];e.env.XDG_CONFIG_HOME&&n.push(u(e.env.XDG_CONFIG_HOME,`.bashrc`),u(e.env.XDG_CONFIG_HOME,`.bash_profile`),u(e.env.XDG_CONFIG_HOME,`bashrc`),u(e.env.XDG_CONFIG_HOME,`bash_profile`));for(let e of n)if(O(e))return e;return null}case`zsh`:{let n=e.env.ZDOTDIR||t||userHomeDir();return u(n,`.zshrc`)}case`fish`:return u(t,`.config`,`fish`,`config.fish`);case`unknown`:return null}}function parseWaitForFinishMillis(e){if(e===void 0)return;let t=Number.parseInt(e,10);if(!(!Number.isFinite(t)||t<0))return t*1e3}const ir=[`Apify collects telemetry data about general usage of Apify CLI to help us improve the product.`,`This feature is enabled by default, and you can disable it by setting the "APIFY_CLI_DISABLE_TELEMETRY" environment variable to "1", or by running "apify telemetry disable".`,`You can find more information about our telemetry in https://docs.apify.com/cli/docs/telemetry.`].join(`
54
- `);function createAnonymousId(){return`CLI:${De()}`}async function migrateStateV0ToV1(e){if(e.version&&e.version>=1)return!1;let t=e,n=await getLocalUserInfo().catch(()=>({}));return updateTelemetryState({version:1,enabled:!0},e=>{n.id&&t.distinctId===n.id?(e.anonymousId=createAnonymousId(),e.userId=n.id):e.anonymousId=t.distinctId}),!0}async function useTelemetryState(){let e=TELEMETRY_FILE_PATH();if(!O(e)){let e=await getLocalUserInfo().catch(()=>({}));return updateTelemetryState({version:1,enabled:!0,anonymousId:createAnonymousId(),userId:e.id}),(!process.env.APIFY_CLI_DISABLE_TELEMETRY||[`false`,`0`].includes(process.env.APIFY_CLI_DISABLE_TELEMETRY))&&info({message:ir}),useTelemetryState()}let t=JSON.parse(M(e,`utf-8`));return await migrateStateV0ToV1(t)?useTelemetryState():t}function updateTelemetryState(e,t){let n={...e};t?.(n);let r=TELEMETRY_FILE_PATH(),i=c(r);A(i,{recursive:!0}),I(TELEMETRY_FILE_PATH(),JSON.stringify(n,null,` `))}async function updateUserId(e){updateTelemetryState(await useTelemetryState(),t=>{t.userId=e})}async function checkAndUpdateLastCommand(e){try{let t=await useTelemetryState(),n=Date.now(),r=t.lastCommand===e&&n-(t.lastCommandTimestamp??0)<1e4;return updateTelemetryState(t,t=>{t.lastCommand=e,t.lastCommandTimestamp=n}),r}catch{return!1}}async function updateTelemetryEnabled(e){updateTelemetryState(await useTelemetryState(),t=>{t.enabled=e})}async function useTelemetryEnabled(){if(process.env.APIFY_CLI_DISABLE_TELEMETRY&&![`false`,`0`].includes(process.env.APIFY_CLI_DISABLE_TELEMETRY))return cliDebugPrint(`telemetry`,`disabled by env variable`),!1;let e=await useTelemetryState();return cliDebugPrint(`telemetry state`,{telemetryState:e}),e.enabled}async function useTelemetryIdentifiers(){let e=await useTelemetryState();return{anonymousId:e.anonymousId,userId:e.userId}}const ar=useCLIMetadata(),or=ar.isBeta?`rT67mFpIQD5qS9bJBoIYSFbZucrt2DZC`:`2uPK6yhPqjC0eNUFhaY78S26cRKyaa6t`;async function trackEvent(e,t){let n=await useTelemetryIdentifiers(),r={anonymousId:n.anonymousId,context:{app:{name:`apify-cli`,version:ar.version,build:ar.hash},library:{name:`apify-cli`,version:ar.version},os:{name:ar.platform},userAgent:vn,channel:`server`},event:e,properties:{...t,app:`cli`},timestamp:(/* @__PURE__ */ new Date()).toISOString(),userId:n.userId,writeKey:or};if(cliDebugPrint(`trackEvent`,r),!await useTelemetryEnabled()){cliDebugPrint(`trackEvent`,`telemetry disabled`);return}try{let e=await fetch(`https://api.segment.io/v1/track`,{method:`POST`,body:JSON.stringify(r)});if(!e.ok){cliDebugPrint(`trackEvent`,`failed to send event`,await e.text());return}cliDebugPrint(`trackEvent`,`event sent`)}catch(e){cliDebugPrint(`trackEvent`,`failed to send event`,e)}}function shouldSkipRentalSunsetNotice({now:e,isCi:t,skipEnvValue:n}){return!!(n&&![`0`,`false`].includes(n)||t||e>=an)}function wasNotifiedRecently(e,t,n){return!e?.lastNotifiedAt||e.username!==t?!1:n-e.lastNotifiedAt<864e5}function renderRentalSunsetNotice(e){let n=e===1?`rental Actor`:`rental Actors`;return[t.bold(`Rental model sunset`),``,`You have ${e} ${n} published in Apify Store. Apify is sunsetting the rental pricing model.`,``,` ${t.bold(`April 1, 2026`)} Publishing new rental Actors and pricing changes on existing ones were disabled.`,` ${t.bold(`October 1, 2026`)} Rental Actors are fully retired. All remaining Actors move to pay-per-usage pricing.`,``,`Switch your ${n} to pay-per-event before October 1 to keep control over what you charge.`,`This guide walks through picking events, setting prices, and shipping the change:`,` ${t.cyan(`https://blog.apify.com/migrating-to-pay-per-event-pricing/`)}`,``,`Questions? Ask in the ${t.cyan(`#project-rentals`)} channel on Apify Discord:`,` ${t.cyan(`https://apify.com/discord`)}`,``,t.dim(`To silence this notice, set APIFY_CLI_SKIP_RENTAL_SUNSET_NOTICE=1.`),``].join(`
55
- `)}function getLocalUsername(){return getCurrentProfile()?.username}async function fetchRentalActorCount(t){let n=useCLIMetadata(),r=new URL(`/v2/store`,e.env.APIFY_CLIENT_BASE_URL||`https://api.apify.com`);try{let{data:e}=await we.get(r.href,{params:{username:t,pricingModel:`FLAT_PRICE_PER_MONTH`,limit:1},timeout:3e3,headers:{...un,"User-Agent":`Apify CLI/${n.version} (https://github.com/apify/apify-cli)`}});return typeof e?.data?.total==`number`?e.data.total:(cliDebugPrint(`useRentalSunsetNotice`,`Store response has no data.total`,{body:e}),null)}catch(e){return cliDebugPrint(`useRentalSunsetNotice`,`Failed to look up rental Actors`,e),null}}async function resolveRentalActorCount(e,t,n){let r=e?.username===t?e:void 0;return r&&n-r.lastChecked<864e5?{rentalActorCount:r.rentalActorCount,lastChecked:r.lastChecked,fromCache:!0}:{rentalActorCount:await fetchRentalActorCount(t)??r?.rentalActorCount??0,lastChecked:n,fromCache:!1}}async function useRentalSunsetNotice(){try{let t=Date.now(),n=useLocalState();if(shouldSkipRentalSunsetNotice({now:t,isCi:ue,skipEnvValue:e.env.APIFY_CLI_SKIP_RENTAL_SUNSET_NOTICE}))return;let r=getLocalUsername();if(!r){cliDebugPrint(`useRentalSunsetNotice`,`Not logged in, skipping the check`);return}if(wasNotifiedRecently(n.rentalSunset,r,t))return;let{rentalActorCount:i,lastChecked:a,fromCache:s}=await resolveRentalActorCount(n.rentalSunset,r,t),c=i>0;if(s&&!c||(updateLocalState(n,e=>{e.rentalSunset={lastChecked:a,username:r,rentalActorCount:i,...c?{lastNotifiedAt:t}:{}}}),!c))return;simpleLog({message:``}),warning({message:renderRentalSunsetNotice(i)})}catch(e){cliDebugPrint(`useRentalSunsetNotice`,`Failed to run the rental sunset check`,e)}}function camelCaseString(e){return e.replace(/[-_\s](.)/g,(e,t)=>t.toUpperCase())}function kebabCaseString(e){return e.replace(/[\s_]+/g,`-`)}function camelCaseToKebabCase(e){return e.replace(/([A-Z])/g,`-$1`).toLowerCase()}const sr={type:`boolean`,multiple:!1,short:`h`},cr={type:`boolean`,multiple:!1},lr={type:`string`,multiple:!1},ur={type:`string`,multiple:!1},dr=`user-agent`,fr=/* @__PURE__ */ new Set([`apify`]);function sanitizeUserAgentValue(e){if(typeof e!=`string`)return;let t=e.replace(/[\u0000-\u001f\u007f]/g,``).trim();if(t)return t.length>256?t.slice(0,256):t}function resolveUserAgentForTelemetry(e,t){return sanitizeUserAgentValue(e)??sanitizeUserAgentValue(t)}const J=/* @__PURE__ */ new Map,pr=[`init`,`run`,`push`,`actors push`,`pull`,`actors pull`,`call`,`actors call`,`actors start`];var ApifyCommand=class{static args;static flags;static subcommands;static enableJsonFlag=!1;static enableProfileFlag=!1;static name;static shortDescription;static description;static examples;static docsUrl;static interactive;static interactiveNote;static group;static aliases;static hidden;static hiddenAliases;telemetryData={};flags;args;entrypoint;commandString;aliasUsed;subcommandAliasUsed;skipTelemetry=!1;skipNotices=!1;constructor(e,t,n,r){this.entrypoint=e,this.commandString=t,this.aliasUsed=n,this.subcommandAliasUsed=r;let i=useCLIMetadata();this.telemetryData.installMethod=i.installMethod,this.telemetryData.osArch=i.arch,this.telemetryData.runtime=i.runtime.runtime,this.telemetryData.runtimeVersion=i.runtime.version,this.telemetryData.runtimeNodeVersion=i.runtime.nodeVersion??i.runtime.version,this.telemetryData.commandString=t,this.telemetryData.entrypoint=e;let a=detectCi();this.telemetryData.aiAgent=detectAiAgent(),this.telemetryData.isCi=a.isCi,this.telemetryData.ciProvider=a.ciProvider,this.telemetryData.isInteractive=detectIsInteractive()}get ctor(){return this.constructor}pluralString(e,t,n){return e===1?t:n}static printHelp(){console.log(renderHelpForCommand(this)),e.exit(0)}printHelp(){return this.ctor.printHelp()}async _run(t){let n=Date.now(),{values:r,positionals:i,tokens:a}=t;if(r.help&&this.ctor.printHelp(),fr.has(this.entrypoint)){let t=r[dr],n=resolveUserAgentForTelemetry(typeof t==`string`?t:void 0,e.env.APIFY_CLI_USER_AGENT);n&&(this.telemetryData.userAgent=n)}this.args={},this.flags={},this.ctor.enableJsonFlag&&(typeof r.json==`boolean`?this.flags.json=r.json:this.flags.json=!1,this.flags.json&&keepStdoutClean());let s=/* @__PURE__ */ new Map;if(this.ctor.args){let e=0;for(let[t,n]of Object.entries(this.ctor.args)){if(typeof n==`string`)throw RangeError(`Do not provide the string for the json arg! It is a type level assertion!`);let r=camelCaseString(t),a=i[e++];a?(n.argTag,this.args[r]=String(a),a===`-`&&n.stdin&&(this.args[r]=this._handleStdin(n.stdin)),n.catchAll&&(this.args[r]=i.slice(e-1).join(` `))):n.required&&s.set(t,n)}}if(s.size){e.exitCode=1,this._printMissingRequiredArgs(s);return}this._parseFlags(r,a);try{this.ctor.enableProfileFlag&&typeof r.profile==`string`&&(this.flags.profile=r.profile,await selectProfile(r.profile)),await this.run()}catch(t){error({message:t.message}),e.exitCode||=1}finally{!this.telemetryData.actorLanguage&&pr.includes(this.commandString)&&(await useCwdProject()).inspect(e=>{e.type===0?(this.telemetryData.actorLanguage=`javascript`,this.telemetryData.actorRuntime=e.runtime.runtimeShorthand||`node`,this.telemetryData.actorRuntimeVersion=e.runtime.version):(e.type===1||e.type===2)&&(this.telemetryData.actorLanguage=`python`,this.telemetryData.actorRuntime=`python`,this.telemetryData.actorRuntimeVersion=e.runtime.version)}),this.skipTelemetry||(this.telemetryData.flagsUsed=Object.keys(this.flags),this.telemetryData.exitCode=typeof e.exitCode==`number`?e.exitCode:0,this.telemetryData.durationMs=Date.now()-n,this.telemetryData.wasRetried=await checkAndUpdateLastCommand(this.commandString),await trackEvent(`cli_command`,this.telemetryData)),!this.skipNotices&&!e.exitCode&&await useRentalSunsetNotice()}}_userFlagNameToRegisteredName(e,t){let n=kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),r=n;n.startsWith(`no-`)&&(r=n.slice(3));let i=/* @__PURE__ */ new Set;for(let e of t.aliases??[])i.add(kebabCaseString(camelCaseToKebabCase(e)).toLowerCase());return{baseFlagName:r,rawBaseFlagName:n,allMatchers:[r,...i]}}_commandFlagKeyToKebabCaseRegisteredName(e){let t=kebabCaseString(camelCaseToKebabCase(e)).toLowerCase();return t.startsWith(`no-`)&&(t=t.slice(3)),t}_parseFlags(e,n){if(!this.ctor.flags)return;let r=/* @__PURE__ */ new Map,i;for(let[a,s]of Object.entries(this.ctor.flags)){if(typeof s==`string`)throw RangeError(`Do not provide the string for the json arg! It is a type level assertion!`);let{allMatchers:c,baseFlagName:l,rawBaseFlagName:u}=this._userFlagNameToRegisteredName(a,s),f=camelCaseString(u),p=n.some(e=>e.kind===`option`&&e.name===l);if(s.exclusive?.length){let e=r.get(l)??/* @__PURE__ */ new Set;for(let t of s.exclusive)e.add(this._commandFlagKeyToKebabCaseRegisteredName(t));r.set(l,e);for(let e of s.exclusive){let t=this._commandFlagKeyToKebabCaseRegisteredName(e),n=r.get(t)??/* @__PURE__ */ new Set;n.add(l),r.set(t,n)}}let m=c.filter(t=>Object.hasOwn(e,t));if(m.length>1)throw new Qt({code:3,command:this.ctor,metadata:{flag:l}});let h=e[m[0]];if(h===void 0&&s.required)throw new Qt({code:6,command:this.ctor,metadata:{flag:l,matcher:m[0]}});if(Array.isArray(h)){if(h.length>1)throw new Qt({code:3,command:this.ctor,metadata:{flag:l}});h=h[0]}if(p&&typeof h==`string`&&h.startsWith(`=`)&&(h=h.slice(1)),h!==void 0)switch(s.flagTag){case`boolean`:this.flags[f]=u.startsWith(`no-`)?!h:h;break;case`integer`:{let e=Number(h);if(Number.isNaN(e)||!Number.isInteger(e))throw new Qt({code:4,command:this.ctor,metadata:{flag:l,value:String(h)}});this.flags[f]=e;break}default:if(this.flags[f]=h,h===`-`&&s.stdin){if(i)throw new Qt({code:8,command:this.ctor,metadata:{firstUse:i,secondUse:l}});i=l,this.flags[f]=this._handleStdin(s.stdin)}}else s.hasDefault!==void 0&&(this.flags[f]=s.hasDefault);if(this.flags[f]!=null&&s.choices&&!s.choices.includes(this.flags[f]))throw new Qt({code:5,command:this.ctor,metadata:{flag:l,choices:s.choices.map(e=>t.white.bold(e)).join(`, `)}});if(this.flags[f]==null&&(s.required||h!=null))throw new Qt({code:6,command:this.ctor,metadata:{flag:l,matcher:m[0],providedButReceivedNoValue:!!h}})}let a=[];for(let[t,n]of r)if(e[t]!=null)for(let r of n){if(e[r]==null)continue;let n=e[t][0],i=e[r][0],flagRepresentation=(e,t)=>typeof t==`boolean`?t?`--${e}`:`--no-${e}`:`--${e}=${t}`;a.push([flagRepresentation(t,n),flagRepresentation(r,i)]);break}if(a.length)throw new Qt({code:7,command:this.ctor,metadata:{flagPairs:a}})}_printMissingRequiredArgs(e){let a;try{a=selectiveRenderHelpForCommand(this.ctor,{showUsageString:!0})}catch{}let s=r([...e.keys()].join(`
54
+ `);function createAnonymousId(){return`CLI:${De()}`}async function migrateStateV0ToV1(e){if(e.version&&e.version>=1)return!1;let t=e,n=await getLocalUserInfo().catch(()=>({}));return updateTelemetryState({version:1,enabled:!0},e=>{n.id&&t.distinctId===n.id?(e.anonymousId=createAnonymousId(),e.userId=n.id):e.anonymousId=t.distinctId}),!0}async function useTelemetryState(){let e=TELEMETRY_FILE_PATH();if(!O(e)){let e=await getLocalUserInfo().catch(()=>({}));return updateTelemetryState({version:1,enabled:!0,anonymousId:createAnonymousId(),userId:e.id}),(!process.env.APIFY_CLI_DISABLE_TELEMETRY||[`false`,`0`].includes(process.env.APIFY_CLI_DISABLE_TELEMETRY))&&info({message:ir}),useTelemetryState()}let t=JSON.parse(M(e,`utf-8`));return await migrateStateV0ToV1(t)?useTelemetryState():t}function updateTelemetryState(e,t){let n={...e};t?.(n);let r=TELEMETRY_FILE_PATH(),i=c(r);A(i,{recursive:!0}),I(TELEMETRY_FILE_PATH(),JSON.stringify(n,null,` `))}async function updateUserId(e){updateTelemetryState(await useTelemetryState(),t=>{t.userId=e})}async function checkAndUpdateLastCommand(e){try{let t=await useTelemetryState(),n=Date.now(),r=t.lastCommand===e&&n-(t.lastCommandTimestamp??0)<1e4;return updateTelemetryState(t,t=>{t.lastCommand=e,t.lastCommandTimestamp=n}),r}catch{return!1}}async function updateTelemetryEnabled(e){updateTelemetryState(await useTelemetryState(),t=>{t.enabled=e})}async function useTelemetryEnabled(){if(process.env.APIFY_CLI_DISABLE_TELEMETRY&&![`false`,`0`].includes(process.env.APIFY_CLI_DISABLE_TELEMETRY))return cliDebugPrint(`telemetry`,`disabled by env variable`),!1;let e=await useTelemetryState();return cliDebugPrint(`telemetry state`,{telemetryState:e}),e.enabled}async function useTelemetryIdentifiers(){let e=await useTelemetryState();return{anonymousId:e.anonymousId,userId:e.userId}}const ar=useCLIMetadata(),or=ar.isBeta?`rT67mFpIQD5qS9bJBoIYSFbZucrt2DZC`:`2uPK6yhPqjC0eNUFhaY78S26cRKyaa6t`;async function trackEvent(e,t){let n=await useTelemetryIdentifiers(),r={anonymousId:n.anonymousId,context:{app:{name:`apify-cli`,version:ar.version,build:ar.hash},library:{name:`apify-cli`,version:ar.version},os:{name:ar.platform},userAgent:vn,channel:`server`},event:e,properties:{...t,app:`cli`},timestamp:(/* @__PURE__ */ new Date()).toISOString(),userId:n.userId,writeKey:or};if(cliDebugPrint(`trackEvent`,r),!await useTelemetryEnabled())cliDebugPrint(`trackEvent`,`telemetry disabled`);else try{let e=await fetch(`https://api.segment.io/v1/track`,{method:`POST`,body:JSON.stringify(r)});if(!e.ok){cliDebugPrint(`trackEvent`,`failed to send event`,await e.text());return}cliDebugPrint(`trackEvent`,`event sent`)}catch(e){cliDebugPrint(`trackEvent`,`failed to send event`,e)}}function shouldSkipRentalSunsetNotice({now:e,isCi:t,skipEnvValue:n}){return!!(n&&![`0`,`false`].includes(n)||t||e>=an)}function wasNotifiedRecently(e,t,n){return!e?.lastNotifiedAt||e.username!==t?!1:n-e.lastNotifiedAt<864e5}function renderRentalSunsetNotice(e){let n=e===1?`rental Actor`:`rental Actors`;return[t.bold(`Rental model sunset`),``,`You have ${e} ${n} published in Apify Store. Apify is sunsetting the rental pricing model.`,``,` ${t.bold(`April 1, 2026`)} Publishing new rental Actors and pricing changes on existing ones were disabled.`,` ${t.bold(`October 1, 2026`)} Rental Actors are fully retired. All remaining Actors move to pay-per-usage pricing.`,``,`Switch your ${n} to pay-per-event before October 1 to keep control over what you charge.`,`This guide walks through picking events, setting prices, and shipping the change:`,` ${t.cyan(`https://blog.apify.com/migrating-to-pay-per-event-pricing/`)}`,``,`Questions? Ask in the ${t.cyan(`#project-rentals`)} channel on Apify Discord:`,` ${t.cyan(`https://apify.com/discord`)}`,``,t.dim(`To silence this notice, set APIFY_CLI_SKIP_RENTAL_SUNSET_NOTICE=1.`),``].join(`
55
+ `)}function getLocalUsername(){return getCurrentProfile()?.username}async function fetchRentalActorCount(t){let n=useCLIMetadata(),r=new URL(`/v2/store`,e.env.APIFY_CLIENT_BASE_URL||`https://api.apify.com`);try{let{data:e}=await we.get(r.href,{params:{username:t,pricingModel:`FLAT_PRICE_PER_MONTH`,limit:1},timeout:3e3,headers:{...un,"User-Agent":`Apify CLI/${n.version} (https://github.com/apify/apify-cli)`}});return typeof e?.data?.total==`number`?e.data.total:(cliDebugPrint(`useRentalSunsetNotice`,`Store response has no data.total`,{body:e}),null)}catch(e){return cliDebugPrint(`useRentalSunsetNotice`,`Failed to look up rental Actors`,e),null}}async function resolveRentalActorCount(e,t,n){let r=e?.username===t?e:void 0;return r&&n-r.lastChecked<864e5?{rentalActorCount:r.rentalActorCount,lastChecked:r.lastChecked,fromCache:!0}:{rentalActorCount:await fetchRentalActorCount(t)??r?.rentalActorCount??0,lastChecked:n,fromCache:!1}}async function useRentalSunsetNotice(){try{let t=Date.now(),n=useLocalState();if(shouldSkipRentalSunsetNotice({now:t,isCi:ue,skipEnvValue:e.env.APIFY_CLI_SKIP_RENTAL_SUNSET_NOTICE}))return;let r=getLocalUsername();if(!r){cliDebugPrint(`useRentalSunsetNotice`,`Not logged in, skipping the check`);return}if(wasNotifiedRecently(n.rentalSunset,r,t))return;let{rentalActorCount:i,lastChecked:a,fromCache:s}=await resolveRentalActorCount(n.rentalSunset,r,t),c=i>0;if(s&&!c||(updateLocalState(n,e=>{e.rentalSunset={lastChecked:a,username:r,rentalActorCount:i,...c?{lastNotifiedAt:t}:{}}}),!c))return;simpleLog({message:``}),warning({message:renderRentalSunsetNotice(i)})}catch(e){cliDebugPrint(`useRentalSunsetNotice`,`Failed to run the rental sunset check`,e)}}function camelCaseString(e){return e.replace(/[-_\s](.)/g,(e,t)=>t.toUpperCase())}function kebabCaseString(e){return e.replace(/[\s_]+/g,`-`)}function camelCaseToKebabCase(e){return e.replace(/([A-Z])/g,`-$1`).toLowerCase()}const sr={type:`boolean`,multiple:!1,short:`h`},cr={type:`boolean`,multiple:!1},lr={type:`string`,multiple:!1},ur={type:`string`,multiple:!1},dr=`user-agent`,fr=/* @__PURE__ */ new Set([`apify`]);function sanitizeUserAgentValue(e){if(typeof e!=`string`)return;let t=e.replace(/[\u0000-\u001f\u007f]/g,``).trim();if(t)return t.length>256?t.slice(0,256):t}function resolveUserAgentForTelemetry(e,t){return sanitizeUserAgentValue(e)??sanitizeUserAgentValue(t)}const J=/* @__PURE__ */ new Map,pr=[`init`,`run`,`push`,`actors push`,`pull`,`actors pull`,`call`,`actors call`,`actors start`];var ApifyCommand=class{static args;static flags;static subcommands;static enableJsonFlag=!1;static enableProfileFlag=!1;static name;static shortDescription;static description;static examples;static docsUrl;static interactive;static interactiveNote;static group;static aliases;static hidden;static hiddenAliases;telemetryData={};flags;args;entrypoint;commandString;aliasUsed;subcommandAliasUsed;skipTelemetry=!1;skipNotices=!1;constructor(e,t,n,r){this.entrypoint=e,this.commandString=t,this.aliasUsed=n,this.subcommandAliasUsed=r;let i=useCLIMetadata();this.telemetryData.installMethod=i.installMethod,this.telemetryData.osArch=i.arch,this.telemetryData.runtime=i.runtime.runtime,this.telemetryData.runtimeVersion=i.runtime.version,this.telemetryData.runtimeNodeVersion=i.runtime.nodeVersion??i.runtime.version,this.telemetryData.commandString=t,this.telemetryData.entrypoint=e;let a=detectCi();this.telemetryData.aiAgent=detectAiAgent(),this.telemetryData.isCi=a.isCi,this.telemetryData.ciProvider=a.ciProvider,this.telemetryData.isInteractive=detectIsInteractive()}get ctor(){return this.constructor}pluralString(e,t,n){return e===1?t:n}static printHelp(){console.log(renderHelpForCommand(this)),e.exit(0)}printHelp(){return this.ctor.printHelp()}async _run(t){let n=Date.now(),{values:r,positionals:i,tokens:a}=t;if(r.help&&this.ctor.printHelp(),fr.has(this.entrypoint)){let t=r[dr],n=resolveUserAgentForTelemetry(typeof t==`string`?t:void 0,e.env.APIFY_CLI_USER_AGENT);n&&(this.telemetryData.userAgent=n)}this.args={},this.flags={},this.ctor.enableJsonFlag&&(typeof r.json==`boolean`?this.flags.json=r.json:this.flags.json=!1,this.flags.json&&keepStdoutClean());let s=/* @__PURE__ */ new Map;if(this.ctor.args){let e=0;for(let[t,n]of Object.entries(this.ctor.args)){if(typeof n==`string`)throw RangeError(`Do not provide the string for the json arg! It is a type level assertion!`);let r=camelCaseString(t),a=i[e++];a?(n.argTag,this.args[r]=String(a),a===`-`&&n.stdin&&(this.args[r]=this._handleStdin(n.stdin)),n.catchAll&&(this.args[r]=i.slice(e-1).join(` `))):n.required&&s.set(t,n)}}if(s.size)e.exitCode=1,this._printMissingRequiredArgs(s);else{this._parseFlags(r,a);try{this.ctor.enableProfileFlag&&typeof r.profile==`string`&&(this.flags.profile=r.profile,await selectProfile(r.profile)),await this.run()}catch(t){error({message:t.message}),e.exitCode||=1}finally{!this.telemetryData.actorLanguage&&pr.includes(this.commandString)&&(await useCwdProject()).inspect(e=>{e.type===0?(this.telemetryData.actorLanguage=`javascript`,this.telemetryData.actorRuntime=e.runtime.runtimeShorthand||`node`,this.telemetryData.actorRuntimeVersion=e.runtime.version):(e.type===1||e.type===2)&&(this.telemetryData.actorLanguage=`python`,this.telemetryData.actorRuntime=`python`,this.telemetryData.actorRuntimeVersion=e.runtime.version)}),this.skipTelemetry||(this.telemetryData.flagsUsed=Object.keys(this.flags),this.telemetryData.exitCode=typeof e.exitCode==`number`?e.exitCode:0,this.telemetryData.durationMs=Date.now()-n,this.telemetryData.wasRetried=await checkAndUpdateLastCommand(this.commandString),await trackEvent(`cli_command`,this.telemetryData)),!this.skipNotices&&!e.exitCode&&await useRentalSunsetNotice()}}}_userFlagNameToRegisteredName(e,t){let n=kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),r=n;n.startsWith(`no-`)&&(r=n.slice(3));let i=/* @__PURE__ */ new Set;for(let e of t.aliases??[])i.add(kebabCaseString(camelCaseToKebabCase(e)).toLowerCase());return{baseFlagName:r,rawBaseFlagName:n,allMatchers:[r,...i]}}_commandFlagKeyToKebabCaseRegisteredName(e){let t=kebabCaseString(camelCaseToKebabCase(e)).toLowerCase();return t.startsWith(`no-`)&&(t=t.slice(3)),t}_parseFlags(e,n){if(!this.ctor.flags)return;let r=/* @__PURE__ */ new Map,i;for(let[a,s]of Object.entries(this.ctor.flags)){if(typeof s==`string`)throw RangeError(`Do not provide the string for the json arg! It is a type level assertion!`);let{allMatchers:c,baseFlagName:l,rawBaseFlagName:u}=this._userFlagNameToRegisteredName(a,s),f=camelCaseString(u),p=n.some(e=>e.kind===`option`&&e.name===l);if(s.exclusive?.length){let e=r.get(l)??/* @__PURE__ */ new Set;for(let t of s.exclusive)e.add(this._commandFlagKeyToKebabCaseRegisteredName(t));r.set(l,e);for(let e of s.exclusive){let t=this._commandFlagKeyToKebabCaseRegisteredName(e),n=r.get(t)??/* @__PURE__ */ new Set;n.add(l),r.set(t,n)}}let m=c.filter(t=>Object.hasOwn(e,t));if(m.length>1)throw new Qt({code:3,command:this.ctor,metadata:{flag:l}});let h=e[m[0]];if(h===void 0&&s.required)throw new Qt({code:6,command:this.ctor,metadata:{flag:l,matcher:m[0]}});if(Array.isArray(h)){if(h.length>1)throw new Qt({code:3,command:this.ctor,metadata:{flag:l}});h=h[0]}if(p&&typeof h==`string`&&h.startsWith(`=`)&&(h=h.slice(1)),h!==void 0)switch(s.flagTag){case`boolean`:this.flags[f]=u.startsWith(`no-`)?!h:h;break;case`integer`:{let e=Number(h);if(Number.isNaN(e)||!Number.isInteger(e))throw new Qt({code:4,command:this.ctor,metadata:{flag:l,value:String(h)}});this.flags[f]=e;break}default:if(this.flags[f]=h,h===`-`&&s.stdin){if(i)throw new Qt({code:8,command:this.ctor,metadata:{firstUse:i,secondUse:l}});i=l,this.flags[f]=this._handleStdin(s.stdin)}}else s.hasDefault!==void 0&&(this.flags[f]=s.hasDefault);if(this.flags[f]!=null&&s.choices&&!s.choices.includes(this.flags[f]))throw new Qt({code:5,command:this.ctor,metadata:{flag:l,choices:s.choices.map(e=>t.white.bold(e)).join(`, `)}});if(this.flags[f]==null&&(s.required||h!=null))throw new Qt({code:6,command:this.ctor,metadata:{flag:l,matcher:m[0],providedButReceivedNoValue:!!h}})}let a=[];for(let[t,n]of r)if(e[t]!=null)for(let r of n){if(e[r]==null)continue;let n=e[t][0],i=e[r][0],flagRepresentation=(e,t)=>typeof t==`boolean`?t?`--${e}`:`--no-${e}`:`--${e}=${t}`;a.push([flagRepresentation(t,n),flagRepresentation(r,i)]);break}if(a.length)throw new Qt({code:7,command:this.ctor,metadata:{flagPairs:a}})}_printMissingRequiredArgs(e){let a;try{a=selectiveRenderHelpForCommand(this.ctor,{showUsageString:!0})}catch{}let s=r([...e.keys()].join(`
56
56
  `)),c=[];for(let[r,a]of e){let e=`${r.padEnd(s)} ${a.description}`,l=i(e,getMaxLineWidth()-s-2),u=n(l,s+2+2).trim();c.push(` ${t.red(`>`)} ${u}`)}let l=[`Missing ${e.size} required ${this.pluralString(e.size,`argument`,`arguments`)}:`,...c,t.gray(` See more help with --help`)];a&&l.push(``,a),error({message:l.join(`
57
- `)})}_handleStdin(e){switch(e){case 2:return(gn?.toString(`utf8`)??``).trim();default:return gn}}_buildParseArgsOption(){let e={help:sr};fr.has(this.entrypoint)&&(e[dr]=ur);let t={allowNegative:!0,allowPositionals:!0,strict:!0,tokens:!0,options:e};if(this.ctor.flags)for(let[e,n]of Object.entries(this.ctor.flags)){if(typeof n==`string`)throw RangeError(`Do not provide the string for the json flag! It is a type level assertion!`);if(e.toLowerCase()===`json`)continue;let r=kebabCaseString(camelCaseToKebabCase(e)).toLowerCase();r.startsWith(`no-`)&&(r=r.slice(3));let i=n.builder(r);for(let{flagName:e,option:n}of i)t.options[e]=n}return this.ctor.enableJsonFlag&&(t.options.json=cr),this.ctor.enableProfileFlag&&(t.options.profile=lr),t}static registerCommand(e){if(registerCommandForHelpGeneration(e,this),J.set(this.name,this),this.aliases?.length)for(let e of this.aliases)J.set(e,this);if(this.hiddenAliases?.length)for(let e of this.hiddenAliases)J.set(e,this);if(this.subcommands?.length)for(let e of this.subcommands){if(J.set(`${this.name} ${e.name}`,e),this.aliases?.length)for(let t of this.aliases)J.set(`${t} ${e.name}`,e);if(this.hiddenAliases?.length)for(let t of this.hiddenAliases)J.set(`${t} ${e.name}`,e);if(e.aliases?.length)for(let t of e.aliases){if(J.set(`${this.name} ${t}`,e),this.aliases?.length)for(let n of this.aliases)J.set(`${n} ${t}`,e);if(this.hiddenAliases?.length)for(let n of this.hiddenAliases)J.set(`${n} ${t}`,e)}if(e.hiddenAliases?.length)for(let t of e.hiddenAliases){if(J.set(`${this.name} ${t}`,e),this.aliases?.length)for(let n of this.aliases)J.set(`${n} ${t}`,e);if(this.hiddenAliases?.length)for(let n of this.hiddenAliases)J.set(`${n} ${t}`,e)}}}};async function internalRunCommand(e,t,n){let r={positionals:[],values:{},tokens:[]},i=0;for(let[e,t]of Object.entries(n)){let[n,a]=e.split(`_`);if(n===`args`)r.positionals[i++]=t;else{let e=kebabCaseString(camelCaseToKebabCase(a)).toLowerCase();e.startsWith(`no-`)?r.values[e.slice(3)]=!t:r.values[e]=t}}let a=new t(e,t.name,t.name);return a.skipTelemetry=!0,a.skipNotices=!0,await a._run(r),a}const Y={string:stringFlag,boolean:booleanFlag,integer:integerFlag};function YesFlag(e=`Answer "yes" to all prompts.`){return{yes:Y.boolean({char:`y`,description:e,default:!1})}}function stringFlag(e){return{flagTag:`string`,builder:t=>{let n=/* @__PURE__ */ new Set([...e.aliases??[]]);n.delete(t);let r=[{flagName:t,option:{type:`string`,multiple:!0}}];e.char&&(r[0].option.short=e.char);for(let e of n)r.push({flagName:kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),option:{type:`string`,multiple:!0}});return r},choices:e.choices,required:e.required??!1,hasDefault:e.default,stdin:e.stdin??2,description:e.description,aliases:e.aliases,char:e.char,hidden:e.hidden,exclusive:e.exclusive}}function booleanFlag(e){return{flagTag:`boolean`,builder:t=>{let n=/* @__PURE__ */ new Set([...e.aliases??[]]);n.delete(t);let r=[{flagName:t,option:{type:`boolean`,multiple:!0}}];e.char&&(r[0].option.short=e.char);for(let e of n)r.push({flagName:kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),option:{type:`boolean`,multiple:!0}});return r},choices:null,required:e.required??!1,hasDefault:e.default,stdin:e.stdin??1,description:e.description,aliases:e.aliases,char:e.char,hidden:e.hidden,exclusive:e.exclusive}}function integerFlag(e){return{flagTag:`integer`,builder:t=>{let n=/* @__PURE__ */ new Set([...e.aliases??[]]);n.delete(t);let r=[{flagName:t,option:{type:`string`,multiple:!0}}];e.char&&(r[0].option.short=e.char);for(let e of n)r.push({flagName:kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),option:{type:`string`,multiple:!0}});return r},choices:null,required:e.required??!1,hasDefault:e.default,stdin:e.stdin??1,description:e.description,aliases:e.aliases,char:e.char,hidden:e.hidden,exclusive:e.exclusive}}function getBooleanValue(e,t){let n=t!==!1;return/^(y|yes)/i.test(e)?n=!0:/^(n|no)/i.test(e)&&(n=!1),n}function boolToString(e){return e?`Yes`:`No`}const mr=ut((e,t)=>{let n=boolToString,[r,i]=ht(`idle`),[a,s]=ht(``),c=ft(),l=mt({status:r,theme:c});pt((r,c)=>{if(dt(r)){let r=getBooleanValue(a,e.default);s(n(r)),i(`done`),t(r);return}if(r.name===`tab`){let t=boolToString(!getBooleanValue(a,e.default));c.clearLine(0),c.write(t),s(t);return}if(r.name===`y`||r.name===`n`){let a=getBooleanValue(r.name,e.default);s(n(a)),i(`done`),t(a);return}c.clearLine(0),c.write(a),s(c.line)});let u=a,f=``;return r===`done`?u=c.style.answer(a):f=` ${c.style.defaultAnswer(e.default===!1?`y/N`:`Y/n`)}`,`${l} ${c.style.message(e.message,r)}${f} ${u}`}),X=stdinCheckWrapper(async({message:e,default:t})=>await mr({message:e,default:t},In)),getDeprecatedLocalConfigPath=e=>u(e,`apify.json`),hr=/* @__PURE__ */ new Map;async function useActorConfig({cwd:t=e.cwd(),migrateConfig:n=!0,warnAboutOldConfig:r=!0}={cwd:e.cwd(),migrateConfig:!0,warnAboutOldConfig:!0}){let i=hr.get(t);if(i)return cliDebugPrint(`useActorConfig`,{cacheHit:!0,config:i}),ze(i);let a=getLocalConfigPath(t),s=getDeprecatedLocalConfigPath(t),c,l;try{c=getJsonFileContent(a)}catch(e){return Le({message:`Failed to read local config at path: '${a}':`,cause:e,exists:!1,config:{}})}try{l=getJsonFileContent(s)}catch(e){return Le({message:`Failed to read local config at path: '${s}':`,cause:e,exists:!1,config:{}})}if(c&&l&&r&&await handleBothConfigVersionsFound(s),!c&&!l)return hr.set(t,{exists:!1,migrated:!1,config:{}}),ze({exists:!1,migrated:!1,config:{}});let u=!1;if(!c&&l&&n){let e=await handleMigrationFlow(l,s,a);if(e.isErr())return Le(e.unwrapErr());c=e.unwrap(),u=!0}return hr.set(t,{exists:!0,migrated:u,config:c||l||{}}),cliDebugPrint(`useActorConfig`,{cacheHit:!1,config:hr.get(t)}),ze({exists:!0,migrated:u,config:c||l||{}})}async function handleBothConfigVersionsFound(e){if(!await X({message:`The new version of Apify CLI uses the ".actor/actor.json" instead of the "apify.json" file. Since we have found both files in your Actor directory, "apify.json" will be renamed to "apify.json.deprecated". Going forward, all commands will use ".actor/actor.json". You can read about the differences between the old and the new config at https://github.com/apify/apify-cli/blob/master/MIGRATIONS.md. Do you want to continue?`})){warning({message:`The "apify.json" file present in your Actor directory will be ignored, and the new ".actor/actor.json" file will be used instead. Please, either rename or remove the old file.`});return}try{await je(e,`${e}.deprecated`),info({message:`The "apify.json" file has been renamed to "apify.json.deprecated". The deprecated file is no longer used by the CLI or Apify Console. If you do not need it for some specific purpose, it can be safely deleted.`})}catch(e){e instanceof Error?error({message:`Failed to rename the deprecated "apify.json" file to "apify.json.deprecated".\n ${e.message||e}`}):error({message:`Failed to rename the deprecated "apify.json" file to "apify.json.deprecated".\n ${h(e,{showHidden:!1})}`})}}const gr=[`name`,`version`,`buildTag`];async function handleMigrationFlow(e,t,n){let r={...e};if(typeof r.version==`object`&&(r=updateLocalConfigStructure(r)),r={actorSpecification:1,environmentVariables:e?.env||void 0,...gr.reduce((t,n)=>(t[n]=e[n],t),{})},!await X({message:`The new version of Apify CLI uses the ".actor/actor.json" instead of the "apify.json" file. Your "apify.json" file will be automatically updated to the new format under ".actor/actor.json". The original file will be renamed by adding the ".deprecated" suffix. Do you want to continue?`}))return Le({message:`Command can not run with old "apify.json" structure. Either let the CLI auto-update it or follow the guide on https://github.com/apify/apify-cli/blob/master/MIGRATIONS.md and update it manually.`,exists:!0,config:r});try{await H(c(n),{recursive:!0}),await G(n,JSON.stringify(r,null,` `))}catch(e){let t=e;return Le({message:`Failed to write the new "actor.json" file to path: '${n}'.\n ${t.message||t}`,exists:!0,config:r})}try{await je(t,`${t}.deprecated`)}catch(e){let t=e;warning({message:`Failed to rename the deprecated "apify.json" file to "apify.json.deprecated".\n ${t.message||t}`})}return info({message:`The "apify.json" file has been migrated to ".actor/actor.json" and the original file renamed to "apify.json.deprecated". The deprecated file is no longer used by the CLI or Apify Console. If you do not need it for some specific purpose, it can be safely deleted. Do not forget to commit the new file to your Git repository.`}),ze(r)}function updateLocalConfigStructure(e){let t={name:e.name,template:e.template,version:e.version.versionNumber,buildTag:e.version.buildTag,env:null};if(e.version.envVars?.length){let n={};e.version.envVars.forEach(e=>{e.name&&e.value&&(n[e.name]=e.value)}),t.env=n}return t}const _r=u(getLocalKeyValueStorePath(`default`),`INPUT.json`);var ActorCalculateMemoryCommand=class extends ApifyCommand{static name=`calculate-memory`;static description=`Calculates the Actor’s dynamic memory usage based on a memory expression from actor.json, input data, and run options.`;static group=`Actor Runtime`;static examples=[{description:`Calculate memory using the expression and input defaults from actor.json.`,command:`actor calculate-memory`},{description:`Override the memory expression and input file.`,command:`actor calculate-memory --defaultMemoryMbytes "input.length * 128" --input ./my-input.json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#actor-calculate-memory`;static flags={input:Y.string({description:`Path to the input JSON file used for the calculation.`,required:!1,default:_r}),defaultMemoryMbytes:Y.string({description:`Memory-calculation expression (in MB). If omitted, the value is loaded from the actor.json file.`,required:!1}),build:Y.string({description:`Actor build version or build tag to evaluate the expression with.`,required:!1}),timeoutSecs:Y.integer({description:`Maximum run timeout, in seconds.`,required:!1}),maxItems:Y.integer({description:`Maximum number of items Actor can output.`,required:!1}),maxTotalChargeUsd:Y.integer({description:`Maximum total charge in USD.`,required:!1})};async run(){let{input:t,memoryExpression:n,minMemory:r,maxMemory:i,runOptions:a}=await this.prepareMemoryArguments();if(!n)throw Error(`No memory-calculation expression found. Provide it via the --default-memory-mbytes flag or define defaultMemoryMbytes in actor.json.`);let s=p(e.cwd(),t),c=getJsonFileContent(s)??{};info({message:`Evaluating memory expression: ${n}`});try{let e=await ct(n,{input:c,runOptions:a});success({message:`Calculated memory: ${Math.min(Math.max(e,r),i)} MB`,stdout:!0})}catch(e){error({message:`Memory calculation failed: ${e.message}`})}}async prepareMemoryArguments(){let{input:e,defaultMemoryMbytes:t,...n}=this.flags,r=t,i=0,a=1/0;return r||({defaultMemoryMbytes:r,minMemoryMbytes:i=i,maxMemoryMbytes:a=a}=await this.getExpressionFromConfig()),{memoryExpression:r,minMemory:i,maxMemory:a,input:e,runOptions:n}}async getExpressionFromConfig(){let t=await useActorConfig({cwd:e.cwd()});if(t.isErr()){let{message:n,cause:r}=t.unwrapErr();return error({message:`${n}${r?`\n ${r.message}`:``}`}),e.exitCode=5,{}}let{config:n}=t.unwrap();return{defaultMemoryMbytes:n?.defaultMemoryMbytes?.toString(),minMemoryMbytes:n?.minMemoryMbytes,maxMemoryMbytes:n?.maxMemoryMbytes}}};function stringArg(e){return{argTag:`string`,required:e.required??!1,stdin:e.stdin??1,description:e.description,aliases:e.aliases,catchAll:e.catchAll??!1}}const Z={string:stringArg};var ActorChargeCommand=class extends ApifyCommand{static name=`charge`;static description=`Charge for a specific event in a pay-per-event Actor run.`;static group=`Actor Runtime`;static examples=[{description:`Charge one event of the given type.`,command:`actor charge result-item`},{description:`Charge 5 events with an idempotency key.`,command:`actor charge result-item --count 5 --idempotency-key req-123`},{description:`Test locally without actually charging.`,command:`actor charge result-item --test-pay-per-event`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#actor-charge`;static args={eventName:Z.string({description:`Name of the event to charge for.`,required:!0})};static flags={count:Y.integer({description:`Number of events to charge.`,required:!1,default:1}),"idempotency-key":Y.string({description:`Idempotency key for the charge request.`,required:!1}),"test-pay-per-event":Y.boolean({description:`Test pay-per-event charging without actually charging.`,required:!1,default:!1})};async run(){let{eventName:e}=this.args,{count:t,testPayPerEvent:n,idempotencyKey:r}=this.flags;if(!process.env.APIFY_IS_AT_HOME){info({message:`No platform detected: would charge ${t} events of type "${e}" with idempotency key "${r??`not-provided`}".`,stdout:!0});return}if(n){info({message:`PPE test mode: would charge ${t} events of type "${e}" with idempotency key "${r??`not-provided`}".`,stdout:!0});return}let i=await getLoggedClientOrThrow(),a=process.env[B.ACTOR_RUN_ID];if(!a)throw Error(`Charge command must be executed in a running Actor. Run ID not found.`);if((await i.run(a).get())?.pricingInfo?.pricingModel!==`PAY_PER_EVENT`)throw Error(`Charge command can only be used with pay-per-event pricing model.`);info({message:`Charging ${t} events of type "${e}" with idempotency key "${r??`not-provided`}" (runId: ${a}).`,stdout:!0}),await i.run(a).charge({eventName:e,count:t,idempotencyKey:r})}};const vr=[`.actor/INPUT_SCHEMA.json`,`./INPUT_SCHEMA.json`,`.actor/input_schema.json`,`./input_schema.json`],readInputSchema=async({forcePath:e,cwd:t,throwOnMissing:n=!1})=>{if(e)return{inputSchema:getJsonFileContent(e),inputSchemaPath:e};let r=getLocalConfig(t);if(typeof r?.input==`object`&&r.input!==null)return{inputSchema:r.input,inputSchemaPath:null};if(typeof r?.input==`string`){let e=u(t,sn,r.input),i=getJsonFileContent(e);if(!i){if(n)throw Error(`Input schema file not found at ${e} (referenced in '${K}').`);return warning({message:`Input schema file not found at ${e} (referenced in '${K}').`}),{inputSchema:null,inputSchemaPath:e}}return{inputSchema:i,inputSchemaPath:e}}for(let e of vr){let n=u(t,e);if(O(n))return{inputSchema:getJsonFileContent(n),inputSchemaPath:n}}return{inputSchema:null,inputSchemaPath:u(t,vr[0])}},readAndValidateInputSchema=async({forcePath:e,cwd:t,getMessage:n})=>{let{inputSchema:r,inputSchemaPath:i}=await readInputSchema({forcePath:e,cwd:t});if(!r)throw Error(`Input schema has not been found at ${i}.`);info({message:n(i)});let a=new Xn({strict:!1});return _t(a,r),{inputSchema:r,inputSchemaPath:i}},readStorageSchema=({cwd:e,key:t,label:n,getRef:r,throwOnMissing:i=!1})=>{let a=getLocalConfig(e),s=r?r(a):a?.storages?.[t];if(typeof s==`object`&&s)return{schema:s,schemaPath:null};if(typeof s==`string`){let t=u(e,sn,s),r=getJsonFileContent(t);if(!r){if(i)throw Error(`${n} schema file not found at ${t} (referenced in '${K}').`);return warning({message:`${n} schema file not found at ${t} (referenced in '${K}').`}),null}return{schema:r,schemaPath:t}}return null},readDatasetSchema=({cwd:e})=>{let t=readStorageSchema({cwd:e,key:`dataset`,label:`Dataset`});return t?{datasetSchema:t.schema,datasetSchemaPath:t.schemaPath}:null},readOutputSchema=({cwd:e})=>{let t=readStorageSchema({cwd:e,key:`output`,label:`Output`,getRef:e=>e?.output});return t?{outputSchema:t.schema,outputSchemaPath:t.schemaPath}:null},createPrefilledInputFileFromInputSchema=async e=>{let t={};try{let{inputSchema:n}=await readInputSchema({cwd:e});if(n){let e=new Xn({strict:!1});_t(e,n),t=Object.entries(n.properties).reduce((e,[t,n])=>(e[t]=n.type===`boolean`||n.editor===`hidden`?n.default:n.prefill,e),{})}}catch(e){warning({message:`Could not create default input based on input schema, creating empty input instead. Cause: ${e.message}`})}finally{await writeKvsRecord({storePath:u(e,getLocalKeyValueStorePath()),key:me.INPUT,fileName:`${me.INPUT}.json`,contentType:`application/json; charset=utf-8`,body:JSON.stringify(t,null,` `)})}},getDefaultsFromInputSchema=e=>{let t={};for(let[n,r]of Object.entries(e.properties))r.default!==void 0&&(t[n]=r.default);return t};function formatSchemaValidationErrors(e,t){return`${t} schema is not valid:\n${e.map(e=>{let t=e.instancePath?` at ${e.instancePath}`:``;return` - ${e.message}${t}`}).join(`
57
+ `)})}_handleStdin(e){switch(e){case 2:return(gn?.toString(`utf8`)??``).trim();default:return gn}}_buildParseArgsOption(){let e={help:sr};fr.has(this.entrypoint)&&(e[dr]=ur);let t={allowNegative:!0,allowPositionals:!0,strict:!0,tokens:!0,options:e};if(this.ctor.flags)for(let[e,n]of Object.entries(this.ctor.flags)){if(typeof n==`string`)throw RangeError(`Do not provide the string for the json flag! It is a type level assertion!`);if(e.toLowerCase()===`json`)continue;let r=kebabCaseString(camelCaseToKebabCase(e)).toLowerCase();r.startsWith(`no-`)&&(r=r.slice(3));let i=n.builder(r);for(let{flagName:e,option:n}of i)t.options[e]=n}return this.ctor.enableJsonFlag&&(t.options.json=cr),this.ctor.enableProfileFlag&&(t.options.profile=lr),t}static registerCommand(e){if(registerCommandForHelpGeneration(e,this),J.set(this.name,this),this.aliases?.length)for(let e of this.aliases)J.set(e,this);if(this.hiddenAliases?.length)for(let e of this.hiddenAliases)J.set(e,this);if(this.subcommands?.length)for(let e of this.subcommands){if(J.set(`${this.name} ${e.name}`,e),this.aliases?.length)for(let t of this.aliases)J.set(`${t} ${e.name}`,e);if(this.hiddenAliases?.length)for(let t of this.hiddenAliases)J.set(`${t} ${e.name}`,e);if(e.aliases?.length)for(let t of e.aliases){if(J.set(`${this.name} ${t}`,e),this.aliases?.length)for(let n of this.aliases)J.set(`${n} ${t}`,e);if(this.hiddenAliases?.length)for(let n of this.hiddenAliases)J.set(`${n} ${t}`,e)}if(e.hiddenAliases?.length)for(let t of e.hiddenAliases){if(J.set(`${this.name} ${t}`,e),this.aliases?.length)for(let n of this.aliases)J.set(`${n} ${t}`,e);if(this.hiddenAliases?.length)for(let n of this.hiddenAliases)J.set(`${n} ${t}`,e)}}}};async function internalRunCommand(e,t,n){let r={positionals:[],values:{},tokens:[]},i=0;for(let[e,t]of Object.entries(n)){let[n,a]=e.split(`_`);if(n===`args`)r.positionals[i++]=t;else{let e=kebabCaseString(camelCaseToKebabCase(a)).toLowerCase();e.startsWith(`no-`)?r.values[e.slice(3)]=!t:r.values[e]=t}}let a=new t(e,t.name,t.name);return a.skipTelemetry=!0,a.skipNotices=!0,await a._run(r),a}const Y={string:stringFlag,boolean:booleanFlag,integer:integerFlag};function YesFlag(e=`Answer "yes" to all prompts.`){return{yes:Y.boolean({char:`y`,description:e,default:!1})}}function stringFlag(e){return{flagTag:`string`,builder:t=>{let n=/* @__PURE__ */ new Set([...e.aliases??[]]);n.delete(t);let r=[{flagName:t,option:{type:`string`,multiple:!0}}];e.char&&(r[0].option.short=e.char);for(let e of n)r.push({flagName:kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),option:{type:`string`,multiple:!0}});return r},choices:e.choices,required:e.required??!1,hasDefault:e.default,stdin:e.stdin??2,description:e.description,aliases:e.aliases,char:e.char,hidden:e.hidden,exclusive:e.exclusive}}function booleanFlag(e){return{flagTag:`boolean`,builder:t=>{let n=/* @__PURE__ */ new Set([...e.aliases??[]]);n.delete(t);let r=[{flagName:t,option:{type:`boolean`,multiple:!0}}];e.char&&(r[0].option.short=e.char);for(let e of n)r.push({flagName:kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),option:{type:`boolean`,multiple:!0}});return r},choices:null,required:e.required??!1,hasDefault:e.default,stdin:e.stdin??1,description:e.description,aliases:e.aliases,char:e.char,hidden:e.hidden,exclusive:e.exclusive}}function integerFlag(e){return{flagTag:`integer`,builder:t=>{let n=/* @__PURE__ */ new Set([...e.aliases??[]]);n.delete(t);let r=[{flagName:t,option:{type:`string`,multiple:!0}}];e.char&&(r[0].option.short=e.char);for(let e of n)r.push({flagName:kebabCaseString(camelCaseToKebabCase(e)).toLowerCase(),option:{type:`string`,multiple:!0}});return r},choices:null,required:e.required??!1,hasDefault:e.default,stdin:e.stdin??1,description:e.description,aliases:e.aliases,char:e.char,hidden:e.hidden,exclusive:e.exclusive}}function getBooleanValue(e,t){let n=t!==!1;return/^(y|yes)/i.test(e)?n=!0:/^(n|no)/i.test(e)&&(n=!1),n}function boolToString(e){return e?`Yes`:`No`}const mr=ut((e,t)=>{let n=boolToString,[r,i]=ht(`idle`),[a,s]=ht(``),c=ft(),l=mt({status:r,theme:c});pt((r,c)=>{if(dt(r)){let r=getBooleanValue(a,e.default);s(n(r)),i(`done`),t(r)}else if(r.name===`tab`){let t=boolToString(!getBooleanValue(a,e.default));c.clearLine(0),c.write(t),s(t)}else if(r.name===`y`||r.name===`n`){let a=getBooleanValue(r.name,e.default);s(n(a)),i(`done`),t(a)}else c.clearLine(0),c.write(a),s(c.line)});let u=a,f=``;return r===`done`?u=c.style.answer(a):f=` ${c.style.defaultAnswer(e.default===!1?`y/N`:`Y/n`)}`,`${l} ${c.style.message(e.message,r)}${f} ${u}`}),X=stdinCheckWrapper(async({message:e,default:t})=>await mr({message:e,default:t},In)),getDeprecatedLocalConfigPath=e=>u(e,`apify.json`),hr=/* @__PURE__ */ new Map;async function useActorConfig({cwd:t=e.cwd(),migrateConfig:n=!0,warnAboutOldConfig:r=!0}={cwd:e.cwd(),migrateConfig:!0,warnAboutOldConfig:!0}){let i=hr.get(t);if(i)return cliDebugPrint(`useActorConfig`,{cacheHit:!0,config:i}),ze(i);let a=getLocalConfigPath(t),s=getDeprecatedLocalConfigPath(t),c,l;try{c=getJsonFileContent(a)}catch(e){return Le({message:`Failed to read local config at path: '${a}':`,cause:e,exists:!1,config:{}})}try{l=getJsonFileContent(s)}catch(e){return Le({message:`Failed to read local config at path: '${s}':`,cause:e,exists:!1,config:{}})}if(c&&l&&r&&await handleBothConfigVersionsFound(s),!c&&!l)return hr.set(t,{exists:!1,migrated:!1,config:{}}),ze({exists:!1,migrated:!1,config:{}});let u=!1;if(!c&&l&&n){let e=await handleMigrationFlow(l,s,a);if(e.isErr())return Le(e.unwrapErr());c=e.unwrap(),u=!0}return hr.set(t,{exists:!0,migrated:u,config:c||l||{}}),cliDebugPrint(`useActorConfig`,{cacheHit:!1,config:hr.get(t)}),ze({exists:!0,migrated:u,config:c||l||{}})}async function handleBothConfigVersionsFound(e){if(!await X({message:`The new version of Apify CLI uses the ".actor/actor.json" instead of the "apify.json" file. Since we have found both files in your Actor directory, "apify.json" will be renamed to "apify.json.deprecated". Going forward, all commands will use ".actor/actor.json". You can read about the differences between the old and the new config at https://github.com/apify/apify-cli/blob/master/MIGRATIONS.md. Do you want to continue?`}))warning({message:`The "apify.json" file present in your Actor directory will be ignored, and the new ".actor/actor.json" file will be used instead. Please, either rename or remove the old file.`});else try{await je(e,`${e}.deprecated`),info({message:`The "apify.json" file has been renamed to "apify.json.deprecated". The deprecated file is no longer used by the CLI or Apify Console. If you do not need it for some specific purpose, it can be safely deleted.`})}catch(e){e instanceof Error?error({message:`Failed to rename the deprecated "apify.json" file to "apify.json.deprecated".\n ${e.message||e}`}):error({message:`Failed to rename the deprecated "apify.json" file to "apify.json.deprecated".\n ${h(e,{showHidden:!1})}`})}}const gr=[`name`,`version`,`buildTag`];async function handleMigrationFlow(e,t,n){let r={...e};if(typeof r.version==`object`&&(r=updateLocalConfigStructure(r)),r={actorSpecification:1,environmentVariables:e?.env||void 0,...gr.reduce((t,n)=>(t[n]=e[n],t),{})},!await X({message:`The new version of Apify CLI uses the ".actor/actor.json" instead of the "apify.json" file. Your "apify.json" file will be automatically updated to the new format under ".actor/actor.json". The original file will be renamed by adding the ".deprecated" suffix. Do you want to continue?`}))return Le({message:`Command can not run with old "apify.json" structure. Either let the CLI auto-update it or follow the guide on https://github.com/apify/apify-cli/blob/master/MIGRATIONS.md and update it manually.`,exists:!0,config:r});try{await H(c(n),{recursive:!0}),await G(n,JSON.stringify(r,null,` `))}catch(e){let t=e;return Le({message:`Failed to write the new "actor.json" file to path: '${n}'.\n ${t.message||t}`,exists:!0,config:r})}try{await je(t,`${t}.deprecated`)}catch(e){let t=e;warning({message:`Failed to rename the deprecated "apify.json" file to "apify.json.deprecated".\n ${t.message||t}`})}return info({message:`The "apify.json" file has been migrated to ".actor/actor.json" and the original file renamed to "apify.json.deprecated". The deprecated file is no longer used by the CLI or Apify Console. If you do not need it for some specific purpose, it can be safely deleted. Do not forget to commit the new file to your Git repository.`}),ze(r)}function updateLocalConfigStructure(e){let t={name:e.name,template:e.template,version:e.version.versionNumber,buildTag:e.version.buildTag,env:null};if(e.version.envVars?.length){let n={};e.version.envVars.forEach(e=>{e.name&&e.value&&(n[e.name]=e.value)}),t.env=n}return t}const _r=u(getLocalKeyValueStorePath(`default`),`INPUT.json`);var ActorCalculateMemoryCommand=class extends ApifyCommand{static name=`calculate-memory`;static description=`Calculates the Actor’s dynamic memory usage based on a memory expression from actor.json, input data, and run options.`;static group=`Actor Runtime`;static examples=[{description:`Calculate memory using the expression and input defaults from actor.json.`,command:`actor calculate-memory`},{description:`Override the memory expression and input file.`,command:`actor calculate-memory --defaultMemoryMbytes "input.length * 128" --input ./my-input.json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#actor-calculate-memory`;static flags={input:Y.string({description:`Path to the input JSON file used for the calculation.`,required:!1,default:_r}),defaultMemoryMbytes:Y.string({description:`Memory-calculation expression (in MB). If omitted, the value is loaded from the actor.json file.`,required:!1}),build:Y.string({description:`Actor build version or build tag to evaluate the expression with.`,required:!1}),timeoutSecs:Y.integer({description:`Maximum run timeout, in seconds.`,required:!1}),maxItems:Y.integer({description:`Maximum number of items Actor can output.`,required:!1}),maxTotalChargeUsd:Y.integer({description:`Maximum total charge in USD.`,required:!1})};async run(){let{input:t,memoryExpression:n,minMemory:r,maxMemory:i,runOptions:a}=await this.prepareMemoryArguments();if(!n)throw Error(`No memory-calculation expression found. Provide it via the --default-memory-mbytes flag or define defaultMemoryMbytes in actor.json.`);let s=p(e.cwd(),t),c=getJsonFileContent(s)??{};info({message:`Evaluating memory expression: ${n}`});try{let e=await ct(n,{input:c,runOptions:a});success({message:`Calculated memory: ${Math.min(Math.max(e,r),i)} MB`,stdout:!0})}catch(e){error({message:`Memory calculation failed: ${e.message}`})}}async prepareMemoryArguments(){let{input:e,defaultMemoryMbytes:t,...n}=this.flags,r=t,i=0,a=1/0;return r||({defaultMemoryMbytes:r,minMemoryMbytes:i=i,maxMemoryMbytes:a=a}=await this.getExpressionFromConfig()),{memoryExpression:r,minMemory:i,maxMemory:a,input:e,runOptions:n}}async getExpressionFromConfig(){let t=await useActorConfig({cwd:e.cwd()});if(t.isErr()){let{message:n,cause:r}=t.unwrapErr();return error({message:`${n}${r?`\n ${r.message}`:``}`}),e.exitCode=5,{}}let{config:n}=t.unwrap();return{defaultMemoryMbytes:n?.defaultMemoryMbytes?.toString(),minMemoryMbytes:n?.minMemoryMbytes,maxMemoryMbytes:n?.maxMemoryMbytes}}};function stringArg(e){return{argTag:`string`,required:e.required??!1,stdin:e.stdin??1,description:e.description,aliases:e.aliases,catchAll:e.catchAll??!1}}const Z={string:stringArg};var ActorChargeCommand=class extends ApifyCommand{static name=`charge`;static description=`Charge for a specific event in a pay-per-event Actor run.`;static group=`Actor Runtime`;static examples=[{description:`Charge one event of the given type.`,command:`actor charge result-item`},{description:`Charge 5 events with an idempotency key.`,command:`actor charge result-item --count 5 --idempotency-key req-123`},{description:`Test locally without actually charging.`,command:`actor charge result-item --test-pay-per-event`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#actor-charge`;static args={eventName:Z.string({description:`Name of the event to charge for.`,required:!0})};static flags={count:Y.integer({description:`Number of events to charge.`,required:!1,default:1}),"idempotency-key":Y.string({description:`Idempotency key for the charge request.`,required:!1}),"test-pay-per-event":Y.boolean({description:`Test pay-per-event charging without actually charging.`,required:!1,default:!1})};async run(){let{eventName:e}=this.args,{count:t,testPayPerEvent:n,idempotencyKey:r}=this.flags;if(!process.env.APIFY_IS_AT_HOME){info({message:`No platform detected: would charge ${t} events of type "${e}" with idempotency key "${r??`not-provided`}".`,stdout:!0});return}if(n){info({message:`PPE test mode: would charge ${t} events of type "${e}" with idempotency key "${r??`not-provided`}".`,stdout:!0});return}let i=await getLoggedClientOrThrow(),a=process.env[B.ACTOR_RUN_ID];if(!a)throw Error(`Charge command must be executed in a running Actor. Run ID not found.`);if((await i.run(a).get())?.pricingInfo?.pricingModel!==`PAY_PER_EVENT`)throw Error(`Charge command can only be used with pay-per-event pricing model.`);info({message:`Charging ${t} events of type "${e}" with idempotency key "${r??`not-provided`}" (runId: ${a}).`,stdout:!0}),await i.run(a).charge({eventName:e,count:t,idempotencyKey:r})}};const vr=[`.actor/INPUT_SCHEMA.json`,`./INPUT_SCHEMA.json`,`.actor/input_schema.json`,`./input_schema.json`],readInputSchema=async({forcePath:e,cwd:t,throwOnMissing:n=!1})=>{if(e)return{inputSchema:getJsonFileContent(e),inputSchemaPath:e};let r=getLocalConfig(t);if(typeof r?.input==`object`&&r.input!==null)return{inputSchema:r.input,inputSchemaPath:null};if(typeof r?.input==`string`){let e=u(t,sn,r.input),i=getJsonFileContent(e);if(!i){if(n)throw Error(`Input schema file not found at ${e} (referenced in '${K}').`);return warning({message:`Input schema file not found at ${e} (referenced in '${K}').`}),{inputSchema:null,inputSchemaPath:e}}return{inputSchema:i,inputSchemaPath:e}}for(let e of vr){let n=u(t,e);if(O(n))return{inputSchema:getJsonFileContent(n),inputSchemaPath:n}}return{inputSchema:null,inputSchemaPath:u(t,vr[0])}},readAndValidateInputSchema=async({forcePath:e,cwd:t,getMessage:n})=>{let{inputSchema:r,inputSchemaPath:i}=await readInputSchema({forcePath:e,cwd:t});if(!r)throw Error(`Input schema has not been found at ${i}.`);info({message:n(i)});let a=new Xn({strict:!1});return _t(a,r),{inputSchema:r,inputSchemaPath:i}},readStorageSchema=({cwd:e,key:t,label:n,getRef:r,throwOnMissing:i=!1})=>{let a=getLocalConfig(e),s=r?r(a):a?.storages?.[t];if(typeof s==`object`&&s)return{schema:s,schemaPath:null};if(typeof s==`string`){let t=u(e,sn,s),r=getJsonFileContent(t);if(!r){if(i)throw Error(`${n} schema file not found at ${t} (referenced in '${K}').`);return warning({message:`${n} schema file not found at ${t} (referenced in '${K}').`}),null}return{schema:r,schemaPath:t}}return null},readDatasetSchema=({cwd:e})=>{let t=readStorageSchema({cwd:e,key:`dataset`,label:`Dataset`});return t?{datasetSchema:t.schema,datasetSchemaPath:t.schemaPath}:null},readOutputSchema=({cwd:e})=>{let t=readStorageSchema({cwd:e,key:`output`,label:`Output`,getRef:e=>e?.output});return t?{outputSchema:t.schema,outputSchemaPath:t.schemaPath}:null},createPrefilledInputFileFromInputSchema=async e=>{let t={};try{let{inputSchema:n}=await readInputSchema({cwd:e});if(n){let e=new Xn({strict:!1});_t(e,n),t=Object.entries(n.properties).reduce((e,[t,n])=>(e[t]=n.type===`boolean`||n.editor===`hidden`?n.default:n.prefill,e),{})}}catch(e){warning({message:`Could not create default input based on input schema, creating empty input instead. Cause: ${e.message}`})}finally{await writeKvsRecord({storePath:u(e,getLocalKeyValueStorePath()),key:me.INPUT,fileName:`${me.INPUT}.json`,contentType:`application/json; charset=utf-8`,body:JSON.stringify(t,null,` `)})}},getDefaultsFromInputSchema=e=>{let t={};for(let[n,r]of Object.entries(e.properties))r.default!==void 0&&(t[n]=r.default);return t};function formatSchemaValidationErrors(e,t){return`${t} schema is not valid:\n${e.map(e=>{let t=e.instancePath?` at ${e.instancePath}`:``;return` - ${e.message}${t}`}).join(`
58
58
  `)}`}function validateDatasetSchema(e){let t=yt();if(!t(e))throw Error(formatSchemaValidationErrors(t.errors,`Dataset`))}function validateOutputSchema(e){let t=xt();if(!t(e))throw Error(formatSchemaValidationErrors(t.errors,`Output`))}function validateKvsSchema(e){let t=bt();if(!t(e))throw Error(formatSchemaValidationErrors(t.errors,`Key-Value Store`))}const getAjvValidator=(e,t)=>{let n=structuredClone(e);n.required=[];for(let[t,r]of Object.entries(e.properties)){let i=e.required?.includes(t),a=r.default!==void 0;i&&!a&&(n.required.push(t),r.type===`array`&&(r.minItems=Math.max(1,r.minItems||0)))}return delete n.$schema,t.compile(n)};function makePropertiesRequired(e){let t=structuredClone(e);if(!t.properties||typeof t.properties!=`object`)return t;let n=t.properties,r=new Set(Array.isArray(t.required)?t.required:[]);for(let[e,t]of Object.entries(n))t.default!==void 0&&r.add(e),t.type===`object`&&t.properties&&(n[e]=makePropertiesRequired(t));return t.required=Array.from(r),t}function clearAllRequired(e){let t=structuredClone(e);if(delete t.required,t.properties&&typeof t.properties==`object`){let e=t.properties;for(let[t,n]of Object.entries(e))n.type===`object`&&n.properties&&(e[t]=clearAllRequired(n))}return t}function stripTitles(e){let t=structuredClone(e);if(delete t.title,t.properties&&typeof t.properties==`object`){let e=t.properties;for(let[t,n]of Object.entries(e))n&&typeof n==`object`&&(e[t]=stripTitles(n))}t.items&&typeof t.items==`object`&&(t.items=stripTitles(t.items));for(let e of[`allOf`,`anyOf`,`oneOf`])Array.isArray(t[e])&&(t[e]=t[e].map(e=>e&&typeof e==`object`?stripTitles(e):e));for(let e of[`definitions`,`$defs`])if(t[e]&&typeof t[e]==`object`&&!Array.isArray(t[e])){let n=t[e];for(let[e,t]of Object.entries(n))t&&typeof t==`object`&&(n[e]=stripTitles(t))}t.additionalProperties&&typeof t.additionalProperties==`object`&&(t.additionalProperties=stripTitles(t.additionalProperties));for(let e of[`if`,`then`,`else`,`not`])t[e]&&typeof t[e]==`object`&&(t[e]=stripTitles(t[e]));if(t.patternProperties&&typeof t.patternProperties==`object`&&!Array.isArray(t.patternProperties)){let e=t.patternProperties;for(let[t,n]of Object.entries(e))n&&typeof n==`object`&&(e[t]=stripTitles(n))}return t}function prepareFieldsSchemaForCompilation(e){let t=e.fields;if(!t||typeof t!=`object`||!t.properties||typeof t.properties!=`object`)return null;let n=structuredClone(t);return n.type||=`object`,n}function prepareOutputSchemaForCompilation(e){let t=e.properties;if(!t||typeof t!=`object`||Object.keys(t).length===0)return null;let n=structuredClone(t);for(let e of Object.values(n))e&&typeof e==`object`&&delete e.template;let r={type:e.type||`object`,properties:n};return Array.isArray(e.required)&&(r.required=[...e.required]),r}function prepareKvsCollectionsForCompilation(e){let t=e.collections;if(!t||typeof t!=`object`)return[];let n=[];for(let[e,r]of Object.entries(t)){if(!r||typeof r!=`object`)continue;let t=r.jsonSchema;if(!t||typeof t!=`object`||Object.keys(t).length===0)continue;let i=structuredClone(t);i.type||=`object`,n.push({name:e,schema:i})}return n}var ActorGenerateSchemaTypesCommand=class extends ApifyCommand{static name=`generate-schema-types`;static hiddenAliases=[`generate-types`];static description=`Generate TypeScript types from Actor schemas.
59
59
 
60
60
  Generates types from the input schema and, when no custom path is provided,
@@ -87,10 +87,10 @@ just as if the command were run from that directory with no argument.`;static gr
87
87
 
88
88
  For platform-level management (deploy, list, call Actors), see 'apify actors' (plural).`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actor`;static subcommands=[ActorSetValueCommand,ActorPushDataCommand,ActorGetValueCommand,ActorGetPublicUrlCommand,ActorGetInputCommand,ActorChargeCommand,ActorCalculateMemoryCommand,ActorGenerateSchemaTypesCommand];async run(){this.printHelp()}};function OverrideClassName(e){return e}function getConsoleUrl(){let t=e.env.APIFY_CONSOLE_URL;if(t){let e=stripTrailingSlash(t);if(!URL.canParse(e))throw Error(`Invalid APIFY_CONSOLE_URL environment variable: "${t}" is not a valid URL.`);return e}return`https://console.apify.com`}function getConsoleRoutePrefix(e){return e?.organizationOwnerUserId&&e.id?`/organization/${e.id}`:null}function getConsoleIntegrationsUrl(e){return`${getConsoleUrl()}${getConsoleRoutePrefix(e)??``}/settings/integrations`}function stripTrailingSlash(e){return e.replace(/\/+$/,``)}function isTerminalStatus(e){return!!e&&de.includes(e)}function exitCodeForJobStatus(e,t){switch(e){case R.SUCCEEDED:return 0;case R.TIMED_OUT:case R.TIMING_OUT:return z.BUILD,2;case R.ABORTED:case R.ABORTING:return z.BUILD,3;default:return z.BUILD,1}}function exitCodeForWaitResult(e,t){return e.timedOutWaiting?6:exitCodeForJobStatus(e.job.status,t)}async function waitForTerminalStatus(e){let{apifyClient:t,jobId:n,kind:r,pollIntervalMillis:i=2e3,maxWaitMillis:a}=e,s=Date.now();for(;;){let e=r===z.BUILD?await t.build(n).get():await t.run(n).get();if(!e)throw Error(`${r===z.BUILD?`Build`:`Run`} with ID "${n}" was not found.`);if(isTerminalStatus(e.status))return{job:e,timedOutWaiting:!1};if(a&&Date.now()-s>=a)return{job:e,timedOutWaiting:!0};let c=a?Math.min(i,a-(Date.now()-s)):i;await new Promise(e=>setTimeout(e,Math.max(0,c)))}}async function fetchLogTail(e,t,n=20){try{let r=await e.log(t).get();return r?r.split(`
89
89
  `).map(e=>e.trimEnd()).filter(e=>e.length>0).slice(-n):[]}catch{return[]}}function consoleActorUrl(e){return`${getConsoleUrl()}/actors/${e}`}function consoleRunUrl(e,t){return`${getConsoleUrl()}/actors/${e}/runs/${t}`}function consoleBuildUrl(e,t){return`${getConsoleUrl()}/actors/${e}/builds/${t}`}function consoleDatasetUrl(e){return`${getConsoleUrl()}/storage/datasets/${e}`}function consoleKeyValueStoreUrl(e){return`${getConsoleUrl()}/storage/key-value-stores/${e}`}function statusColor(e){return e===R.SUCCEEDED?t.green(e):e===R.RUNNING||e===R.READY?t.blue(e):t.red(e)}function formatResultSummary(e){let n=[];n.push(`${t.bold(e.resultLabel)}: ${statusColor(e.overallStatus)}`),n.push(``);for(let t of e.lines)n.push(`${t.label}: ${t.value}`);if(e.links?.length){n.push(``);for(let r of e.links)n.push(`${r.label}: ${t.blue(r.url)}`)}if(e.errorReason?.length){n.push(``),n.push(t.red(`Reason:`));for(let t of e.errorReason)n.push(t)}return n.join(`
90
- `)}async function resolveActorContext({providedActorNameOrId:t,client:n}){let r=await getCurrentUserInfo(),i=r.username||r.id,a=getLocalConfig(e.cwd())||{};if(t?.includes(`/`)){let e=await n.actor(t).get();return e?{valid:!0,userFriendlyId:`${e.username}/${e.name}`,id:e.id}:{valid:!1,reason:`Actor with ID "${t}" was not found`}}if(t){let e=await n.actor(t).get();if(e)return{valid:!0,userFriendlyId:`${e.username}/${e.name}`,id:e.id};let r=await n.actor(`${i}/${t.toLowerCase()}`).get();return r?{valid:!0,userFriendlyId:`${r.username}/${r.name}`,id:r.id}:{valid:!1,reason:`Actor with name or ID "${t}" was not found`}}if(a.name){let e=await n.actor(`${i}/${a.name}`).get();return e?{valid:!0,userFriendlyId:`${e.username}/${e.name}`,id:e.id}:{valid:!1,reason:`Actor with name "${a.name}" was not found`}}return{valid:!1,reason:`Unable to detect what Actor to create a build for`}}function useSignalHandler({signals:e,handler:t,cleanTerminalLine:n=!0,once:r=!0}){let i=!1,wrapped=a=>{if(!i){if(r){i=!0;for(let t of e)process.off(t,wrapped)}n&&process.stderr.isTTY&&process.stderr.write(`\r\x1B[2K\x1B[0m`),cliDebugPrint(`useSignalHandler`,{event:`fired`,signal:a,once:r}),(async()=>{try{await t(a)}catch(e){cliDebugPrint(`useSignalHandler`,{event:`handler-threw`,signal:a,err:e})}})()}};for(let t of e)process.on(t,wrapped);return cliDebugPrint(`useSignalHandler`,{event:`registered`,signals:e,once:r}),{[Symbol.dispose](){if(!i){i=!0;for(let t of e)process.off(t,wrapped);cliDebugPrint(`useSignalHandler`,{event:`disposed`,signals:e})}}}}function useAbortJobOnSignal(e){let{apifyClient:n,silent:r=!1}=e,i=0;return useSignalHandler({signals:on,once:!1,handler:async a=>{if(i+=1,e.kind===z.BUILD){if(i>1)return;r||info({message:t.gray(`Received ${t.yellow(a)}, aborting build "${t.yellow(e.jobId)}" on the Apify platform...`),stdout:!0});try{await n.build(e.jobId).abort()}catch(t){error({message:`Failed to abort build "${e.jobId}": ${t.message}`,stdout:!0})}return}if(i>2)return;let s=i===1,c=`${e.runType.toLowerCase()} run`;if(!r){let n=s?`Received ${t.yellow(a)}, gracefully aborting ${c} "${t.yellow(e.jobId)}" on the Apify platform... ${t.dim(`(press Ctrl+C again to abort immediately)`)}`:`Received ${t.yellow(a)} again, aborting ${c} "${t.yellow(e.jobId)}" immediately...`;info({message:t.gray(n),stdout:!0})}try{await n.run(e.jobId).abort({gracefully:s})}catch(t){error({message:`Failed to abort run "${e.jobId}": ${t.message}`,stdout:!0})}}})}function _usingCtx(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function using(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function o(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:using.bind(null,!1),a:using.bind(null,!0),d:function d(){var r,i=this.e,a=0;function next(){for(;r=n.pop();)try{if(!r.a&&a===1)return a=0,n.push(r),Promise.resolve().then(next);if(r.d){var e=r.d.call(r.v);if(r.a)return a|=2,Promise.resolve(e).then(next,err)}else a|=1}catch(e){return err(e)}if(a===1)return i===t?Promise.resolve():Promise.reject(i);if(i!==t)throw i}function err(n){return i=i===t?n:new e(n,i),next()}return next()}}}var BuildsCreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates a new build of the Actor.`;static examples=[{description:`Build the Actor in the current directory with the default "latest" tag.`,command:`apify builds create`},{description:`Build a specific Actor with a custom tag and stream the build log.`,command:`apify builds create apify/hello-world --tag beta --log`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-create`;static flags={tag:Y.string({description:`Build tag to be applied to the successful Actor build. By default, this is "latest".`}),version:Y.string({description:`Optional Actor Version to build. By default, this will be inferred from the tag, but this flag is required when multiple versions have the same tag.`,required:!1}),log:Y.boolean({description:`Whether to print out the build log after the build is triggered.`}),wait:Y.boolean({description:`Wait for the build to reach a terminal status. Returns exit code 0 only when the build SUCCEEDED.`,default:!1})};static args={actorId:Z.string({description:`Optional Actor ID or Name to trigger a build for. By default, it will use the Actor from the current directory.`})};static enableJsonFlag=!0;async run(){let{tag:n,version:r,json:i,log:a,wait:s}=this.flags,{actorId:c}=this.args;if(a&&s){error({message:`The --log and --wait flags cannot be used together. --log already waits for the build to finish while streaming its log.`}),e.exitCode=5;return}let l=await getLoggedClientOrThrow(),u=await resolveActorContext({providedActorNameOrId:c,client:l});if(!u.valid){error({message:`${u.reason}. Please run this command in an Actor directory, or specify the Actor ID.`,stdout:!0});return}let f=await l.actor(u.id).get(),p=objectGroupBy(f.versions,e=>e.buildTag??`latest`)[n??`latest`],m=f.versions.find(e=>e.versionNumber===r),h;if(m){if(n&&(!p||!p.some(e=>e.versionNumber===r))){error({message:`The Actor Version "${r}" does not have the tag "${n}".`,stdout:!0});return}h=r}else if(p&&(h=p[0].versionNumber,p.length>1&&!r)){error({message:`Multiple Actor versions with the tag "${n}" found. Please specify the version number using the "--version" flag.\n Available versions for this tag: ${p.map(e=>t.yellow(e.versionNumber)).join(`, `)}`,stdout:!0});return}if(!h){error({message:`No Actor versions with the tag "${n}" found. You can push a new version with this tag by using "apify push --build-tag=${n}".`,stdout:!0});return}let g=await l.actor(u.id).build(h,{tag:n}),_=f?.name??`unknown-actor`,v=consoleBuildUrl(g.actId,g.buildNumber);if(a||s)try{var y=_usingCtx();if(y.u(useAbortJobOnSignal({apifyClient:l,kind:z.BUILD,jobId:g.id})),a)try{await outputJobLog({job:g,apifyClient:l})}catch(e){error({message:`Failed to print log for build with ID "${g.id}": ${e.message}`,stdout:!0})}let{job:e}=await waitForTerminalStatus({apifyClient:l,jobId:g.id,kind:z.BUILD});g=e}catch(e){y.e=e}finally{y.d()}if(a||s){let t=g.status===R.SUCCEEDED,n=exitCodeForJobStatus(g.status,z.BUILD),r=t?[]:await fetchLogTail(l,g.id);if(i){printJsonToStdout({ok:t,operation:`builds.create`,waited:!0,actor:{id:g.actId,name:_},build:{id:g.id,number:g.buildNumber,status:g.status,url:v},...t?{}:{error:{phase:`build`,message:`Actor build did not succeed`,logTail:r}},exitCode:n}),e.exitCode=n;return}simpleLog({message:formatResultSummary({resultLabel:`Apify build result`,overallStatus:g.status,lines:[{label:`Build`,value:g.status},{label:`Build ID`,value:g.id},{label:`Build number`,value:g.buildNumber},{label:`Actor ID`,value:g.actId}],links:[{label:`Build URL`,url:v}],errorReason:t?void 0:r}),stdout:!0}),e.exitCode=n;return}if(i){printJsonToStdout({ok:!0,operation:`builds.create`,waited:!1,actor:{id:g.actId,name:_},build:{id:g.id,number:g.buildNumber,status:g.status,url:v},next:{wait:`apify builds wait ${g.id} --json`,log:`apify builds log ${g.id}`,info:`apify builds info ${g.id} --json`},exitCode:0});return}simpleLog({message:[t.greenBright(`Build started.`),``,`${t.yellow(`Actor`)}: ${_} (${t.gray(g.actId)})`,`${t.yellow(`Build ID`)}: ${g.id}`,`${t.yellow(`Build number`)}: ${g.buildNumber}`,`${t.yellow(`Status`)}: ${g.status}`,``,t.gray(`This command does not wait for the build to finish.`),``,`To wait for the final status:`,` apify builds wait ${g.id} --json`,``,`To inspect logs:`,` apify builds log ${g.id}`,``,`To inspect build metadata:`,` apify builds info ${g.id} --json`].join(`
90
+ `)}async function resolveActorContext({providedActorNameOrId:t,client:n}){let r=await getCurrentUserInfo(),i=r.username||r.id,a=getLocalConfig(e.cwd())||{};if(t?.includes(`/`)){let e=await n.actor(t).get();return e?{valid:!0,userFriendlyId:`${e.username}/${e.name}`,id:e.id}:{valid:!1,reason:`Actor with ID "${t}" was not found`}}if(t){let e=await n.actor(t).get();if(e)return{valid:!0,userFriendlyId:`${e.username}/${e.name}`,id:e.id};let r=await n.actor(`${i}/${t.toLowerCase()}`).get();return r?{valid:!0,userFriendlyId:`${r.username}/${r.name}`,id:r.id}:{valid:!1,reason:`Actor with name or ID "${t}" was not found`}}if(a.name){let e=await n.actor(`${i}/${a.name}`).get();return e?{valid:!0,userFriendlyId:`${e.username}/${e.name}`,id:e.id}:{valid:!1,reason:`Actor with name "${a.name}" was not found`}}return{valid:!1,reason:`Unable to detect what Actor to create a build for`}}function useSignalHandler({signals:e,handler:t,cleanTerminalLine:n=!0,once:r=!0}){let i=!1,wrapped=a=>{if(!i){if(r){i=!0;for(let t of e)process.off(t,wrapped)}n&&process.stderr.isTTY&&process.stderr.write(`\r\x1B[2K\x1B[0m`),cliDebugPrint(`useSignalHandler`,{event:`fired`,signal:a,once:r}),(async()=>{try{await t(a)}catch(e){cliDebugPrint(`useSignalHandler`,{event:`handler-threw`,signal:a,err:e})}})()}};for(let t of e)process.on(t,wrapped);return cliDebugPrint(`useSignalHandler`,{event:`registered`,signals:e,once:r}),{[Symbol.dispose](){if(!i){i=!0;for(let t of e)process.off(t,wrapped);cliDebugPrint(`useSignalHandler`,{event:`disposed`,signals:e})}}}}function useAbortJobOnSignal(e){let{apifyClient:n,silent:r=!1}=e,i=0;return useSignalHandler({signals:on,once:!1,handler:async a=>{if(i+=1,e.kind===z.BUILD){if(i>1)return;r||info({message:t.gray(`Received ${t.yellow(a)}, aborting build "${t.yellow(e.jobId)}" on the Apify platform...`),stdout:!0});try{await n.build(e.jobId).abort()}catch(t){error({message:`Failed to abort build "${e.jobId}": ${t.message}`,stdout:!0})}return}if(i>2)return;let s=i===1,c=`${e.runType.toLowerCase()} run`;if(!r){let n=s?`Received ${t.yellow(a)}, gracefully aborting ${c} "${t.yellow(e.jobId)}" on the Apify platform... ${t.dim(`(press Ctrl+C again to abort immediately)`)}`:`Received ${t.yellow(a)} again, aborting ${c} "${t.yellow(e.jobId)}" immediately...`;info({message:t.gray(n),stdout:!0})}try{await n.run(e.jobId).abort({gracefully:s})}catch(t){error({message:`Failed to abort run "${e.jobId}": ${t.message}`,stdout:!0})}}})}function _usingCtx(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function using(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function o(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:using.bind(null,!1),a:using.bind(null,!0),d:function d(){var r,i=this.e,a=0;function next(){for(;r=n.pop();)try{if(!r.a&&a===1)return a=0,n.push(r),Promise.resolve().then(next);if(r.d){var e=r.d.call(r.v);if(r.a)return a|=2,Promise.resolve(e).then(next,err)}else a|=1}catch(e){return err(e)}if(a===1)return i===t?Promise.resolve():Promise.reject(i);if(i!==t)throw i}function err(n){return i=i===t?n:new e(n,i),next()}return next()}}}var BuildsCreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates a new build of the Actor.`;static examples=[{description:`Build the Actor in the current directory with the default "latest" tag.`,command:`apify builds create`},{description:`Build a specific Actor with a custom tag and stream the build log.`,command:`apify builds create apify/hello-world --tag beta --log`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-create`;static flags={tag:Y.string({description:`Build tag to be applied to the successful Actor build. By default, this is "latest".`}),version:Y.string({description:`Optional Actor Version to build. By default, this will be inferred from the tag, but this flag is required when multiple versions have the same tag.`,required:!1}),log:Y.boolean({description:`Whether to print out the build log after the build is triggered.`}),wait:Y.boolean({description:`Wait for the build to reach a terminal status. Returns exit code 0 only when the build SUCCEEDED.`,default:!1})};static args={actorId:Z.string({description:`Optional Actor ID or Name to trigger a build for. By default, it will use the Actor from the current directory.`})};static enableJsonFlag=!0;async run(){let{tag:n,version:r,json:i,log:a,wait:s}=this.flags,{actorId:c}=this.args;if(a&&s){error({message:`The --log and --wait flags cannot be used together. --log already waits for the build to finish while streaming its log.`}),e.exitCode=5;return}let l=await getLoggedClientOrThrow(),u=await resolveActorContext({providedActorNameOrId:c,client:l});if(!u.valid){error({message:`${u.reason}. Please run this command in an Actor directory, or specify the Actor ID.`,stdout:!0});return}let f=await l.actor(u.id).get(),p=objectGroupBy(f.versions,e=>e.buildTag??`latest`)[n??`latest`],m=f.versions.find(e=>e.versionNumber===r),h;if(m){if(n&&(!p||!p.some(e=>e.versionNumber===r))){error({message:`The Actor Version "${r}" does not have the tag "${n}".`,stdout:!0});return}h=r}else if(p&&(h=p[0].versionNumber,p.length>1&&!r)){error({message:`Multiple Actor versions with the tag "${n}" found. Please specify the version number using the "--version" flag.\n Available versions for this tag: ${p.map(e=>t.yellow(e.versionNumber)).join(`, `)}`,stdout:!0});return}if(!h){error({message:`No Actor versions with the tag "${n}" found. You can push a new version with this tag by using "apify push --build-tag=${n}".`,stdout:!0});return}let g=await l.actor(u.id).build(h,{tag:n}),_=f?.name??`unknown-actor`,v=consoleBuildUrl(g.actId,g.buildNumber);if(a||s)try{var y=_usingCtx();if(y.u(useAbortJobOnSignal({apifyClient:l,kind:z.BUILD,jobId:g.id})),a)try{await outputJobLog({job:g,apifyClient:l})}catch(e){error({message:`Failed to print log for build with ID "${g.id}": ${e.message}`,stdout:!0})}let{job:e}=await waitForTerminalStatus({apifyClient:l,jobId:g.id,kind:z.BUILD});g=e}catch(e){y.e=e}finally{y.d()}if(a||s){let t=g.status===R.SUCCEEDED,n=exitCodeForJobStatus(g.status,z.BUILD),r=t?[]:await fetchLogTail(l,g.id);if(i){printJsonToStdout({ok:t,operation:`builds.create`,waited:!0,actor:{id:g.actId,name:_},build:{id:g.id,number:g.buildNumber,status:g.status,url:v},...t?{}:{error:{phase:`build`,message:`Actor build did not succeed`,logTail:r}},exitCode:n}),e.exitCode=n;return}simpleLog({message:formatResultSummary({resultLabel:`Apify build result`,overallStatus:g.status,lines:[{label:`Build`,value:g.status},{label:`Build ID`,value:g.id},{label:`Build number`,value:g.buildNumber},{label:`Actor ID`,value:g.actId}],links:[{label:`Build URL`,url:v}],errorReason:t?void 0:r}),stdout:!0}),e.exitCode=n}else i?printJsonToStdout({ok:!0,operation:`builds.create`,waited:!1,actor:{id:g.actId,name:_},build:{id:g.id,number:g.buildNumber,status:g.status,url:v},next:{wait:`apify builds wait ${g.id} --json`,log:`apify builds log ${g.id}`,info:`apify builds info ${g.id} --json`},exitCode:0}):simpleLog({message:[t.greenBright(`Build started.`),``,`${t.yellow(`Actor`)}: ${_} (${t.gray(g.actId)})`,`${t.yellow(`Build ID`)}: ${g.id}`,`${t.yellow(`Build number`)}: ${g.buildNumber}`,`${t.yellow(`Status`)}: ${g.status}`,``,t.gray(`This command does not wait for the build to finish.`),``,`To wait for the final status:`,` apify builds wait ${g.id} --json`,``,`To inspect logs:`,` apify builds log ${g.id}`,``,`To inspect build metadata:`,` apify builds info ${g.id} --json`].join(`
91
91
  `),stdout:!0})}},ActorsBuildCommand=class extends OverrideClassName(BuildsCreateCommand){static name=`build`};function withSchemaHint(e,t){return t?`${e}\n${t}`:e}function resolveInput(e,t){let n,r;if(t)n=t,r=`application/json`;else{let t=getLocalInput(e);t&&(rt.getExtension(t.contentType)===`json`?(n=JSON.parse(t.body.toString(`utf8`)),r=`application/json`):(n=t.body,r=t.contentType))}return!n||!r?null:{inputToUse:n,contentType:r}}async function getInputOverride(t,n,r,i={}){let s,c,{schemaHint:l}=i;if(!n&&!r){let t=gn;if(t)try{let n=JSON.parse(t.toString(`utf8`));if(Array.isArray(n))return error({message:withSchemaHint(`The provided input is invalid. It should be an object, not an array.`,l)}),e.exitCode=5,!1;s=n,c=`stdin`}catch(t){return error({message:withSchemaHint(`Cannot parse JSON input from standard input.\n ${t.message}`,l)}),e.exitCode=5,!1}}if(n)switch(n[0]){case`-`:return error({message:"You need to pipe something into standard input when you specify the `-` value to `--input`."}),e.exitCode=5,!1;default:{let r=await Oe(p(t,n)).then(()=>!0).catch(()=>!1),i=n.endsWith(`.json`)||n.endsWith(`.json5`)||a.isAbsolute(n)||n.startsWith(`./`)||n.startsWith(`../`)||n.startsWith(`~`)||n.startsWith(`.\\`)||n.startsWith(`..\\`);if(r||i)return error({message:`Providing a JSON file path in the --input flag is not supported. Use the "--input-file=" flag instead`}),e.exitCode=5,!1;try{let t=JSON.parse(n);if(Array.isArray(t))return error({message:withSchemaHint(`The provided input is invalid. It should be an object, not an array.`,l)}),e.exitCode=5,!1;s=t,c=`input`}catch(t){return error({message:withSchemaHint(`Cannot parse JSON input.\n ${t.message}`,l)}),e.exitCode=5,!1}}}else if(r)switch(r[0]){case`-`:return error({message:"You need to pipe something into standard input when you specify the `-` value to `--input-file`."}),e.exitCode=5,!1;default:{let n=p(t,r),i;try{let t=await U(n,`utf8`),i=JSON.parse(t);if(Array.isArray(i))return error({message:withSchemaHint(`The provided input is invalid. It should be an object, not an array.`,l)}),e.exitCode=5,!1;s=i,c=r}catch(e){i=e}if(i)try{let t=JSON.parse(r);if(Array.isArray(t))return error({message:withSchemaHint(`The provided input is invalid. It should be an object, not an array.`,l)}),e.exitCode=5,!1;s=t,c=r}catch{return error({message:withSchemaHint(`Cannot read input file at path "${n}".\n ${i.message}`,i instanceof SyntaxError?l:void 0)}),e.exitCode=5,!1}}}return s?{input:s,source:c}:void 0}const br=[R.SUCCEEDED,R.ABORTED,R.FAILED,R.TIMED_OUT];async function*runActorOrTaskOnCloud(n,r){try{var i=_usingCtx();let a=e.cwd(),{actorOrTaskData:s,runOptions:c,type:l,waitForFinishMillis:u,inputOverride:f,silent:p,waitForRunToFinish:m,printRunLogs:h,suppressFinalStatus:g}=r,_=l===`Actor`?`actor`:`task`,v=resolveInput(a,f);p||(l===`Actor`?run({message:`Calling ${l} ${s.userFriendlyId} (${t.gray(s.id)})\n`}):s.title?run({message:`Calling ${l} ${s.title} (${s.userFriendlyId}, ${t.gray(s.id)})\n`}):run({message:`Calling ${l} ${s.userFriendlyId} (${t.gray(s.id)})\n`}));let y;try{y=v&&l===`Actor`?await n[_](s.id).start(v.inputToUse,{...c,contentType:v.contentType}):await n[_](s.id).start(void 0,c)}catch(e){if(e.type===`record-not-found`)throw Error(`${l} ${s.userFriendlyId} (${s.id}) not found!`);if(e.type===`full-permission-actor-not-approved`){let n=e.data?.approvalUrl,r=[`${l} ${s.userFriendlyId} requires full access to your Apify account and has not been approved yet.`];throw n&&r.push(``,`Approve here: ${t.blue(n)}`),Error(r.join(`
92
92
  `))}throw e}if(i.u(useAbortJobOnSignal({apifyClient:n,kind:z.RUN,jobId:y.id,runType:l,silent:p})),yield y,!p&&h)try{await outputJobLog({job:y,timeoutMillis:u,apifyClient:n})===`timeouts`?console.error(`\n${t.gray(`Timeout for printing logs was hit, there may be future logs.`)}\n`):console.error()}catch(e){warning({message:`Can not get log:`}),console.error(e)}if(y=await n.run(y.id).get(),m)for(;!br.includes(y.status)&&(y=await n.run(y.id).get(),!br.includes(y.status));)await new Promise(e=>{setTimeout(e,1e3)});g||(y.status===R.SUCCEEDED?p||success({message:`${l} finished.`}):y.status===R.RUNNING?p||warning({message:`${l} is still running!`}):y.status===R.ABORTED||y.status===R.ABORTING?(p||warning({message:`${l} was aborted!`}),e.exitCode=3):(p||error({message:`${l} failed!`}),e.exitCode=1)),yield y}catch(e){i.e=e}finally{i.d()}}const SharedRunOnCloudFlags=e=>({build:Y.string({char:`b`,description:`Tag or number of the build to run (e.g. "latest" or "1.2.34").`,required:!1}),timeout:Y.integer({char:`t`,description:`Timeout for the ${e} run in seconds. Zero value means there is no timeout.`,required:!1}),memory:Y.integer({char:`m`,description:`Amount of memory allocated for the ${e} run, in megabytes.`,required:!1})}),xr={call:`Apify call`,"task-run":`Apify task run`};function isSucceeded(e){return e.status===R.SUCCEEDED}function getRunExitCode(e){switch(e.status){case R.SUCCEEDED:return 0;case R.ABORTED:case R.ABORTING:return 3;case R.TIMED_OUT:case R.TIMING_OUT:return 2;default:return e.exitCode&&e.exitCode!==0?e.exitCode:1}}function genericReason(e){switch(e.status){case R.ABORTED:case R.ABORTING:return`Actor run was aborted`;case R.TIMED_OUT:case R.TIMING_OUT:return`Actor run timed out`;default:return`Actor run failed`}}async function fetchRunLogTail(e,t){return isSucceeded(t)?[]:fetchLogTail(e,t.id,10)}function buildRunResultJson({run:e,operation:t,logTail:n}){let r=isSucceeded(e),i={ok:r,operation:t,actor:{id:e.actId,url:consoleActorUrl(e.actId)},run:{id:e.id,status:e.status,url:consoleRunUrl(e.actId,e.id)},storage:{defaultDatasetId:e.defaultDatasetId,defaultKeyValueStoreId:e.defaultKeyValueStoreId,datasetUrl:consoleDatasetUrl(e.defaultDatasetId)},exitCode:getRunExitCode(e)};return r||(i.error={phase:`run`,message:e.statusMessage||genericReason(e),logTail:n}),i}function printRunResultSummary({run:e,operation:n,logTail:r}){let i=isSucceeded(e),a=i?t.green:t.red,s=[`${xr[n]} result: ${a(e.status)}`,``,`${t.yellow(`Run`)}: ${a(e.status)}`,`${t.yellow(`Actor ID`)}: ${e.actId}`,`${t.yellow(`Run ID`)}: ${e.id}`,`${t.yellow(`Build number`)}: ${e.buildNumber}`];!i&&e.exitCode!=null&&s.push(`${t.yellow(`Exit code`)}: ${e.exitCode}`),s.push(`${t.yellow(`Dataset ID`)}: ${e.defaultDatasetId}`,`${t.yellow(`Key-value store ID`)}: ${e.defaultKeyValueStoreId}`,``,`${t.blue(`Run URL`)}: ${consoleRunUrl(e.actId,e.id)}`,`${t.blue(`Dataset URL`)}: ${consoleDatasetUrl(e.defaultDatasetId)}`),i||s.push(``,`${t.yellow(`Reason`)}:`,e.statusMessage||genericReason(e),...r),simpleLog({message:s.join(`
93
- `),stdout:!0})}async function finalizeRun({apifyClient:t,run:n,operation:r,json:i,silent:a}){if(e.exitCode=getRunExitCode(n),a)return;let s=await fetchRunLogTail(t,n);if(i){printJsonToStdout(buildRunResultJson({run:n,operation:r,logTail:s}));return}printRunResultSummary({run:n,operation:r,logTail:s})}var Sr=class ActorsCallCommand extends ApifyCommand{static name=`call`;static enableProfileFlag=!0;static description=`Executes Actor remotely using your authenticated account.
93
+ `),stdout:!0})}async function finalizeRun({apifyClient:t,run:n,operation:r,json:i,silent:a}){if(e.exitCode=getRunExitCode(n),a)return;let s=await fetchRunLogTail(t,n);i?printJsonToStdout(buildRunResultJson({run:n,operation:r,logTail:s})):printRunResultSummary({run:n,operation:r,logTail:s})}var Sr=class ActorsCallCommand extends ApifyCommand{static name=`call`;static enableProfileFlag=!0;static description=`Executes Actor remotely using your authenticated account.
94
94
  Reads input from local key-value store by default.
95
95
  To inspect the input schema before creating a JSON input, use "apify actors info <actor> --input".`;static group=`Apify Console`;static examples=[{description:`Call the Actor defined in the current directory (from .actor/actor.json).`,command:`apify call`},{description:`Call a specific Actor by its full name.`,command:`apify call apify/hello-world`},{description:`Inspect the Actor input schema before preparing JSON input.`,command:`apify actors info apify/hello-world --input`},{description:`Call an Actor with inline JSON input.`,command:`apify call apify/hello-world --input '{"url":"https://example.com"}'`},{description:`Call an Actor with input from a file and print the dataset on success.`,command:`apify call apify/web-scraper --input-file input.json --output-dataset`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-call`;static flags={...SharedRunOnCloudFlags(`Actor`),input:Y.string({char:`i`,description:`Optional inline JSON object input for the Actor. To avoid shell parsing issues, wrap the JSON in quotes. For JSON files, use --input-file.`,required:!1,stdin:2,exclusive:[`input-file`]}),"input-file":Y.string({char:`f`,description:"Optional path to a file with JSON input to be given to the Actor. The file must be a valid JSON file. You can also specify `-` to read from standard input.",required:!1,stdin:2,exclusive:[`input`]}),silent:Y.boolean({char:`s`,description:`Prevents printing the logs of the Actor run to the console.`,default:!1}),"output-dataset":Y.boolean({char:`o`,description:`Prints out the entire default dataset on successful run of the Actor.`})};static enableJsonFlag=!0;static args={actorId:Z.string({required:!1,description:`Name or ID of the Actor to run (e.g. "my-actor", "apify/hello-world" or "E2jjCZBezvAZnX8Rb"). If not provided, the command runs the remote Actor specified in the '${K}' file.`})};async run(){let n=e.cwd(),r=getLocalConfig(n)||{},i=await getLoggedClientOrThrow(),a=await getCurrentUserInfo(),s=a.username||a.id;if(this.flags.json&&this.flags.outputDataset){error({message:`You cannot use both --json and --output-dataset. Use --json for run details or --output-dataset for dataset items.`}),e.exitCode=5;return}let{id:c,userFriendlyId:l,actorData:u}=await ActorsCallCommand.resolveActorId({client:i,localActorName:r.name,usernameOrId:s,providedActorNameOrId:this.args.actorId}),f={waitForFinish:2};this.flags.build&&(f.build=this.flags.build),this.flags.timeout!==void 0&&(f.timeout=this.flags.timeout),this.flags.memory&&(f.memory=this.flags.memory);let p=await getInputOverride(n,this.flags.input,this.flags.inputFile,{schemaHint:`Run "apify actors info ${l} --input" to inspect the Actor input schema.`});if(p===!1)return;let m=!1,h,g=runActorOrTaskOnCloud(i,{actorOrTaskData:{id:c,userFriendlyId:l},runOptions:f,type:`Actor`,inputOverride:p?.input,silent:this.flags.silent,waitForRunToFinish:!0,printRunLogs:!0,suppressFinalStatus:!0});for await(let e of g)if(h=e,!m&&(m=!0,!this.flags.silent)){let n=consoleRunUrl(c,e.id),r=[`${t.yellow(`Started`)}: ${q.display(e.startedAt)}`];e.containerUrl&&r.push(`${t.yellow(`Container URL`)}: ${t.blue(e.containerUrl)}`);let i=h.buildNumber.split(`.`).slice(0,2).join(`.`),a=u.versions.find(e=>e.versionNumber===i),s=Object.entries(u.taggedBuilds??{}).find(([,t])=>t.buildNumber===e.buildNumber)?.[0],l=[`${t.yellow(`Build`)}:`,t.cyan(h.buildNumber)];s?l.push(`(${t.yellow(s)})`):l.push(`(${t.gray(`N/A`)})`),a&&l.push(`| ${t.gray(`Actor version:`)} ${t.cyan(a.versionNumber)} (${t.yellow(a.buildTag)})`),r.push(l.join(` `)),r.push(`${t.yellow(`Timeout`)}: ${h.options.timeoutSecs.toLocaleString(`en-US`)} seconds`),r.push(`${t.yellow(`Memory`)}: ${h.options.memoryMbytes} MB`),r.push(`${t.blue(`View on Apify Console`)}: ${n}`,``),simpleLog({message:r.join(`
96
96
  `),stdout:!this.flags.json})}if(await finalizeRun({apifyClient:i,run:h,operation:`call`,json:this.flags.json,silent:this.flags.silent}),!this.flags.json&&this.flags.outputDataset&&h.status===R.SUCCEEDED){let e=h.defaultDatasetId,t,n=4;do{if(t=await i.dataset(e).get(),t?.itemCount)break;await new Promise(e=>{setTimeout(e,250)})}while(n--);let r=await i.dataset(e).downloadItems(V.JSON,{clean:!0});console.log(r.toString())}}static async resolveActorId({client:e,localActorName:t,usernameOrId:n,providedActorNameOrId:r}){if(r?.includes(`/`)){let t=await e.actor(r).get();if(!t)throw Error(`Cannot find Actor with ID '${r}' in your account.`);return{userFriendlyId:`${t.username}/${t.name}`,id:t.id,actorData:t}}if(r){let t=await e.actor(r).get();if(t)return{userFriendlyId:`${t.username}/${t.name}`,id:t.id,actorData:t};let i=await e.actor(`${n}/${r.toLowerCase()}`).get();if(i)return{userFriendlyId:`${i.username}/${i.name}`,id:i.id,actorData:i};throw Error(`Cannot find Actor with name or ID '${r}' in your account.`)}if(t){let r=await e.actor(`${n}/${t}`).get();if(!r)throw Error(`Cannot find Actor with ID '${n}/${t}' in your account. Call "apify push" to push this Actor to Apify platform.`);return{userFriendlyId:`${r.username}/${r.name}`,id:r.id,actorData:r}}throw Error(`Please provide an Actor ID or name, or run this command from a directory with a valid Apify Actor.`)}};const Cr={[-1]:void 0,0:{mid:``,"left-mid":``,"mid-mid":``,"right-mid":``,middle:` `,"top-mid":`─`,"bottom-mid":`─`},1:{middle:` `,"top-mid":`─`,"bottom-mid":`─`,top:`─`,bottom:`─`,"left-mid":`├`,mid:`─`,"mid-mid":`─`,"right-mid":`┤`},2:{left:``,right:``,mid:``,"bottom-left":``,"bottom-mid":``,"bottom-right":``,top:``,"top-left":``,"top-mid":``,"top-right":``,"left-mid":``,"mid-mid":``,"right-mid":``,bottom:``,middle:` `}};function generateHeaderColors(e){return Array.from({length:e},()=>`cyan`)}const wr=process.stdout.columns??100,Tr=Symbol.for(`@apify/cli:responsive-table:skip-column`);var Q=class ResponsiveTable{options;rows=[];constructor(e){this.options=e}pushRow(e){this.rows.push(e)}render(e){let t=ResponsiveTable.isSmallTerminal()?this.options.mandatoryColumns:this.options.allColumns,n=generateHeaderColors(t.length),r=e===0||e===2,i=Cr[e],a=[],s=[],c=[];for(let e of t)this.options.hiddenColumns?.includes(e)||this.rows.some(t=>t[e]===Tr)||(a.push(this.options.columnAlignments?.[e]||`left`),ResponsiveTable.isSmallTerminal()?(s.push(this.options.breakpointOverrides?.small?.[e]?.label??e),c.push(this.options.breakpointOverrides?.small?.[e]?.valueFrom??e)):(s.push(e),c.push(e)));let l=new wt({head:s,style:{head:n,compact:r},colAligns:a,chars:i});for(let e of this.rows){let t=c.map(t=>e[t]);l.push(t)}return l.toString()}static isSmallTerminal(){return wr<100}};function formatEventPrice(e){return e===0?`$0.00`:e>=.01?`$${e.toFixed(2)}`:`$${Number(e.toPrecision(2))}`}async function getDefaultBuild(e,t,n){try{return await(await e.actor(t).defaultBuild()).get()??n}catch(e){if(e.statusCode===404)return n;throw e}}const Er=`​​`,Dr=new Q({allColumns:[`​`,Er],mandatoryColumns:[`​`,Er],columnAlignments:{"​":`left`,[Er]:`right`}});var ActorsInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Get information about an Actor.`;static examples=[{description:`Print summary information about an Actor.`,command:`apify actors info apify/hello-world`},{description:`Print the Actor README only.`,command:`apify actors info apify/hello-world --readme`},{description:`Print the Actor input schema as JSON.`,command:`apify actors info apify/hello-world --input`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors-info`;static flags={readme:Y.boolean({description:`Return the Actor README.`,exclusive:[`input`]}),input:Y.boolean({description:`Return the Actor input schema.`,exclusive:[`readme`]})};static args={actorId:Z.string({description:`The ID of the Actor to return information about.`,required:!0})};static enableJsonFlag=!0;async run(){let{actorId:e}=this.args,{readme:n,input:r,json:i}=this.flags,a=await getLoggedClientOrThrow(),s=await resolveActorContext({providedActorNameOrId:e,client:a});if(!s.valid){error({message:`${s.reason}. Please specify the Actor ID.`,stdout:!0});return}let c=await a.actor(s.id).get();c.actorMaker=await a.user(c.userId).get();for(let e of Object.values(c.taggedBuilds??{}))e.buildId&&(e.build=await a.build(e.buildId).get());if(i){printJsonToStdout(c);return}if(n||r){let e=await getDefaultBuild(a,s.id,c.taggedBuilds?.latest?.build);if(n){if(!e?.readme){error({message:`No README found for this Actor.`,stdout:!0});return}simpleLog({message:e.readme,stdout:!0});return}if(!e?.inputSchema){error({message:`No input schema found for this Actor.`,stdout:!0});return}simpleLog({message:e.inputSchema,stdout:!0});return}let l=[`Information about Actor ${t.yellow(`${c.username}/${c.name}`)} (${t.gray(c.id)})`,``];c.title&&l.push(`${t.yellow(`Title:`)} ${t.bold(c.title)}`),c.description&&l.push(`${t.yellow(`Description:`)} ${c.description}`),l.push(`${t.yellow(`Created at:`)} ${t.cyan(q.display(c.createdAt))} ${t.gray(`|`)} ${t.yellow(`Updated at:`)} ${t.cyan(q.display(c.modifiedAt))}`),c.actorMaker&&(l.push(``,`${t.yellow(`Made by:`)} ${t.cyan(c.actorMaker.profile.name??c.actorMaker.username)}`),Reflect.get(c,`isCritical`)&&(l[l.length-1]+=` ${t.bgGray(`Maintained by Apify`)}`)),c.isPublic?l.push(``,`${t.yellow(`Actor is`)} ${t.green(`PUBLIC`)}`):l.push(``,`${t.yellow(`Actor is`)} ${t.cyan(`PRIVATE`)}`),c.isDeprecated&&l.push(``,`${t.yellow(`Actor is`)} ${t.red(`DEPRECATED`)}`);let u=c.pricingInfos;if(u?.length){let e=u.at(-1);switch(e.pricingModel){case`FLAT_PRICE_PER_MONTH`:if(l.push(`${t.yellow(`Pricing information:`)} ${t.bgGray(`$${e.pricePerUnitUsd}/month + usage`)}`),e.trialMinutes){let n=e.trialMinutes*60*1e3,r=nr.format(n);l.push(` ${t.yellow(`Trial duration:`)} ${t.bold(r)}`)}break;case`PRICE_PER_DATASET_ITEM`:{let n=e.pricePerUnitUsd*1e3;l.push(`${t.yellow(`Pricing information:`)} ${t.bgGray(`$${n.toFixed(2)} / 1,000 results`)}`);break}case`PAY_PER_EVENT`:{l.push(`${t.yellow(`Pricing information:`)} ${t.bgGray(`Pay per event`)}`);let n=Object.values(e.pricingPerEvent?.actorChargeEvents??{});for(let e of n){let n=e.eventPriceUsd,r=e.eventTieredPricingUsd,i;i=typeof n==`number`?formatEventPrice(n):r&&Object.keys(r).length>0?`from ${formatEventPrice(Math.min(...Object.values(r).map(e=>e.tieredEventPriceUsd)))} (tiered)`:`N/A`,Dr.pushRow({"​":e.eventTitle,[Er]:t.bold(i)})}let r=Dr.render(0).split(`
@@ -109,38 +109,38 @@ Use --force to override newer remote versions.`;static group=`Local Actor Develo
109
109
  `)}),e.exitCode=4;return}let i=await getLoggedClientOrThrow(),a=await useActorConfig({cwd:n});if(a.isErr()){error({message:a.unwrapErr().message}),e.exitCode=5;return}let{config:s}=a.unwrap(),c=await getCurrentUserInfo(),l=c.organizationOwnerUserId?`/organization/${c.id}`:``,f,m,h=!1,g=this.flags.version||s?.version||`0.0`,_=this.flags.buildTag||s?.buildTag;!_&&g===`0.0`&&(_=`latest`);let v=parseWaitForFinishMillis(this.flags.waitForFinish),y=this.args.actorId;if(y){if(m=await i.actor(y).get(),!m)throw Error(`Cannot find Actor with ID '${y}' in your account.`);f=m.id}else{let e=c.username||c.id;if(m=await i.actor(`${e}/${s.name}`).get(),m)f=m.id;else{let{templates:e}=await Ot(),t=e.find(e=>e.name===s.template)?.defaultRunOptions||Nr,n={name:s.name,title:s.title,description:s.description,defaultRunOptions:t,versions:[{versionNumber:g,buildTag:_,sourceType:pe.SOURCE_FILES,sourceFiles:[]}]};s.usesStandbyMode&&(n.actorStandby={isEnabled:!0}),m=await i.actors().create(n),f=m.id,h=!0,info({message:`Created Actor with name ${s.name} on Apify.`})}}this.telemetryData.push={actorId:f,wasCreated:h};let b=i.actor(f);info({message:`Deploying Actor '${s.name}' to Apify.`});let x=await sumFilesSizeInBytes(r,n);if(x<_e&&!h){let e=await b.get(),t=r.reduce((e,t)=>{let{mtimeMs:r,ctimeMs:i}=te(u(n,t)),a=r>i?r:i;return e>a?e:a},0),i=e?.modifiedAt.valueOf();if(!this.flags.force&&i&&t<i&&(s?.name||y))throw Error(`Actor with identifier "${s?.name||y}" already exists on the platform and has newer changes than your local copy.
110
110
  Skipping push. Use --force to override.`)}let S=await b.version(g).get();if(S?.sourceType===pe.GIT_REPO&&!await confirmGitSourceSwitch({actorName:m.name,gitRepoUrl:S.gitRepoUrl,force:this.flags.force})){info({message:`Push aborted. Actor ${m.name} still builds from its Git repository.`});return}let C,w,T;if(x<_e)w=await createSourceFiles(r,n),C=pe.SOURCE_FILES;else{run({message:`Zipping Actor files`}),await createActZip(Mr,r,n);let e=await i.keyValueStores().getOrCreate(`actor-${f}-source`),t=`version-${g}.zip`,a=M(Mr);await i.keyValueStore(e.id).setRecord({key:t,value:a,contentType:`application/zip`}),ne(Mr);let s=new URL(`${i.baseUrl}/key-value-stores/${e.id}/records/${t}?disableRedirect=true`);if(e?.urlSigningSecretKey){let n=Ee(e.urlSigningSecretKey,t);s.searchParams.set(`signature`,n)}T=s.toString(),C=pe.TARBALL}let E=s.environmentVariables?transformEnvToEnvVars(s.environmentVariables,void 0,{allowMissing:this.flags.allowMissingSecrets}):void 0,D=this.flags.applyEnvVarsToBuild??s.applyEnvVarsToBuild;if(S){let e={tarballUrl:T,sourceFiles:w,buildTag:_,sourceType:C,envVars:E,applyEnvVarsToBuild:D};await b.version(g).update(e),run({message:`Updated version ${g} for Actor ${m.name}.`})}else{let e={versionNumber:g,tarballUrl:T,sourceFiles:w,buildTag:_,sourceType:C,envVars:E,applyEnvVarsToBuild:D};await b.versions().create({...e}),run({message:`Created version ${g} for Actor ${m.name}.`})}if(!h&&!!s.usesStandbyMode!=!!m.actorStandby?.isEnabled){let e=!!s.usesStandbyMode;await b.update({actorStandby:{isEnabled:e}}),info({message:`${e?`Enabled`:`Disabled`} standby mode for Actor ${m.name}.`})}run({message:`Building Actor ${m.name}`});let O=v===void 0?1/0:Date.now()+v,k=await b.build(g,{useCache:!0,waitForFinish:2});t.u(useAbortJobOnSignal({apifyClient:i,kind:z.BUILD,jobId:k.id}));try{let e=Number.isFinite(O)?Math.max(0,O-Date.now()):void 0;await outputJobLog({job:k,timeoutMillis:e,apifyClient:i})}catch(e){warning({message:`Can not get log:`}),console.error(e)}let A=k.id;if(k=await i.build(A).get(),!k){error({message:`Could not fetch build with ID "${A}" after deployment.`}),e.exitCode=1;return}for(;!isTerminalStatus(k.status)&&Date.now()<O;)await new Promise(e=>setTimeout(e,1e3)),k=await i.build(k.id).get();if(k.status===R.SUCCEEDED&&_&&v!==0){run({message:`Applying build tag "${_}"...`});let e=Date.now()+5e3,t=!1;for(;Date.now()<e;){if((await b.get())?.taggedBuilds?.[_]?.buildId===k.id){t=!0;break}await new Promise(e=>setTimeout(e,1e3))}t||warning({message:`Build succeeded but tag "${_}" was not set after 5 seconds; subsequent calls referencing this tag may not find it.`})}let j=k.status,N=resolvePushOutcome(j),ee=`${getConsoleUrl()}${l}/actors/${k.actId}`,P=`${ee}/builds/${k.buildNumber}`,F=[];if(N.errorMessage)try{let e=await i.log(k.id).get();e&&(F=e.split(`
111
111
  `).map(e=>e.trimEnd()).filter(e=>e.length>0).slice(-10))}catch{}N.exitCode&&(e.exitCode=N.exitCode);let I={ok:N.ok,operation:`push`,actor:{id:k.actId,url:ee},build:{id:k.id,number:k.buildNumber,status:j,url:P}};if(N.exitCode!==void 0&&(I.exitCode=N.exitCode),N.errorMessage&&(I.error={phase:`build`,message:N.errorMessage,logTail:F}),this.flags.json){printJsonToStdout(I);return}simpleLog({stdout:!0,message:[`Apify push result: ${N.resultLabel}`,``,`Upload: SUCCEEDED`,`Build: ${j}`,`Actor ID: ${k.actId}`,`Build ID: ${k.id}`,`Build number: ${k.buildNumber}`,...N.exitCode?[`Exit code: ${N.exitCode}`]:[],``,`Actor URL: ${ee}`,`Build URL: ${P}`,...N.errorMessage&&F.length?[``,`Reason:`,...F]:[]].join(`
112
- `)}),this.flags.open&&await Dt(ee)}catch(e){t.e=e}finally{t.d()}}},ActorsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes an Actor from your account.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete an Actor by its full name (prompts for confirmation).`,command:`apify actors rm my-username/my-actor`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors-rm`;static args={actorId:Z.string({description:`The Actor ID to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{actorId:e}=this.args,{yes:t}=this.flags,n=await getLoggedClientOrThrow();if(!await n.actor(e).get()){error({message:`Actor with ID "${e}" was not found on your account.`});return}if(!await X({message:`Are you sure you want to delete this Actor?`,providedConfirmFromStdin:t||void 0})){info({message:`Deletion of Actor "${e}" was canceled.`});return}try{await n.actor(e).delete(),success({message:`Actor with ID "${e}" was deleted.`})}catch(t){let n=t;error({message:`Failed to delete Actor "${e}".\n ${n.message||n}`})}}};const Pr={FREE:`Free`,FLAT_PRICE_PER_MONTH:`Subscription`,PRICE_PER_DATASET_ITEM:`Pay per result`,PAY_PER_EVENT:`Pay per event`};function formatPricingModel(e){return e?Pr[e]??e:t.gray(`Unknown`)}function truncateDescription(e,t=60){return e?e.length<=t?e:`${e.slice(0,t-1)}…`:``}var ActorsSearchCommand=class extends ApifyCommand{static name=`search`;static description=`Searches Actors in the Apify Store.
112
+ `)}),this.flags.open&&await Dt(ee)}catch(e){t.e=e}finally{t.d()}}},ActorsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes an Actor from your account.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete an Actor by its full name (prompts for confirmation).`,command:`apify actors rm my-username/my-actor`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors-rm`;static args={actorId:Z.string({description:`The Actor ID to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{actorId:e}=this.args,{yes:t}=this.flags,n=await getLoggedClientOrThrow();if(!await n.actor(e).get())error({message:`Actor with ID "${e}" was not found on your account.`});else if(!await X({message:`Are you sure you want to delete this Actor?`,providedConfirmFromStdin:t||void 0}))info({message:`Deletion of Actor "${e}" was canceled.`});else try{await n.actor(e).delete(),success({message:`Actor with ID "${e}" was deleted.`})}catch(t){let n=t;error({message:`Failed to delete Actor "${e}".\n ${n.message||n}`})}}};const Pr={FREE:`Free`,FLAT_PRICE_PER_MONTH:`Subscription`,PRICE_PER_DATASET_ITEM:`Pay per result`,PAY_PER_EVENT:`Pay per event`};function formatPricingModel(e){return e?Pr[e]??e:t.gray(`Unknown`)}function truncateDescription(e,t=60){return e?e.length<=t?e:`${e.slice(0,t-1)}…`:``}var ActorsSearchCommand=class extends ApifyCommand{static name=`search`;static description=`Searches Actors in the Apify Store.
113
113
 
114
114
  Searches the Apify Store for Actors matching the given query. Results can be filtered by category, author, pricing model, and more. This command does not require authentication.`;static examples=[{description:`Search the Apify Store for "web scraper" Actors.`,command:`apify actors search "web scraper"`},{description:`Search for TikTok Actors sorted by popularity, limit to 5 results.`,command:`apify actors search "tiktok" --limit 5 --sort-by popularity`},{description:`Find free AI Actors.`,command:`apify actors search "ai" --category AI --pricing-model FREE`},{description:`Output results as JSON for scripting.`,command:`apify actors search "web scraper" --json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors-search`;static args={query:Z.string({description:`Search query to find Actors by title, name, description, username, or readme.`,required:!1})};static flags={"sort-by":Y.string({description:`Sort order for the results.`,choices:[`relevance`,`popularity`,`newest`,`lastUpdate`],default:`relevance`}),category:Y.string({description:`Filter by category (e.g. AI).`}),username:Y.string({description:`Filter by Actor author username.`}),"pricing-model":Y.string({description:`Filter by pricing model.`,choices:[`FREE`,`FLAT_PRICE_PER_MONTH`,`PRICE_PER_DATASET_ITEM`,`PAY_PER_EVENT`]}),limit:Y.integer({description:`Maximum number of results to return.`,default:20}),offset:Y.integer({description:`Number of results to skip for pagination.`,default:0})};static enableJsonFlag=!0;async run(){let{query:e}=this.args,{json:n,sortBy:r,category:i,username:a,pricingModel:s,limit:c,offset:l}=this.flags,u=new Ce(getAnonymousApifyClientOptions()),f;try{f=await u.store().list({search:e,sortBy:r,category:i,username:a,pricingModel:s,limit:c,offset:l})}catch(e){process.exitCode=1,error({message:`Failed to search Apify Store: ${e instanceof Error?e.message:String(e)}`,stdout:!0});return}if(f.count===0){if(n){printJsonToStdout(f);return}info({message:`No Actors found matching your search.`,stdout:!0});return}if(n){printJsonToStdout(f);return}let p=new Q({allColumns:[`Name`,`Description`,`Users (30d)`,`Pricing`],mandatoryColumns:[`Name`,`Pricing`],columnAlignments:{"Users (30d)":`right`,Name:`left`}});for(let e of f.items)p.pushRow({Name:`${e.title}\n${t.gray(`${e.username}/${e.name}`)}`,Description:truncateDescription(e.description),"Users (30d)":t.cyan(`${e.stats?.totalUsers30Days??0}`),Pricing:formatPricingModel(e.currentPricingInfo?.pricingModel)});simpleLog({message:p.render(1),stdout:!0})}},ActorsStartCommand=class extends ApifyCommand{static name=`start`;static enableProfileFlag=!0;static description=`Starts Actor remotely and returns run details immediately.
115
- Uses authenticated account and local key-value store for input.`;static examples=[{description:`Start the Actor defined in the current directory and return immediately.`,command:`apify actors start`},{description:`Start a specific Actor with inline JSON input.`,command:`apify actors start apify/hello-world --input '{"url":"https://example.com"}'`},{description:`Start with input from a file and custom memory/timeout.`,command:`apify actors start apify/web-scraper --input-file ./input.json --memory 4096 --timeout 600`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors-start`;static flags={...SharedRunOnCloudFlags(`Actor`),input:Y.string({char:`i`,description:`Optional JSON input to be given to the Actor.`,required:!1,stdin:2,exclusive:[`input-file`]}),"input-file":Y.string({aliases:[`if`],description:"Optional path to a file with JSON input to be given to the Actor. The file must be a valid JSON file. You can also specify `-` to read from standard input.",required:!1,stdin:2,exclusive:[`input`]})};static enableJsonFlag=!0;static args={actorId:Z.string({required:!1,description:`Name or ID of the Actor to run (e.g. "my-actor", "apify/hello-world" or "E2jjCZBezvAZnX8Rb"). If not provided, the command runs the remote Actor specified in the '${K}' file.`})};async run(){let n=e.cwd(),r=getLocalConfig(n)||{},i=await getLoggedClientOrThrow(),a=await getCurrentUserInfo(),s=a.username||a.id,{id:c,userFriendlyId:l,actorData:u}=await Sr.resolveActorId({client:i,localActorName:r.name,usernameOrId:s,providedActorNameOrId:this.args.actorId}),f={};this.flags.build&&(f.build=this.flags.build),this.flags.timeout!==void 0&&(f.timeout=this.flags.timeout),this.flags.memory&&(f.memory=this.flags.memory);let p=await getInputOverride(n,this.flags.input,this.flags.inputFile);if(p===!1)return;let m=runActorOrTaskOnCloud(i,{actorOrTaskData:{id:c,userFriendlyId:l},runOptions:f,type:`Actor`,inputOverride:p?.input,silent:!0,waitForRunToFinish:!1,printRunLogs:!1}),h;for await(let e of m)h=e;if(!h){simpleLog({message:`Actor run did not start.`,stdout:!1}),e.exitCode=1;return}let g=consoleRunUrl(c,h.id);if(this.flags.json){printJsonToStdout({ok:!0,operation:`actors.start`,waited:!1,actor:{id:c,url:consoleActorUrl(c)},run:{id:h.id,status:h.status,url:g},next:{wait:`apify runs wait ${h.id} --json`,log:`apify runs log ${h.id}`,info:`apify runs info ${h.id} --json`},exitCode:0});return}simpleLog({message:[t.greenBright(`Run started.`),``,`${t.yellow(`Actor`)}: ${u.name} (${t.gray(c)})`,`${t.yellow(`Run ID`)}: ${h.id}`,`${t.yellow(`Status`)}: ${h.status}`,``,t.gray(`This command does not wait for the run to finish.`),``,`To wait for the final status:`,` apify runs wait ${h.id} --json`,``,`To stream or inspect logs:`,` apify runs log ${h.id}`,``,`To inspect run metadata:`,` apify runs info ${h.id} --json`].join(`
115
+ Uses authenticated account and local key-value store for input.`;static examples=[{description:`Start the Actor defined in the current directory and return immediately.`,command:`apify actors start`},{description:`Start a specific Actor with inline JSON input.`,command:`apify actors start apify/hello-world --input '{"url":"https://example.com"}'`},{description:`Start with input from a file and custom memory/timeout.`,command:`apify actors start apify/web-scraper --input-file ./input.json --memory 4096 --timeout 600`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors-start`;static flags={...SharedRunOnCloudFlags(`Actor`),input:Y.string({char:`i`,description:`Optional JSON input to be given to the Actor.`,required:!1,stdin:2,exclusive:[`input-file`]}),"input-file":Y.string({aliases:[`if`],description:"Optional path to a file with JSON input to be given to the Actor. The file must be a valid JSON file. You can also specify `-` to read from standard input.",required:!1,stdin:2,exclusive:[`input`]})};static enableJsonFlag=!0;static args={actorId:Z.string({required:!1,description:`Name or ID of the Actor to run (e.g. "my-actor", "apify/hello-world" or "E2jjCZBezvAZnX8Rb"). If not provided, the command runs the remote Actor specified in the '${K}' file.`})};async run(){let n=e.cwd(),r=getLocalConfig(n)||{},i=await getLoggedClientOrThrow(),a=await getCurrentUserInfo(),s=a.username||a.id,{id:c,userFriendlyId:l,actorData:u}=await Sr.resolveActorId({client:i,localActorName:r.name,usernameOrId:s,providedActorNameOrId:this.args.actorId}),f={};this.flags.build&&(f.build=this.flags.build),this.flags.timeout!==void 0&&(f.timeout=this.flags.timeout),this.flags.memory&&(f.memory=this.flags.memory);let p=await getInputOverride(n,this.flags.input,this.flags.inputFile);if(p===!1)return;let m=runActorOrTaskOnCloud(i,{actorOrTaskData:{id:c,userFriendlyId:l},runOptions:f,type:`Actor`,inputOverride:p?.input,silent:!0,waitForRunToFinish:!1,printRunLogs:!1}),h;for await(let e of m)h=e;if(!h){simpleLog({message:`Actor run did not start.`,stdout:!1}),e.exitCode=1;return}let g=consoleRunUrl(c,h.id);this.flags.json?printJsonToStdout({ok:!0,operation:`actors.start`,waited:!1,actor:{id:c,url:consoleActorUrl(c)},run:{id:h.id,status:h.status,url:g},next:{wait:`apify runs wait ${h.id} --json`,log:`apify runs log ${h.id}`,info:`apify runs info ${h.id} --json`},exitCode:0}):simpleLog({message:[t.greenBright(`Run started.`),``,`${t.yellow(`Actor`)}: ${u.name} (${t.gray(c)})`,`${t.yellow(`Run ID`)}: ${h.id}`,`${t.yellow(`Status`)}: ${h.status}`,``,t.gray(`This command does not wait for the run to finish.`),``,`To wait for the final status:`,` apify runs wait ${h.id} --json`,``,`To stream or inspect logs:`,` apify runs log ${h.id}`,``,`To inspect run metadata:`,` apify runs info ${h.id} --json`].join(`
116
116
  `),stdout:!0})}},ActorsIndexCommand=class extends ApifyCommand{static name=`actors`;static description=`Search, list, deploy, and call Actors on the Apify platform.
117
117
  For runtime operations inside a running Actor (push-data, get-input, set-value...), see 'apify actor' (singular).`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors`;static subcommands=[ActorsStartCommand,ActorsRmCommand,ActorsSearchCommand,ActorsPushCommand,ActorsPullCommand,ActorsLsCommand,ActorsInfoCommand,Sr,ActorsBuildCommand];async run(){this.printHelp()}};const Fr=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`],Ir=/* @__PURE__ */ new Set([`GET`,`HEAD`]),Lr=`https://docs.apify.com/api/openapi.json`;function parseParams(e){if(!e)return``;let t;try{t=JSON.parse(e)}catch{throw Error(`Invalid JSON in --params flag. Please provide a valid JSON object, e.g. '{"limit": 1}'.`)}if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`--params must be a JSON object (e.g. '{"limit": 1}').`);let n=new URLSearchParams;for(let[e,r]of Object.entries(t))if(r!=null){if(typeof r==`object`)throw Error(`--params value for "${e}" must be a scalar (string, number, or boolean), got ${Array.isArray(r)?`array`:`object`}. Query parameters cannot contain nested objects or arrays.`);n.append(e,String(r))}return n.toString()}function parseHeaders(e){if(!e)return{};let t=e.trim();if(t.startsWith(`{`)){let e;try{e=JSON.parse(t)}catch{throw Error(`Invalid JSON in --header flag. Provide a JSON object like '{"X-Foo": "bar"}'.`)}if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`--header JSON must be an object mapping header names to string values.`);let n={};for(let[t,r]of Object.entries(e)){if(typeof r!=`string`)throw Error(`--header value for "${t}" must be a string, got ${typeof r}.`);n[t.trim()]=r.trim()}return n}let n=t.indexOf(`:`);if(n===-1)throw Error(`Header must be in "key:value" format, or a JSON object for multiple headers.`);return{[t.slice(0,n).trim()]:t.slice(n+1).trim()}}const Rr={GET:t.green,POST:t.yellow,PUT:t.blue,PATCH:t.cyan,DELETE:t.red};function formatEndpointLine(e){let n=(Rr[e.method]||t.white)(e.method.padEnd(7)),r=e.summary?t.gray(` ${e.summary}`):``;return`${n} ${e.path}${r}`}const zr=`Run ${t.cyan(`apify api --list-endpoints`)} to see all available Apify API endpoints.`;function printSuggestions(e){if(e.length>0){simpleLog({message:`
118
118
  Did you mean:`,stdout:!1});for(let t of e)simpleLog({message:` ${formatEndpointLine(t)}`,stdout:!1})}simpleLog({message:`\n${zr}`,stdout:!1})}var ApiCommand=class extends ApifyCommand{cachedEndpoints=null;static name=`api`;static enableProfileFlag=!0;static description=`Makes an authenticated HTTP request to the Apify API and prints the response.
119
119
  The endpoint can be a relative path (e.g. "acts", "v2/acts", or "/v2/acts"); the "v2/" prefix is added automatically if omitted.
120
120
 
121
- Use --list-endpoints to see all available API endpoints.`;static examples=[{description:`Make a GET request to an API endpoint (defaults to GET).`,command:`apify api users/me`},{description:`Pass the HTTP method as a positional argument before the endpoint.`,command:`apify api GET /v2/actor-runs`},{description:`Create a resource by POSTing a JSON body.`,command:`apify api POST acts -d '{"name":"my-actor"}'`},{description:`Pass query parameters as a JSON object.`,command:`apify api actor-runs -p '{"limit":1,"desc":true}'`},{description:`Send one or more custom headers as a JSON object.`,command:`apify api acts -H '{"X-Foo":"bar","X-Baz":"qux"}'`},{description:`List all available Apify API endpoints.`,command:`apify api --list-endpoints`},{description:`Search for endpoints matching a query.`,command:`apify api --list-endpoints --search "actor run"`},{description:`Print a reference for an endpoint (methods, summary, path params).`,command:`apify api --describe actor-runs/{runId}`}];static docsUrl=`https://docs.apify.com/api/v2`;static args={methodOrEndpoint:Z.string({required:!1,description:`The API endpoint path (e.g. "acts", "v2/acts", "/v2/users/me"), or an HTTP method followed by the endpoint (e.g. "GET /v2/users/me").`}),endpoint:Z.string({required:!1,description:`The API endpoint path when the first argument is an HTTP method.`})};static flags={method:Y.string({char:`X`,description:`The HTTP method to use. Defaults to GET.`,choices:Fr}),body:Y.string({char:`d`,description:`The request body (JSON string). Use "-" to read from stdin.`,required:!1,stdin:2}),header:Y.string({char:`H`,description:`Additional HTTP header(s). Pass a single "key:value" string, or a JSON object like '{"X-Foo": "bar", "X-Baz": "qux"}' to send multiple headers. The flag can only be used once; use the JSON form for multiple headers.`,required:!1}),params:Y.string({char:`p`,description:`Query parameters as a JSON object, e.g. '{"limit": 1, "desc": true}'.`,required:!1}),"list-endpoints":Y.boolean({char:`l`,description:`List all available Apify API endpoints.`,default:!1,exclusive:[`describe`]}),search:Y.string({char:`s`,description:`Filter results returned by --list-endpoints. The query is case-insensitive and split into tokens by spaces. For an endpoint to be returned, every token must appear in that endpoint's method, path, or summary.`,required:!1,exclusive:[`describe`]}),describe:Y.string({description:`Print a reference for an endpoint path: its HTTP methods, summary, and path parameters. Leading slashes and a version prefix in the path are optional. For example, "actor-runs/{runId}" and "/v2/actor-runs/{runId}" are both accepted.`,required:!1,exclusive:[`list-endpoints`,`search`]})};async run(){if(this.flags.search&&!this.flags.listEndpoints)throw Error(`The --search flag can only be used together with --list-endpoints.`);if(this.flags.describe){await this.describeEndpoint(this.flags.describe);return}if(this.flags.listEndpoints){await this.printEndpoints(this.flags.search);return}let t=this.flags.method?.toUpperCase(),n,r=this.args.methodOrEndpoint;if(r&&Fr.includes(r.toUpperCase())){let e=r.toUpperCase();if(t&&t!==e)throw Error(`Conflicting HTTP methods: positional "${e}" vs --method "${t}". Please specify the method only once.`);n=e,r=this.args.endpoint}else n=t;if(n??=`GET`,!r){this.printHelp();return}let i=parseParams(this.flags.params),a=parseHeaders(this.flags.header);if(this.flags.body){if(Ir.has(n))throw Error(`HTTP ${n} requests cannot have a request body. Use a different method (e.g. POST, PUT, PATCH) or omit --body.`);try{JSON.parse(this.flags.body)}catch{throw Error(`Invalid JSON in --body flag. Please provide a valid JSON string.`)}}let s=await getLoggedClientOrThrow(),c=s.token,l=normalizePath(r),u=`${s.baseUrl}/${l}`;if(i){let e=u.includes(`?`)?`&`:`?`;u=`${u}${e}${i}`}let f={...un,Authorization:`Bearer ${c}`};this.flags.body&&(f[`Content-Type`]=`application/json`);for(let[e,t]of Object.entries(a)){for(let t of Object.keys(f))t.toLowerCase()===e.toLowerCase()&&delete f[t];f[e]=t}let p=await fetch(u,{method:n,headers:f,body:this.flags.body||void 0}),m=await p.text();if(!p.ok){if(e.exitCode=1,error({message:`${p.status} ${p.statusText}`}),m)try{let e=JSON.parse(m);simpleLog({message:JSON.stringify(e,null,2),stdout:!0})}catch{simpleLog({message:m,stdout:!0})}p.status===404&&await this.print404Suggestions(l);return}if(m)try{let e=JSON.parse(m);simpleLog({message:JSON.stringify(e,null,2),stdout:!0})}catch{simpleLog({message:m,stdout:!0})}}async getEndpoints(){return this.cachedEndpoints??=await fetchEndpoints(),this.cachedEndpoints}async printEndpoints(e){let t=await this.getEndpoints();if(e&&(t=filterEndpoints(t,e),t.length===0)){simpleLog({message:`No endpoints matched the query "${e}".`,stdout:!1});return}for(let e of t)console.log(formatEndpointLine(e))}async describeEndpoint(e){let n=normalizePath(e),r=await this.getEndpoints(),i=r.filter(e=>normalizePath(e.path)===n);if(i.length>0){let e=extractPathParams(i[0].path);console.log(t.bold(i[0].path)),console.log(``);for(let e of i){let n=Rr[e.method]||t.white;console.log(` ${n(e.method.padEnd(7))} ${e.summary||t.gray(`(no summary)`)}`)}if(e.length>0){console.log(``),console.log(t.bold(`Path parameters:`));for(let n of e)console.log(` ${t.yellow(`{${n}}`)}`)}console.log(``),console.log(t.gray(`Docs: https://docs.apify.com/api/v2`));return}simpleLog({message:`No endpoint found for "${e}".`,stdout:!1}),printSuggestions(findClosestEndpoints(r,n))}async print404Suggestions(e){try{printSuggestions(findClosestEndpoints(await this.getEndpoints(),e))}catch{simpleLog({message:`\n${zr}`,stdout:!1})}}};async function fetchEndpoints(){let e;try{e=await fetch(Lr)}catch(e){throw Error(`Failed to download the Apify OpenAPI spec from ${Lr}: ${e.message}`)}if(!e.ok)throw Error(`Failed to download the Apify OpenAPI spec from ${Lr}: ${e.status} ${e.statusText}`);let t=await e.json(),n=[];for(let[e,r]of Object.entries(t.paths))for(let[t,i]of Object.entries(r))Fr.includes(t.toUpperCase())&&n.push({method:t.toUpperCase(),path:e,summary:i.summary||``});return n.sort((e,t)=>e.path.localeCompare(t.path)||e.method.localeCompare(t.method)),n}function normalizePath(e){let t=e;return t.startsWith(`/`)&&(t=t.slice(1)),t=t.replace(/^v2\//i,``),t}function filterEndpoints(e,t){let n=t.toLowerCase().split(/\s+/).filter(Boolean);return n.length===0?e:e.filter(e=>{let t=`${e.method} ${e.path} ${e.summary}`.toLowerCase();return n.every(e=>t.includes(e))})}function extractPathParams(e){let t=e.match(/\{([^}]+)\}/g);return t?t.map(e=>e.slice(1,-1)):[]}function findClosestEndpoints(e,t,n=5){let r=t.toLowerCase(),i=r.split(`/`).filter(Boolean),a=/* @__PURE__ */ new Map;for(let t of e){if(a.has(t.path))continue;let e=normalizePath(t.path).toLowerCase(),n=0;(e.includes(r)||r.includes(e))&&(n+=10);let s=e.split(`/`).filter(Boolean),c=Math.min(i.length,s.length);for(let e=0;e<c;e++)s[e]===i[e]?n+=2:s[e].startsWith(`{`)&&(n+=1);i.length===s.length&&(n+=1),n>0&&a.set(t.path,n)}let s=[...a.entries()].sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).slice(0,n).map(([e])=>e),c=new Set(s),l=/* @__PURE__ */ new Map;for(let t of e)if(c.has(t.path)){let e=l.get(t.path)||[];e.push(t),l.set(t.path,e)}return s.flatMap(e=>l.get(e)||[])}const Br={keyring:`OS keyring`,file:`auth.json`,none:t.gray(`None`)},Vr=new Q({allColumns:[`Name`,`User ID`,`Type`,`Last login`,`Storage`],mandatoryColumns:[`Name`,`User ID`]});var AuthListCommand=class extends ApifyCommand{static name=`list`;static aliases=[`ls`];static description=`Lists the stored Apify accounts and marks the active one. Reads only the local login, so it works offline and doesn't check that the tokens are still valid.`;static enableJsonFlag=!0;static group=`Authentication`;static examples=[{description:`List the stored accounts.`,command:`apify auth list`},{description:`List the stored accounts as JSON, for scripts.`,command:`apify auth list --json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth-list`;async run(){assertSupportedAuthFileVersion();let e=readAuthFile(),n=getActiveProfileId(),r=readEnvToken(),i=await getBackend(),a=listProfiles().map(t=>({id:t.id,name:profileLabel(t),username:t.username??null,active:t.id===n,isOrganization:!!t.organizationOwnerUserId,organizationOwnerUserId:t.organizationOwnerUserId??null,loggedInAt:t.loggedInAt,secretsBackend:(t.token??(t.id===n?e.token:void 0))===void 0?i===`keyring`?i:null:`file`}));if(this.flags.json){printJsonToStdout({envTokenInUse:r.kind!==`unset`,profiles:a});return}if(r.kind===`token`?warning({message:`${B.TOKEN} is set, so commands use it instead of the active account.`}):r.kind===`invalid`&&warning({message:invalidEnvTokenMessage(r.raw)}),!a.length){simpleLog({message:Fn,stdout:!0});return}for(let e of a)Vr.pushRow({Name:e.active?`${t.bold(e.name)} ${t.green(`(active)`)}`:e.name,"User ID":t.gray(e.id),Type:e.isOrganization?`Organization`:`Personal`,"Last login":e.loggedInAt?q.display(new Date(e.loggedInAt)):t.gray(`Unknown`),Storage:Br[e.secretsBackend??`none`]});simpleLog({message:Vr.render(1),stdout:!0})}};const Hr=stdinCheckWrapper(async({message:e,mask:t})=>await Mt({message:e,mask:t??`*`},In)),wrapResponse=e=>({status(t){e.statusCode=t},send(t){typeof t==`string`?(e.setHeader(`Content-Type`,`text/plain; charset=utf-8`),e.end(t)):(e.setHeader(`Content-Type`,`application/json; charset=utf-8`),e.end(JSON.stringify(t)))},end(){e.end()}});function createLocalApiServer({corsOrigin:e,authToken:t,routes:n}){return Nt(async(r,i)=>{if(i.setHeader(`Connection`,`close`),i.setHeader(`Vary`,`Origin`),i.setHeader(`Access-Control-Allow-Origin`,e),r.method===`OPTIONS`){i.setHeader(`Access-Control-Allow-Methods`,`GET,HEAD,PUT,PATCH,POST,DELETE`),i.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),i.statusCode=204,i.end();return}let a=new URL(r.url??`/`,`http://localhost`),s=wrapResponse(i),c=a.searchParams.get(`token`);if(!c){let e=r.headers.authorization;if(e){let[t,n,...r]=e.trim().split(/\s+/);t.toLowerCase()===`bearer`&&n&&r.length===0&&(c=n)}}if(c!==t){s.status(401),s.send(`Authorization failed`);return}let l=n[`${r.method} ${a.pathname}`];if(!l){s.status(404),s.send(`Not found`);return}let u=[];for await(let e of r)u.push(e);let f=Buffer.concat(u).toString(`utf-8`),p={};if(f)try{p=JSON.parse(f)}catch{s.status(400),s.send(`Invalid JSON body`);return}await l(p,s)})}function pkceChallengeFromVerifier(e){return Pt(`sha256`).update(e).digest(`base64url`)}const Ur=`/callback`;async function loginWithAuthorizationCode({metadata:e,clientId:t,signal:n,onPrompt:r}){if(!e.authorization_endpoint)return{unsupported:!0,reason:`the authorization server does not advertise an authorization endpoint`};let i=Ft(32).toString(`base64url`),a=pkceChallengeFromVerifier(i),s=Ft(16).toString(`base64url`),c,l=new Promise(e=>{c=e}),u=Nt((e,t)=>{t.setHeader(`Connection`,`close`);let n=new URL(e.url??`/`,`http://127.0.0.1`);if(e.method!==`GET`||n.pathname!==Ur){t.statusCode=404,t.end(`Not found`);return}if(n.searchParams.get(`state`)!==s){t.statusCode=400,t.end(`Invalid state`);return}let r=n.searchParams.get(`error`),i=n.searchParams.get(`code`);if(r||!i){t.statusCode=400,t.end(`Login failed. You can close this tab.`);let e=n.searchParams.get(`error_description`)??r??`no authorization code was returned`;c({stopReason:`accessDenied`,message:`Login to Apify failed: ${e}.`});return}t.setHeader(`Content-Type`,`text/html; charset=utf-8`),t.end(`<!doctype html><html><head><meta charset="utf-8"><title>Apify CLI</title></head>
121
+ Use --list-endpoints to see all available API endpoints.`;static examples=[{description:`Make a GET request to an API endpoint (defaults to GET).`,command:`apify api users/me`},{description:`Pass the HTTP method as a positional argument before the endpoint.`,command:`apify api GET /v2/actor-runs`},{description:`Create a resource by POSTing a JSON body.`,command:`apify api POST acts -d '{"name":"my-actor"}'`},{description:`Pass query parameters as a JSON object.`,command:`apify api actor-runs -p '{"limit":1,"desc":true}'`},{description:`Send one or more custom headers as a JSON object.`,command:`apify api acts -H '{"X-Foo":"bar","X-Baz":"qux"}'`},{description:`List all available Apify API endpoints.`,command:`apify api --list-endpoints`},{description:`Search for endpoints matching a query.`,command:`apify api --list-endpoints --search "actor run"`},{description:`Print a reference for an endpoint (methods, summary, path params).`,command:`apify api --describe actor-runs/{runId}`}];static docsUrl=`https://docs.apify.com/api/v2`;static args={methodOrEndpoint:Z.string({required:!1,description:`The API endpoint path (e.g. "acts", "v2/acts", "/v2/users/me"), or an HTTP method followed by the endpoint (e.g. "GET /v2/users/me").`}),endpoint:Z.string({required:!1,description:`The API endpoint path when the first argument is an HTTP method.`})};static flags={method:Y.string({char:`X`,description:`The HTTP method to use. Defaults to GET.`,choices:Fr}),body:Y.string({char:`d`,description:`The request body (JSON string). Use "-" to read from stdin.`,required:!1,stdin:2}),header:Y.string({char:`H`,description:`Additional HTTP header(s). Pass a single "key:value" string, or a JSON object like '{"X-Foo": "bar", "X-Baz": "qux"}' to send multiple headers. The flag can only be used once; use the JSON form for multiple headers.`,required:!1}),params:Y.string({char:`p`,description:`Query parameters as a JSON object, e.g. '{"limit": 1, "desc": true}'.`,required:!1}),"list-endpoints":Y.boolean({char:`l`,description:`List all available Apify API endpoints.`,default:!1,exclusive:[`describe`]}),search:Y.string({char:`s`,description:`Filter results returned by --list-endpoints. The query is case-insensitive and split into tokens by spaces. For an endpoint to be returned, every token must appear in that endpoint's method, path, or summary.`,required:!1,exclusive:[`describe`]}),describe:Y.string({description:`Print a reference for an endpoint path: its HTTP methods, summary, and path parameters. Leading slashes and a version prefix in the path are optional. For example, "actor-runs/{runId}" and "/v2/actor-runs/{runId}" are both accepted.`,required:!1,exclusive:[`list-endpoints`,`search`]})};async run(){if(this.flags.search&&!this.flags.listEndpoints)throw Error(`The --search flag can only be used together with --list-endpoints.`);if(this.flags.describe){await this.describeEndpoint(this.flags.describe);return}if(this.flags.listEndpoints){await this.printEndpoints(this.flags.search);return}let t=this.flags.method?.toUpperCase(),n,r=this.args.methodOrEndpoint;if(r&&Fr.includes(r.toUpperCase())){let e=r.toUpperCase();if(t&&t!==e)throw Error(`Conflicting HTTP methods: positional "${e}" vs --method "${t}". Please specify the method only once.`);n=e,r=this.args.endpoint}else n=t;if(n??=`GET`,!r){this.printHelp();return}let i=parseParams(this.flags.params),a=parseHeaders(this.flags.header);if(this.flags.body){if(Ir.has(n))throw Error(`HTTP ${n} requests cannot have a request body. Use a different method (e.g. POST, PUT, PATCH) or omit --body.`);try{JSON.parse(this.flags.body)}catch{throw Error(`Invalid JSON in --body flag. Please provide a valid JSON string.`)}}let s=await getLoggedClientOrThrow(),c=s.token,l=normalizePath(r),u=`${s.baseUrl}/${l}`;if(i){let e=u.includes(`?`)?`&`:`?`;u=`${u}${e}${i}`}let f={...un,Authorization:`Bearer ${c}`};this.flags.body&&(f[`Content-Type`]=`application/json`);for(let[e,t]of Object.entries(a)){for(let t of Object.keys(f))t.toLowerCase()===e.toLowerCase()&&delete f[t];f[e]=t}let p=await fetch(u,{method:n,headers:f,body:this.flags.body||void 0}),m=await p.text();if(!p.ok){if(e.exitCode=1,error({message:`${p.status} ${p.statusText}`}),m)try{let e=JSON.parse(m);simpleLog({message:JSON.stringify(e,null,2),stdout:!0})}catch{simpleLog({message:m,stdout:!0})}p.status===404&&await this.print404Suggestions(l)}else if(m)try{let e=JSON.parse(m);simpleLog({message:JSON.stringify(e,null,2),stdout:!0})}catch{simpleLog({message:m,stdout:!0})}}async getEndpoints(){return this.cachedEndpoints??=await fetchEndpoints(),this.cachedEndpoints}async printEndpoints(e){let t=await this.getEndpoints();if(e&&(t=filterEndpoints(t,e),t.length===0))simpleLog({message:`No endpoints matched the query "${e}".`,stdout:!1});else for(let e of t)console.log(formatEndpointLine(e))}async describeEndpoint(e){let n=normalizePath(e),r=await this.getEndpoints(),i=r.filter(e=>normalizePath(e.path)===n);if(i.length>0){let e=extractPathParams(i[0].path);console.log(t.bold(i[0].path)),console.log(``);for(let e of i){let n=Rr[e.method]||t.white;console.log(` ${n(e.method.padEnd(7))} ${e.summary||t.gray(`(no summary)`)}`)}if(e.length>0){console.log(``),console.log(t.bold(`Path parameters:`));for(let n of e)console.log(` ${t.yellow(`{${n}}`)}`)}console.log(``),console.log(t.gray(`Docs: https://docs.apify.com/api/v2`))}else simpleLog({message:`No endpoint found for "${e}".`,stdout:!1}),printSuggestions(findClosestEndpoints(r,n))}async print404Suggestions(e){try{printSuggestions(findClosestEndpoints(await this.getEndpoints(),e))}catch{simpleLog({message:`\n${zr}`,stdout:!1})}}};async function fetchEndpoints(){let e;try{e=await fetch(Lr)}catch(e){throw Error(`Failed to download the Apify OpenAPI spec from ${Lr}: ${e.message}`)}if(!e.ok)throw Error(`Failed to download the Apify OpenAPI spec from ${Lr}: ${e.status} ${e.statusText}`);let t=await e.json(),n=[];for(let[e,r]of Object.entries(t.paths))for(let[t,i]of Object.entries(r))Fr.includes(t.toUpperCase())&&n.push({method:t.toUpperCase(),path:e,summary:i.summary||``});return n.sort((e,t)=>e.path.localeCompare(t.path)||e.method.localeCompare(t.method)),n}function normalizePath(e){let t=e;return t.startsWith(`/`)&&(t=t.slice(1)),t=t.replace(/^v2\//i,``),t}function filterEndpoints(e,t){let n=t.toLowerCase().split(/\s+/).filter(Boolean);return n.length===0?e:e.filter(e=>{let t=`${e.method} ${e.path} ${e.summary}`.toLowerCase();return n.every(e=>t.includes(e))})}function extractPathParams(e){let t=e.match(/\{([^}]+)\}/g);return t?t.map(e=>e.slice(1,-1)):[]}function findClosestEndpoints(e,t,n=5){let r=t.toLowerCase(),i=r.split(`/`).filter(Boolean),a=/* @__PURE__ */ new Map;for(let t of e){if(a.has(t.path))continue;let e=normalizePath(t.path).toLowerCase(),n=0;(e.includes(r)||r.includes(e))&&(n+=10);let s=e.split(`/`).filter(Boolean),c=Math.min(i.length,s.length);for(let e=0;e<c;e++)s[e]===i[e]?n+=2:s[e].startsWith(`{`)&&(n+=1);i.length===s.length&&(n+=1),n>0&&a.set(t.path,n)}let s=[...a.entries()].sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).slice(0,n).map(([e])=>e),c=new Set(s),l=/* @__PURE__ */ new Map;for(let t of e)if(c.has(t.path)){let e=l.get(t.path)||[];e.push(t),l.set(t.path,e)}return s.flatMap(e=>l.get(e)||[])}const Br={keyring:`OS keyring`,file:`auth.json`,none:t.gray(`None`)},Vr=new Q({allColumns:[`Name`,`User ID`,`Type`,`Last login`,`Storage`],mandatoryColumns:[`Name`,`User ID`]});var AuthListCommand=class extends ApifyCommand{static name=`list`;static aliases=[`ls`];static description=`Lists the stored Apify accounts and marks the active one. Reads only the local login, so it works offline and doesn't check that the tokens are still valid.`;static enableJsonFlag=!0;static group=`Authentication`;static examples=[{description:`List the stored accounts.`,command:`apify auth list`},{description:`List the stored accounts as JSON, for scripts.`,command:`apify auth list --json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth-list`;async run(){assertSupportedAuthFileVersion();let e=readAuthFile(),n=getActiveProfileId(),r=readEnvToken(),i=await getBackend(),a=listProfiles().map(t=>({id:t.id,name:profileLabel(t),username:t.username??null,active:t.id===n,isOrganization:!!t.organizationOwnerUserId,organizationOwnerUserId:t.organizationOwnerUserId??null,loggedInAt:t.loggedInAt,secretsBackend:(t.token??(t.id===n?e.token:void 0))===void 0?i===`keyring`?i:null:`file`}));if(this.flags.json)printJsonToStdout({envTokenInUse:r.kind!==`unset`,profiles:a});else if(r.kind===`token`?warning({message:`${B.TOKEN} is set, so commands use it instead of the active account.`}):r.kind===`invalid`&&warning({message:invalidEnvTokenMessage(r.raw)}),!a.length)simpleLog({message:Fn,stdout:!0});else{for(let e of a)Vr.pushRow({Name:e.active?`${t.bold(e.name)} ${t.green(`(active)`)}`:e.name,"User ID":t.gray(e.id),Type:e.isOrganization?`Organization`:`Personal`,"Last login":e.loggedInAt?q.display(new Date(e.loggedInAt)):t.gray(`Unknown`),Storage:Br[e.secretsBackend??`none`]});simpleLog({message:Vr.render(1),stdout:!0})}}};const Hr=stdinCheckWrapper(async({message:e,mask:t})=>await Mt({message:e,mask:t??`*`},In)),wrapResponse=e=>({status(t){e.statusCode=t},send(t){typeof t==`string`?(e.setHeader(`Content-Type`,`text/plain; charset=utf-8`),e.end(t)):(e.setHeader(`Content-Type`,`application/json; charset=utf-8`),e.end(JSON.stringify(t)))},end(){e.end()}});function createLocalApiServer({corsOrigin:e,authToken:t,routes:n}){return Nt(async(r,i)=>{if(i.setHeader(`Connection`,`close`),i.setHeader(`Vary`,`Origin`),i.setHeader(`Access-Control-Allow-Origin`,e),r.method===`OPTIONS`){i.setHeader(`Access-Control-Allow-Methods`,`GET,HEAD,PUT,PATCH,POST,DELETE`),i.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),i.statusCode=204,i.end();return}let a=new URL(r.url??`/`,`http://localhost`),s=wrapResponse(i),c=a.searchParams.get(`token`);if(!c){let e=r.headers.authorization;if(e){let[t,n,...r]=e.trim().split(/\s+/);t.toLowerCase()===`bearer`&&n&&r.length===0&&(c=n)}}if(c!==t){s.status(401),s.send(`Authorization failed`);return}let l=n[`${r.method} ${a.pathname}`];if(!l){s.status(404),s.send(`Not found`);return}let u=[];for await(let e of r)u.push(e);let f=Buffer.concat(u).toString(`utf-8`),p={};if(f)try{p=JSON.parse(f)}catch{s.status(400),s.send(`Invalid JSON body`);return}await l(p,s)})}function pkceChallengeFromVerifier(e){return Pt(`sha256`).update(e).digest(`base64url`)}const Ur=`/callback`;async function loginWithAuthorizationCode({metadata:e,clientId:t,signal:n,onPrompt:r}){if(!e.authorization_endpoint)return{unsupported:!0,reason:`the authorization server does not advertise an authorization endpoint`};let i=Ft(32).toString(`base64url`),a=pkceChallengeFromVerifier(i),s=Ft(16).toString(`base64url`),c,l=new Promise(e=>{c=e}),u=Nt((e,t)=>{t.setHeader(`Connection`,`close`);let n=new URL(e.url??`/`,`http://127.0.0.1`);if(e.method!==`GET`||n.pathname!==Ur){t.statusCode=404,t.end(`Not found`);return}if(n.searchParams.get(`state`)!==s){t.statusCode=400,t.end(`Invalid state`);return}let r=n.searchParams.get(`error`),i=n.searchParams.get(`code`);if(r||!i){t.statusCode=400,t.end(`Login failed. You can close this tab.`);let e=n.searchParams.get(`error_description`)??r??`no authorization code was returned`;c({stopReason:`accessDenied`,message:`Login to Apify failed: ${e}.`})}else t.setHeader(`Content-Type`,`text/html; charset=utf-8`),t.end(`<!doctype html><html><head><meta charset="utf-8"><title>Apify CLI</title></head>
122
122
  <body style="font-family:system-ui,sans-serif;text-align:center;padding:4rem">
123
123
  <h1>You are logged in to the Apify CLI</h1><p>You can close this tab and return to your terminal.</p>
124
124
  </body></html>`),c({code:i})}),f=setTimeout(()=>c({stopReason:`timedOut`,message:`Login to Apify did not finish within ${On/6e4} minutes.`}),On);n?.addEventListener(`abort`,()=>c({stopReason:`aborted`,message:`Login was aborted.`}),{once:!0});try{await new Promise((e,t)=>{u.once(`error`,t),u.listen(0,`127.0.0.1`,()=>e())})}catch(e){return clearTimeout(f),{unsupported:!0,reason:`could not start a loopback server: ${e.message}`}}let{port:p}=u.address(),m=`http://127.0.0.1:${p}${Ur}`,h=new URL(e.authorization_endpoint);h.searchParams.set(`response_type`,`code`),h.searchParams.set(`client_id`,t),h.searchParams.set(`redirect_uri`,m),h.searchParams.set(`scope`,Dn),h.searchParams.set(`state`,s),h.searchParams.set(`code_challenge`,a),h.searchParams.set(`code_challenge_method`,`S256`);let g;try{await r(h.href),g=await l}finally{clearTimeout(f),u.closeAllConnections(),u.close()}if(`stopReason`in g)return g;let _=await postTokenRequest(e.token_endpoint,{grant_type:`authorization_code`,code:g.code,redirect_uri:m,client_id:t,code_verifier:i});return _.ok?{tokens:_.tokens}:{stopReason:`exchangeFailed`,message:`Login to Apify failed, the authorization code could not be exchanged: ${_.error.message}`}}const requestDeviceAuthorization=async(e,t)=>{let n;try{n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,Accept:`application/json`,...un},body:new URLSearchParams({client_id:t,scope:Dn}),signal:AbortSignal.timeout(kn)})}catch(t){return{ok:!1,reason:`could not reach ${e}: ${t.message}`}}let r={};try{r=await n.json()}catch{}return!n.ok||!r.device_code||!r.user_code||!r.verification_uri||!r.expires_in?{ok:!1,reason:`device authorization failed (${r.error_description??r.error??`status ${n.status}`})`}:{ok:!0,body:r}};async function loginWithDeviceCode({metadata:e,clientId:t,signal:n,onPrompt:r}){if(!e.device_authorization_endpoint)return{unsupported:!0,reason:`the authorization server does not advertise a device authorization endpoint`};let i=await requestDeviceAuthorization(e.device_authorization_endpoint,t);if(!i.ok)return{unsupported:!0,reason:i.reason};let{device_code:a,user_code:s,verification_uri:c,verification_uri_complete:l,expires_in:u,interval:f}=i.body;await r({verificationUri:c,verificationUriComplete:l,userCode:s,expiresInSeconds:u});let p=f??5,m=Date.now()+u*1e3;for(;Date.now()<m;){try{await Fe(p*1e3,void 0,{signal:n})}catch{return{stopReason:`aborted`,message:`Login was aborted.`}}if(n?.aborted)return{stopReason:`aborted`,message:`Login was aborted.`};let r;try{r=await postTokenRequest(e.token_endpoint,{grant_type:`urn:ietf:params:oauth:grant-type:device_code`,device_code:a,client_id:t})}catch(e){cliDebugPrint(`oauth`,`device code poll failed`,e);continue}if(r.ok)return{tokens:r.tokens};switch(cliDebugPrint(`oauth`,`device code poll`,r.error.code,`next in ${p}s`),r.error.code){case`authorization_pending`:continue;case`slow_down`:p+=5;continue;case`access_denied`:return{stopReason:`accessDenied`,message:`Login to Apify failed, the request was denied in Apify Console.`};case`expired_token`:return{stopReason:`expired`,message:`Login to Apify failed, the device code expired before it was confirmed.`};default:return{stopReason:`accessDenied`,message:`Login to Apify failed, the authorization server answered: ${r.error.message}`}}}return{stopReason:`expired`,message:`Login to Apify failed, the device code expired before it was confirmed.`}}var OAuthDiscoveryError=class extends Error{name=`OAuthDiscoveryError`};async function fetchAuthorizationServerMetadata(e){let t=`${e}/.well-known/oauth-authorization-server`,n;try{n=await fetch(t,{headers:{Accept:`application/json`,...un},signal:AbortSignal.timeout(kn)})}catch(e){throw new OAuthDiscoveryError(`Could not reach ${t}: ${e.message}`)}if(!n.ok)throw new OAuthDiscoveryError(`Fetching ${t} failed with status ${n.status}.`);let r;try{r=await n.json()}catch{throw new OAuthDiscoveryError(`${t} did not return valid JSON.`)}if(typeof r.token_endpoint!=`string`)throw new OAuthDiscoveryError(`${t} is missing "token_endpoint".`);if(r.issuer!==e)throw new OAuthDiscoveryError(`${t} reports issuer "${r.issuer}", expected "${e}".`);return r}const getApiBaseUrlForLogin=()=>getConsoleUrl().includes(`localhost`)?`http://localhost:3333`:void 0,describeTokenLocation=async t=>await backendFor(t)===`keyring`?`your OS keyring`:e.env.APIFY_DISABLE_KEYRING===`1`?`${AUTH_FILE_PATH()} (OS keyring disabled via APIFY_DISABLE_KEYRING)`:`${AUTH_FILE_PATH()} (OS keyring unavailable; set APIFY_DISABLE_KEYRING=1 to silence)`,reportLoginSuccess=async(e,{refreshes:n})=>{await updateUserId(e.id);let r=await describeTokenLocation(e.id),i=n?`Your session refreshes automatically; the token is stored in ${r}.`:`Your token is stored in ${r}.`;success({message:`You are logged in to Apify as ${e.username||e.id}. ${t.gray(i)}`});let a=Object.entries(readAuthFile().profiles??{}).filter(([t])=>t!==e.id).map(([e,t])=>profileLabel({id:e,...t}));a.length>0&&info({message:`Other stored accounts: ${a.join(`, `)}.`})},tryToLogin=async t=>{let n=await loginWithToken(t,getApiBaseUrlForLogin());return n?await reportLoginSuccess(n.userInfo,{refreshes:!1}):(e.exitCode=1,error({message:`Login to Apify failed, the provided API token is not valid.`})),n};var AuthLoginCommand=class extends ApifyCommand{static name=`login`;static description=`Authenticates your Apify account and saves credentials to '${tildify(AUTH_FILE_PATH())}'.\nAll other commands use these stored credentials.
125
125
 
126
- By default, you confirm logging in to Apify Console in your browser by entering a code. To remove authentication, run 'apify logout'.`;static group=`Authentication`;static interactive=!0;static interactiveNote=`Opens Apify Console in your browser to confirm the login. To run non-interactively, pass --token <api-token>.`;static examples=[{description:`Log in by confirming the request in Apify Console in your browser.`,command:`apify login`},{description:`Log in non-interactively with an API token.`,command:`apify login --token apify_api_xxxxx`},{description:`Log in through the legacy Apify Console hand-off.`,command:`apify login --method console`},{description:`Type an API token into a prompt.`,command:`apify login --method manual`},{description:`Log in on a remote machine by confirming the request in Apify Console in your browser.`,command:`apify login --method oauth2`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-login`;static flags={token:Y.string({char:`t`,description:`Apify API token to log in with and save to your OS keyring.`,required:!1}),method:Y.string({char:`m`,description:`Method of logging in to Apify. The default method ('oauth2') confirms the login when you enter a code. The 'manual' method prompts for an API token. The 'console' method uses the legacy Console hand-off, which is deprecated.`,choices:[`oauth2`,`console`,`manual`],default:`oauth2`,required:!1})};async run(){let{token:t,method:n}=this.flags,r=readEnvToken();if(r.kind===`invalid`&&warning({message:invalidEnvTokenMessage(r.raw)}),r.kind===`token`&&r.token!==t?.trim()){error({message:`${B.TOKEN} is set, so other commands will ignore this login. Unset ${B.TOKEN} and try again.`}),e.exitCode=5;return}if(t){this.telemetryData.login={method:`token`},await tryToLogin(t);return}switch(n){case`manual`:await this.loginManually();break;case`console`:this.telemetryData.login={method:`console`},await this.loginViaLegacyConsole();break;default:await this.loginViaOAuth()}}async loginManually(){this.telemetryData.login={method:`manual`},console.log(`Enter your Apify API token. You can find it at ${getConsoleIntegrationsUrl()}`);let e=await Hr({message:`token:`});await tryToLogin(e)}async loginViaOAuth(){try{var e=_usingCtx();let n=getOAuthIssuerUrl(),r=getOAuthClientId(),i;try{i=await fetchAuthorizationServerMetadata(n)}catch(e){cliDebugPrint(`oauth`,`discovery failed`,e),this.reportUnavailableLogin(`Could not reach the Apify Console authorization server at ${n}.`);return}let a=new AbortController;e.u(useSignalHandler({signals:on,handler:()=>a.abort()})),this.telemetryData.login={method:`oauth2-device`};let s=await loginWithDeviceCode({metadata:i,clientId:r,signal:a.signal,onPrompt:({verificationUri:e,verificationUriComplete:n,userCode:r})=>{let i=n??e;info({message:[`${t.white(`Info:`)} Opening Apify Console to confirm your login...`,``,t.gray(`If the browser does not open, visit ${t.bold(i)} and approve the login.`),``,t.gray(`If prompted, enter the code ${t.reset.bold(r)}.`),``,`${t.white(`Info:`)} Waiting for you to confirm the login in your browser...`].join(`
127
- `)}),Dt(i).catch(e=>cliDebugPrint(`oauth`,`could not open the browser`,e))}});if(`tokens`in s){await this.finishOAuthLogin(s.tokens,i,r);return}if(`stopReason`in s){this.reportStoppedLogin(s);return}cliDebugPrint(`oauth`,`device code flow unavailable`,s.reason),info({message:`Device code login is not available. Opening the Apify Console sign-in page instead.`}),this.telemetryData.login={method:`oauth2-code`,fellBackFrom:`oauth2-device`};let c=await loginWithAuthorizationCode({metadata:i,clientId:r,signal:a.signal,onPrompt:e=>{info({message:`Opening Apify Console at "${e}"...`}),Dt(e).catch(e=>cliDebugPrint(`oauth`,`could not open the browser`,e)),info({message:`Waiting for you to confirm the login in your browser...`})}});if(`tokens`in c){await this.finishOAuthLogin(c.tokens,i,r);return}if(`stopReason`in c){this.reportStoppedLogin(c);return}cliDebugPrint(`oauth`,`authorization code flow unavailable`,c.reason),this.reportUnavailableLogin(`Browser login is not available.`)}catch(t){e.e=t}finally{e.d()}}reportUnavailableLogin(t){error({message:`${t} Log in with "apify login --method manual" or "apify login --token <api-token>" instead.`}),e.exitCode=1}reportStoppedLogin({stopReason:t,message:n}){t===`aborted`?info({message:`Login cancelled.`}):error({message:n}),e.exitCode=1}async finishOAuthLogin(t,n,r){let i=await loginWithToken(t.access_token,getApiBaseUrlForLogin());if(!i){error({message:`Login to Apify failed, the token issued by Apify Console was not accepted by the Apify API.`}),e.exitCode=1;return}await saveOAuthSession(i.userInfo.id,t,{issuer:n.issuer,clientId:r,tokenEndpoint:n.token_endpoint}),await reportLoginSuccess(i.userInfo,{refreshes:!0})}async loginViaLegacyConsole(){let e=new URL(getConsoleUrl()).origin,t=De(),n=createLocalApiServer({corsOrigin:e,authToken:t,routes:{"POST /api/v1/login-token":async(e,t)=>{try{if(e.apiToken)await tryToLogin(e.apiToken);else throw Error(`Request did not contain API token`);t.end()}catch(e){let n=`Login to Apify failed with error: ${e.message}`;error({message:n}),t.status(500),t.send(n)}n.close()},"POST /api/v1/exit":(e,t)=>{e.isWindowClosed?error({message:`Login to Apify failed, the console window was closed.`}):e.actionCanceled?error({message:`Login to Apify failed, the action was canceled in the Apify Console.`}):error({message:`Login to Apify failed.`}),t.end(),n.close()}}});n.listen(0);let{port:r}=n.address(),i=new URL(getConsoleIntegrationsUrl());i.searchParams.set(`localCliCommand`,`login`),i.searchParams.set(`localCliPort`,`${r}`),i.searchParams.set(`localCliToken`,t),i.searchParams.set(`localCliApiVersion`,`v1`);try{i.searchParams.set(`localCliComputerName`,encodeURIComponent(jt()))}catch{}info({message:`Opening Apify Console at "${i.href}"...`}),await Dt(i.href)}},AuthLogoutCommand=class extends ApifyCommand{static name=`logout`;static description=`Logs out of the active account by deleting its API token and account information from '${tildify(AUTH_FILE_PATH())}'.\nIf other accounts are stored, the most recently logged-in one becomes active.
128
- Run 'apify login' to authenticate again.`;static group=`Authentication`;static examples=[{description:`Remove the stored Apify credentials.`,command:`apify logout`},{description:`Log out of one stored account and keep the active one.`,command:`apify logout --profile my-org`},{description:`Log out of every stored account without a prompt.`,command:`apify logout --all --yes`}];static flags={profile:Y.string({description:`The stored account to log out of, by name or user ID. See "apify auth list".`,exclusive:[`all`]}),all:Y.boolean({description:`Log out of every stored account.`,exclusive:[`profile`]}),...YesFlag()};static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-logout`;async run(){if(!this.flags.profile&&!O(AUTH_FILE_PATH())){let t=await clearKeyringSecrets();t.length?(error({message:partialLogoutMessage(t,null,{hadFile:!1})}),e.exitCode=1):info({message:Fn})}else if(!(this.flags.all?await this.logOutOfAll():await this.logOutOf(this.flags.profile)))return;let t=readEnvToken();t.kind===`token`?warning({message:`${B.TOKEN} is still set, so commands stay authenticated with that token.`}):t.kind===`invalid`&&warning({message:invalidEnvTokenMessage(t.raw)})}async logOutOf(t){let n=getActiveProfileId(),r=t?await requireProfile(t):void 0,i=r?.id??n,a=i===n,s=await clearKeyringSecrets(i,{keepLegacy:!a}),c=null,l={};try{l=removeProfile(i)}catch(e){c=e}let{removed:u,active:f}=l;if(a&&!c&&await updateUserId(f?.id??null),s.length||c){let t=!a&&r?profileLabel(r):void 0;error({message:partialLogoutMessage(s,c,{keptAccount:t})}),e.exitCode=1}else success(a?f?{message:`You are logged out${u?` of ${profileLabel(u)}`:``}. ${profileLabel(f)} is now the active account.`}:{message:`You are logged out from your Apify account.`}:{message:`You are logged out${u?` of ${profileLabel(u)}`:``}.${f?` ${profileLabel(f)} is still the active account.`:``}`});return!0}async logOutOfAll(){let t=listProfiles();if(t.length&&!this.flags.yes&&!await X({message:`Log out of ${t.length===1?`your stored account`:`all ${t.length} stored accounts`}?`,errorMessageForStdin:`Use --yes to log out of every stored account without a prompt.`}))return info({message:`Logout was cancelled.`}),!1;let n=await clearKeyringSecrets();for(let e of/* @__PURE__ */ new Set([getActiveProfileId(),...t.map(e=>e.id)]))n.push(...await clearKeyringSecrets(e,{keepLegacy:!0}));let r=null;try{removeAllProfiles()}catch(e){r=e}return r||await updateUserId(null),n.length||r?(error({message:partialLogoutMessage(n,r)}),e.exitCode=1):success({message:`You are logged out of all your Apify accounts.`}),!0}};function reasonOf(e){return e instanceof Error?e.message:String(e)}function partialLogoutMessage(e,t,{hadFile:n=!0,keptAccount:r}={}){return`Logout did not finish. ${e.length?`Your secrets are still in the OS keyring at ${describeLeftovers(e)}; delete them with your OS keyring app.`:`Your secrets were removed from the OS keyring.`}${n?t?r?` ${r} is still stored in ${tildify(AUTH_FILE_PATH())}; run the logout again to remove it.`:` Your account is still in ${tildify(AUTH_FILE_PATH())}; delete that file to finish logging out.`:` Your account was removed from ${tildify(AUTH_FILE_PATH())}.`:``} The reason was: ${[leftoverReasons(e),t?reasonOf(t):``].filter(Boolean).join(` `)}`}const Wr=stdinCheckWrapper(async({message:e,choices:t,pageSize:n,loop:r,default:i})=>await It({message:e,choices:t,pageSize:n,loop:r,default:i},In),{errorMessageForStdin:`Please provide the selection using the command options.`});var AuthSwitchCommand=class extends ApifyCommand{static name=`switch`;static description=`Sets the stored account that commands use. Without an argument, prompts you to pick one of the stored accounts.`;static group=`Authentication`;static interactive=!0;static interactiveNote=`Prompts for the account when called without an argument. Pass the name or user ID to skip the prompt.`;static args={profile:Z.string({description:`The stored account to make active, by name or user ID. See "apify auth list".`})};static examples=[{description:`Pick the active account from a list.`,command:`apify auth switch`},{description:`Make the "my-org" account active.`,command:`apify auth switch my-org`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth-switch`;async run(){if(readEnvToken().kind!==`unset`)throw e.exitCode=5,Error(envTokenOverridesProfileMessage(`the active account`));let t=await requireProfile(this.args.profile??await this.pickProfile());if(!await getSecret(t.id,`token`))throw e.exitCode=1,Error(missingProfileTokenMessage(t));if(t.id===getActiveProfileId()){info({message:`${profileLabel(t)} is already the active account.`});return}setActiveProfile(t.id),await updateUserId(t.id),success({message:`${profileLabel(t)} is now the active account.`})}async pickProfile(){await ensureCredentialsCurrent();let t=listProfiles();if(!t.length)throw e.exitCode=1,Error(Fn);return Wr({message:`Which account do you want to use?`,choices:t.map(e=>({name:`${profileLabel(e)} (${e.id})`,value:e.id})),default:getActiveProfileId(),errorMessageForStdin:`Pass the account to switch to, for example "apify auth switch <name>". Run "apify auth list" to see the stored accounts.`})}},AuthTokenCommand=class extends ApifyCommand{static name=`token`;static enableProfileFlag=!0;static description=`Prints the API token the CLI authenticates with, resolved from APIFY_TOKEN or the token from 'apify login'.
129
- Tokens from an OAuth login expire after about an hour. The command prints the expiry time to stderr.`;static examples=[{description:`Print the resolved API token to stdout. Be careful with the output, it's a secret.`,command:`apify auth token`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth-token`;async run(){await getLoggedClientOrThrow();let e=await resolveAuth();simpleLog({message:e.token,stdout:!0});let t=e.profile?lookUpProfile(e.profile.id).profile:void 0;t?.authMethod===`oauth2`&&t.expiresAt&&simpleLog({message:`Note: this token expires at ${t.expiresAt}.`})}},AuthIndexCommand=class extends ApifyCommand{static name=`auth`;static description="Log in, log out, switch between stored accounts, and inspect your stored Apify API token. Also available as `apify login` and `apify logout`.";static group=`Authentication`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth`;static subcommands=[AuthLoginCommand,AuthLogoutCommand,AuthListCommand,AuthSwitchCommand,AuthTokenCommand];async run(){this.printHelp()}},BuildsAddTagCommand=class extends ApifyCommand{static name=`add-tag`;static enableProfileFlag=!0;static description=`Adds a tag to a specific Actor build.`;static examples=[{description:`Tag a successful build as "latest".`,command:`apify builds add-tag --build <buildId> --tag latest`},{description:`Tag a build with a custom name like "beta".`,command:`apify builds add-tag --build <buildId> --tag beta`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-add-tag`;static flags={build:Y.string({char:`b`,description:`The build ID to tag.`,required:!0}),tag:Y.string({char:`t`,description:`The tag to add to the build.`,required:!0})};async run(){let{build:e,tag:n}=this.flags,r=await getLoggedClientOrThrow(),i=await r.build(e).get();if(!i){error({message:`Build with ID "${e}" was not found on your account.`,stdout:!0});return}if(i.status!==`SUCCEEDED`){error({message:`Build with ID "${e}" has status "${i.status}". Only successful builds can be tagged.`,stdout:!0});return}let a=await r.actor(i.actId).get();if(!a){error({message:`Actor with ID "${i.actId}" was not found.`,stdout:!0});return}let s=(a.taggedBuilds??{})[n];if(s?.buildId===e){warning({message:`Build "${e}" is already tagged as "${n}".`,stdout:!0});return}try{await r.actor(i.actId).update({taggedBuilds:{[n]:{buildId:i.id}}});let a=s?.buildNumber?` (previously pointed to build ${t.gray(s.buildNumber)})`:``;success({message:`Tag "${t.yellow(n)}" added to build ${t.gray(i.buildNumber)} (${t.gray(e)})${a}`,stdout:!0})}catch(t){let r=t;error({message:`Failed to add tag "${n}" to build "${e}".\n ${r.message||r}`,stdout:!0})}}};const noColor=e=>e;function prettyPrintBytes({bytes:e,shortBytes:t=!1,colorFunc:n=noColor,precision:r=2}){let i=[t?`B`:`Bytes`,`KB`,`MB`,`GB`,`TB`];if(e===0)return t?`${0 .toPrecision(r)} B`:`${0 .toPrecision(r)} Byte`;let a=Math.floor(Math.log(e)/Math.log(1e3));return`${(e/1e3**a).toFixed(r)} ${n(i[a])}`}var BuildsInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Prints information about a specific build.`;static examples=[{description:`Print information about a build.`,command:`apify builds info <buildId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-info`;static args={buildId:Z.string({required:!0,description:`The build ID to get information about.`})};static enableJsonFlag=!0;async run(){let{buildId:e}=this.args,n=await getLoggedClientOrThrow(),r=await n.build(e).get();if(!r){error({message:`Build with ID "${e}" was not found on your account.`,stdout:!0});return}if(this.flags.json){printJsonToStdout(r);return}let i=await n.actor(r.actId).get(),a;if(i?.taggedBuilds){for(let[e,t]of Object.entries(i.taggedBuilds))if(t.buildId===r.id){a=e;break}}let s=Reflect.get(r,`exitCode`),c=i?.username?`${i.username}/${i.name}`:i?.name??`unknown-actor`,l=a?` (tagged as ${t.yellow(a)})`:``,u=s===void 0?``:` (exit code: ${t.gray(s)})`,f=[`${t.yellow(`Actor`)}: ${c} (${t.gray(r.actId)})`,``,`${t.yellow(`Build Information`)} (ID: ${t.gray(r.id)})`,` ${t.yellow(`Build Number`)}: ${r.buildNumber}${l}`,` ${t.yellow(`Status`)}: ${prettyPrintStatus(r.status)}${u}`,` ${t.yellow(`Started`)}: ${q.display(r.startedAt)}`];if(r.finishedAt)f.push(` ${t.yellow(`Finished`)}: ${q.display(r.finishedAt)} (took ${t.gray(nr.format(r.stats?.durationMillis??0))})`);else{let e=Date.now()-r.startedAt.getTime();f.push(` ${t.yellow(`Finished`)}: ${t.gray(`Running for ${nr.format(e)}`)}`)}r.stats?.computeUnits&&f.push(` ${t.yellow(`Compute Units`)}: ${r.stats.computeUnits.toFixed(3)}`);let p=Reflect.get(r.stats??{},`imageSizeBytes`);p&&f.push(` ${t.yellow(`Docker Image Size`)}: ${prettyPrintBytes({bytes:p})}`),f.push(` ${t.yellow(`Origin`)}: ${r.meta.origin??`UNKNOWN`}`),f.push(``);let m=consoleBuildUrl(r.actId,r.buildNumber);f.push(`${t.blue(`View in Apify Console`)}: ${m}`),simpleLog({message:f.join(`
126
+ By default, you confirm logging in to Apify Console in your browser by entering a code. To remove authentication, run 'apify logout'.`;static group=`Authentication`;static interactive=!0;static interactiveNote=`Opens Apify Console in your browser to confirm the login. To run non-interactively, pass --token <api-token>.`;static examples=[{description:`Log in by confirming the request in Apify Console in your browser.`,command:`apify login`},{description:`Log in non-interactively with an API token.`,command:`apify login --token apify_api_xxxxx`},{description:`Log in through the legacy Apify Console hand-off.`,command:`apify login --method console`},{description:`Type an API token into a prompt.`,command:`apify login --method manual`},{description:`Log in on a remote machine by confirming the request in Apify Console in your browser.`,command:`apify login --method oauth2`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-login`;static flags={token:Y.string({char:`t`,description:`Apify API token to log in with and save to your OS keyring.`,required:!1}),method:Y.string({char:`m`,description:`Method of logging in to Apify. The default method ('oauth2') confirms the login when you enter a code. The 'manual' method prompts for an API token. The 'console' method uses the legacy Console hand-off, which is deprecated.`,choices:[`oauth2`,`console`,`manual`],default:`oauth2`,required:!1})};async run(){let{token:t,method:n}=this.flags,r=readEnvToken();if(r.kind===`invalid`&&warning({message:invalidEnvTokenMessage(r.raw)}),r.kind===`token`&&r.token!==t?.trim())error({message:`${B.TOKEN} is set, so other commands will ignore this login. Unset ${B.TOKEN} and try again.`}),e.exitCode=5;else if(t)this.telemetryData.login={method:`token`},await tryToLogin(t);else switch(n){case`manual`:await this.loginManually();break;case`console`:this.telemetryData.login={method:`console`},await this.loginViaLegacyConsole();break;default:await this.loginViaOAuth()}}async loginManually(){this.telemetryData.login={method:`manual`},console.log(`Enter your Apify API token. You can find it at ${getConsoleIntegrationsUrl()}`);let e=await Hr({message:`token:`});await tryToLogin(e)}async loginViaOAuth(){try{var e=_usingCtx();let n=getOAuthIssuerUrl(),r=getOAuthClientId(),i;try{i=await fetchAuthorizationServerMetadata(n)}catch(e){cliDebugPrint(`oauth`,`discovery failed`,e),this.reportUnavailableLogin(`Could not reach the Apify Console authorization server at ${n}.`);return}let a=new AbortController;e.u(useSignalHandler({signals:on,handler:()=>a.abort()})),this.telemetryData.login={method:`oauth2-device`};let s=await loginWithDeviceCode({metadata:i,clientId:r,signal:a.signal,onPrompt:({verificationUri:e,verificationUriComplete:n,userCode:r})=>{let i=n??e;info({message:[`${t.white(`Info:`)} Opening Apify Console to confirm your login...`,``,t.gray(`If the browser does not open, visit ${t.bold(i)} and approve the login.`),``,t.gray(`If prompted, enter the code ${t.reset.bold(r)}.`),``,`${t.white(`Info:`)} Waiting for you to confirm the login in your browser...`].join(`
127
+ `)}),Dt(i).catch(e=>cliDebugPrint(`oauth`,`could not open the browser`,e))}});if(`tokens`in s){await this.finishOAuthLogin(s.tokens,i,r);return}if(`stopReason`in s){this.reportStoppedLogin(s);return}cliDebugPrint(`oauth`,`device code flow unavailable`,s.reason),info({message:`Device code login is not available. Opening the Apify Console sign-in page instead.`}),this.telemetryData.login={method:`oauth2-code`,fellBackFrom:`oauth2-device`};let c=await loginWithAuthorizationCode({metadata:i,clientId:r,signal:a.signal,onPrompt:e=>{info({message:`Opening Apify Console at "${e}"...`}),Dt(e).catch(e=>cliDebugPrint(`oauth`,`could not open the browser`,e)),info({message:`Waiting for you to confirm the login in your browser...`})}});if(`tokens`in c){await this.finishOAuthLogin(c.tokens,i,r);return}if(`stopReason`in c){this.reportStoppedLogin(c);return}cliDebugPrint(`oauth`,`authorization code flow unavailable`,c.reason),this.reportUnavailableLogin(`Browser login is not available.`)}catch(t){e.e=t}finally{e.d()}}reportUnavailableLogin(t){error({message:`${t} Log in with "apify login --method manual" or "apify login --token <api-token>" instead.`}),e.exitCode=1}reportStoppedLogin({stopReason:t,message:n}){t===`aborted`?info({message:`Login cancelled.`}):error({message:n}),e.exitCode=1}async finishOAuthLogin(t,n,r){let i=await loginWithToken(t.access_token,getApiBaseUrlForLogin());i?(await saveOAuthSession(i.userInfo.id,t,{issuer:n.issuer,clientId:r,tokenEndpoint:n.token_endpoint}),await reportLoginSuccess(i.userInfo,{refreshes:!0})):(error({message:`Login to Apify failed, the token issued by Apify Console was not accepted by the Apify API.`}),e.exitCode=1)}async loginViaLegacyConsole(){let e=new URL(getConsoleUrl()).origin,t=De(),n=createLocalApiServer({corsOrigin:e,authToken:t,routes:{"POST /api/v1/login-token":async(e,t)=>{try{if(e.apiToken)await tryToLogin(e.apiToken);else throw Error(`Request did not contain API token`);t.end()}catch(e){let n=`Login to Apify failed with error: ${e.message}`;error({message:n}),t.status(500),t.send(n)}n.close()},"POST /api/v1/exit":(e,t)=>{e.isWindowClosed?error({message:`Login to Apify failed, the console window was closed.`}):e.actionCanceled?error({message:`Login to Apify failed, the action was canceled in the Apify Console.`}):error({message:`Login to Apify failed.`}),t.end(),n.close()}}});n.listen(0);let{port:r}=n.address(),i=new URL(getConsoleIntegrationsUrl());i.searchParams.set(`localCliCommand`,`login`),i.searchParams.set(`localCliPort`,`${r}`),i.searchParams.set(`localCliToken`,t),i.searchParams.set(`localCliApiVersion`,`v1`);try{i.searchParams.set(`localCliComputerName`,encodeURIComponent(jt()))}catch{}info({message:`Opening Apify Console at "${i.href}"...`}),await Dt(i.href)}},AuthLogoutCommand=class extends ApifyCommand{static name=`logout`;static description=`Logs out of the active account by deleting its API token and account information from '${tildify(AUTH_FILE_PATH())}'.\nIf other accounts are stored, the most recently logged-in one becomes active.
128
+ Run 'apify login' to authenticate again.`;static group=`Authentication`;static examples=[{description:`Remove the stored Apify credentials.`,command:`apify logout`},{description:`Log out of one stored account and keep the active one.`,command:`apify logout --profile my-org`},{description:`Log out of every stored account without a prompt.`,command:`apify logout --all --yes`}];static flags={profile:Y.string({description:`The stored account to log out of, by name or user ID. See "apify auth list".`,exclusive:[`all`]}),all:Y.boolean({description:`Log out of every stored account.`,exclusive:[`profile`]}),...YesFlag()};static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-logout`;async run(){if(!this.flags.profile&&!O(AUTH_FILE_PATH())){let t=await clearKeyringSecrets();t.length?(error({message:partialLogoutMessage(t,null,{hadFile:!1})}),e.exitCode=1):info({message:Fn})}else if(!(this.flags.all?await this.logOutOfAll():await this.logOutOf(this.flags.profile)))return;let t=readEnvToken();t.kind===`token`?warning({message:`${B.TOKEN} is still set, so commands stay authenticated with that token.`}):t.kind===`invalid`&&warning({message:invalidEnvTokenMessage(t.raw)})}async logOutOf(t){let n=getActiveProfileId(),r=t?await requireProfile(t):void 0,i=r?.id??n,a=i===n,s=await clearKeyringSecrets(i,{keepLegacy:!a}),c=null,l={};try{l=removeProfile(i)}catch(e){c=e}let{removed:u,active:f}=l;if(a&&!c&&await updateUserId(f?.id??null),s.length||c){let t=!a&&r?profileLabel(r):void 0;error({message:partialLogoutMessage(s,c,{keptAccount:t})}),e.exitCode=1}else success(a?f?{message:`You are logged out${u?` of ${profileLabel(u)}`:``}. ${profileLabel(f)} is now the active account.`}:{message:`You are logged out from your Apify account.`}:{message:`You are logged out${u?` of ${profileLabel(u)}`:``}.${f?` ${profileLabel(f)} is still the active account.`:``}`});return!0}async logOutOfAll(){let t=listProfiles();if(t.length&&!this.flags.yes&&!await X({message:`Log out of ${t.length===1?`your stored account`:`all ${t.length} stored accounts`}?`,errorMessageForStdin:`Use --yes to log out of every stored account without a prompt.`}))return info({message:`Logout was cancelled.`}),!1;let n=await clearKeyringSecrets();for(let e of/* @__PURE__ */ new Set([getActiveProfileId(),...t.map(e=>e.id)]))n.push(...await clearKeyringSecrets(e,{keepLegacy:!0}));let r=null;try{removeAllProfiles()}catch(e){r=e}return r||await updateUserId(null),n.length||r?(error({message:partialLogoutMessage(n,r)}),e.exitCode=1):success({message:`You are logged out of all your Apify accounts.`}),!0}};function reasonOf(e){return e instanceof Error?e.message:String(e)}function partialLogoutMessage(e,t,{hadFile:n=!0,keptAccount:r}={}){return`Logout did not finish. ${e.length?`Your secrets are still in the OS keyring at ${describeLeftovers(e)}; delete them with your OS keyring app.`:`Your secrets were removed from the OS keyring.`}${n?t?r?` ${r} is still stored in ${tildify(AUTH_FILE_PATH())}; run the logout again to remove it.`:` Your account is still in ${tildify(AUTH_FILE_PATH())}; delete that file to finish logging out.`:` Your account was removed from ${tildify(AUTH_FILE_PATH())}.`:``} The reason was: ${[leftoverReasons(e),t?reasonOf(t):``].filter(Boolean).join(` `)}`}const Wr=stdinCheckWrapper(async({message:e,choices:t,pageSize:n,loop:r,default:i})=>await It({message:e,choices:t,pageSize:n,loop:r,default:i},In),{errorMessageForStdin:`Please provide the selection using the command options.`});var AuthSwitchCommand=class extends ApifyCommand{static name=`switch`;static description=`Sets the stored account that commands use. Without an argument, prompts you to pick one of the stored accounts.`;static group=`Authentication`;static interactive=!0;static interactiveNote=`Prompts for the account when called without an argument. Pass the name or user ID to skip the prompt.`;static args={profile:Z.string({description:`The stored account to make active, by name or user ID. See "apify auth list".`})};static examples=[{description:`Pick the active account from a list.`,command:`apify auth switch`},{description:`Make the "my-org" account active.`,command:`apify auth switch my-org`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth-switch`;async run(){if(readEnvToken().kind!==`unset`)throw e.exitCode=5,Error(envTokenOverridesProfileMessage(`the active account`));let t=await requireProfile(this.args.profile??await this.pickProfile());if(!await getSecret(t.id,`token`))throw e.exitCode=1,Error(missingProfileTokenMessage(t));t.id===getActiveProfileId()?info({message:`${profileLabel(t)} is already the active account.`}):(setActiveProfile(t.id),await updateUserId(t.id),success({message:`${profileLabel(t)} is now the active account.`}))}async pickProfile(){await ensureCredentialsCurrent();let t=listProfiles();if(!t.length)throw e.exitCode=1,Error(Fn);return Wr({message:`Which account do you want to use?`,choices:t.map(e=>({name:`${profileLabel(e)} (${e.id})`,value:e.id})),default:getActiveProfileId(),errorMessageForStdin:`Pass the account to switch to, for example "apify auth switch <name>". Run "apify auth list" to see the stored accounts.`})}},AuthTokenCommand=class extends ApifyCommand{static name=`token`;static enableProfileFlag=!0;static description=`Prints the API token the CLI authenticates with, resolved from APIFY_TOKEN or the token from 'apify login'.
129
+ Tokens from an OAuth login expire after about an hour. The command prints the expiry time to stderr.`;static examples=[{description:`Print the resolved API token to stdout. Be careful with the output, it's a secret.`,command:`apify auth token`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth-token`;async run(){await getLoggedClientOrThrow();let e=await resolveAuth();simpleLog({message:e.token,stdout:!0});let t=e.profile?lookUpProfile(e.profile.id).profile:void 0;t?.authMethod===`oauth2`&&t.expiresAt&&simpleLog({message:`Note: this token expires at ${t.expiresAt}.`})}},AuthIndexCommand=class extends ApifyCommand{static name=`auth`;static description="Log in, log out, switch between stored accounts, and inspect your stored Apify API token. Also available as `apify login` and `apify logout`.";static group=`Authentication`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth`;static subcommands=[AuthLoginCommand,AuthLogoutCommand,AuthListCommand,AuthSwitchCommand,AuthTokenCommand];async run(){this.printHelp()}},BuildsAddTagCommand=class extends ApifyCommand{static name=`add-tag`;static enableProfileFlag=!0;static description=`Adds a tag to a specific Actor build.`;static examples=[{description:`Tag a successful build as "latest".`,command:`apify builds add-tag --build <buildId> --tag latest`},{description:`Tag a build with a custom name like "beta".`,command:`apify builds add-tag --build <buildId> --tag beta`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-add-tag`;static flags={build:Y.string({char:`b`,description:`The build ID to tag.`,required:!0}),tag:Y.string({char:`t`,description:`The tag to add to the build.`,required:!0})};async run(){let{build:e,tag:n}=this.flags,r=await getLoggedClientOrThrow(),i=await r.build(e).get();if(!i){error({message:`Build with ID "${e}" was not found on your account.`,stdout:!0});return}if(i.status!==`SUCCEEDED`){error({message:`Build with ID "${e}" has status "${i.status}". Only successful builds can be tagged.`,stdout:!0});return}let a=await r.actor(i.actId).get();if(!a){error({message:`Actor with ID "${i.actId}" was not found.`,stdout:!0});return}let s=(a.taggedBuilds??{})[n];if(s?.buildId===e)warning({message:`Build "${e}" is already tagged as "${n}".`,stdout:!0});else try{await r.actor(i.actId).update({taggedBuilds:{[n]:{buildId:i.id}}});let a=s?.buildNumber?` (previously pointed to build ${t.gray(s.buildNumber)})`:``;success({message:`Tag "${t.yellow(n)}" added to build ${t.gray(i.buildNumber)} (${t.gray(e)})${a}`,stdout:!0})}catch(t){let r=t;error({message:`Failed to add tag "${n}" to build "${e}".\n ${r.message||r}`,stdout:!0})}}};const noColor=e=>e;function prettyPrintBytes({bytes:e,shortBytes:t=!1,colorFunc:n=noColor,precision:r=2}){let i=[t?`B`:`Bytes`,`KB`,`MB`,`GB`,`TB`];if(e===0)return t?`${0 .toPrecision(r)} B`:`${0 .toPrecision(r)} Byte`;let a=Math.floor(Math.log(e)/Math.log(1e3));return`${(e/1e3**a).toFixed(r)} ${n(i[a])}`}var BuildsInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Prints information about a specific build.`;static examples=[{description:`Print information about a build.`,command:`apify builds info <buildId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-info`;static args={buildId:Z.string({required:!0,description:`The build ID to get information about.`})};static enableJsonFlag=!0;async run(){let{buildId:e}=this.args,n=await getLoggedClientOrThrow(),r=await n.build(e).get();if(!r){error({message:`Build with ID "${e}" was not found on your account.`,stdout:!0});return}if(this.flags.json){printJsonToStdout(r);return}let i=await n.actor(r.actId).get(),a;if(i?.taggedBuilds){for(let[e,t]of Object.entries(i.taggedBuilds))if(t.buildId===r.id){a=e;break}}let s=Reflect.get(r,`exitCode`),c=i?.username?`${i.username}/${i.name}`:i?.name??`unknown-actor`,l=a?` (tagged as ${t.yellow(a)})`:``,u=s===void 0?``:` (exit code: ${t.gray(s)})`,f=[`${t.yellow(`Actor`)}: ${c} (${t.gray(r.actId)})`,``,`${t.yellow(`Build Information`)} (ID: ${t.gray(r.id)})`,` ${t.yellow(`Build Number`)}: ${r.buildNumber}${l}`,` ${t.yellow(`Status`)}: ${prettyPrintStatus(r.status)}${u}`,` ${t.yellow(`Started`)}: ${q.display(r.startedAt)}`];if(r.finishedAt)f.push(` ${t.yellow(`Finished`)}: ${q.display(r.finishedAt)} (took ${t.gray(nr.format(r.stats?.durationMillis??0))})`);else{let e=Date.now()-r.startedAt.getTime();f.push(` ${t.yellow(`Finished`)}: ${t.gray(`Running for ${nr.format(e)}`)}`)}r.stats?.computeUnits&&f.push(` ${t.yellow(`Compute Units`)}: ${r.stats.computeUnits.toFixed(3)}`);let p=Reflect.get(r.stats??{},`imageSizeBytes`);p&&f.push(` ${t.yellow(`Docker Image Size`)}: ${prettyPrintBytes({bytes:p})}`),f.push(` ${t.yellow(`Origin`)}: ${r.meta.origin??`UNKNOWN`}`),f.push(``);let m=consoleBuildUrl(r.actId,r.buildNumber);f.push(`${t.blue(`View in Apify Console`)}: ${m}`),simpleLog({message:f.join(`
130
130
  `),stdout:!0})}},BuildsLogCommand=class extends ApifyCommand{static name=`log`;static enableProfileFlag=!0;static description=`Prints the log of a specific build.`;static examples=[{description:`Print the build log.`,command:`apify builds log <buildId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-log`;static args={buildId:Z.string({required:!0,description:`The build ID to get the log from.`})};async run(){let{buildId:e}=this.args,t=await getLoggedClientOrThrow(),n=await t.build(e).get();if(!n)throw Error(`Build with ID "${e}" was not found on your account.`);info({message:`Log for build with ID "${e}":\n`}),await outputJobLog({job:n,apifyClient:t})}};const tableFactory=()=>new Q({allColumns:[`Number`,`ID`,`Status`,`Took`],mandatoryColumns:[`Number`,`ID`,`Status`,`Took`],columnAlignments:{Took:`right`}});var BuildsLsCommand=class extends ApifyCommand{static name=`ls`;static enableProfileFlag=!0;static description=`Lists all builds of the Actor.`;static examples=[{description:`List builds of the Actor in the current directory.`,command:`apify builds ls`},{description:`List builds of a specific Actor.`,command:`apify builds ls apify/hello-world`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-ls`;static flags={offset:Y.integer({description:`Number of builds that will be skipped.`,default:0}),limit:Y.integer({description:`Number of builds that will be listed.`,default:10}),desc:Y.boolean({description:`Sort builds in descending order.`,default:!1}),compact:Y.boolean({description:`Display a compact table.`,default:!1,char:`c`})};static args={actorId:Z.string({description:`Optional Actor ID or Name to list runs for. By default, it will use the Actor from the current directory.`})};static enableJsonFlag=!0;async run(){let{desc:e,limit:n,offset:r,compact:i,json:a}=this.flags,{actorId:s}=this.args,c=await getLoggedClientOrThrow(),l=await resolveActorContext({providedActorNameOrId:s,client:c});if(!l.valid){error({message:`${l.reason}. Please run this command in an Actor directory, or specify the Actor ID.`,stdout:!0});return}let u=await c.actor(l.id).builds().list({desc:e,limit:n,offset:r}),f=await c.actor(l.id).get(),p=objectGroupBy(u.items,e=>{let[t,n]=Reflect.get(e,`buildNumber`).split(`.`);return`${t}.${n}`}),m=Object.entries(f.taggedBuilds??{}).reduce((e,[t,n])=>(e[n.buildNumber]=t,e),{});if(a){for(let e of u.items){let t=m[Reflect.get(e,`buildNumber`)];t&&Reflect.set(e,`buildTag`,t)}printJsonToStdout(u);return}simpleLog({message:`${t.reset(`Showing`)} ${t.yellow(u.items.length)} out of ${t.yellow(u.total)} builds for Actor ${t.yellow(l.userFriendlyId)} (${t.gray(l.id)})\n`,stdout:!0});let h=Object.entries(p).sort((e,t)=>e[0].localeCompare(t[0]));for(let[e,n]of h){if(!n?.length){simpleLog({message:`No builds for version ${e}`,stdout:!0});continue}let r=f.versions.find(t=>t.versionNumber===e)?.buildTag,a=this.generateTableForActorVersion({buildsForVersion:n,buildTagToActorVersion:m}),s=r?` (latest build gets tagged with ${t.yellow(r)})`:``;simpleLog({message:[t.reset(`Builds for Actor Version ${t.yellow(e)}${s}`),a.render(i?0:-1),``].join(`
131
- `),stdout:!0})}}generateTableForActorVersion({buildsForVersion:e,buildTagToActorVersion:n}){let r=tableFactory();for(let i of e){let e=Reflect.get(i,`buildNumber`),a=n[e]?` (${t.yellow(n[e])})`:``,s;if(i.finishedAt){let e=i.finishedAt.getTime()-i.startedAt.getTime();s=t.gray(`${rr.format(e,void 0,{left:``})}`)}else{let e=Date.now()-i.startedAt.getTime();s=t.gray(`Running for ${rr.format(e,void 0,{left:``})}`)}r.pushRow({Number:`${e}${a}`,ID:t.gray(i.id),Status:prettyPrintStatus(i.status),Took:s})}return r}},BuildsRemoveTagCommand=class extends ApifyCommand{static name=`remove-tag`;static enableProfileFlag=!0;static description=`Removes a tag from a specific Actor build.`;static examples=[{description:`Remove a tag from a build (prompts for confirmation).`,command:`apify builds remove-tag --build <buildId> --tag beta`},{description:`Remove a tag non-interactively.`,command:`apify builds remove-tag --build <buildId> --tag beta --yes`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-remove-tag`;static flags={build:Y.string({char:`b`,description:`The build ID to remove the tag from.`,required:!0}),tag:Y.string({char:`t`,description:`The tag to remove from the build.`,required:!0}),...YesFlag()};async run(){let{build:e,tag:n,yes:r}=this.flags,i=await getLoggedClientOrThrow(),a=await i.build(e).get();if(!a){error({message:`Build with ID "${e}" was not found on your account.`,stdout:!0});return}let s=await i.actor(a.actId).get();if(!s){error({message:`Actor with ID "${a.actId}" was not found.`,stdout:!0});return}let c=(s.taggedBuilds??{})[n];if(!c){error({message:`Tag "${n}" does not exist on Actor "${s.name}".`,stdout:!0});return}if(c.buildId!==e){error({message:`Tag "${n}" is not associated with build "${e}". It points to build "${c.buildNumber}" (${c.buildId}).`,stdout:!0});return}if(!await X({message:`Are you sure you want to remove tag "${t.yellow(n)}" from build ${t.gray(a.buildNumber)}?`,providedConfirmFromStdin:r||void 0})){info({message:`Tag removal was canceled.`,stdout:!0});return}try{await i.actor(a.actId).update({taggedBuilds:{[n]:null}}),success({message:`Tag "${t.yellow(n)}" removed from build ${t.gray(a.buildNumber)} (${t.gray(e)})`,stdout:!0})}catch(t){let r=t;error({message:`Failed to remove tag "${n}" from build "${e}".\n ${r.message||r}`,stdout:!0})}}};const Gr=stdinCheckWrapper(async({message:e,expectedValue:t,failureMessage:n})=>await Ue({message:e,validate(e){return e===t?!0:n??`That is not the correct input!`}},In));var BuildsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes an Actor build from the Apify platform.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Tagged builds additionally require typing the tag name.`;static examples=[{description:`Delete a build (prompts for confirmation).`,command:`apify builds rm <buildId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-rm`;static args={buildId:Z.string({description:`The build ID to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{buildId:e}=this.args,{yes:t}=this.flags,n=await getLoggedClientOrThrow(),r=await n.build(e).get();if(!r)throw Error(`Build with ID "${e}" was not found on your account.`);let i=await n.actor(r.actId).get(),a;if(i?.taggedBuilds){for(let[t,n]of Object.entries(i.taggedBuilds))if(e===n.buildId){a=t;break}}let s;if(s=a?await Gr({message:`Are you sure you want to delete this Actor Build? If so, please type in "${a}":`,expectedValue:a,failureMessage:`Your provided value does not match the build tag.`,providedConfirmFromStdin:t?a:void 0}):await X({message:`Are you sure you want to delete this Actor Build?`,providedConfirmFromStdin:t||void 0}),!s){info({message:`Deletion of build "${e}" was canceled.`,stdout:!0});return}await n.build(e).delete(),success({message:`Build with ID "${e}" was deleted.`,stdout:!0})}},BuildsWaitCommand=class extends ApifyCommand{static name=`wait`;static enableProfileFlag=!0;static description=`Waits for an Actor build to reach a terminal status (SUCCEEDED, FAILED, ABORTED, TIMED-OUT).
132
- Returns exit code 0 only when the build SUCCEEDED. Designed for CI and agentic workflows.`;static examples=[{description:`Wait for a build to finish and return a non-zero exit code on failure.`,command:`apify builds wait <buildId>`},{description:`Wait for a build and emit a structured JSON result.`,command:`apify builds wait <buildId> --json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-wait`;static enableJsonFlag=!0;static args={buildId:Z.string({required:!0,description:`The build ID to wait for.`})};static flags={timeout:Y.integer({char:`t`,description:`In seconds, how long to wait before giving up. If skipped, it waits indefinitely.`,required:!1}),"poll-interval":Y.integer({description:`In seconds, how often to poll the platform. Defaults to 2.`,required:!1})};async run(){let{buildId:t}=this.args,{timeout:n,pollInterval:r,json:i}=this.flags,a=await getLoggedClientOrThrow(),{job:s,timedOutWaiting:c}=await waitForTerminalStatus({apifyClient:a,jobId:t,kind:z.BUILD,maxWaitMillis:n?n*1e3:void 0,pollIntervalMillis:r?r*1e3:void 0}),l=s,u=consoleBuildUrl(l.actId,l.buildNumber),f=l.status===R.SUCCEEDED,p=exitCodeForWaitResult({job:s,timedOutWaiting:c},z.BUILD),m=`Gave up waiting after ${n}s; build is still ${l.status}`,h=[];if(f||(h=await fetchLogTail(a,l.id)),i){printJsonToStdout({ok:f,operation:`builds.wait`,timedOutWaiting:c,build:{id:l.id,status:l.status,number:l.buildNumber,url:u},...f?{}:{error:{phase:`build`,message:c?m:`Actor build did not succeed`,logTail:h}},exitCode:p}),e.exitCode=p;return}let g=[{label:`Build`,value:l.status},{label:`Build ID`,value:l.id},{label:`Build number`,value:l.buildNumber},{label:`Actor ID`,value:l.actId}],_=[{label:`Build URL`,url:u}];simpleLog({message:formatResultSummary({resultLabel:`Apify build result`,overallStatus:l.status,lines:g,links:_,errorReason:f?void 0:h}),stdout:!0}),c?error({message:`${m}.`}):f||error({message:`Build ended with status ${l.status}.`}),e.exitCode=p}},BuildsIndexCommand=class extends ApifyCommand{static name=`builds`;static description=`Create, inspect, tag, and delete Actor builds on the Apify platform.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds`;static subcommands=[BuildsAddTagCommand,BuildsRemoveTagCommand,BuildsRmCommand,BuildsLsCommand,BuildsLogCommand,BuildsInfoCommand,BuildsCreateCommand,BuildsWaitCommand];async run(){this.printHelp()}},TopLevelCallCommand=class extends Sr{static name=`call`};const pathToInstallMarker=e=>u(e,`.install-marker`);var InstallCommand=class extends ApifyCommand{static name=`install`;static description=`Finalizes the first-time setup of Apify and Actor CLI.`;static hidden=!0;static flags={"shims-only":Y.boolean({description:`Only (re)create the apify/actor wrapper scripts next to the bundle, then exit. Used by the install/upgrade scripts.`,hidden:!0,default:!1})};async run(){let{installMethod:n,installPath:r,version:i}=useCLIMetadata();if(n!==`bundle`){info({message:`Apify and Actor CLI are already fully configured! 👍`});return}if(Lt(r,`When CLI is installed via bundles, the install path must be set`),writeEntrypointShims(r,e.platform===`win32`),cliDebugPrint(`[install] wrote entrypoint shims to`,r),this.flags.shimsOnly)return;let a=pathToInstallMarker(r);if(O(a)){info({message:`Apify and Actor CLI are already fully configured! 👍`});return}if(e.platform!==`win32`){await this.symlinkToLocalBin(r);try{await this.promptAddToShell()}catch(e){error({message:e.message||`Failed to automatically handle shell integration`})}simpleLog({message:``})}await G(a,i),cliDebugPrint(`[install] install marker written to`,a),simpleLog({message:[``,t.green(`Apify and Actor CLI were installed successfully!`),``,t.gray(` Version: ${t.green(i)}`),t.gray(` Location: ${t.bold.white(tildify(u(r,`apify`)))} and ${t.bold.white(tildify(u(r,`actor`)))}`)].join(`
131
+ `),stdout:!0})}}generateTableForActorVersion({buildsForVersion:e,buildTagToActorVersion:n}){let r=tableFactory();for(let i of e){let e=Reflect.get(i,`buildNumber`),a=n[e]?` (${t.yellow(n[e])})`:``,s;if(i.finishedAt){let e=i.finishedAt.getTime()-i.startedAt.getTime();s=t.gray(`${rr.format(e,void 0,{left:``})}`)}else{let e=Date.now()-i.startedAt.getTime();s=t.gray(`Running for ${rr.format(e,void 0,{left:``})}`)}r.pushRow({Number:`${e}${a}`,ID:t.gray(i.id),Status:prettyPrintStatus(i.status),Took:s})}return r}},BuildsRemoveTagCommand=class extends ApifyCommand{static name=`remove-tag`;static enableProfileFlag=!0;static description=`Removes a tag from a specific Actor build.`;static examples=[{description:`Remove a tag from a build (prompts for confirmation).`,command:`apify builds remove-tag --build <buildId> --tag beta`},{description:`Remove a tag non-interactively.`,command:`apify builds remove-tag --build <buildId> --tag beta --yes`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-remove-tag`;static flags={build:Y.string({char:`b`,description:`The build ID to remove the tag from.`,required:!0}),tag:Y.string({char:`t`,description:`The tag to remove from the build.`,required:!0}),...YesFlag()};async run(){let{build:e,tag:n,yes:r}=this.flags,i=await getLoggedClientOrThrow(),a=await i.build(e).get();if(!a){error({message:`Build with ID "${e}" was not found on your account.`,stdout:!0});return}let s=await i.actor(a.actId).get();if(!s){error({message:`Actor with ID "${a.actId}" was not found.`,stdout:!0});return}let c=(s.taggedBuilds??{})[n];if(!c)error({message:`Tag "${n}" does not exist on Actor "${s.name}".`,stdout:!0});else if(c.buildId!==e)error({message:`Tag "${n}" is not associated with build "${e}". It points to build "${c.buildNumber}" (${c.buildId}).`,stdout:!0});else if(!await X({message:`Are you sure you want to remove tag "${t.yellow(n)}" from build ${t.gray(a.buildNumber)}?`,providedConfirmFromStdin:r||void 0}))info({message:`Tag removal was canceled.`,stdout:!0});else try{await i.actor(a.actId).update({taggedBuilds:{[n]:null}}),success({message:`Tag "${t.yellow(n)}" removed from build ${t.gray(a.buildNumber)} (${t.gray(e)})`,stdout:!0})}catch(t){let r=t;error({message:`Failed to remove tag "${n}" from build "${e}".\n ${r.message||r}`,stdout:!0})}}};const Gr=stdinCheckWrapper(async({message:e,expectedValue:t,failureMessage:n})=>await Ue({message:e,validate(e){return e===t?!0:n??`That is not the correct input!`}},In));var BuildsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes an Actor build from the Apify platform.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Tagged builds additionally require typing the tag name.`;static examples=[{description:`Delete a build (prompts for confirmation).`,command:`apify builds rm <buildId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-rm`;static args={buildId:Z.string({description:`The build ID to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{buildId:e}=this.args,{yes:t}=this.flags,n=await getLoggedClientOrThrow(),r=await n.build(e).get();if(!r)throw Error(`Build with ID "${e}" was not found on your account.`);let i=await n.actor(r.actId).get(),a;if(i?.taggedBuilds){for(let[t,n]of Object.entries(i.taggedBuilds))if(e===n.buildId){a=t;break}}let s;s=a?await Gr({message:`Are you sure you want to delete this Actor Build? If so, please type in "${a}":`,expectedValue:a,failureMessage:`Your provided value does not match the build tag.`,providedConfirmFromStdin:t?a:void 0}):await X({message:`Are you sure you want to delete this Actor Build?`,providedConfirmFromStdin:t||void 0}),s?(await n.build(e).delete(),success({message:`Build with ID "${e}" was deleted.`,stdout:!0})):info({message:`Deletion of build "${e}" was canceled.`,stdout:!0})}},BuildsWaitCommand=class extends ApifyCommand{static name=`wait`;static enableProfileFlag=!0;static description=`Waits for an Actor build to reach a terminal status (SUCCEEDED, FAILED, ABORTED, TIMED-OUT).
132
+ Returns exit code 0 only when the build SUCCEEDED. Designed for CI and agentic workflows.`;static examples=[{description:`Wait for a build to finish and return a non-zero exit code on failure.`,command:`apify builds wait <buildId>`},{description:`Wait for a build and emit a structured JSON result.`,command:`apify builds wait <buildId> --json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds-wait`;static enableJsonFlag=!0;static args={buildId:Z.string({required:!0,description:`The build ID to wait for.`})};static flags={timeout:Y.integer({char:`t`,description:`In seconds, how long to wait before giving up. If skipped, it waits indefinitely.`,required:!1}),"poll-interval":Y.integer({description:`In seconds, how often to poll the platform. Defaults to 2.`,required:!1})};async run(){let{buildId:t}=this.args,{timeout:n,pollInterval:r,json:i}=this.flags,a=await getLoggedClientOrThrow(),{job:s,timedOutWaiting:c}=await waitForTerminalStatus({apifyClient:a,jobId:t,kind:z.BUILD,maxWaitMillis:n?n*1e3:void 0,pollIntervalMillis:r?r*1e3:void 0}),l=s,u=consoleBuildUrl(l.actId,l.buildNumber),f=l.status===R.SUCCEEDED,p=exitCodeForWaitResult({job:s,timedOutWaiting:c},z.BUILD),m=`Gave up waiting after ${n}s; build is still ${l.status}`,h=[];if(f||(h=await fetchLogTail(a,l.id)),i){printJsonToStdout({ok:f,operation:`builds.wait`,timedOutWaiting:c,build:{id:l.id,status:l.status,number:l.buildNumber,url:u},...f?{}:{error:{phase:`build`,message:c?m:`Actor build did not succeed`,logTail:h}},exitCode:p}),e.exitCode=p;return}let g=[{label:`Build`,value:l.status},{label:`Build ID`,value:l.id},{label:`Build number`,value:l.buildNumber},{label:`Actor ID`,value:l.actId}],_=[{label:`Build URL`,url:u}];simpleLog({message:formatResultSummary({resultLabel:`Apify build result`,overallStatus:l.status,lines:g,links:_,errorReason:f?void 0:h}),stdout:!0}),c?error({message:`${m}.`}):f||error({message:`Build ended with status ${l.status}.`}),e.exitCode=p}},BuildsIndexCommand=class extends ApifyCommand{static name=`builds`;static description=`Create, inspect, tag, and delete Actor builds on the Apify platform.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-builds`;static subcommands=[BuildsAddTagCommand,BuildsRemoveTagCommand,BuildsRmCommand,BuildsLsCommand,BuildsLogCommand,BuildsInfoCommand,BuildsCreateCommand,BuildsWaitCommand];async run(){this.printHelp()}},TopLevelCallCommand=class extends Sr{static name=`call`};const pathToInstallMarker=e=>u(e,`.install-marker`);var InstallCommand=class extends ApifyCommand{static name=`install`;static description=`Finalizes the first-time setup of Apify and Actor CLI.`;static hidden=!0;static flags={"shims-only":Y.boolean({description:`Only (re)create the apify/actor wrapper scripts next to the bundle, then exit. Used by the install/upgrade scripts.`,hidden:!0,default:!1})};async run(){let{installMethod:n,installPath:r,version:i}=useCLIMetadata();if(n!==`bundle`){info({message:`Apify and Actor CLI are already fully configured! 👍`});return}if(Lt(r,`When CLI is installed via bundles, the install path must be set`),writeEntrypointShims(r,e.platform===`win32`),cliDebugPrint(`[install] wrote entrypoint shims to`,r),this.flags.shimsOnly)return;let a=pathToInstallMarker(r);if(O(a))info({message:`Apify and Actor CLI are already fully configured! 👍`});else{if(e.platform!==`win32`){await this.symlinkToLocalBin(r);try{await this.promptAddToShell()}catch(e){error({message:e.message||`Failed to automatically handle shell integration`})}simpleLog({message:``})}await G(a,i),cliDebugPrint(`[install] install marker written to`,a),simpleLog({message:[``,t.green(`Apify and Actor CLI were installed successfully!`),``,t.gray(` Version: ${t.green(i)}`),t.gray(` Location: ${t.bold.white(tildify(u(r,`apify`)))} and ${t.bold.white(tildify(u(r,`actor`)))}`)].join(`
133
133
  `)}),simpleLog({message:``}),success({message:`To get started, run:`}),simpleLog({message:t.white.bold(` apify --help
134
- actor --help`)})}async symlinkToLocalBin(e){let n=userHomeDir();if(cliDebugPrint(`[install -> symlinkToLocalBin] user home directory`,n),!n){cliDebugPrint(`[install -> symlinkToLocalBin] user home directory not found`),warning({message:t.gray(`User home directory not found, cannot symlink to ~/.local/bin`)});return}let r=u(n,`.local`,`bin`);await H(r,{recursive:!0});for(let n of[`apify`,`actor`,`apify-cli`]){let i=u(e,n);if(!O(i)){cliDebugPrint(`[install] file not found for symlinking`,n,i),warning({message:t.gray(`Bundle not found for symlinking: ${n}`)});continue}let a=u(r,n);await Pe(a).catch(()=>{}),await Ne(i,a),cliDebugPrint(`[install] symlink created for item`,n,a)}info({message:t.gray(`Symlinked apify, actor, and apify-cli to ${tildify(r)}`)})}async confirmFromTty(n){let r,i,a=`${t.green(`?`)} ${t.bold(n)} ${t.dim(`(Y/n)`)} `,writeDone=r=>{e.stdout.write(`\r\x1b[2K${t.green(`?`)} ${t.bold(n)} ${t.cyan(r)}\n`)};try{return cliDebugPrint(`[install] opening /dev/tty for raw mode`),r=j(`/dev/tty`,`r`),i=new Rt(r),e.stdout.write(a),i.setRawMode(!0),i.resume(),await new Promise(t=>{let onData=n=>{let r=n.toString();r===`y`||r===`Y`||r===`\r`||r===`
134
+ actor --help`)})}}async symlinkToLocalBin(e){let n=userHomeDir();if(cliDebugPrint(`[install -> symlinkToLocalBin] user home directory`,n),!n){cliDebugPrint(`[install -> symlinkToLocalBin] user home directory not found`),warning({message:t.gray(`User home directory not found, cannot symlink to ~/.local/bin`)});return}let r=u(n,`.local`,`bin`);await H(r,{recursive:!0});for(let n of[`apify`,`actor`,`apify-cli`]){let i=u(e,n);if(!O(i)){cliDebugPrint(`[install] file not found for symlinking`,n,i),warning({message:t.gray(`Bundle not found for symlinking: ${n}`)});continue}let a=u(r,n);await Pe(a).catch(()=>{}),await Ne(i,a),cliDebugPrint(`[install] symlink created for item`,n,a)}info({message:t.gray(`Symlinked apify, actor, and apify-cli to ${tildify(r)}`)})}async confirmFromTty(n){let r,i,a=`${t.green(`?`)} ${t.bold(n)} ${t.dim(`(Y/n)`)} `,writeDone=r=>{e.stdout.write(`\r\x1b[2K${t.green(`?`)} ${t.bold(n)} ${t.cyan(r)}\n`)};try{return cliDebugPrint(`[install] opening /dev/tty for raw mode`),r=j(`/dev/tty`,`r`),i=new Rt(r),e.stdout.write(a),i.setRawMode(!0),i.resume(),await new Promise(t=>{let onData=n=>{let r=n.toString();r===`y`||r===`Y`||r===`\r`||r===`
135
135
  `?(i.removeListener(`data`,onData),writeDone(`Yes`),t(!0)):r===`n`||r===`N`?(i.removeListener(`data`,onData),writeDone(`No`),t(!1)):(r===``||r===``)&&(i.removeListener(`data`,onData),e.stdout.write(`
136
136
  `),t(!1))};i.on(`data`,onData)})}catch(e){return cliDebugPrint(`[install] failed to open /dev/tty for raw mode`,e),!1}finally{i&&(i.setRawMode(!1),i.pause(),i.destroy())}}async promptAddToShell(){let[n,r]=await Promise.allSettled([We(`apify`,{nothrow:!0}),We(`actor`,{nothrow:!0})]);if(n.status===`fulfilled`&&r.status===`fulfilled`&&n.value&&r.value){cliDebugPrint(`[install -> promptAddToShell] already in PATH`,{apifyCliPath:n,actorCliPath:r}),info({message:t.gray(`Apify and Actor CLIs are already in PATH, skipping shell integration`)});return}let i=userHomeDir();cliDebugPrint(`[install -> promptAddToShell] user home directory`,i);let a=e.env.APIFY_CLI_INSTALL??u(i,`.apify`),s=e.env.FINAL_BIN_DIR??u(a,`bin`),l=e.env.PROVIDED_INSTALL_DIR??a;if(!l){warning({message:t.gray(`Install directory not found, cannot add to shell`)});return}let f=e.env.FINAL_BIN_DIR??s;simpleLog({message:``});let p=`Should the CLI handle adding itself to your shell automatically?`,m;e.env.APIFY_OPEN_TTY?m=await this.confirmFromTty(p):(cliDebugPrint(`[install] opening /dev/tty for raw mode not requested, falling back to normal flow`),m=await X({message:p,providedConfirmFromStdin:!1}));let h=detectShell(),g=shellConfigFile(i,h),_=`"${l.replaceAll(`"`,`\\"`)}"`,v=[],y=!0;switch(h){case`bash`:case`zsh`:v.push(`export APIFY_CLI_INSTALL=${_}`),v.push(`export PATH="$APIFY_CLI_INSTALL/bin:$PATH"`);break;case`fish`:v.push(`set --export APIFY_CLI_INSTALL ${_}`),v.push(`set --export PATH ${f} $PATH`);break;default:v.push(`export APIFY_CLI_INSTALL=${_}`),v.push(`export PATH="$APIFY_CLI_INSTALL/bin:$PATH"`),m=!1,y=!1}if(simpleLog({message:``}),m&&g){let e=`${await U(g,`utf-8`).catch(e=>{if(e.code===`ENOENT`)return``;throw Error(`Failed to read config file "${tildify(g)}". Received error code: ${e.code}; ${e.message}`)})}\n\n# apify cli\n${v.join(`
137
137
  `)}\n`;try{await H(c(g),{recursive:!0}),await G(g,e)}catch(e){throw e.code===`EACCES`?Error(`Failed to write to config file "${tildify(g)}", as the CLI does not have permission to write to it.`):Error(`Failed to write to config file "${tildify(g)}". Received error code: ${e.code}; ${e.message}`)}info({message:[t.gray(`Added "${tildify(f)}" to your PATH in ${tildify(g)}.`),t.gray(` You may need to run ${t.white.bold(`source ${tildify(g)}`)} to reload your shell.`)].join(`
138
138
  `)});return}let b=g??`your shell config file`;if(y){let e=`echo -e '${v.join(`\\n`)}' >> "${b}" && source "${b}"`;info({message:[t.gray(`The Apify & Actor CLIs are not in your PATH. Run:`),``,t.white.bold(` ${e}`)].join(`
139
- `)});return}info({message:[t.gray(`Manually add the following lines to ${b} or similar:`),...v.map(e=>t.white.bold(` ${e}`))].join(`
139
+ `)})}else info({message:[t.gray(`Manually add the following lines to ${b} or similar:`),...v.map(e=>t.white.bold(` ${e}`))].join(`
140
140
  `)})}};const Kr=useCLIMetadata();function isInstalledOnMusl(){return Kr.platform===`linux`&&O(`/etc/alpine-release`)}function isInstalledOnBaseline(){return Kr.platform===`darwin`&&Kr.arch===`x64`?!Ge(`sysctl -a`,{encoding:`utf-8`}).includes(`AVX2`):Kr.platform===`linux`&&Kr.arch===`x64`?!M(`/proc/cpuinfo`,`utf-8`).includes(`avx2`):Kr.platform===`windows`&&Kr.arch!==`arm64`&&Ge(`pwsh -c "!(Add-Type -MemberDefinition '[DllImport(\\"kernel32.dll\\")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);' -Name 'Kernel32' -Namespace 'Win32' -PassThru)::IsProcessorFeaturePresent(40)"`,{encoding:`utf-8`,windowsHide:!0}).trim().toLowerCase()===`true`}async function useCLIVersionAssets(e){let t=e.replace(/^v(\d+)/,`$1`),n=t===`latest`?`latest`:`tags/v${t}`,r=await fetch(`https://api.github.com/repos/apify/apify-cli/releases/${n}`,{headers:{"User-Agent":vn}});if(!r.ok)return cliDebugPrint(`useCLIVersionAssets`,`Failed to fetch release`,{statusCode:r.status,body:await r.text(),version:e,tag:n}),null;let i=await r.json(),a=isInstalledOnMusl(),s=isInstalledOnBaseline(),c=i.assets.filter(e=>{if(!e.name.startsWith(`apify-cli-`))return!1;let[n,r,i,...c]=e.name.slice(10).replace(t,`version`).replace(`.exe`,``).split(`-`);return r===Kr.platform&&i===Kr.arch&&c.includes(`musl`)===a&&c.includes(`baseline`)===s});return cliDebugPrint(`useCLIVersionAssets`,`Fetched release`,{version:i.tag_name,filteredAssets:c}),{assets:c,version:i.tag_name.replace(/^v(\d+)/,`$1`)}}const qr={bundle:(e,t)=>[`${t}`,`upgrade`],npm:e=>[`npm`,`install`,`-g`,`apify-cli@${e}`],pnpm:e=>[`pnpm`,`install`,`-g`,`apify-cli@${e}`],bun:e=>[`bun`,`install`,`-g`,`apify-cli@${e}`],homebrew:()=>[`brew`,`upgrade`,`apify-cli`],volta:e=>[`volta`,`install`,`apify-cli@${e}`]},Jr=`1.0.1`,Yr=`https://raw.githubusercontent.com/apify/apify-cli/refs/heads/master/scripts/install/upgrade.ps1`;var UpgradeCommand=class extends ApifyCommand{static name=`upgrade`;static description=`Checks that installed Apify CLI version is up to date.`;static group=`Utilities`;static examples=[{description:`Check for a newer CLI version and upgrade if available.`,command:`apify upgrade`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-upgrade`;static hidden=!0;static aliases=[`cv`,`check-version`];static flags={force:Y.boolean({description:`[DEPRECATED] This flag is now ignored, as running the command manually will always check for the latest version.`,required:!1,char:`f`}),version:Y.string({description:`The version of the CLI to upgrade to. If not provided, the latest version will be used.`,required:!1}),"internal-automatic-call":Y.boolean({description:`Whether the command was called automatically by the CLI for a version check.`,hidden:!0,default:!1})};get cliName(){return this.entrypoint===`apify`?`Apify CLI`:`Actor CLI`}async run(){if(this.flags.version){await this.handleInstallSpecificVersion(this.flags.version);return}let e=await useCLIVersionCheck(!this.flags.internalAutomaticCall),{installMethod:n}=useCLIMetadata();if(!e.shouldUpdate||e.currentVersion===`0.0.0`){cliDebugPrint(`[upgrade] no update needed`,{shouldUpdate:e.shouldUpdate,currentVersion:e.currentVersion}),this.flags.internalAutomaticCall||info({message:`${this.cliName} is up to date 👍 \n`});return}if(!this.flags.internalAutomaticCall){await this.handleInstallSpecificVersion(`latest`);return}let r=qr[n](`latest`,this.entrypoint).join(` `);simpleLog({message:``}),warning({message:[`You are using an old version of ${this.cliName}. We strongly recommend you always use the latest available version.`,` ↪ Run ${t.bgWhite(t.black(r))} to update! 👍 \n`].join(`
141
141
  `)})}async handleInstallSpecificVersion(t){if(t!==`latest`&&!y(t,Jr)){error({message:`The minimum version of the CLI you can manually downgrade/upgrade to is ${Jr}.`});return}let n=await useCLIVersionAssets(t);if(!n){error({message:`The provided version does not exist. Please check the version number and try again.`});return}let{assets:r,version:i}=n;if(!y(i,Jr)){error({message:`The minimum version of the CLI you can manually downgrade/upgrade to is ${Jr}.`});return}let a=useCLIMetadata();if(a.installMethod===`bundle`){if(!r.length){error({message:[`Failed to find the assets for your system and the provided version. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`,`- The version you are trying to upgrade to: ${i}`,`- The system you are running on: ${a.platform} ${a.arch}`].join(`
142
142
  `)});return}let t=c(e.execPath);cliDebugPrint(`[upgrade] bundleDirectory`,t);let n=await Ae(t);if(!n.some(e=>e.startsWith(`apify`)||e.startsWith(`actor`))){cliDebugPrint(`[upgrade] directoryEntries`,n),error({message:[`Failed to find the currently installed ${this.cliName} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`,`- The version you are trying to upgrade to: ${i}`,`- The system you are running on: ${a.platform} ${a.arch}`,`- The directory where the ${this.cliName} bundle is installed: ${t}`].join(`
143
- `)});return}if(a.platform===`windows`)return this.startUpgradeProcess(t,i,r);await this.handleUnixUpgrade(t,i,r)&&this.successMessage(i);return}let s=qr[a.installMethod](t,this.entrypoint);if(e.env.APIFY_CLI_DEBUG){info({message:`Would run command: ${s.join(` `)}`});return}try{await execWithLog({cmd:s[0],args:s.slice(1)}),this.successMessage(i)}catch{error({message:`Failed to upgrade the CLI. Please run the following command manually: ${s.join(` `)}`})}}successMessage(e){success({message:`Successfully upgraded to ${e} 👍`})}async startUpgradeProcess(t,n,r){await this.upsertUpgradeScript(t);let i=[`-ExecutionPolicy`,`Bypass`,`-File`,`"${u(t,`upgrade.ps1`)}"`,`-ProcessId`,e.pid.toString(),`-InstallLocation`,`"${t}"`,`-Version`,`"${n}"`],a=r.map(e=>e.browser_download_url).join(`,`);i.push(`-AllUrls`,`"${a}"`),cliDebugPrint(`[upgrade] starting upgrade process with args`,i),info({message:`Starting upgrade process...`});let s=Ke(`powershell.exe`,i,{detached:!0,shell:!0,stdio:`inherit`,windowsHide:!1,windowsVerbatimArguments:!0});s.on(`spawn`,()=>{cliDebugPrint(`[upgrade] upgrade process spawned`),s.unref(),e.exit(0)}),s.on(`error`,e=>{error({message:`Failed to start the upgrade process: ${e.message}`})})}async upsertUpgradeScript(t){let n=u(t,`upgrade.ps1`);if(O(n))return;let r=useCLIMetadata(),i=await fetch(Yr,{headers:{"User-Agent":vn}});i.ok||(error({message:[`Failed to fetch the upgrade script. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`,`- The system you are running on: ${r.platform} ${r.arch}`,`- The URL of the asset that failed to fetch: ${Yr}`,`- The status code of the response: ${i.status}`].join(`
143
+ `)});return}if(a.platform===`windows`)return this.startUpgradeProcess(t,i,r);await this.handleUnixUpgrade(t,i,r)&&this.successMessage(i);return}let s=qr[a.installMethod](t,this.entrypoint);if(e.env.APIFY_CLI_DEBUG)info({message:`Would run command: ${s.join(` `)}`});else try{await execWithLog({cmd:s[0],args:s.slice(1)}),this.successMessage(i)}catch{error({message:`Failed to upgrade the CLI. Please run the following command manually: ${s.join(` `)}`})}}successMessage(e){success({message:`Successfully upgraded to ${e} 👍`})}async startUpgradeProcess(t,n,r){await this.upsertUpgradeScript(t);let i=[`-ExecutionPolicy`,`Bypass`,`-File`,`"${u(t,`upgrade.ps1`)}"`,`-ProcessId`,e.pid.toString(),`-InstallLocation`,`"${t}"`,`-Version`,`"${n}"`],a=r.map(e=>e.browser_download_url).join(`,`);i.push(`-AllUrls`,`"${a}"`),cliDebugPrint(`[upgrade] starting upgrade process with args`,i),info({message:`Starting upgrade process...`});let s=Ke(`powershell.exe`,i,{detached:!0,shell:!0,stdio:`inherit`,windowsHide:!1,windowsVerbatimArguments:!0});s.on(`spawn`,()=>{cliDebugPrint(`[upgrade] upgrade process spawned`),s.unref(),e.exit(0)}),s.on(`error`,e=>{error({message:`Failed to start the upgrade process: ${e.message}`})})}async upsertUpgradeScript(t){let n=u(t,`upgrade.ps1`);if(O(n))return;let r=useCLIMetadata(),i=await fetch(Yr,{headers:{"User-Agent":vn}});i.ok||(error({message:[`Failed to fetch the upgrade script. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`,`- The system you are running on: ${r.platform} ${r.arch}`,`- The URL of the asset that failed to fetch: ${Yr}`,`- The status code of the response: ${i.status}`].join(`
144
144
  `)}),e.exit(1));let a=await i.arrayBuffer();await G(n,Buffer.from(a)),cliDebugPrint(`[upgrade] downloaded upgrade script to`,n)}async handleUnixUpgrade(n,r,i){let a=useCLIMetadata();for(let s of i){let i=`apify-cli`,c=u(n,i);info({message:`Downloading \`${i}\` binary of the Apify CLI...`});let l=await fetch(s.browser_download_url,{headers:{"User-Agent":vn}});if(!l.ok){let t=await l.text();return cliDebugPrint(`[upgrade] failed to fetch asset`,{asset:s,status:l.status,body:t}),error({message:[`Failed to fetch the ${i} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`,`- The version you are trying to upgrade to: ${r}`,`- The system you are running on: ${a.platform} ${a.arch}`,`- The URL of the asset that failed to fetch: ${s.browser_download_url}`,`- The status code of the response: ${l.status}`,`- The body of the response: ${t}`].join(`
145
145
  `)}),e.exitCode=1,!1}if(e.env.APIFY_CLI_DEBUG&&!e.env.APIFY_CLI_FORCE){info({message:`Would write asset ${i} to ${c}`});continue}info({message:t.gray(`Writing ${i} to ${c}...`)});let f=await l.arrayBuffer(),p=`${c}.${e.pid}.tmp`;try{await G(p,Buffer.from(f),{mode:493}),await je(p,c),writeEntrypointShims(n,!1),cliDebugPrint(`[upgrade ${i}] wrote asset to`,c)}catch(t){return await Me(p,{force:!0}).catch(()=>{}),cliDebugPrint(`[upgrade] failed to write asset`,{error:t}),error({message:[`Failed to write the ${i} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`,`- The version you are trying to upgrade to: ${r}`,`- The system you are running on: ${a.platform} ${a.arch}`,`- The URL of the asset that failed to fetch: ${s.browser_download_url}`,`- The error: ${t.message}`].join(`
146
146
  `)}),e.exitCode=1,!1}}return!0}};const Xr={STARTER:`STARTER`,WEB_SCRAPING:`WEB_SCRAPING`,INTEGRATION:`INTEGRATION`,AUTOMATION:`AUTOMATION`,AI:`AI`},$={JAVASCRIPT:`javascript`,TYPESCRIPT:`typescript`,PYTHON:`python`},Zr=`any-language`,Qr=`any-use-case`,$r={[$.TYPESCRIPT]:`ts-crawlee-cheerio`,[$.JAVASCRIPT]:`js-crawlee-cheerio`,[$.PYTHON]:`python-crawlee-beautifulsoup`},ei={[$.TYPESCRIPT]:`ts-empty`,[$.JAVASCRIPT]:`js-empty`,[$.PYTHON]:`python-empty`},ti=[{cliFlag:`web-scraper`,templateTag:Xr.WEB_SCRAPING,label:`Web scraper`},{cliFlag:`ai-agent`,templateTag:Xr.AI,label:`AI agent`},{cliFlag:`data-pipeline`,templateTag:Xr.INTEGRATION,label:`API & data pipeline`},{cliFlag:`browser-automation`,templateTag:Xr.AUTOMATION,label:`Browser automation`}],ni=[{cliFlag:$.JAVASCRIPT,templateTag:$.JAVASCRIPT,label:`JavaScript`,aliases:[`js`]},{cliFlag:$.TYPESCRIPT,templateTag:$.TYPESCRIPT,label:`TypeScript`,aliases:[`ts`]},{cliFlag:$.PYTHON,templateTag:$.PYTHON,label:`Python`,aliases:[`py`]}],ri=ni.flatMap(e=>[e.cliFlag,...e.aliases]),ii=ti.map(e=>e.cliFlag);function useCaseFlagToTag(e){return ti.find(t=>t.cliFlag===e)?.templateTag}function languageFlagToTag(e){return ni.find(t=>t.cliFlag===e||t.aliases.includes(e))?.templateTag}function useCaseLabel(e){return ti.find(t=>t.templateTag===e)?.label??e}function languageLabel(e){return e===`any-language`?`any language`:ni.find(t=>t.templateTag===e)?.label??e}function getTemplateRecommendation(e,t,n){let r=n!==Zr,i=t!==Qr,matchesLanguage=e=>!r||e.category===n,matchesUseCase=e=>!i||!!e.useCases?.includes(t),isExactMatch=e=>matchesLanguage(e)&&matchesUseCase(e),a=/* @__PURE__ */ new Set,s=[],addCandidates=e=>{for(let t of e)a.has(t.id)||(a.add(t.id),s.push(t))},addCuratedTemplates=t=>{let i=r?[t[n]]:Object.values(t);addCandidates(e.filter(e=>i.includes(e.id)))};return(r||i)&&addCandidates(e.filter(isExactMatch)),addCuratedTemplates($r),addCuratedTemplates(ei),r&&addCandidates(e.filter(matchesLanguage)),i&&addCandidates(e.filter(matchesUseCase)),addCandidates(e),s.map(e=>({template:e,isExactMatch:isExactMatch(e)}))}function buildTemplateChoiceList(e,t,n){let r=e.some(e=>e.isExactMatch),i=e.map(({template:e,isExactMatch:t})=>({template:e,label:formatTemplateLabel(e,n),isExactMatch:t})),a=i.findIndex(e=>!e.isExactMatch);return{rows:i,separatorIndex:r&&a>0?a:null,noExactMatchHint:!r&&i.length>0?`No template matches ${describeSelection(t,n)} exactly — showing the closest alternatives.`:null}}function formatTemplateLabel(e,t){let n=ni.find(t=>t.templateTag===e.category)?.label,r=t===`any-language`||e.category!==t;return n&&r?`${e.label} (${n})`:e.label}function describeSelection(e,t){let n=[];return e!==`any-use-case`&&n.push(useCaseLabel(e)),n.push(languageLabel(t)),n.join(` + `)}async function ensureValidActorName(e){return e?(validateActorName(e),e):promptActorName()}async function getTemplateDefinition(e,t,n={}){let r=await t;if(r instanceof Error)throw r;if(e){let t=r.templates.find(t=>t.name===e||t.id===e);if(!t)throw Error(`Could not find the selected template: ${e} in the list of templates.`);return t}return executePrompts(r,n)}async function enhanceReadmeWithLocalSuffix(e,t){let n=await t;if(n instanceof Error)throw n;try{let t=await we.get(n.localReadmeSuffixUrl,{responseType:`text`});await ke(e,`\n\n${t.data}`)}catch(e){warning({message:`Could not append local development instructions to README.md. Cause: ${e.message}`})}}function buildNextSteps(e){let{actorName:t,dependenciesInstalled:n,installCommandSuggestion:r}=e,i=[`cd "${t}"`];return n||i.push(r||`install dependencies with your package manager`),i.push(`apify run`),i}function formatCreateSuccessMessage(e){let{actorName:t,dependenciesInstalled:n,postCreate:r,gitRepositoryInitialized:i,installCommandSuggestion:a,gitRemote:s}=e,c=`✅ Actor '${t}' created successfully!`,l=buildNextSteps({actorName:t,dependenciesInstalled:n,installCommandSuggestion:a});return c+=`\n\nNext steps:\n\n${l.join(`
@@ -150,13 +150,13 @@ Returns exit code 0 only when the build SUCCEEDED. Designed for CI and agentic w
150
150
 
151
151
  💡 Tip: Use 'apify push' to deploy your Actor to the Apify platform`,i&&(c+=`\n🌱 Git repository initialized in '${t}'. You can now commit and push your Actor to Git.`)),c+=`
152
152
  📖 Docs: https://docs.apify.com/platform/actors/development`,r&&(c+=`\n\n${r}`),c}async function executePrompts(e,t){return promptTemplate(e,t.useCase?useCaseFlagToTag(t.useCase)??`any-use-case`:await promptUseCase(),t.language?languageFlagToTag(t.language)??t.language:await promptLanguage())}async function promptActorName(){return await zn({message:`Name of your new Actor:`,validate:validateActorNameForPrompt})}async function promptUseCase(){let e=[...ti.map(e=>({name:e.label,value:e.templateTag})),new lt,{name:`Any use case`,value:Qr}];return Wr({message:`What do you want to build?`,choices:e,default:ti[0].templateTag,loop:!1})}async function promptLanguage(){let e=[...ni.map(e=>({name:e.label,value:e.templateTag})),new lt,{name:`Any language`,value:Zr}];return Wr({message:`Choose the programming language of your new Actor:`,choices:e,default:ni[0].templateTag,loop:!1})}async function promptTemplate(e,t,n){let{rows:r,separatorIndex:i,noExactMatchHint:a}=buildTemplateChoiceList(getTemplateRecommendation(e.templates,t,n),t,n);if(r.length===0)throw Error(`No Actor templates are available right now. Please try again later.`);let s=[];return r.forEach((e,t)=>{t===i&&s.push(new lt(`── The templates below don't exactly match your selection ──`)),s.push({name:e.label,value:e.template})}),a&&info({message:a,stdout:!1}),Wr({message:`Choose a template for your new Actor. More info at https://apify.com/templates`,choices:s,default:r[0].template,loop:!1,pageSize:8})}const ai=3e5,connectViaConsole=async(e,t,{abortSignal:n,account:r}={})=>{let i=getConsoleUrl(),a=De(),s,c=new Promise(e=>{s=e}),l=createLocalApiServer({corsOrigin:new URL(i).origin,authToken:a,routes:{"POST /api/v1/git-provider-connected":(e,t)=>{t.end(),cliDebugPrint(`git-source`,`connected`,e),s({connected:!0})},"POST /api/v1/exit":(e,n)=>{n.end(),s({stopReason:`connectCancelled`,message:e.isWindowClosed?`Connecting your ${t} account stopped: the Apify Console window was closed.`:`Connecting your ${t} account was canceled in Apify Console.`})}}}),u=setTimeout(()=>s({stopReason:`connectTimedOut`,message:`Connecting your ${t} account did not finish within ${ai/6e4} minutes.`}),ai);n?.addEventListener(`abort`,()=>s({abandoned:!0}),{once:!0}),l.listen(0);let{port:f}=l.address(),p=new URL(getConsoleIntegrationsUrl(r));p.searchParams.set(`localCliCommand`,`connect-git-provider`),p.searchParams.set(`gitProvider`,e),p.searchParams.set(`localCliPort`,`${f}`),p.searchParams.set(`localCliToken`,a),p.searchParams.set(`localCliApiVersion`,`v1`);try{p.searchParams.set(`localCliComputerName`,encodeURIComponent(jt()))}catch{}info({message:`Connect your ${t} account to Apify: ${p.href}`}),Dt(p.href).catch(()=>void 0),info({message:`Waiting for the connection to complete in your browser...`});try{return await c}finally{clearTimeout(u),l.closeAllConnections(),l.close()}},oi=[`apify`,`github`,`gitlab`,`bitbucket`],si={github:{label:`GitHub`,authorize:{endpoint:`https://github.com/login/oauth/authorize`,defaultClientId:`Iv1.e39b3ed87e74885f`,clientIdEnvVar:`APIFY_GITHUB_APP_CLIENT_ID`,defaultAppName:`apify`,appNameEnvVar:`APIFY_GITHUB_APP_NAME`,appInstallUrl:`https://github.com/apps/{app}/installations/new`,redirectPath:`/actors/new/git/connected?service=github`}},gitlab:{label:`GitLab`},bitbucket:{label:`Bitbucket`}},isGitProvider=e=>Object.hasOwn(si,e),toGitAccount=({id:e,username:t,organizationOwnerUserId:n})=>({id:e,username:t,organizationOwnerUserId:n}),getGitConnectUrl=(t,n)=>{let{authorize:r}=si[t];if(!r)return getConsoleIntegrationsUrl(n);let i=new URL(r.redirectPath,getConsoleUrl()),a=getConsoleRoutePrefix(n);a&&i.searchParams.set(`routePrefix`,encodeURIComponent(a));let s=new URL(r.endpoint);return s.searchParams.set(`client_id`,e.env[r.clientIdEnvVar]||r.defaultClientId),s.searchParams.set(`redirect_uri`,i.href),s.href},getAddWorkspaceUrl=(t,n)=>{let{authorize:r}=si[t];return r?r.appInstallUrl.replace(`{app}`,e.env[r.appNameEnvVar]||r.defaultAppName):getConsoleIntegrationsUrl(n)},promptGitSource=async()=>Wr({message:`How do you want to set up the source code?`,choices:[{name:`Local only`,value:`apify`,description:`Everything stays on this machine and nothing is uploaded. Deploy with "apify push".`},...oi.filter(isGitProvider).map(e=>{let{label:t}=si[e];return{name:`Host on ${t}`,value:e,description:`Apify creates a private repository on ${t}, clones it into the Actor directory, and creates an Actor that builds from it.`}})],default:`apify`,loop:!1}),parseGitRepoFlag=(e,t)=>{if(!e)return{workspace:void 0,repoName:t};let n=e.lastIndexOf(`/`);if(n===-1)return{workspace:void 0,repoName:e};let r=e.slice(0,n),i=e.slice(n+1);if(!r||!i)throw Error(`Invalid --git-repo "${e}". Use "workspace/name" or just "name".`);return{workspace:r,repoName:i}},apiUrl=({client:e},t)=>`${e.baseUrl}/${t}`,authHeader=({client:e})=>({Authorization:`Bearer ${e.token}`}),fetchGitIntegrations=async e=>{let t=apiUrl(e,`integrations/git`);cliDebugPrint(`git-source`,`GET`,t);let n=await fetch(t,{headers:authHeader(e)}),r=await n.text();if(cliDebugPrint(`git-source`,`GET`,t,`->`,n.status,r.slice(0,400)),!n.ok)throw Error(`Could not read your Git integrations (${n.status} ${n.statusText}).`);return(()=>{try{return JSON.parse(r)}catch{return null}})()?.data??[]},readProviderState=(e,t)=>{let n=e.filter(e=>e.provider===t);return{connected:n.length>0,workspaces:n.flatMap(e=>e.workspaces.map(t=>({...t,providerId:e.id}))),addWorkspaceUrl:n.find(({addWorkspaceUrl:e})=>e)?.addWorkspaceUrl}},ci=2e3,li=18e4,pollForWorkspaces=async(e,{timeoutMs:t,abortSignal:n,onState:r})=>{let i=Date.now()+t,a=ci,s=null;for(;Date.now()<i;){try{await Fe(a,void 0,{signal:n})}catch{return s}a=Math.min(Math.round(a*1.5),1e4);try{s=await e()}catch(e){cliDebugPrint(`git-source`,`poll failed:`,e);continue}if(s.workspaces.length)return s;await r?.(s)}return s},ensureUsableIntegration=async(e,{client:t,isInteractive:n,account:r})=>{let load=async()=>readProviderState(await fetchGitIntegrations({client:t}),e),i=await load();if(cliDebugPrint(`git-source`,`integrations:`,e,i.connected,`workspaces=${i.workspaces.length}`),i.workspaces.length||!n)return i;let{label:a,authorize:s}=si[e];if(!i.connected&&!s){let t=new AbortController,n=Date.now(),s=connectViaConsole(e,a,{abortSignal:t.signal,account:r}),c;try{c=await Promise.race([s.then(()=>null),pollForWorkspaces(load,{timeoutMs:ai,abortSignal:t.signal})])}finally{t.abort()}if(c?.workspaces.length)return c;let l=await s;if(`stopReason`in l)return warning({message:l.message}),i;if(i=await load(),i.workspaces.length)return i;let u=Math.min(li,ai-(Date.now()-n));return u<ci?i:(info({message:`Waiting for Apify to finish connecting your ${a} account...`}),await pollForWorkspaces(load,{timeoutMs:u})??i)}let c=null,offer=async t=>{let n=t.connected?t.addWorkspaceUrl??getAddWorkspaceUrl(e,r):getGitConnectUrl(e,r);n!==c&&(c=n,info({message:`${t.connected?`Give Apify access to a ${a} account`:`Connect your ${a} account to Apify`}: ${n}`}),await Dt(n).catch(()=>void 0),info({message:r?.username?`Waiting for authorization to complete in your browser. It connects ${a} to the Apify account ${r.username}.`:`Waiting for authorization to complete in your browser...`}))};return await offer(i),await pollForWorkspaces(load,{timeoutMs:li,onState:offer})??i},chooseWorkspace=async(e,t,n)=>{if(t){let n=t.toLowerCase(),r=e.find(({id:e,label:t})=>e.toLowerCase()===n||t.toLowerCase()===n);return r?{workspace:r}:{stopReason:`unknownWorkspace`}}return e.length===1?{workspace:e[0]}:n?{workspace:await Wr({message:`Which account should own the repository?`,choices:e.map(e=>({name:e.label,value:e})),loop:!1})}:{stopReason:`ambiguousWorkspace`}};var CreateRemoteRepoError=class extends Error{stopReason;constructor(e,t){super(e),this.stopReason=t,this.name=`CreateRemoteRepoError`}};const ui=/* @__PURE__ */ new Set([`integration-auth-error`,`invalid-git-auth-token`]),withoutUserInfo=e=>{if(!URL.canParse(e))return e;let t=new URL(e);return t.username=``,t.password=``,t.href},createRemoteRepo=async e=>{let{providerId:t,workspace:n,repoName:r,isPrivate:i,templateArchiveUrl:a}=e,s=apiUrl(e,`integrations/git/${t}/create-repo`),c=JSON.stringify({workspace:n,repoName:r,isPrivate:i,templateArchiveUrl:a});cliDebugPrint(`git-source`,`POST`,s,c);let l=await fetch(s,{method:`POST`,headers:{...authHeader(e),"Content-Type":`application/json`},body:c}),u=await l.text();cliDebugPrint(`git-source`,`POST`,s,`->`,l.status,u.slice(0,400));let f=(()=>{try{return JSON.parse(u)}catch{return null}})();if(l.ok&&f?.data)return{...f.data,httpsUrl:withoutUserInfo(f.data.httpsUrl)};let p=f?.error?.type,m=f?.error?.message||`${l.status} ${l.statusText}`;throw p&&ui.has(p)?new CreateRemoteRepoError(m,`notAuthorized`):p===`invalid-parameter`?new CreateRemoteRepoError(m,`repoNameRejected`):new CreateRemoteRepoError(m,`repoCreateFailed`)},cloneRepo=async(e,t,n)=>{await Ve(`git`,[`clone`,t,e],{env:n?void 0:{GIT_TERMINAL_PROMPT:`0`,GIT_SSH_COMMAND:`ssh -o BatchMode=yes`}})},createGitActor=async({client:e,actorName:t,gitRepoUrl:n})=>e.actors().create({name:t,versions:[{versionNumber:`0.0`,sourceType:pe.GIT_REPO,gitRepoUrl:n}]}),registerDeploymentKey=async({client:e,providerId:t,actorId:n,repoUrl:r})=>{let i=apiUrl({client:e},`integrations/git/${t}/register-deployment-key`),a=JSON.stringify({actorId:n,repoName:r});cliDebugPrint(`git-source`,`POST`,i,a);let s=await fetch(i,{method:`POST`,headers:{...authHeader({client:e}),"Content-Type":`application/json`},body:a}),c=await s.text();if(cliDebugPrint(`git-source`,`POST`,i,`->`,s.status,c.slice(0,400)),s.ok)return;let l=(()=>{try{return JSON.parse(c).error?.message}catch{return null}})();throw Error(l||`${s.status} ${s.statusText}`)},enableAutomaticBuilds=async({client:e,providerId:t,actorId:n})=>{let r=apiUrl({client:e},`actors/${n}/versions/0.0/build-on-push`),i=JSON.stringify({providerId:t,enabled:!0});cliDebugPrint(`git-source`,`PUT`,r,i);let a=await fetch(r,{method:`PUT`,headers:{...authHeader({client:e}),"Content-Type":`application/json`},body:i}),s=await a.text();if(cliDebugPrint(`git-source`,`PUT`,r,`->`,a.status,s.slice(0,400)),a.ok)return;let c=(()=>{try{return JSON.parse(s).error?.message}catch{return null}})();throw Error(c||`${a.status} ${a.statusText}`)},runGitSourceFlow=async({client:e,provider:t,actorDir:n,actorName:r,workspace:i,repoName:a,isPrivate:s,templateArchiveUrl:c,isInteractive:l,account:u,autoBuild:f,customize:p})=>{let m=!1,stopped=(e,t,n={})=>({remoteUrl:null,httpsUrl:null,actorId:null,workspaces:null,scaffolded:m,automaticBuilds:`off`,...n,stopReason:e,error:t instanceof Error?t.message:String(t)}),h;try{h=await ensureUsableIntegration(t,{client:e,isInteractive:l,account:u})}catch(e){return stopped(`lookupFailed`,e)}let{label:g}=si[t],_=u?.username?`The Apify account ${u.username}`:`Apify`;if(!h.connected)return stopped(`notAuthorized`,/* @__PURE__ */ Error(`${_} is not authorized to access your ${g} account.`));if(!h.workspaces.length)return stopped(`noWorkspace`,/* @__PURE__ */ Error(`${_} has no ${g} account to create the repository in.`));let v=h.workspaces.map(({label:e})=>e),y=v.join(`, `),b=await chooseWorkspace(h.workspaces,i,l);if(`stopReason`in b)return stopped(b.stopReason,/* @__PURE__ */ Error(b.stopReason===`unknownWorkspace`?`"${i}" is not one of your connected accounts (${y}).`:`Several accounts are connected (${y}); pick one with --git-repo <account>/<name>.`),{workspaces:v});let{workspace:x}=b,S;for(;;)try{info({message:`Creating ${s?`private`:`public`} repository ${x.label}/${a} from the template...`}),S=await createRemoteRepo({client:e,providerId:x.providerId,workspace:x.id,repoName:a,isPrivate:s,templateArchiveUrl:c});break}catch(e){if(e instanceof CreateRemoteRepoError&&e.stopReason===`repoNameRejected`&&l){warning({message:e.message}),a=await zn({message:`Choose a different repository name:`,validate:e=>e.trim().length>0||`Enter a repository name.`});continue}return stopped(e instanceof CreateRemoteRepoError?e.stopReason:`repoCreateFailed`,e,{workspaces:v})}let C=null;try{info({message:`Cloning ${S.httpsUrl}...`}),await cloneRepo(n,S.httpsUrl,l),m=!0,await p(n)}catch(e){let t=e.stderr?.trim();C=t?Error(t):e}let w;try{let t=await createGitActor({client:e,actorName:r,gitRepoUrl:S.sshUrl});info({message:`Created Actor ${t.name} on Apify.`}),w=t.id}catch(e){return stopped(`actorCreateFailed`,e,{workspaces:v,remoteUrl:S.sshUrl,httpsUrl:S.httpsUrl})}try{await registerDeploymentKey({client:e,providerId:x.providerId,actorId:w,repoUrl:S.htmlUrl})}catch(e){return stopped(`deploymentKeyFailed`,e,{workspaces:v,remoteUrl:S.sshUrl,httpsUrl:S.httpsUrl,actorId:w})}let T=`off`;if(f)try{await enableAutomaticBuilds({client:e,providerId:x.providerId,actorId:w}),T=`on`,info({message:`Turned on automatic builds.`})}catch(e){T=`failed`,warning({message:`Automatic builds stay off: ${e instanceof Error?e.message:String(e)}`})}else info({message:`Automatic builds stay off, so a push does not rebuild the Actor.`});return C?stopped(`gitSetupFailed`,C,{workspaces:v,remoteUrl:S.sshUrl,httpsUrl:S.httpsUrl,actorId:w,automaticBuilds:T}):{remoteUrl:S.sshUrl,httpsUrl:S.httpsUrl,actorId:w,workspaces:v,stopReason:null,error:null,scaffolded:!0,automaticBuilds:T}},getGitStopUrl=(e,t,n)=>t===`notAuthorized`?getGitConnectUrl(e,n):t===`noWorkspace`?getAddWorkspaceUrl(e,n):null,buildGitSourceNextSteps=({actorName:e,stopReason:t,provider:n,remoteUrl:r,httpsUrl:i,repoName:a,scaffolded:s,actorId:c,account:l})=>{let u=`cd "${e}"`;switch(t){case`lookupFailed`:return[`Re-run with APIFY_CLI_DEBUG=1 to see the failing request`];case`notAuthorized`:return[`Connect your ${si[n].label} account to Apify: ${getGitConnectUrl(n,l)}`,`then re-run apify create`];case`noWorkspace`:return[`Give Apify access to a ${si[n].label} account: ${getAddWorkspaceUrl(n,l)}`,`then re-run apify create`];case`unknownWorkspace`:case`ambiguousWorkspace`:return[`Re-run naming the account: --git-repo <account>/${a}`];case`repoNameRejected`:return[`Re-run with a different repository name: --git-repo <account>/<other-name>`,`The name has to be free, and to use only letters, numbers, hyphens and underscores`];case`repoCreateFailed`:return[`Re-run apify create to try again`];case`gitSetupFailed`:return s?[u,`Apply the local configuration by hand: the error above says what failed`]:[`git clone ${i} "${e}"`,`Or clone over SSH, if you have a key for the provider: git clone ${r} "${e}"`,u];case`actorCreateFailed`:return[u,`Create an Actor from ${r} in Apify Console`];case`deploymentKeyFailed`:return[...s?[u]:[`git clone ${i} "${e}"`,u],`Add the Apify deploy key in the Actor's Source settings before building: ${getConsoleUrl()}/actors/${c}`]}},logGitSourceOutcome=(e,t)=>{e.stopReason&&(warning({message:`${e.scaffolded?`Actor scaffolded, but the Git setup did not finish`:e.actorId?`Actor created, but the clone failed`:`The Actor was not created: the Git setup stopped`}: ${e.error}`}),info({message:`Next steps:\n${t.map(e=>` ${e}`).join(`
153
- `)}`}))};var CreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates an Actor project from a template in a new directory. The command automatically initializes a git repository in the newly created Actor directory.`;static group=`Local Actor Development`;static interactive=!0;static interactiveNote=`Prompts for an Actor name, then guides you through what you want to build, a language, a template, and how the source code is set up when they are not provided. To run non-interactively, pass the name and --template; --source defaults to "apify". Use --use-case and --language to narrow the template list.`;static examples=[{description:`Create a new Actor project interactively, with guided prompts for the name, use case, language, template, and source.`,command:`apify create`},{description:`Narrow the guided template list by use case and language.`,command:`apify create my-actor --use-case web-scraper --language python`},{description:`Create non-interactively with explicit name and template.`,command:`apify create my-actor --template js-crawlee-cheerio`},{description:`Create without installing dependencies (faster; run install yourself later).`,command:`apify create my-actor --template python-start --skip-dependency-install`},{description:`Host the source code on GitHub. Apify creates the repository and builds the Actor from it.`,command:`apify create my-actor --template js-crawlee-cheerio --source github`},{description:`Name the account and the repository to create, instead of being asked.`,command:`apify create my-actor --template js-crawlee-cheerio --source github --git-repo my-org/my-scraper`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-create`;static flags={template:Y.string({char:`t`,description:`Template for the Actor. If not provided, the command will prompt for it. Visit ${kt} to find available template names.`,required:!1}),"use-case":Y.string({char:`u`,description:`Filter templates by use case. Ignored when --template is provided. To see the use cases each template supports, run "apify templates ls".`,choices:ii,required:!1}),language:Y.string({char:`l`,description:`Filter templates by programming language. Ignored when --template is provided.`,choices:ri,required:!1}),"skip-dependency-install":Y.boolean({description:`Skip installing Actor dependencies.`,required:!1}),"template-archive-url":Y.string({description:`Actor template archive url. Useful for developing new templates.`,required:!1,hidden:!0}),"omit-optional-deps":Y.boolean({aliases:[`no-optional`],description:`Skip installing optional dependencies.`,required:!1}),"skip-git-init":Y.boolean({description:`Skip initializing a git repository in the Actor directory.`,required:!1}),source:Y.string({description:`Where the Actor source code lives. With "apify", the code stays on your machine and nothing is uploaded. You can still deploy your Actor with "apify push". With a Git provider, Apify creates a private repository from the template on your connected account, clones the repository into the Actor directory, and builds the Actor from it.`,choices:[...oi],required:!1}),"git-repo":Y.string({description:`Repository to create, as "workspace/name" — a workspace being an account or organization you have given Apify access to. A bare value is read as the name, not the workspace. The name defaults to the Actor name, and the workspace is asked for when you have more than one. List yours with "apify api integrations/git". Only used when --source is a Git provider.`,required:!1}),"auto-build":Y.string({description:`Whether a push to the repository rebuilds the Actor. On by default. Turning it on registers a push webhook on the new repository, which needs admin rights on it. Only used when --source is a Git provider.`,choices:[`on`,`off`],required:!1}),origin:Y.string({description:`Where the command was invoked from. Used for funnel telemetry.`,choices:[`console`,`cli`],default:`cli`,required:!1,hidden:!0})};static args={actorName:Z.string({required:!1,description:`Name of the Actor and its directory.`})};static enableJsonFlag=!0;async run(){let{actorName:t}=this.args,{template:n,useCase:r,language:i,skipDependencyInstall:a,skipGitInit:s,origin:c,json:l,gitRepo:f}=this.flags,{templateArchiveUrl:p}=this.flags,m=!1,h=!n&&!p;if(l&&(!t||h)){let e=[...t?[]:[`the Actor name as an argument`],...h?[`--template <name>`]:[]],n=h?` Run "apify templates ls" to list template names.`:``;throw Error(`--json runs non-interactively. Pass ${e.join(` and `)}.${n}`)}let g=this.flags.source,_=Ot().catch(e=>/* @__PURE__ */ Error(`Could not fetch template list from server. Cause: ${e?.message}`));t=await ensureValidActorName(t);let v=e.cwd(),x=u(v,t);for(;;){let e=await W(x).catch(()=>null),n=e&&await Ae(x).then(e=>e.length>0).catch(()=>!1);if(e?.isDirectory()&&n){let e=`Cannot create new Actor, directory '${t}' already exists. Provide a different name. To create a local Actor environment inside an existing directory, use "apify init".`;if(l)throw Error(e);error({message:e}),t=await ensureValidActorName(),x=u(v,t);continue}e||await H(x,{recursive:!0});break}let S=null,C=null;if(this.telemetryData.create={fromArchiveUrl:!!p,origin:c},!p){let e=await getTemplateDefinition(n,_,{useCase:r,language:i});({archiveUrl:p,messages:S}=e),C=e.id,this.telemetryData.create.templateId=e.id,this.telemetryData.create.templateName=e.name,this.telemetryData.create.templateLanguage=e.category,`skipOptionalDeps`in e&&(m=e.skipOptionalDeps)}this.flags.omitOptionalDeps&&(m=!0);let{isTTY:w}=await useStdin(),T=w&&!ue&&!l;g??=T?await promptGitSource():`apify`;let E=isGitProvider(g)?g:null;if(this.telemetryData.create.source=g,E&&s)throw Error(`--source ${g} clones a git repository, so --skip-git-init cannot apply.`);if(!E&&f)throw Error(`--git-repo only applies to a Git source, so add --source github|gitlab|bitbucket or drop it.`);if(!E&&this.flags.autoBuild)throw Error(`--auto-build only applies to a Git source, so add --source github|gitlab|bitbucket or drop it.`);if(E&&this.flags.templateArchiveUrl)throw Error(`--template-archive-url is not supported with --source ${g}.`);let D=E?{provider:E,client:await getLoggedClientOrThrow(),account:toGitAccount(await getCurrentUserInfo()),autoBuild:this.flags.autoBuild!==`off`,...parseGitRepoFlag(f,t)}:null,applyLocalConfig=async e=>{let n=getJsonFileContent(u(e,K));await setLocalConfig(Object.assign(n||rn,{name:t}),e),await setLocalEnv(e),await createPrefilledInputFileFromInputSchema(e)};E||(await downloadAndUnzip({url:p,pathTo:x}),await applyLocalConfig(x),await enhanceReadmeWithLocalSuffix(u(x,`README.md`),_));let O=u(x,`package.json`),k=null;D&&(k=await runGitSourceFlow({provider:D.provider,actorDir:x,actorName:t,workspace:D.workspace,repoName:D.repoName,isPrivate:!0,templateArchiveUrl:p,client:D.client,isInteractive:T,account:D.account,autoBuild:D.autoBuild,customize:applyLocalConfig}));let A=!1;a||await(await useCwdProject({cwd:x})).inspectAsync(async n=>{let r=b(cn);if((n.type===1||n.type===2)&&n.packageManager===`uv`){let e=await We(`uv`,{nothrow:!0});if(!e){warning({message:`This Actor uses uv to manage its dependencies, but the uv executable was not found. Install uv (https://docs.astral.sh/uv/getting-started/installation/), then run "uv sync" in the Actor directory.`});return}info({message:`Installing dependencies with "uv sync"...`}),await execWithLog({cmd:e,args:[`sync`],opts:{cwd:x}}),A=!0;return}if(!n.runtime){switch(n.type){case 0:warning({message:`No Node.js detected! Please install Node.js ${r} or higher to be able to run Node.js Actors locally.`});break;case 2:case 1:warning({message:`No Python detected! Please install Python ${dn} or higher to be able to run Python Actors locally.`})}return}let{runtime:i}=n;switch(n.type){case 0:{isNodeVersionSupported(i.version)||warning({message:`You are running Node.js version ${i.version}, which is no longer supported. Please upgrade to Node.js version ${r} or later.`}),await updateLocalJson(O,{name:t});let e=[`install`];if(m)switch(i.pmName){case`npm`:y(i.pmVersion,`7.0.0`)?e.push(`--omit=optional`):e.push(`--no-optional`);break;case`bun`:e.push(`--omit=optional`);break;case`deno`:e.push(`--node-modules-dir`)}await execWithLog({cmd:i.pmPath,args:e,opts:{cwd:x},overrideCommand:i.pmName}),A=!0;break}case 1:case 2:{if(!isPythonVersionSupported(i.version)){warning({message:`Python Actors require Python ${dn} or higher, but you have Python ${i.version}!`}),warning({message:`Please install Python ${dn} or higher to be able to run Python Actors locally.`});return}let t=u(x,`.venv`);info({message:`Python version ${i.version} detected.`}),info({message:`Creating a virtual environment in "${t}" and installing dependencies from "requirements.txt"...`}),e.env.VIRTUAL_ENV||(await execWithLog({cmd:i.executablePath,args:[`-m`,`venv`,`--prompt`,`.`,`.venv`],opts:{cwd:x}}),i=(await usePythonRuntime({cwd:x,force:!0})).unwrap(),n.runtime=i),await execWithLog({cmd:i.executablePath,args:[`-m`,`pip`,`install`,`--no-cache-dir`,`--no-warn-script-location`,`--upgrade`,`pip`,`setuptools`,`wheel`],opts:{cwd:x}}),await execWithLog({cmd:i.executablePath,args:[`-m`,`pip`,`install`,`--no-cache-dir`,`--no-warn-script-location`,`-r`,`requirements.txt`],opts:{cwd:x}}),A=!0;break}}});let j={success:!0},M=await W(u(v,`.git`)).catch(()=>null),N=await W(u(x,`.git`)).catch(()=>null),ee=k!==null&&!k.scaffolded,P=!s&&!M&&!N&&!ee;if(P)try{await execWithLog({cmd:`git`,args:[`init`],opts:{cwd:x}})}catch(e){j={success:!1,error:e}}let F=A?null:await getInstallCommandSuggestion(x),te=P&&j.success||!!N;k?.stopReason&&(e.exitCode=1);let ne=D&&k?.stopReason?buildGitSourceNextSteps({actorName:t,stopReason:k.stopReason,provider:D.provider,remoteUrl:k.remoteUrl,httpsUrl:k.httpsUrl,repoName:D.repoName,scaffolded:k.scaffolded,actorId:k.actorId,account:D.account}):buildNextSteps({actorName:t,dependenciesInstalled:A,installCommandSuggestion:F}),I=!k?.stopReason;l?printJsonToStdout({dir:x,actorJsonPath:u(x,K),template:C,source:g,nextSteps:ne,postCreate:S?.postCreate??null,gitRepositoryInitialized:te,remote:k?.remoteUrl??null,automaticBuilds:k?.automaticBuilds??null,actorId:k?.actorId??null,stopReason:k?.stopReason??null,error:k?.error??null,gitConnectUrl:E?getGitStopUrl(E,k?.stopReason??null,D?.account):null,workspaces:k?.workspaces??null}):I&&(simpleLog({message:``}),success({message:formatCreateSuccessMessage({actorName:t,dependenciesInstalled:A,postCreate:S?.postCreate??null,gitRepositoryInitialized:te,installCommandSuggestion:F,gitRemote:k?.remoteUrl&&k.actorId?{remoteUrl:k.remoteUrl,actorId:k.actorId,automaticBuilds:k.automaticBuilds}:null})})),P&&!j.success&&(warning({message:`Failed to initialize git repository: ${j.error.message}`}),warning({message:`You can manually run "git init" in the Actor directory if needed.`})),k&&!l&&logGitSourceOutcome(k,ne)}};async function tryToGetStorage(e,t,n){let r=await e[n](t).get().catch(()=>void 0);if(r)return{[n]:r,[`${n}Client`]:e[n](r.id)};let i=await getCurrentUserInfo(),a=await e[n](`${i.username}/${t}`).get().catch(()=>void 0);return a?{[n]:a,[`${n}Client`]:e[n](a.id)}:null}async function tryToGetDataset(e,t){return tryToGetStorage(e,t,`dataset`)}async function tryToGetKeyValueStore(e,t){return tryToGetStorage(e,t,`keyValueStore`)}var DatasetsCreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates a new dataset for storing structured data on your account.`;static examples=[{description:`Create an unnamed dataset.`,command:`apify datasets create`},{description:`Create a named dataset.`,command:`apify datasets create my-dataset`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-create`;static args={datasetName:Z.string({description:`Optional name for the Dataset.`,required:!1})};static enableJsonFlag=!0;async run(){let{datasetName:e}=this.args,n=await getLoggedClientOrThrow();if(e&&await tryToGetDataset(n,e)){error({message:`A Dataset with this name already exists!`});return}let r=await n.datasets().getOrCreate(e);if(this.flags.json){printJsonToStdout(r);return}success({message:`Dataset with ID ${t.yellow(r.id)}${e?` (called ${t.yellow(e)})`:``} was created.`,stdout:!0})}};const di={[V.JSON]:`application/json`,[V.JSONL]:`application/jsonl`,[V.CSV]:`text/csv`,[V.HTML]:`text/html`,[V.RSS]:`application/rss+xml`,[V.XML]:`application/xml`,[V.XLSX]:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`};var DatasetsGetItems=class extends ApifyCommand{static name=`get-items`;static enableProfileFlag=!0;static description=`Retrieves dataset items in specified format (JSON, CSV, etc).`;static examples=[{description:`Print all items from a dataset as JSON.`,command:`apify datasets get-items <datasetId>`},{description:`Export the first 100 items as CSV to a file.`,command:`apify datasets get-items <datasetId> --format csv --limit 100 > items.csv`},{description:`Paginate: skip the first 500 items, return the next 500.`,command:`apify datasets get-items <datasetId> --offset 500 --limit 500`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-get-items`;static flags={limit:Y.integer({description:`The amount of elements to get from the dataset. By default, it will return all available items.`}),offset:Y.integer({description:`The offset in the dataset where to start getting items.`}),format:Y.string({description:`The format of the returned output. By default, it is set to 'json'.`,choices:Object.keys(di),default:V.JSON})};static args={datasetId:Z.string({description:`The ID of the Dataset to export the items for.`,required:!0})};async run(){let{limit:e,offset:t,format:n}=this.flags,{datasetId:r}=this.args,i=await getLoggedClientOrThrow(),a=await this.tryToGetDataset(i,r);if(!a){error({message:`Dataset with ID "${r}" not found.`});return}let{datasetClient:s}=a;process.stdout.write(``);let c=await s.downloadItems(n,{limit:e,offset:t});simpleLog({message:di[n]??`application/octet-stream`}),process.stdout.write(c),process.stdout.write(`
153
+ `)}`}))};var CreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates an Actor project from a template in a new directory. The command automatically initializes a git repository in the newly created Actor directory.`;static group=`Local Actor Development`;static interactive=!0;static interactiveNote=`Prompts for an Actor name, then guides you through what you want to build, a language, a template, and how the source code is set up when they are not provided. To run non-interactively, pass the name and --template; --source defaults to "apify". Use --use-case and --language to narrow the template list.`;static examples=[{description:`Create a new Actor project interactively, with guided prompts for the name, use case, language, template, and source.`,command:`apify create`},{description:`Narrow the guided template list by use case and language.`,command:`apify create my-actor --use-case web-scraper --language python`},{description:`Create non-interactively with explicit name and template.`,command:`apify create my-actor --template js-crawlee-cheerio`},{description:`Create without installing dependencies (faster; run install yourself later).`,command:`apify create my-actor --template python-start --skip-dependency-install`},{description:`Host the source code on GitHub. Apify creates the repository and builds the Actor from it.`,command:`apify create my-actor --template js-crawlee-cheerio --source github`},{description:`Name the account and the repository to create, instead of being asked.`,command:`apify create my-actor --template js-crawlee-cheerio --source github --git-repo my-org/my-scraper`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-create`;static flags={template:Y.string({char:`t`,description:`Template for the Actor. If not provided, the command will prompt for it. Visit ${kt} to find available template names.`,required:!1}),"use-case":Y.string({char:`u`,description:`Filter templates by use case. Ignored when --template is provided. To see the use cases each template supports, run "apify templates ls".`,choices:ii,required:!1}),language:Y.string({char:`l`,description:`Filter templates by programming language. Ignored when --template is provided.`,choices:ri,required:!1}),"skip-dependency-install":Y.boolean({description:`Skip installing Actor dependencies.`,required:!1}),"template-archive-url":Y.string({description:`Actor template archive url. Useful for developing new templates.`,required:!1,hidden:!0}),"omit-optional-deps":Y.boolean({aliases:[`no-optional`],description:`Skip installing optional dependencies.`,required:!1}),"skip-git-init":Y.boolean({description:`Skip initializing a git repository in the Actor directory.`,required:!1}),source:Y.string({description:`Where the Actor source code lives. With "apify", the code stays on your machine and nothing is uploaded. You can still deploy your Actor with "apify push". With a Git provider, Apify creates a private repository from the template on your connected account, clones the repository into the Actor directory, and builds the Actor from it.`,choices:[...oi],required:!1}),"git-repo":Y.string({description:`Repository to create, as "workspace/name" — a workspace being an account or organization you have given Apify access to. A bare value is read as the name, not the workspace. The name defaults to the Actor name, and the workspace is asked for when you have more than one. List yours with "apify api integrations/git". Only used when --source is a Git provider.`,required:!1}),"auto-build":Y.string({description:`Whether a push to the repository rebuilds the Actor. On by default. Turning it on registers a push webhook on the new repository, which needs admin rights on it. Only used when --source is a Git provider.`,choices:[`on`,`off`],required:!1}),origin:Y.string({description:`Where the command was invoked from. Used for funnel telemetry.`,choices:[`console`,`cli`],default:`cli`,required:!1,hidden:!0})};static args={actorName:Z.string({required:!1,description:`Name of the Actor and its directory.`})};static enableJsonFlag=!0;async run(){let{actorName:t}=this.args,{template:n,useCase:r,language:i,skipDependencyInstall:a,skipGitInit:s,origin:c,json:l,gitRepo:f}=this.flags,{templateArchiveUrl:p}=this.flags,m=!1,h=!n&&!p;if(l&&(!t||h)){let e=[...t?[]:[`the Actor name as an argument`],...h?[`--template <name>`]:[]],n=h?` Run "apify templates ls" to list template names.`:``;throw Error(`--json runs non-interactively. Pass ${e.join(` and `)}.${n}`)}let g=this.flags.source,_=Ot().catch(e=>/* @__PURE__ */ Error(`Could not fetch template list from server. Cause: ${e?.message}`));t=await ensureValidActorName(t);let v=e.cwd(),x=u(v,t);for(;;){let e=await W(x).catch(()=>null),n=e&&await Ae(x).then(e=>e.length>0).catch(()=>!1);if(e?.isDirectory()&&n){let e=`Cannot create new Actor, directory '${t}' already exists. Provide a different name. To create a local Actor environment inside an existing directory, use "apify init".`;if(l)throw Error(e);error({message:e}),t=await ensureValidActorName(),x=u(v,t)}else{e||await H(x,{recursive:!0});break}}let S=null,C=null;if(this.telemetryData.create={fromArchiveUrl:!!p,origin:c},!p){let e=await getTemplateDefinition(n,_,{useCase:r,language:i});({archiveUrl:p,messages:S}=e),C=e.id,this.telemetryData.create.templateId=e.id,this.telemetryData.create.templateName=e.name,this.telemetryData.create.templateLanguage=e.category,`skipOptionalDeps`in e&&(m=e.skipOptionalDeps)}this.flags.omitOptionalDeps&&(m=!0);let{isTTY:w}=await useStdin(),T=w&&!ue&&!l;g??=T?await promptGitSource():`apify`;let E=isGitProvider(g)?g:null;if(this.telemetryData.create.source=g,E&&s)throw Error(`--source ${g} clones a git repository, so --skip-git-init cannot apply.`);if(!E&&f)throw Error(`--git-repo only applies to a Git source, so add --source github|gitlab|bitbucket or drop it.`);if(!E&&this.flags.autoBuild)throw Error(`--auto-build only applies to a Git source, so add --source github|gitlab|bitbucket or drop it.`);if(E&&this.flags.templateArchiveUrl)throw Error(`--template-archive-url is not supported with --source ${g}.`);let D=E?{provider:E,client:await getLoggedClientOrThrow(),account:toGitAccount(await getCurrentUserInfo()),autoBuild:this.flags.autoBuild!==`off`,...parseGitRepoFlag(f,t)}:null,applyLocalConfig=async e=>{let n=getJsonFileContent(u(e,K));await setLocalConfig(Object.assign(n||rn,{name:t}),e),await setLocalEnv(e),await createPrefilledInputFileFromInputSchema(e)};E||(await downloadAndUnzip({url:p,pathTo:x}),await applyLocalConfig(x),await enhanceReadmeWithLocalSuffix(u(x,`README.md`),_));let O=u(x,`package.json`),k=null;D&&(k=await runGitSourceFlow({provider:D.provider,actorDir:x,actorName:t,workspace:D.workspace,repoName:D.repoName,isPrivate:!0,templateArchiveUrl:p,client:D.client,isInteractive:T,account:D.account,autoBuild:D.autoBuild,customize:applyLocalConfig}));let A=!1;a||await(await useCwdProject({cwd:x})).inspectAsync(async n=>{let r=b(cn);if((n.type===1||n.type===2)&&n.packageManager===`uv`){let e=await We(`uv`,{nothrow:!0});if(!e){warning({message:`This Actor uses uv to manage its dependencies, but the uv executable was not found. Install uv (https://docs.astral.sh/uv/getting-started/installation/), then run "uv sync" in the Actor directory.`});return}info({message:`Installing dependencies with "uv sync"...`}),await execWithLog({cmd:e,args:[`sync`],opts:{cwd:x}}),A=!0;return}if(!n.runtime){switch(n.type){case 0:warning({message:`No Node.js detected! Please install Node.js ${r} or higher to be able to run Node.js Actors locally.`});break;case 2:case 1:warning({message:`No Python detected! Please install Python ${dn} or higher to be able to run Python Actors locally.`})}return}let{runtime:i}=n;switch(n.type){case 0:{isNodeVersionSupported(i.version)||warning({message:`You are running Node.js version ${i.version}, which is no longer supported. Please upgrade to Node.js version ${r} or later.`}),await updateLocalJson(O,{name:t});let e=[`install`];if(m)switch(i.pmName){case`npm`:y(i.pmVersion,`7.0.0`)?e.push(`--omit=optional`):e.push(`--no-optional`);break;case`bun`:e.push(`--omit=optional`);break;case`deno`:e.push(`--node-modules-dir`)}await execWithLog({cmd:i.pmPath,args:e,opts:{cwd:x},overrideCommand:i.pmName}),A=!0;break}case 1:case 2:{if(!isPythonVersionSupported(i.version)){warning({message:`Python Actors require Python ${dn} or higher, but you have Python ${i.version}!`}),warning({message:`Please install Python ${dn} or higher to be able to run Python Actors locally.`});return}let t=u(x,`.venv`);info({message:`Python version ${i.version} detected.`}),info({message:`Creating a virtual environment in "${t}" and installing dependencies from "requirements.txt"...`}),e.env.VIRTUAL_ENV||(await execWithLog({cmd:i.executablePath,args:[`-m`,`venv`,`--prompt`,`.`,`.venv`],opts:{cwd:x}}),i=(await usePythonRuntime({cwd:x,force:!0})).unwrap(),n.runtime=i),await execWithLog({cmd:i.executablePath,args:[`-m`,`pip`,`install`,`--no-cache-dir`,`--no-warn-script-location`,`--upgrade`,`pip`,`setuptools`,`wheel`],opts:{cwd:x}}),await execWithLog({cmd:i.executablePath,args:[`-m`,`pip`,`install`,`--no-cache-dir`,`--no-warn-script-location`,`-r`,`requirements.txt`],opts:{cwd:x}}),A=!0;break}}});let j={success:!0},M=await W(u(v,`.git`)).catch(()=>null),N=await W(u(x,`.git`)).catch(()=>null),ee=k!==null&&!k.scaffolded,P=!s&&!M&&!N&&!ee;if(P)try{await execWithLog({cmd:`git`,args:[`init`],opts:{cwd:x}})}catch(e){j={success:!1,error:e}}let F=A?null:await getInstallCommandSuggestion(x),te=P&&j.success||!!N;k?.stopReason&&(e.exitCode=1);let ne=D&&k?.stopReason?buildGitSourceNextSteps({actorName:t,stopReason:k.stopReason,provider:D.provider,remoteUrl:k.remoteUrl,httpsUrl:k.httpsUrl,repoName:D.repoName,scaffolded:k.scaffolded,actorId:k.actorId,account:D.account}):buildNextSteps({actorName:t,dependenciesInstalled:A,installCommandSuggestion:F}),I=!k?.stopReason;l?printJsonToStdout({dir:x,actorJsonPath:u(x,K),template:C,source:g,nextSteps:ne,postCreate:S?.postCreate??null,gitRepositoryInitialized:te,remote:k?.remoteUrl??null,automaticBuilds:k?.automaticBuilds??null,actorId:k?.actorId??null,stopReason:k?.stopReason??null,error:k?.error??null,gitConnectUrl:E?getGitStopUrl(E,k?.stopReason??null,D?.account):null,workspaces:k?.workspaces??null}):I&&(simpleLog({message:``}),success({message:formatCreateSuccessMessage({actorName:t,dependenciesInstalled:A,postCreate:S?.postCreate??null,gitRepositoryInitialized:te,installCommandSuggestion:F,gitRemote:k?.remoteUrl&&k.actorId?{remoteUrl:k.remoteUrl,actorId:k.actorId,automaticBuilds:k.automaticBuilds}:null})})),P&&!j.success&&(warning({message:`Failed to initialize git repository: ${j.error.message}`}),warning({message:`You can manually run "git init" in the Actor directory if needed.`})),k&&!l&&logGitSourceOutcome(k,ne)}};async function tryToGetStorage(e,t,n){let r=await e[n](t).get().catch(()=>void 0);if(r)return{[n]:r,[`${n}Client`]:e[n](r.id)};let i=await getCurrentUserInfo(),a=await e[n](`${i.username}/${t}`).get().catch(()=>void 0);return a?{[n]:a,[`${n}Client`]:e[n](a.id)}:null}async function tryToGetDataset(e,t){return tryToGetStorage(e,t,`dataset`)}async function tryToGetKeyValueStore(e,t){return tryToGetStorage(e,t,`keyValueStore`)}var DatasetsCreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates a new dataset for storing structured data on your account.`;static examples=[{description:`Create an unnamed dataset.`,command:`apify datasets create`},{description:`Create a named dataset.`,command:`apify datasets create my-dataset`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-create`;static args={datasetName:Z.string({description:`Optional name for the Dataset.`,required:!1})};static enableJsonFlag=!0;async run(){let{datasetName:e}=this.args,n=await getLoggedClientOrThrow();if(e&&await tryToGetDataset(n,e)){error({message:`A Dataset with this name already exists!`});return}let r=await n.datasets().getOrCreate(e);this.flags.json?printJsonToStdout(r):success({message:`Dataset with ID ${t.yellow(r.id)}${e?` (called ${t.yellow(e)})`:``} was created.`,stdout:!0})}};const di={[V.JSON]:`application/json`,[V.JSONL]:`application/jsonl`,[V.CSV]:`text/csv`,[V.HTML]:`text/html`,[V.RSS]:`application/rss+xml`,[V.XML]:`application/xml`,[V.XLSX]:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`};var DatasetsGetItems=class extends ApifyCommand{static name=`get-items`;static enableProfileFlag=!0;static description=`Retrieves dataset items in specified format (JSON, CSV, etc).`;static examples=[{description:`Print all items from a dataset as JSON.`,command:`apify datasets get-items <datasetId>`},{description:`Export the first 100 items as CSV to a file.`,command:`apify datasets get-items <datasetId> --format csv --limit 100 > items.csv`},{description:`Paginate: skip the first 500 items, return the next 500.`,command:`apify datasets get-items <datasetId> --offset 500 --limit 500`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-get-items`;static flags={limit:Y.integer({description:`The amount of elements to get from the dataset. By default, it will return all available items.`}),offset:Y.integer({description:`The offset in the dataset where to start getting items.`}),format:Y.string({description:`The format of the returned output. By default, it is set to 'json'.`,choices:Object.keys(di),default:V.JSON})};static args={datasetId:Z.string({description:`The ID of the Dataset to export the items for.`,required:!0})};async run(){let{limit:e,offset:t,format:n}=this.flags,{datasetId:r}=this.args,i=await getLoggedClientOrThrow(),a=await this.tryToGetDataset(i,r);if(!a){error({message:`Dataset with ID "${r}" not found.`});return}let{datasetClient:s}=a;process.stdout.write(``);let c=await s.downloadItems(n,{limit:e,offset:t});simpleLog({message:di[n]??`application/octet-stream`}),process.stdout.write(c),process.stdout.write(`
154
154
  `)}async tryToGetDataset(e,t){let n=await e.dataset(t).get().catch(()=>void 0);if(n)return{dataset:n,datasetClient:e.dataset(n.id)};let r=await getCurrentUserInfo(),i=await e.dataset(`${r.username}/${t}`).get().catch(()=>void 0);return i?{dataset:i,datasetClient:e.dataset(i.id)}:null}};function getUserPlanPricing(e){let t=Reflect.get(e,`planPricing`);return t?Reflect.get(t,`chargeableServiceUnitPricesUsd`):null}const fi=new Q({allColumns:[`Row1`,`Row2`],mandatoryColumns:[`Row1`,`Row2`]});var DatasetsInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Prints information about a specific dataset.`;static examples=[{description:`Show dataset metadata (item count, size, timestamps).`,command:`apify datasets info <datasetId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-info`;static args={storeId:Z.string({description:`The dataset store ID to print information about.`,required:!0})};static enableJsonFlag=!0;async run(){let{storeId:e}=this.args,n=await getLoggedClientOrThrow(),r=await tryToGetDataset(n,e);if(!r){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{dataset:i}=r,[a,s,c]=await Promise.all([n.user(i.userId).get().then(e=>e),i.actId?n.actor(i.actId).get():Promise.resolve(void 0),i.actRunId?n.run(i.actRunId).get():Promise.resolve(void 0)]),l;if(c?.actorTaskId&&(l=await n.task(c.actorTaskId).get().catch(()=>void 0)),this.flags.json){printJsonToStdout({...i,user:a,actor:s||null,run:c||null,task:l||null});return}let u=i.stats?.storageBytes||0,f=i.stats?.readCount||0,p=i.stats?.writeCount||0,m=(i.cleanItemCount||0).toLocaleString(`en-US`),h=(i.itemCount||0).toLocaleString(`en-US`),g=[`${t.bold(f.toLocaleString(`en-US`))} ${t.gray(this.pluralString(f,`read`,`reads`))}`,`${t.bold(p.toLocaleString(`en-US`))} ${t.gray(this.pluralString(p,`write`,`writes`))}`],_=`Items: ${t.bold(m)} ${t.gray(`clean`)} / ${t.bold(h)} ${t.gray(`total`)}\nOperations: ${g.join(` / `)}`;if(a.plan){let e=getUserPlanPricing(a.plan);if(e){let n=e.KEY_VALUE_STORE_TIMED_STORAGE_GBYTE_HOURS*(u/1e3**3),r=n*24*30,i=r>1?`$${r.toFixed(2)}`:`$${n.toFixed(3)}`;_+=`\nStorage size: ${prettyPrintBytes({bytes:u,shortBytes:!0,precision:1})} / ${t.gray(`${i} per month`)}`}}else _+=`\nStorage size: ${prettyPrintBytes({bytes:u,shortBytes:!0,precision:1})}`;let v=[`Dataset ID: ${t.bgGray(i.id)}`,`Name: ${i.name?t.bgGray(i.name):t.bold(t.italic(`Unnamed`))}`,`Created: ${t.bold(q.display(i.createdAt))}`,`Modified: ${t.bold(q.display(i.modifiedAt))}`].join(`
155
155
  `),y=t.bold(`—`);i.actRunId&&(y=c?t.bgBlue(c.id):t.italic(t.gray(`Run removed`)));let b=t.bold(`—`);s&&(b=t.blue(s.title||s.name));let x=t.bold(`—`);l&&(x=t.blue(l.title||l.name));let S=[`Run: ${y}`,`Actor: ${b}`,`Task: ${x}`].join(`
156
156
  `);fi.pushRow({Row1:v,Row2:S});let C=fi.render(2).split(`
157
157
  `).map(e=>e.trim());C.shift(),simpleLog({message:[`${t.bold(i.name||t.italic(`Unnamed`))}`,`${t.gray(i.name?`${a.username}/${i.name}`:i.id)} ${t.gray(`Owned by`)} ${t.blue(a.username)}`,``,C.join(`
158
158
  `),``,_].join(`
159
- `),stdout:!0})}};const pi=new Q({allColumns:[`Dataset ID`,`Name`,`Items`,`Size`,`Created`,`Modified`],mandatoryColumns:[`Dataset ID`,`Name`,`Items`,`Size`],columnAlignments:{Items:`right`}});var DatasetsLsCommand=class extends ApifyCommand{static name=`ls`;static enableProfileFlag=!0;static description=`Prints all datasets on your account.`;static examples=[{description:`List your datasets (most recently modified first).`,command:`apify datasets ls --desc`},{description:`List only unnamed (auto-generated) datasets.`,command:`apify datasets ls --unnamed`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-ls`;static flags={offset:Y.integer({description:`Number of datasets that will be skipped.`,default:0}),limit:Y.integer({description:`Number of datasets that will be listed.`,default:20}),desc:Y.boolean({description:`Sorts datasets in descending order.`,default:!1}),unnamed:Y.boolean({description:`Lists datasets that don't have a name set.`,default:!1})};static enableJsonFlag=!0;async run(){let{desc:e,offset:n,limit:r,json:i,unnamed:a}=this.flags,s=await getLoggedClientOrThrow(),c=await getCurrentUserInfo(),l=await s.datasets().list({desc:e,offset:n,limit:r,unnamed:a});if(i){printJsonToStdout(l);return}if(l.count===0){info({message:`You don't have any Datasets on your account`,stdout:!0});return}for(let e of l.items){let n=Reflect.get(e.stats,`s3StorageBytes`);pi.pushRow({"Dataset ID":e.id,Created:q.display(e.createdAt),Items:`${e.itemCount}`,Modified:q.display(e.modifiedAt),Name:e.name?`${c.username}/${e.name}`:``,Size:typeof n==`number`?prettyPrintBytes({bytes:n,shortBytes:!0,colorFunc:t.gray,precision:0}):t.gray(`N/A`)})}simpleLog({message:pi.render(1),stdout:!0})}},DatasetsPushDataCommand=class extends ApifyCommand{static name=`push-items`;static enableProfileFlag=!0;static description=`Adds data items to specified dataset. Accepts single object or array of objects.`;static examples=[{description:`Push a single item as an inline JSON argument.`,command:`apify datasets push-items my-dataset '{"url":"https://example.com"}'`},{description:`Push an array of items from stdin.`,command:`cat ./items.json | apify datasets push-items my-dataset`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-push-items`;static args={nameOrId:Z.string({required:!0,description:`The dataset ID or name to push the objects to.`,ignoreStdin:!0}),item:Z.string({description:`The object or array of objects to be pushed.`})};async run(){let{nameOrId:e,item:n}=this.args,r=await tryToGetDataset(await getLoggedClientOrThrow(),e);if(!r){error({message:`Dataset with ID or name "${e}" not found.`});return}let{datasetClient:i,dataset:a}=r,s,c=n||gn;if(!c){error({message:`No items were provided.`});return}try{s=JSON.parse(c.toString(`utf8`))}catch(e){error({message:`Failed to parse data as JSON string: ${e.message}`});return}if(Array.isArray(s)&&s.length===0){error({message:`No items were provided.`});return}let l=a.name?`Dataset named ${t.yellow(a.name)} (${t.gray(`ID:`)} ${t.yellow(a.id)})`:`Dataset with ID ${t.yellow(a.id)}`;try{await i.pushItems(s),success({message:`${this.pluralString(Array.isArray(s)?s.length:1,`Object`,`Objects`)} pushed to ${l} successfully.`})}catch(e){let t=e;error({message:`Failed to push items into ${l}\n ${t.message||t}`})}}},DatasetsRenameCommand=class extends ApifyCommand{static name=`rename`;static enableProfileFlag=!0;static description=`Change the dataset name or remove the name with --unname flag.`;static examples=[{description:`Rename a dataset.`,command:`apify datasets rename old-name new-name`},{description:`Remove the name from a dataset (makes it unnamed).`,command:`apify datasets rename my-dataset --unname`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-rename`;static flags={unname:Y.boolean({description:`Removes the unique name of the dataset.`})};static args={nameOrId:Z.string({description:`The dataset ID or name to delete.`,required:!0}),newName:Z.string({description:`The new name for the dataset.`})};async run(){let{unname:e}=this.flags,{newName:n,nameOrId:r}=this.args;if(!n&&!e){error({message:`You must provide either a new name or the --unname flag.`});return}if(n&&e){error({message:`You cannot provide a new name and the --unname flag.`});return}let i=await tryToGetDataset(await getLoggedClientOrThrow(),r);if(!i){error({message:`Dataset with ID or name "${r}" not found.`});return}let{id:a,name:s}=i.dataset,c=s?e?`The name of the dataset with ID ${t.yellow(a)} has been removed (was ${t.yellow(s)} previously).`:`The name of the dataset with ID ${t.yellow(a)} was changed from ${t.yellow(s)} to ${t.yellow(n)}.`:`The name of the dataset with ID ${t.yellow(a)} has been set to: ${t.yellow(n)}`;try{await i.datasetClient.update({name:e?null:n}),success({message:c,stdout:!0})}catch(e){let n=e;error({message:`Failed to rename dataset with ID ${t.yellow(a)}\n ${n.message||n}`})}}},DatasetsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes a dataset.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a dataset by name or ID (prompts for confirmation).`,command:`apify datasets rm my-dataset`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-rm`;static args={datasetNameOrId:Z.string({description:`The dataset ID or name to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{datasetNameOrId:e}=this.args,{yes:n}=this.flags,r=await tryToGetDataset(await getLoggedClientOrThrow(),e);if(!r){error({message:`Dataset with ID or name "${e}" not found.`});return}if(!await X({message:`Are you sure you want to delete this Dataset?`,providedConfirmFromStdin:n||void 0})){info({message:`Dataset deletion has been aborted.`});return}let{id:i,name:a}=r.dataset;try{await r.datasetClient.delete(),success({message:`Dataset with ID ${t.yellow(i)}${a?` (called ${t.yellow(a)})`:``} has been deleted.`,stdout:!0})}catch(e){let n=e;error({message:`Failed to delete dataset with ID ${t.yellow(i)}\n ${n.message||n}`})}}},DatasetsIndexCommand=class extends ApifyCommand{static name=`datasets`;static description=`Manage Apify datasets — create, list, rename, delete, push items, and download items in various formats.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets`;static subcommands=[DatasetsCreateCommand,DatasetsGetItems,DatasetsLsCommand,DatasetsInfoCommand,DatasetsRmCommand,DatasetsRenameCommand,DatasetsPushDataCommand];async run(){this.printHelp()}};const mi=`https://apify.github.io/input-schema-editor-react/`,hi=new URL(mi).origin;var EditInputSchemaCommand=class extends ApifyCommand{static name=`edit-input-schema`;static description=`Lets you edit your input schema that would be used on the platform in a visual input schema editor.`;static group=`Local Actor Development`;static interactive=!0;static interactiveNote=`Opens a browser-based schema editor. Requires a local display; cannot be run headlessly.`;static examples=[{description:`Edit the input schema of the Actor in the current directory.`,command:`apify edit-input-schema`},{description:`Edit a specific INPUT_SCHEMA.json file.`,command:`apify edit-input-schema ./.actor/INPUT_SCHEMA.json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-edit-input-schema`;static args={path:Z.string({required:!1,description:`Optional path to your INPUT_SCHEMA.json file. If not provided default platform location for input schema is used.`})};static hidden=!0;static aliases=[`eis`];async run(){let{inputSchema:e,inputSchemaPath:t}=await readInputSchema({forcePath:this.args.path,cwd:process.cwd()});if(e&&!t)throw Error(`Editing an input schema directly embedded in '${K}' is not yet supported.`);warning({message:`This command is still experimental and might break at any time. Use at your own risk.
159
+ `),stdout:!0})}};const pi=new Q({allColumns:[`Dataset ID`,`Name`,`Items`,`Size`,`Created`,`Modified`],mandatoryColumns:[`Dataset ID`,`Name`,`Items`,`Size`],columnAlignments:{Items:`right`}});var DatasetsLsCommand=class extends ApifyCommand{static name=`ls`;static enableProfileFlag=!0;static description=`Prints all datasets on your account.`;static examples=[{description:`List your datasets (most recently modified first).`,command:`apify datasets ls --desc`},{description:`List only unnamed (auto-generated) datasets.`,command:`apify datasets ls --unnamed`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-ls`;static flags={offset:Y.integer({description:`Number of datasets that will be skipped.`,default:0}),limit:Y.integer({description:`Number of datasets that will be listed.`,default:20}),desc:Y.boolean({description:`Sorts datasets in descending order.`,default:!1}),unnamed:Y.boolean({description:`Lists datasets that don't have a name set.`,default:!1})};static enableJsonFlag=!0;async run(){let{desc:e,offset:n,limit:r,json:i,unnamed:a}=this.flags,s=await getLoggedClientOrThrow(),c=await getCurrentUserInfo(),l=await s.datasets().list({desc:e,offset:n,limit:r,unnamed:a});if(i)printJsonToStdout(l);else if(l.count===0)info({message:`You don't have any Datasets on your account`,stdout:!0});else{for(let e of l.items){let n=Reflect.get(e.stats,`s3StorageBytes`);pi.pushRow({"Dataset ID":e.id,Created:q.display(e.createdAt),Items:`${e.itemCount}`,Modified:q.display(e.modifiedAt),Name:e.name?`${c.username}/${e.name}`:``,Size:typeof n==`number`?prettyPrintBytes({bytes:n,shortBytes:!0,colorFunc:t.gray,precision:0}):t.gray(`N/A`)})}simpleLog({message:pi.render(1),stdout:!0})}}},DatasetsPushDataCommand=class extends ApifyCommand{static name=`push-items`;static enableProfileFlag=!0;static description=`Adds data items to specified dataset. Accepts single object or array of objects.`;static examples=[{description:`Push a single item as an inline JSON argument.`,command:`apify datasets push-items my-dataset '{"url":"https://example.com"}'`},{description:`Push an array of items from stdin.`,command:`cat ./items.json | apify datasets push-items my-dataset`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-push-items`;static args={nameOrId:Z.string({required:!0,description:`The dataset ID or name to push the objects to.`,ignoreStdin:!0}),item:Z.string({description:`The object or array of objects to be pushed.`})};async run(){let{nameOrId:e,item:n}=this.args,r=await tryToGetDataset(await getLoggedClientOrThrow(),e);if(!r){error({message:`Dataset with ID or name "${e}" not found.`});return}let{datasetClient:i,dataset:a}=r,s,c=n||gn;if(!c){error({message:`No items were provided.`});return}try{s=JSON.parse(c.toString(`utf8`))}catch(e){error({message:`Failed to parse data as JSON string: ${e.message}`});return}if(Array.isArray(s)&&s.length===0){error({message:`No items were provided.`});return}let l=a.name?`Dataset named ${t.yellow(a.name)} (${t.gray(`ID:`)} ${t.yellow(a.id)})`:`Dataset with ID ${t.yellow(a.id)}`;try{await i.pushItems(s),success({message:`${this.pluralString(Array.isArray(s)?s.length:1,`Object`,`Objects`)} pushed to ${l} successfully.`})}catch(e){let t=e;error({message:`Failed to push items into ${l}\n ${t.message||t}`})}}},DatasetsRenameCommand=class extends ApifyCommand{static name=`rename`;static enableProfileFlag=!0;static description=`Change the dataset name or remove the name with --unname flag.`;static examples=[{description:`Rename a dataset.`,command:`apify datasets rename old-name new-name`},{description:`Remove the name from a dataset (makes it unnamed).`,command:`apify datasets rename my-dataset --unname`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-rename`;static flags={unname:Y.boolean({description:`Removes the unique name of the dataset.`})};static args={nameOrId:Z.string({description:`The dataset ID or name to delete.`,required:!0}),newName:Z.string({description:`The new name for the dataset.`})};async run(){let{unname:e}=this.flags,{newName:n,nameOrId:r}=this.args;if(!n&&!e){error({message:`You must provide either a new name or the --unname flag.`});return}if(n&&e){error({message:`You cannot provide a new name and the --unname flag.`});return}let i=await tryToGetDataset(await getLoggedClientOrThrow(),r);if(!i){error({message:`Dataset with ID or name "${r}" not found.`});return}let{id:a,name:s}=i.dataset,c=s?e?`The name of the dataset with ID ${t.yellow(a)} has been removed (was ${t.yellow(s)} previously).`:`The name of the dataset with ID ${t.yellow(a)} was changed from ${t.yellow(s)} to ${t.yellow(n)}.`:`The name of the dataset with ID ${t.yellow(a)} has been set to: ${t.yellow(n)}`;try{await i.datasetClient.update({name:e?null:n}),success({message:c,stdout:!0})}catch(e){let n=e;error({message:`Failed to rename dataset with ID ${t.yellow(a)}\n ${n.message||n}`})}}},DatasetsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes a dataset.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a dataset by name or ID (prompts for confirmation).`,command:`apify datasets rm my-dataset`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets-rm`;static args={datasetNameOrId:Z.string({description:`The dataset ID or name to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{datasetNameOrId:e}=this.args,{yes:n}=this.flags,r=await tryToGetDataset(await getLoggedClientOrThrow(),e);if(!r){error({message:`Dataset with ID or name "${e}" not found.`});return}if(!await X({message:`Are you sure you want to delete this Dataset?`,providedConfirmFromStdin:n||void 0})){info({message:`Dataset deletion has been aborted.`});return}let{id:i,name:a}=r.dataset;try{await r.datasetClient.delete(),success({message:`Dataset with ID ${t.yellow(i)}${a?` (called ${t.yellow(a)})`:``} has been deleted.`,stdout:!0})}catch(e){let n=e;error({message:`Failed to delete dataset with ID ${t.yellow(i)}\n ${n.message||n}`})}}},DatasetsIndexCommand=class extends ApifyCommand{static name=`datasets`;static description=`Manage Apify datasets — create, list, rename, delete, push items, and download items in various formats.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-datasets`;static subcommands=[DatasetsCreateCommand,DatasetsGetItems,DatasetsLsCommand,DatasetsInfoCommand,DatasetsRmCommand,DatasetsRenameCommand,DatasetsPushDataCommand];async run(){this.printHelp()}};const mi=`https://apify.github.io/input-schema-editor-react/`,hi=new URL(mi).origin;var EditInputSchemaCommand=class extends ApifyCommand{static name=`edit-input-schema`;static description=`Lets you edit your input schema that would be used on the platform in a visual input schema editor.`;static group=`Local Actor Development`;static interactive=!0;static interactiveNote=`Opens a browser-based schema editor. Requires a local display; cannot be run headlessly.`;static examples=[{description:`Edit the input schema of the Actor in the current directory.`,command:`apify edit-input-schema`},{description:`Edit a specific INPUT_SCHEMA.json file.`,command:`apify edit-input-schema ./.actor/INPUT_SCHEMA.json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-edit-input-schema`;static args={path:Z.string({required:!1,description:`Optional path to your INPUT_SCHEMA.json file. If not provided default platform location for input schema is used.`})};static hidden=!0;static aliases=[`eis`];async run(){let{inputSchema:e,inputSchemaPath:t}=await readInputSchema({forcePath:this.args.path,cwd:process.cwd()});if(e&&!t)throw Error(`Editing an input schema directly embedded in '${K}' is not yet supported.`);warning({message:`This command is still experimental and might break at any time. Use at your own risk.
160
160
  `}),info({message:`Editing input schema at "${t}"...`});let n=De(),r=` `,i=!0,a=createLocalApiServer({corsOrigin:hi,authToken:n,routes:{"GET /api/v1/input-schema":(e,n)=>{let a;try{a=O(t)?M(t,{encoding:`utf-8`}):`{}
161
161
  `,a.length>3&&(r=zt(a).indent||r),a&&(i=a[a.length-1]===`
162
162
  `),O(t)?info({message:`Input schema loaded from "${t}"`}):info({message:`Empty input schema initialized.`})}catch(e){let t=`Reading input schema from disk failed with: ${e.message}`;error({message:t}),n.status(500),n.send(t);return}let s;try{s=JSON.parse(a||`{}`)}catch(e){let t=`Parsing input schema failed with error: ${e.message}`;error({message:t}),n.status(500),n.send(t);return}n.send(s),info({message:`Input schema sent to editor.`})},"POST /api/v1/input-schema":(e,n)=>{try{info({message:`Got input schema from editor...`});let a=JSON.stringify(e,null,r);i&&(a+=`
@@ -171,12 +171,12 @@ It adds the following features:
171
171
  ...
172
172
  `;static args={path:Z.string({required:!1,description:`Optional path to your scrapy project. If not provided, the current directory is used.`})};static hidden=!0;async run(){await wrapScrapyProject({projectPath:this.args.path}),info({message:`Scrapy project wrapped successfully.`})}},InitCommand=class extends ApifyCommand{static name=`init`;static description=`Sets up an Actor project in your current directory by creating actor.json and storage files.
173
173
  If the directory contains a Scrapy project in Python, the command automatically creates wrappers so that you can run your scrapers without changes.
174
- Creates the '${K}' file and the '${nn}' directory in the current directory, but does not touch any other existing files or directories.\n\nWARNING: Overwrites existing '${nn}' directory.`;static group=`Local Actor Development`;static interactive=!0;static interactiveNote=`Prompts for an Actor name if not provided. To run non-interactively, pass the Actor name as a positional argument, or pass --yes to accept the default (current directory name).`;static examples=[{description:`Initialize an Actor in the current directory, prompting for a name.`,command:`apify init`},{description:`Initialize non-interactively with an explicit Actor name.`,command:`apify init my-actor`},{description:`Initialize non-interactively, accepting the default Actor name.`,command:`apify init --yes`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-init`;static args={actorName:Z.string({required:!1,description:`Name of the Actor. If not provided, you will be prompted for it.`})};static flags={...YesFlag(),dockerfile:Y.string({description:`Path to a Dockerfile to use for the Actor (e.g., "./Dockerfile" or "./docker/Dockerfile").`,required:!1})};async run(){let{actorName:t}=this.args,n=e.cwd();t&&validateActorName(t);let r=await useCwdProject();r.isErr()&&(error({message:r.unwrapErr().message}),e.exit(1));let i=r.unwrap();if(i.warnings?.length)for(let e of i.warnings)warning({message:e});let a=s(n);if(i.type===1&&i.entrypoint?.path){let e=i.entrypoint.path;a=e.includes(`.`)?e.split(`.`).pop():e}let c=sanitizeActorName(a);if(i.type===2)return info({message:`The current directory looks like a Scrapy project. Using automatic project wrapping.`}),this.telemetryData.actorWrapper=`scrapy`,wrapScrapyProject({projectPath:n});if(!this.flags.yes&&i.type===3&&(warning({message:`The current directory does not look like a Node.js or Python project.`}),!await X({message:`Do you want to continue?`,errorMessageForStdin:`Confirmation is required to continue. Pass --yes to skip the prompt.`})))return;let l=await useActorConfig({cwd:n});if(l.isOkAnd(e=>e.exists&&!e.migrated))warning({message:`Skipping creation of '${K}', the file already exists in the current directory.`});else{if(l.isErr()){error({message:l.unwrapErr().message}),e.exitCode=5;return}if(!t){let e=l.isOkAnd(e=>e.exists)?l.unwrap().config.name:null;if(e)t=e;else if(this.flags.yes){try{validateActorName(c)}catch{throw Error(`Cannot derive an Actor name from '${a}'. Run 'apify init <name>' to set it.`)}t=c}else t=await zn({message:`Actor name:`,default:c,validate:validateActorNameForPrompt,errorMessageForStdin:`Actor name is required. Run 'apify init <name>', or pass --yes to use the current directory name.`})}let r={...rn,...l.unwrap().config,name:t};this.flags.dockerfile&&(r.dockerfile=this.flags.dockerfile),await setLocalConfig(r,n)}await setLocalEnv(n),await createPrefilledInputFileFromInputSchema(n),success({message:`The Actor has been initialized in the current directory.`})}},KeyValueStoresCreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates a new key-value store on your account.`;static examples=[{description:`Create an unnamed key-value store.`,command:`apify key-value-stores create`},{description:`Create a named key-value store.`,command:`apify key-value-stores create my-store`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-create`;static args={"key-value store name":Z.string({description:`Optional name for the key-value store.`,required:!1})};static enableJsonFlag=!0;async run(){let{keyValueStoreName:e}=this.args,n=await getLoggedClientOrThrow();if(e&&await tryToGetKeyValueStore(n,e)){error({message:`Cannot create a key-value store with the same name!`});return}let r=await n.keyValueStores().getOrCreate(e);if(this.flags.json){printJsonToStdout(r);return}success({message:`Key-value store with ID ${t.yellow(r.id)}${e?` (called ${t.yellow(e)})`:``} was created.`,stdout:!0})}},KeyValueStoresDeleteValueCommand=class extends ApifyCommand{static name=`delete-value`;static enableProfileFlag=!0;static description=`Delete a value from a key-value store.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting the record. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a single record by key.`,command:`apify key-value-stores delete-value <storeId> OUTPUT`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-delete-value`;static args={"store id":Z.string({description:`The key-value store ID to delete the value from.`,required:!0}),itemKey:Z.string({description:`The key of the item in the key-value store.`,required:!0})};static flags={...YesFlag()};async run(){let{storeId:e,itemKey:n}=this.args,{yes:r}=this.flags,i=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!i){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStoreClient:a}=i;if(!await a.getRecord(n)){error({message:`Item with key "${n}" not found in the key-value store.`});return}if(!await X({message:`Are you sure you want to delete this record?`,providedConfirmFromStdin:r||void 0})){info({message:`Key-value store record deletion aborted.`,stdout:!0});return}try{await a.deleteRecord(n),info({message:`Record with key "${t.yellow(n)}" deleted from the key-value store.`,stdout:!0})}catch(e){let t=e;error({message:`Failed to delete record with key "${n}" from the key-value store.\n ${t.message||t}`})}}},KeyValueStoresGetValueCommand=class extends ApifyCommand{static name=`get-value`;static enableProfileFlag=!0;static description=`Retrieves stored value for specified key. Use --only-content-type to check MIME type.`;static examples=[{description:`Read a record value and print it to stdout.`,command:`apify key-value-stores get-value <storeId> INPUT`},{description:`Print only the record content-type.`,command:`apify key-value-stores get-value <storeId> INPUT --only-content-type`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-get-value`;static flags={"only-content-type":Y.boolean({description:`Only return the content type of the specified key.`,default:!1})};static args={keyValueStoreId:Z.string({description:`The key-value store ID to get the value from.`,required:!0}),itemKey:Z.string({description:`The key of the item in the key-value store.`,required:!0})};async run(){let{onlyContentType:e}=this.flags,{keyValueStoreId:t,itemKey:n}=this.args,r=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),t);if(!r){error({message:`Key-value store with ID "${t}" not found.`});return}let{keyValueStoreClient:i}=r,a=await i.getRecord(n,{stream:!0});if(!a){error({message:`Item with key "${n}" not found in the key-value store.`});return}if(simpleLog({message:a.contentType??`application/octet-stream`}),e){a.value.destroy();return}if(a.contentType?.includes(`application/json`)){let{value:e}=a,t=[];for await(let n of e)t.push(n);let n=Buffer.concat(t).toString();try{let e=JSON.parse(n);simpleLog({message:JSON.stringify(e,null,2),stdout:!0})}catch{simpleLog({message:n,stdout:!0})}return}a.value.pipe(process.stdout)}};const yi=new Q({allColumns:[`Row1`,`Row2`],mandatoryColumns:[`Row1`,`Row2`]});var KeyValueStoresInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Shows information about a key-value store.`;static examples=[{description:`Show metadata about a key-value store.`,command:`apify key-value-stores info <storeId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-info`;static args={storeId:Z.string({description:`The key-value store ID to print information about.`,required:!0})};static enableJsonFlag=!0;async run(){let{storeId:e}=this.args,n=await getLoggedClientOrThrow(),r=await tryToGetKeyValueStore(n,e);if(!r){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStore:i}=r,[a,s,c]=await Promise.all([n.user(i.userId).get().then(e=>e),i.actId?n.actor(i.actId).get():Promise.resolve(void 0),i.actRunId?n.run(i.actRunId).get():Promise.resolve(void 0)]),l;if(c?.actorTaskId&&(l=await n.task(c.actorTaskId).get().catch(()=>void 0)),this.flags.json){printJsonToStdout({...i,user:a,actor:s||null,run:c||null,task:l||null});return}let u=i.stats?.storageBytes||0,f=i.stats?.readCount||0,p=i.stats?.writeCount||0,m=i.stats?.deleteCount||0,h=i.stats?.listCount||0,g=`Operations: ${[`${t.bold(f.toLocaleString(`en-US`))} ${t.gray(this.pluralString(f,`read`,`reads`))}`,`${t.bold(p.toLocaleString(`en-US`))} ${t.gray(this.pluralString(p,`write`,`writes`))}`,`${t.bold(m.toLocaleString(`en-US`))} ${t.gray(this.pluralString(m,`delete`,`deletes`))}`,`${t.bold(h.toLocaleString(`en-US`))} ${t.gray(this.pluralString(h,`list`,`lists`))}`].join(` / `)}`;if(a.plan){let e=getUserPlanPricing(a.plan);if(e){let n=e.KEY_VALUE_STORE_TIMED_STORAGE_GBYTE_HOURS*(u/1e3**3),r=n*24*30,i=r>1?`$${r.toFixed(2)}`:`$${n.toFixed(3)}`;g+=`\nStorage size: ${prettyPrintBytes({bytes:u,shortBytes:!0,precision:1})} / ${t.gray(`${i} per month`)}`}}else g+=`\nStorage size: ${prettyPrintBytes({bytes:u,shortBytes:!0,precision:1})} / ${t.gray(`$unknown per month`)}`;let _=[`Store ID: ${t.bgGray(i.id)}`,`Name: ${i.name?t.bgGray(i.name):t.bold(t.italic(`Unnamed`))}`,`Created: ${t.bold(q.display(i.createdAt))}`,`Modified: ${t.bold(q.display(i.modifiedAt))}`].join(`
174
+ Creates the '${K}' file and the '${nn}' directory in the current directory, but does not touch any other existing files or directories.\n\nWARNING: Overwrites existing '${nn}' directory.`;static group=`Local Actor Development`;static interactive=!0;static interactiveNote=`Prompts for an Actor name if not provided. To run non-interactively, pass the Actor name as a positional argument, or pass --yes to accept the default (current directory name).`;static examples=[{description:`Initialize an Actor in the current directory, prompting for a name.`,command:`apify init`},{description:`Initialize non-interactively with an explicit Actor name.`,command:`apify init my-actor`},{description:`Initialize non-interactively, accepting the default Actor name.`,command:`apify init --yes`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-init`;static args={actorName:Z.string({required:!1,description:`Name of the Actor. If not provided, you will be prompted for it.`})};static flags={...YesFlag(),dockerfile:Y.string({description:`Path to a Dockerfile to use for the Actor (e.g., "./Dockerfile" or "./docker/Dockerfile").`,required:!1})};async run(){let{actorName:t}=this.args,n=e.cwd();t&&validateActorName(t);let r=await useCwdProject();r.isErr()&&(error({message:r.unwrapErr().message}),e.exit(1));let i=r.unwrap();if(i.warnings?.length)for(let e of i.warnings)warning({message:e});let a=s(n);if(i.type===1&&i.entrypoint?.path){let e=i.entrypoint.path;a=e.includes(`.`)?e.split(`.`).pop():e}let c=sanitizeActorName(a);if(i.type===2)return info({message:`The current directory looks like a Scrapy project. Using automatic project wrapping.`}),this.telemetryData.actorWrapper=`scrapy`,wrapScrapyProject({projectPath:n});if(!this.flags.yes&&i.type===3&&(warning({message:`The current directory does not look like a Node.js or Python project.`}),!await X({message:`Do you want to continue?`,errorMessageForStdin:`Confirmation is required to continue. Pass --yes to skip the prompt.`})))return;let l=await useActorConfig({cwd:n});if(l.isOkAnd(e=>e.exists&&!e.migrated))warning({message:`Skipping creation of '${K}', the file already exists in the current directory.`});else{if(l.isErr()){error({message:l.unwrapErr().message}),e.exitCode=5;return}if(!t){let e=l.isOkAnd(e=>e.exists)?l.unwrap().config.name:null;if(e)t=e;else if(this.flags.yes){try{validateActorName(c)}catch{throw Error(`Cannot derive an Actor name from '${a}'. Run 'apify init <name>' to set it.`)}t=c}else t=await zn({message:`Actor name:`,default:c,validate:validateActorNameForPrompt,errorMessageForStdin:`Actor name is required. Run 'apify init <name>', or pass --yes to use the current directory name.`})}let r={...rn,...l.unwrap().config,name:t};this.flags.dockerfile&&(r.dockerfile=this.flags.dockerfile),await setLocalConfig(r,n)}await setLocalEnv(n),await createPrefilledInputFileFromInputSchema(n),success({message:`The Actor has been initialized in the current directory.`})}},KeyValueStoresCreateCommand=class extends ApifyCommand{static name=`create`;static enableProfileFlag=!0;static description=`Creates a new key-value store on your account.`;static examples=[{description:`Create an unnamed key-value store.`,command:`apify key-value-stores create`},{description:`Create a named key-value store.`,command:`apify key-value-stores create my-store`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-create`;static args={"key-value store name":Z.string({description:`Optional name for the key-value store.`,required:!1})};static enableJsonFlag=!0;async run(){let{keyValueStoreName:e}=this.args,n=await getLoggedClientOrThrow();if(e&&await tryToGetKeyValueStore(n,e)){error({message:`Cannot create a key-value store with the same name!`});return}let r=await n.keyValueStores().getOrCreate(e);this.flags.json?printJsonToStdout(r):success({message:`Key-value store with ID ${t.yellow(r.id)}${e?` (called ${t.yellow(e)})`:``} was created.`,stdout:!0})}},KeyValueStoresDeleteValueCommand=class extends ApifyCommand{static name=`delete-value`;static enableProfileFlag=!0;static description=`Delete a value from a key-value store.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting the record. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a single record by key.`,command:`apify key-value-stores delete-value <storeId> OUTPUT`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-delete-value`;static args={"store id":Z.string({description:`The key-value store ID to delete the value from.`,required:!0}),itemKey:Z.string({description:`The key of the item in the key-value store.`,required:!0})};static flags={...YesFlag()};async run(){let{storeId:e,itemKey:n}=this.args,{yes:r}=this.flags,i=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!i){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStoreClient:a}=i;if(!await a.getRecord(n))error({message:`Item with key "${n}" not found in the key-value store.`});else if(!await X({message:`Are you sure you want to delete this record?`,providedConfirmFromStdin:r||void 0}))info({message:`Key-value store record deletion aborted.`,stdout:!0});else try{await a.deleteRecord(n),info({message:`Record with key "${t.yellow(n)}" deleted from the key-value store.`,stdout:!0})}catch(e){let t=e;error({message:`Failed to delete record with key "${n}" from the key-value store.\n ${t.message||t}`})}}},KeyValueStoresGetValueCommand=class extends ApifyCommand{static name=`get-value`;static enableProfileFlag=!0;static description=`Retrieves stored value for specified key. Use --only-content-type to check MIME type.`;static examples=[{description:`Read a record value and print it to stdout.`,command:`apify key-value-stores get-value <storeId> INPUT`},{description:`Print only the record content-type.`,command:`apify key-value-stores get-value <storeId> INPUT --only-content-type`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-get-value`;static flags={"only-content-type":Y.boolean({description:`Only return the content type of the specified key.`,default:!1})};static args={keyValueStoreId:Z.string({description:`The key-value store ID to get the value from.`,required:!0}),itemKey:Z.string({description:`The key of the item in the key-value store.`,required:!0})};async run(){let{onlyContentType:e}=this.flags,{keyValueStoreId:t,itemKey:n}=this.args,r=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),t);if(!r){error({message:`Key-value store with ID "${t}" not found.`});return}let{keyValueStoreClient:i}=r,a=await i.getRecord(n,{stream:!0});if(!a)error({message:`Item with key "${n}" not found in the key-value store.`});else if(simpleLog({message:a.contentType??`application/octet-stream`}),e)a.value.destroy();else if(a.contentType?.includes(`application/json`)){let{value:e}=a,t=[];for await(let n of e)t.push(n);let n=Buffer.concat(t).toString();try{let e=JSON.parse(n);simpleLog({message:JSON.stringify(e,null,2),stdout:!0})}catch{simpleLog({message:n,stdout:!0})}}else a.value.pipe(process.stdout)}};const yi=new Q({allColumns:[`Row1`,`Row2`],mandatoryColumns:[`Row1`,`Row2`]});var KeyValueStoresInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Shows information about a key-value store.`;static examples=[{description:`Show metadata about a key-value store.`,command:`apify key-value-stores info <storeId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-info`;static args={storeId:Z.string({description:`The key-value store ID to print information about.`,required:!0})};static enableJsonFlag=!0;async run(){let{storeId:e}=this.args,n=await getLoggedClientOrThrow(),r=await tryToGetKeyValueStore(n,e);if(!r){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStore:i}=r,[a,s,c]=await Promise.all([n.user(i.userId).get().then(e=>e),i.actId?n.actor(i.actId).get():Promise.resolve(void 0),i.actRunId?n.run(i.actRunId).get():Promise.resolve(void 0)]),l;if(c?.actorTaskId&&(l=await n.task(c.actorTaskId).get().catch(()=>void 0)),this.flags.json){printJsonToStdout({...i,user:a,actor:s||null,run:c||null,task:l||null});return}let u=i.stats?.storageBytes||0,f=i.stats?.readCount||0,p=i.stats?.writeCount||0,m=i.stats?.deleteCount||0,h=i.stats?.listCount||0,g=`Operations: ${[`${t.bold(f.toLocaleString(`en-US`))} ${t.gray(this.pluralString(f,`read`,`reads`))}`,`${t.bold(p.toLocaleString(`en-US`))} ${t.gray(this.pluralString(p,`write`,`writes`))}`,`${t.bold(m.toLocaleString(`en-US`))} ${t.gray(this.pluralString(m,`delete`,`deletes`))}`,`${t.bold(h.toLocaleString(`en-US`))} ${t.gray(this.pluralString(h,`list`,`lists`))}`].join(` / `)}`;if(a.plan){let e=getUserPlanPricing(a.plan);if(e){let n=e.KEY_VALUE_STORE_TIMED_STORAGE_GBYTE_HOURS*(u/1e3**3),r=n*24*30,i=r>1?`$${r.toFixed(2)}`:`$${n.toFixed(3)}`;g+=`\nStorage size: ${prettyPrintBytes({bytes:u,shortBytes:!0,precision:1})} / ${t.gray(`${i} per month`)}`}}else g+=`\nStorage size: ${prettyPrintBytes({bytes:u,shortBytes:!0,precision:1})} / ${t.gray(`$unknown per month`)}`;let _=[`Store ID: ${t.bgGray(i.id)}`,`Name: ${i.name?t.bgGray(i.name):t.bold(t.italic(`Unnamed`))}`,`Created: ${t.bold(q.display(i.createdAt))}`,`Modified: ${t.bold(q.display(i.modifiedAt))}`].join(`
175
175
  `),v=t.bold(`—`);i.actRunId&&(v=c?t.bgBlue(c.id):t.italic(t.gray(`Run removed`)));let y=t.bold(`—`);s&&(y=t.blue(s.title||s.name));let b=t.bold(`—`);l&&(b=t.blue(l.title||l.name));let x=[`Run: ${v}`,`Actor: ${y}`,`Task: ${b}`].join(`
176
176
  `);yi.pushRow({Row1:_,Row2:x});let S=yi.render(2).split(`
177
177
  `).map(e=>e.trim());S.shift(),simpleLog({message:[`${t.bold(i.name||t.italic(`Unnamed`))}`,`${t.gray(i.name?`${a.username}/${i.name}`:i.id)} ${t.gray(`Owned by`)} ${t.blue(a.username)}`,``,S.join(`
178
178
  `),``,g].join(`
179
- `),stdout:!0})}};const bi=new Q({allColumns:[`Key`,`Size`],mandatoryColumns:[`Key`,`Size`]});var KeyValueStoresKeysCommand=class extends ApifyCommand{static name=`keys`;static enableProfileFlag=!0;static description=`Lists all keys in a key-value store.`;static examples=[{description:`List the first 20 keys in a key-value store.`,command:`apify key-value-stores keys <storeId>`},{description:`Paginate keys past an exclusive start key.`,command:`apify key-value-stores keys <storeId> --exclusive-start-key last-seen-key --limit 100`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-keys`;static flags={limit:Y.integer({description:`The maximum number of keys to return.`,default:20}),"exclusive-start-key":Y.string({description:`The key to start the list from.`})};static args={storeId:Z.string({description:`The key-value store ID to list keys for.`,required:!0})};static enableJsonFlag=!0;async run(){let{storeId:e}=this.args,{limit:t,exclusiveStartKey:n}=this.flags,r=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!r){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStoreClient:i}=r,a=await i.listKeys({limit:t,exclusiveStartKey:n});if(this.flags.json){printJsonToStdout(a);return}for(let e of a.items)bi.pushRow({Key:e.key,Size:prettyPrintBytes({bytes:e.size,shortBytes:!0,precision:0})});simpleLog({message:bi.render(1),stdout:!0})}};const xi=new Q({allColumns:[`Store ID`,`Name`,`Size`,`Created`,`Modified`],mandatoryColumns:[`Store ID`,`Name`,`Size`]});var KeyValueStoresLsCommand=class extends ApifyCommand{static name=`ls`;static enableProfileFlag=!0;static description=`Lists all key-value stores on your account.`;static examples=[{description:`List your key-value stores.`,command:`apify key-value-stores ls`},{description:`List the next page of stores, sorted descending.`,command:`apify key-value-stores ls --limit 50 --offset 50 --desc`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-ls`;static flags={offset:Y.integer({description:`Number of key-value stores that will be skipped.`,default:0}),limit:Y.integer({description:`Number of key-value stores that will be listed.`,default:20}),desc:Y.boolean({description:`Sorts key-value stores in descending order.`,default:!1}),unnamed:Y.boolean({description:`Lists key-value stores that don't have a name set.`,default:!1})};static enableJsonFlag=!0;async run(){let{desc:e,offset:n,limit:r,json:i,unnamed:a}=this.flags,s=await getLoggedClientOrThrow(),c=await getCurrentUserInfo(),l=await s.keyValueStores().list({desc:e,offset:n,limit:r,unnamed:a});if(i){printJsonToStdout(l);return}if(l.count===0){info({message:`You don't have any key-value stores on your account`,stdout:!0});return}for(let e of l.items){let n=Reflect.get(e,`stats`).s3StorageBytes;xi.pushRow({"Store ID":e.id,Created:q.display(e.createdAt),Modified:q.display(e.modifiedAt),Name:e.name?`${c.username}/${e.name}`:``,Size:typeof n==`number`?prettyPrintBytes({bytes:n,shortBytes:!0,colorFunc:t.gray,precision:0}):t.gray(`N/A`)})}simpleLog({message:xi.render(1),stdout:!0})}},KeyValueStoresRenameCommand=class extends ApifyCommand{static name=`rename`;static enableProfileFlag=!0;static description=`Renames a key-value store, or removes its unique name.`;static examples=[{description:`Rename a key-value store.`,command:`apify key-value-stores rename old-name new-name`},{description:`Remove the name from a key-value store.`,command:`apify key-value-stores rename my-store --unname`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-rename`;static flags={unname:Y.boolean({description:`Removes the unique name of the key-value store.`})};static args={keyValueStoreNameOrId:Z.string({description:`The key-value store ID or name to delete.`,required:!0}),newName:Z.string({description:`The new name for the key-value store.`})};async run(){let{unname:e}=this.flags,{newName:n,keyValueStoreNameOrId:r}=this.args;if(!n&&!e){error({message:`You must provide either a new name or the --unname flag.`});return}if(n&&e){error({message:`You cannot provide a new name and the --unname flag.`});return}let i=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),r);if(!i){error({message:`Key-value store with ID or name "${r}" not found.`});return}let{id:a,name:s}=i.keyValueStore,c=s?e?`The name of the key-value store with ID ${t.yellow(a)} has been removed (was ${t.yellow(s)} previously).`:`The name of the key-value store with ID ${t.yellow(a)} was changed from ${t.yellow(s)} to ${t.yellow(n)}.`:`The name of the key-value store with ID ${t.yellow(a)} has been set to: ${t.yellow(n)}`;try{await i.keyValueStoreClient.update({name:e?null:n}),success({message:c,stdout:!0})}catch(e){let n=e;error({message:`Failed to rename key-value store with ID ${t.yellow(a)}\n ${n.message||n}`})}}},KeyValueStoresRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes a key-value store.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a key-value store (prompts for confirmation).`,command:`apify key-value-stores rm my-store`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-rm`;static args={keyValueStoreNameOrId:Z.string({description:`The key-value store ID or name to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{keyValueStoreNameOrId:e}=this.args,{yes:n}=this.flags,r=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!r){error({message:`Key-value store with ID or name "${e}" not found.`});return}if(!await X({message:`Are you sure you want to delete this Key-value store?`,providedConfirmFromStdin:n||void 0})){info({message:`Key-value store deletion has been aborted.`});return}let{id:i,name:a}=r.keyValueStore;try{await r.keyValueStoreClient.delete(),success({message:`Key-value store with ID ${t.yellow(i)}${a?` (called ${t.yellow(a)})`:``} has been deleted.`,stdout:!0})}catch(e){let n=e;error({message:`Failed to delete key-value store with ID ${t.yellow(i)}\n ${n.message||n}`})}}},KeyValueStoresSetValueCommand=class extends ApifyCommand{static name=`set-value`;static enableProfileFlag=!0;static description=`Stores value with specified key. Set content-type with --content-type flag.`;static examples=[{description:`Store a JSON value under a key.`,command:`apify key-value-stores set-value <storeId> OUTPUT '{"status":"done"}'`},{description:`Store a plain-text file read from stdin.`,command:`cat ./report.txt | apify key-value-stores set-value <storeId> REPORT --content-type text/plain`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-set-value`;static flags={"content-type":Y.string({description:`The MIME content type of the value. By default, "application/json" is assumed.`,default:`application/json`})};static args={storeId:Z.string({description:`The key-value store ID to set the value in.`,required:!0}),itemKey:Z.string({description:`The key of the item in the key-value store.`,required:!0}),value:Z.string({description:`The value to set.`})};async run(){let{storeId:e,itemKey:t,value:n}=this.args,{contentType:r}=this.flags,i=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!i){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStoreClient:a}=i;try{await a.setRecord({key:t,value:n||process.stdin,contentType:r}),success({message:`Value with key "${t}" set in the key-value store.`,stdout:!0})}catch(e){let n=e;error({message:`Failed to set value with key "${t}" in the key-value store.\n ${n.message||n}`})}}},KeyValueStoresIndexCommand=class extends ApifyCommand{static name=`key-value-stores`;static description=`Manage Apify key-value stores — create, list, rename, delete stores, and get/set/delete individual records.
179
+ `),stdout:!0})}};const bi=new Q({allColumns:[`Key`,`Size`],mandatoryColumns:[`Key`,`Size`]});var KeyValueStoresKeysCommand=class extends ApifyCommand{static name=`keys`;static enableProfileFlag=!0;static description=`Lists all keys in a key-value store.`;static examples=[{description:`List the first 20 keys in a key-value store.`,command:`apify key-value-stores keys <storeId>`},{description:`Paginate keys past an exclusive start key.`,command:`apify key-value-stores keys <storeId> --exclusive-start-key last-seen-key --limit 100`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-keys`;static flags={limit:Y.integer({description:`The maximum number of keys to return.`,default:20}),"exclusive-start-key":Y.string({description:`The key to start the list from.`})};static args={storeId:Z.string({description:`The key-value store ID to list keys for.`,required:!0})};static enableJsonFlag=!0;async run(){let{storeId:e}=this.args,{limit:t,exclusiveStartKey:n}=this.flags,r=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!r){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStoreClient:i}=r,a=await i.listKeys({limit:t,exclusiveStartKey:n});if(this.flags.json)printJsonToStdout(a);else{for(let e of a.items)bi.pushRow({Key:e.key,Size:prettyPrintBytes({bytes:e.size,shortBytes:!0,precision:0})});simpleLog({message:bi.render(1),stdout:!0})}}};const xi=new Q({allColumns:[`Store ID`,`Name`,`Size`,`Created`,`Modified`],mandatoryColumns:[`Store ID`,`Name`,`Size`]});var KeyValueStoresLsCommand=class extends ApifyCommand{static name=`ls`;static enableProfileFlag=!0;static description=`Lists all key-value stores on your account.`;static examples=[{description:`List your key-value stores.`,command:`apify key-value-stores ls`},{description:`List the next page of stores, sorted descending.`,command:`apify key-value-stores ls --limit 50 --offset 50 --desc`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-ls`;static flags={offset:Y.integer({description:`Number of key-value stores that will be skipped.`,default:0}),limit:Y.integer({description:`Number of key-value stores that will be listed.`,default:20}),desc:Y.boolean({description:`Sorts key-value stores in descending order.`,default:!1}),unnamed:Y.boolean({description:`Lists key-value stores that don't have a name set.`,default:!1})};static enableJsonFlag=!0;async run(){let{desc:e,offset:n,limit:r,json:i,unnamed:a}=this.flags,s=await getLoggedClientOrThrow(),c=await getCurrentUserInfo(),l=await s.keyValueStores().list({desc:e,offset:n,limit:r,unnamed:a});if(i)printJsonToStdout(l);else if(l.count===0)info({message:`You don't have any key-value stores on your account`,stdout:!0});else{for(let e of l.items){let n=Reflect.get(e,`stats`).s3StorageBytes;xi.pushRow({"Store ID":e.id,Created:q.display(e.createdAt),Modified:q.display(e.modifiedAt),Name:e.name?`${c.username}/${e.name}`:``,Size:typeof n==`number`?prettyPrintBytes({bytes:n,shortBytes:!0,colorFunc:t.gray,precision:0}):t.gray(`N/A`)})}simpleLog({message:xi.render(1),stdout:!0})}}},KeyValueStoresRenameCommand=class extends ApifyCommand{static name=`rename`;static enableProfileFlag=!0;static description=`Renames a key-value store, or removes its unique name.`;static examples=[{description:`Rename a key-value store.`,command:`apify key-value-stores rename old-name new-name`},{description:`Remove the name from a key-value store.`,command:`apify key-value-stores rename my-store --unname`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-rename`;static flags={unname:Y.boolean({description:`Removes the unique name of the key-value store.`})};static args={keyValueStoreNameOrId:Z.string({description:`The key-value store ID or name to delete.`,required:!0}),newName:Z.string({description:`The new name for the key-value store.`})};async run(){let{unname:e}=this.flags,{newName:n,keyValueStoreNameOrId:r}=this.args;if(!n&&!e){error({message:`You must provide either a new name or the --unname flag.`});return}if(n&&e){error({message:`You cannot provide a new name and the --unname flag.`});return}let i=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),r);if(!i){error({message:`Key-value store with ID or name "${r}" not found.`});return}let{id:a,name:s}=i.keyValueStore,c=s?e?`The name of the key-value store with ID ${t.yellow(a)} has been removed (was ${t.yellow(s)} previously).`:`The name of the key-value store with ID ${t.yellow(a)} was changed from ${t.yellow(s)} to ${t.yellow(n)}.`:`The name of the key-value store with ID ${t.yellow(a)} has been set to: ${t.yellow(n)}`;try{await i.keyValueStoreClient.update({name:e?null:n}),success({message:c,stdout:!0})}catch(e){let n=e;error({message:`Failed to rename key-value store with ID ${t.yellow(a)}\n ${n.message||n}`})}}},KeyValueStoresRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Permanently removes a key-value store.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a key-value store (prompts for confirmation).`,command:`apify key-value-stores rm my-store`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-rm`;static args={keyValueStoreNameOrId:Z.string({description:`The key-value store ID or name to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{keyValueStoreNameOrId:e}=this.args,{yes:n}=this.flags,r=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!r){error({message:`Key-value store with ID or name "${e}" not found.`});return}if(!await X({message:`Are you sure you want to delete this Key-value store?`,providedConfirmFromStdin:n||void 0})){info({message:`Key-value store deletion has been aborted.`});return}let{id:i,name:a}=r.keyValueStore;try{await r.keyValueStoreClient.delete(),success({message:`Key-value store with ID ${t.yellow(i)}${a?` (called ${t.yellow(a)})`:``} has been deleted.`,stdout:!0})}catch(e){let n=e;error({message:`Failed to delete key-value store with ID ${t.yellow(i)}\n ${n.message||n}`})}}},KeyValueStoresSetValueCommand=class extends ApifyCommand{static name=`set-value`;static enableProfileFlag=!0;static description=`Stores value with specified key. Set content-type with --content-type flag.`;static examples=[{description:`Store a JSON value under a key.`,command:`apify key-value-stores set-value <storeId> OUTPUT '{"status":"done"}'`},{description:`Store a plain-text file read from stdin.`,command:`cat ./report.txt | apify key-value-stores set-value <storeId> REPORT --content-type text/plain`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores-set-value`;static flags={"content-type":Y.string({description:`The MIME content type of the value. By default, "application/json" is assumed.`,default:`application/json`})};static args={storeId:Z.string({description:`The key-value store ID to set the value in.`,required:!0}),itemKey:Z.string({description:`The key of the item in the key-value store.`,required:!0}),value:Z.string({description:`The value to set.`})};async run(){let{storeId:e,itemKey:t,value:n}=this.args,{contentType:r}=this.flags,i=await tryToGetKeyValueStore(await getLoggedClientOrThrow(),e);if(!i){error({message:`Key-value store with ID or name "${e}" not found.`});return}let{keyValueStoreClient:a}=i;try{await a.setRecord({key:t,value:n||process.stdin,contentType:r}),success({message:`Value with key "${t}" set in the key-value store.`,stdout:!0})}catch(e){let n=e;error({message:`Failed to set value with key "${t}" in the key-value store.\n ${n.message||n}`})}}},KeyValueStoresIndexCommand=class extends ApifyCommand{static name=`key-value-stores`;static description=`Manage Apify key-value stores — create, list, rename, delete stores, and get/set/delete individual records.
180
180
 
181
181
  Alias: kvs.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-key-value-stores`;static hiddenAliases=[`kvs`];static subcommands=[KeyValueStoresCreateCommand,KeyValueStoresDeleteValueCommand,KeyValueStoresGetValueCommand,KeyValueStoresInfoCommand,KeyValueStoresKeysCommand,KeyValueStoresLsCommand,KeyValueStoresRenameCommand,KeyValueStoresRmCommand,KeyValueStoresSetValueCommand];async run(){this.printHelp()}},LoginCommand=class extends AuthLoginCommand{static name=`login`},LogoutCommand=class extends AuthLogoutCommand{static name=`logout`};async function confirmOverwrite({filePath:e,entryKey:t,yes:n}){return X({message:`A server entry named '${t}' already exists in ${tildify(e)}. Overwrite it?`,default:!1,providedConfirmFromStdin:n||void 0,errorMessageForStdin:`An '${t}' entry already exists in ${tildify(e)}. Re-run with --yes to overwrite.`})}async function mergeServerEntry({filePath:t,topLevelKey:n,entryKey:r,serverEntry:i,yes:a}){let s=O(t)?await U(t,`utf-8`):``,l=s.trim(),u;if(l){let e;try{e=Et.parse(s)}catch(e){let n=e instanceof Error?e.message.split(`
182
182
  `)[0]:`invalid JSON`;throw Error(`Cannot install: ${tildify(t)} is not valid JSON (${n}). Fix the file manually and re-run.`)}if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Cannot install: ${tildify(t)} is not a JSON object. Fix the file manually and re-run.`);let c=e[n];if(c!=null&&(typeof c!=`object`||Array.isArray(c)))throw Error(`Cannot install: '${n}' in ${tildify(t)} is not a JSON object. Fix the file manually and re-run.`);let l=c??{};if(Object.prototype.hasOwnProperty.call(l,r)&&!await confirmOverwrite({filePath:t,entryKey:r,yes:a}))return simpleLog({message:`No changes written.`}),!1;l[r]=i,e[n]=l,u=Et.update(s,e)}else{let e={[n]:{[r]:i}};u=`${Et.stringify(e,{mode:`json`,indent:2})}\n`}await H(c(t),{recursive:!0});let f=`${t}.${e.pid}.tmp`;try{await G(f,u,`utf-8`),await je(f,t)}catch(e){throw await Me(f,{force:!0}),e}return!0}function buildMcpUrl(e,t){if(!t)return e;let n=t.split(`,`).map(e=>e.trim()).filter(Boolean).join(`,`);if(!n)return e;let r=new URL(e);return r.searchParams.set(`tools`,n),r.toString()}function maskToken(e){return e.length<=14?`***`:`${e.slice(0,10)}...${e.slice(-4)}`}function maskSecret(e,t){return t?e.split(t).join(maskToken(t)):e}const Si=`apify`,bearer=e=>({Authorization:`Bearer ${e}`});function printResult(e){success({message:`Apify MCP server configured for ${e.clientLabel}.`});let n=[``,` ${t.yellow(`Server URL:`)} ${e.serverUrl}`,` ${t.yellow(`Auth:`)} ${e.authDescription}`];e.configPath&&n.push(` ${t.yellow(`Config:`)} ${tildify(e.configPath)}`),e.nextSteps&&n.push(``,e.nextSteps),simpleLog({message:n.join(`
@@ -229,15 +229,15 @@ Use \`--no-purge\` to keep the storage folder intact.`,required:!1,default:!0,ex
229
229
  `;break;default:m=t?`The input provided through the ${t.source} file is invalid. Please fix the following errors:\n`:`The input in your storage is invalid. Please fix the following errors:
230
230
  `}if(t){let e={...s,...t.input},a=vt(c,r,e);if(a.length>0)throw Error(`${m}${a.map(e=>` - ${e.message.replace(`Field input.`,`Field `)}`).join(`
231
231
  `)}`);let l=`${Kn}${n}`,f=u(i,`${l}.json`);return await H(i,{recursive:!0}),await writeInputRecord(i,l,e),{tempInputKey:l,tempInputFilePath:f}}if(!l)return await H(i,{recursive:!0}),await writeInputRecord(i,n,s),{existingInput:l,inputKey:n,inputFilePath:f,writtenAt:Date.now()};if(rt.getExtension(l.contentType)===`json`){let e=JSON.parse(l.body.toString(`utf-8`));if(Array.isArray(e))throw Error(`The input in your storage is invalid. It should be an object, not an array.`);let t={...s,...e},a=vt(c,r,t);if(a.length>0)throw Error(`${m}${a.map(e=>` - ${e.message.replace(`Field input.`,`Field `)}`).join(`
232
- `)}`);let f=`${Kn}${n}`,p=u(i,`${f}.json`);return await writeInputRecord(i,f,t),{tempInputKey:f,tempInputFilePath:p}}return null}};const Oi=[R.READY,R.RUNNING],ki=[R.ABORTING,R.TIMING_OUT];var RunsAbortCommand=class extends ApifyCommand{static name=`abort`;static enableProfileFlag=!0;static description=`Aborts an Actor run.`;static examples=[{description:`Abort a running Actor gracefully (up to 30s drain).`,command:`apify runs abort <runId>`},{description:`Force-abort a running Actor immediately.`,command:`apify runs abort <runId> --force`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-abort`;static args={runId:Z.string({required:!0,description:`The run ID to abort.`})};static flags={force:Y.boolean({description:`Whether to force the run to abort immediately, instead of gracefully.`,default:!1,char:`f`})};static enableJsonFlag=!0;async run(){let{runId:e}=this.args,t=await getLoggedClientOrThrow(),n=await t.run(e).get();if(!n){error({message:`Run with ID "${e}" was not found on your account.`,stdout:!0});return}if(!Oi.includes(n.status)){ki.includes(n.status)?error({message:`Run with ID "${e}" is already aborting.`,stdout:!0}):error({message:`Run with ID "${e}" is already aborted.`,stdout:!0});return}try{let n=await t.run(e).abort({gracefully:!this.flags.force});if(this.flags.json){printJsonToStdout(n);return}this.flags.force?success({message:`Triggered the immediate abort of run "${e}".`,stdout:!0}):success({message:`Triggered the abort of run "${e}", it should finish aborting in up to 30 seconds.`,stdout:!0})}catch(t){let n=t;error({message:`Failed to abort run "${e}".\n ${n.message||n}`,stdout:!0})}}};const Ai=new Q({allColumns:[``,`Unit`,`USD Amount`],mandatoryColumns:[``,`Unit`,`USD Amount`],columnAlignments:{Unit:`right`,"USD Amount":`right`}}),ji={"Actor compute units":`ACTOR_COMPUTE_UNITS`,"Dataset reads":`DATASET_READS`,"Dataset writes":`DATASET_WRITES`,"Key-value store reads":`KEY_VALUE_STORE_READS`,"Key-value store writes":`KEY_VALUE_STORE_WRITES`,"Key-value store lists":`KEY_VALUE_STORE_LISTS`,"Request queue reads":`REQUEST_QUEUE_READS`,"Request queue writes":`REQUEST_QUEUE_WRITES`,"Data transfer internal":`DATA_TRANSFER_INTERNAL_GBYTES`,"Data transfer external":`DATA_TRANSFER_EXTERNAL_GBYTES`,"Proxy residential data transfer":`PROXY_RESIDENTIAL_TRANSFER_GBYTES`,"Proxy SERPs":`PROXY_SERPS`};var RunsInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Prints information about an Actor run.`;static examples=[{description:`Show a summary of a run.`,command:`apify runs info <runId>`},{description:`Show verbose details including usage breakdown.`,command:`apify runs info <runId> --verbose`},{description:`Emit the full run object as JSON.`,command:`apify runs info <runId> --json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-info`;static args={runId:Z.string({required:!0,description:`The run ID to print information about.`})};static flags={verbose:Y.boolean({char:`v`,description:`Prints more in-depth information about the Actor run.`,default:!1})};static enableJsonFlag=!0;async run(){let{runId:e}=this.args,n=await getLoggedClientOrThrow(),r=await n.run(e).get();if(!r){error({message:`Run with ID "${e}" was not found on your account.`});return}let[i,a,s,c,l]=await Promise.all([n.actor(r.actId).get(),n.build(r.buildId).get(),r.actorTaskId?n.task(r.actorTaskId).get():Promise.resolve(void 0),n.dataset(r.defaultDatasetId).get(),n.requestQueue(r.defaultRequestQueueId).get()]);if(this.flags.json){printJsonToStdout({...r,actor:i,build:a,task:s,defaultDataset:c,defaultRequestQueue:l});return}this.addDetailedUsage(r);let u=i?.username?`${i.username}/${i.name}`:i?.name??`unknown-actor`,f=[`${t.yellow(`Actor`)}: ${u} (${t.grey(r.actId)})`];s?f.push(`└─ ${t.yellow(`Task`)}: ${s.title??s.name} (${t.gray(r.actorTaskId)})`,``):r.actorTaskId?f.push(`└─ ${t.yellow(`Task`)}: unknown-task (${t.gray(r.actorTaskId)})`,``):f.push(``);let p=` (exit code: ${t.gray(r.exitCode===null?`N/A`:r.exitCode)})`;f.push(`${t.yellow(`Status`)}: ${prettyPrintStatus(r.status)}${p}`),r.statusMessage&&f.push(`└─ ${t.yellow(`Status Message:`)} ${r.statusMessage}`);let m=c?.itemCount??0;f.push(`${t.yellow(`Results`)}: ${t.cyan(m.toLocaleString(`en-US`))}`),l?f.push(`${t.yellow(`Requests`)}: ${t.cyan(l.handledRequestCount.toLocaleString(`en-US`))} out of ${t.cyan(l.totalRequestCount.toLocaleString(`en-US`))} handled`):f.push(`${t.yellow(`Requests`)}: ${t.gray(`unknown handled`)}`);let h=this.flags.verbose?``:t.gray(` (run with ${t.yellow(`--verbose`)} for a detailed breakdown)`);if(r.usageTotalUsd?f.push(`${t.yellow(`Usage`)}: ${t.cyan(this.formatUsd(r.usageTotalUsd))}${h}`):f.push(`${t.yellow(`Usage`)}: $${t.gray(`0.000`)}${h}`),this.flags.verbose&&f.push(Ai.render(0)),f.push(``),f.push(`${t.yellow(`Started`)}: ${q.display(r.startedAt)}`),r.finishedAt)f.push(`${t.yellow(`Finished`)}: ${q.display(r.finishedAt)} (took ${t.gray(rr.format(r.stats.durationMillis))})`);else{let e=Date.now()-r.startedAt.getTime();f.push(`${t.yellow(`Finished`)}: ${t.gray(`Running for ${rr.format(e)}`)}`)}if(f.push(``),r.stats.resurrectCount?f.push(`${t.yellow(`Resurrected`)}: Yes, ${t.cyan(r.stats.resurrectCount.toLocaleString(`en-US`))} ${this.pluralString(r.stats.resurrectCount,`time`,`times`)}`):f.push(`${t.yellow(`Resurrected`)}: No`),r.containerUrl&&f.push(`${t.yellow(`Container URL`)}: ${t.blue(r.containerUrl)}`),f.push(`${t.yellow(`Origin`)}: ${r.meta.origin}`),i){let e=r.buildNumber.split(`.`).slice(0,2).join(`.`),n=i.versions.find(t=>t.versionNumber===e),a=Object.entries(i.taggedBuilds??{}).find(([,e])=>e.buildNumber===r.buildNumber)?.[0],s=[`${t.yellow(`Build`)}:`,t.cyan(r.buildNumber)];a?s.push(`(${t.yellow(a)})`):s.push(`(${t.gray(`N/A`)})`),n&&s.push(`| ${t.gray(`Actor version:`)} ${t.cyan(n.versionNumber)} (${t.yellow(n.buildTag)})`),f.push(s.join(` `))}else f.push(`${t.yellow(`Build`)}: ${t.cyan(r.buildNumber)}`);f.push(`${t.yellow(`Timeout`)}: ${r.options.timeoutSecs.toLocaleString(`en-US`)} seconds`),f.push(`${t.yellow(`Memory`)}: ${r.options.memoryMbytes} MB`),f.push(``),f.push(`${t.yellow(`CPU`)}: ${t.gray(`Average:`)} ${r.stats.cpuAvgUsage.toFixed(2)}% | ${t.gray(`Maximum:`)} ${r.stats.cpuMaxUsage.toFixed(2)}%`),f.push(`${t.yellow(`Memory`)}: ${t.gray(`Average:`)} ${prettyPrintBytes({bytes:r.stats.memAvgBytes,shortBytes:!0})} | ${t.gray(`Maximum:`)} ${prettyPrintBytes({bytes:r.stats.memMaxBytes,shortBytes:!0})}`),f.push(``);let g=consoleRunUrl(r.actId,r.id),_=consoleDatasetUrl(r.defaultDatasetId),v=consoleKeyValueStoreUrl(r.defaultKeyValueStoreId);f.push(`${t.blue(`Export results`)}: ${_}`),f.push(`${t.blue(`View saved items`)}: ${v}`),f.push(`${t.blue(`View in Apify Console`)}: ${g}`),simpleLog({message:f.join(`
233
- `),stdout:!0})}addDetailedUsage(e){let{usage:t,usageUsd:n}=e;if(!t||!n){for(let e of Object.keys(ji))Ai.pushRow({"":e,Unit:`N/A`,"USD Amount":`N/A`});return}for(let[e,r]of Object.entries(ji)){let i=t[r]??0,a=n[r]??0;switch(r){case`ACTOR_COMPUTE_UNITS`:Ai.pushRow({"":e,Unit:i.toFixed(4),"USD Amount":this.formatUsd(a)});break;case`DATA_TRANSFER_INTERNAL_GBYTES`:case`DATA_TRANSFER_EXTERNAL_GBYTES`:case`PROXY_RESIDENTIAL_TRANSFER_GBYTES`:Ai.pushRow({"":e,Unit:prettyPrintBytes({bytes:i*1024*1024*1024,shortBytes:!0}),"USD Amount":this.formatUsd(a)});break;default:Ai.pushRow({"":e,Unit:i.toLocaleString(`en-US`),"USD Amount":this.formatUsd(a)})}}}formatUsd(e){return`$${e.toFixed(3)}`}},RunsLogCommand=class extends ApifyCommand{static name=`log`;static enableProfileFlag=!0;static description=`Prints the log of a specific run.`;static examples=[{description:`Print the log of a specific run to stdout.`,command:`apify runs log <runId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-log`;static args={runId:Z.string({required:!0,description:`The run ID to get the log from.`})};async run(){let{runId:e}=this.args,t=await getLoggedClientOrThrow(),n=await t.run(e).get();if(!n){error({message:`Run with ID "${e}" was not found on your account.`,stdout:!0});return}info({message:`Log for run with ID "${e}":\n`,stdout:!0});try{await outputJobLog({job:n,apifyClient:t})}catch(t){error({message:`Failed to get log for run with ID "${e}": ${t.message}`})}}};const Mi=new Q({allColumns:[`ID`,`Status`,`Results`,`Usage`,`Started At`,`Took`,`Build No.`,`Origin`],mandatoryColumns:[`ID`,`Status`,`Results`,`Usage`,`Started At`,`Took`],columnAlignments:{Results:`right`,Usage:`right`,Took:`right`,"Build No.":`right`}});var RunsLsCommand=class extends ApifyCommand{static name=`ls`;static enableProfileFlag=!0;static description=`Lists all runs of the Actor.`;static examples=[{description:`List runs of the Actor in the current directory.`,command:`apify runs ls`},{description:`List runs of a specific Actor.`,command:`apify runs ls apify/hello-world`},{description:`List the 50 most recent runs in descending order.`,command:`apify runs ls --limit 50 --desc`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-ls`;static flags={offset:Y.integer({description:`Number of runs that will be skipped.`,default:0}),limit:Y.integer({description:`Number of runs that will be listed.`,default:10}),desc:Y.boolean({description:`Sort runs in descending order.`,default:!1}),compact:Y.boolean({description:`Display a compact table.`,default:!1,char:`c`})};static args={actorId:Z.string({description:`Optional Actor ID or Name to list runs for. By default, it will use the Actor from the current directory.`})};static enableJsonFlag=!0;async run(){let{desc:e,limit:n,offset:r,compact:i,json:a}=this.flags,{actorId:s}=this.args,c=await getLoggedClientOrThrow(),l=await resolveActorContext({providedActorNameOrId:s,client:c});if(!l.valid){error({message:`${l.reason}. Please run this command in an Actor directory, or specify the Actor ID.`});return}let u=await c.actor(l.id).runs().list({desc:e,limit:n,offset:r});if(a){printJsonToStdout(u);return}if(!u.items.length){simpleLog({message:`There are no recent runs found for this Actor.`});return}let f=[`${t.reset(`Showing`)} ${t.yellow(u.items.length)} out of ${t.yellow(u.total)} runs for Actor ${t.yellow(l.userFriendlyId)} (${t.gray(l.id)})`],p=new Map(await Promise.all(u.items.map(async e=>c.dataset(e.defaultDatasetId).get().then(n=>[e.id,t.yellow(n?.itemCount??0)],()=>[e.id,t.gray(`N/A`)]))));for(let e of u.items){let n;if(e.finishedAt){let r=e.finishedAt.getTime()-e.startedAt.getTime();n=t.gray(`${rr.format(r,void 0,{left:``})}`)}else{let r=Date.now()-e.startedAt.getTime();n=t.gray(`Running for ${rr.format(r,void 0,{left:``})}`)}Mi.pushRow({ID:t.gray(e.id),Status:prettyPrintStatus(e.status),Results:p.get(e.id)||t.gray(`N/A`),Usage:t.cyan(`$${(e.usageTotalUsd??0).toFixed(3)}`),"Started At":er.display(e.startedAt),Took:n,"Build No.":e.buildNumber,Origin:e.meta.origin??`UNKNOWN`})}f.push(Mi.render(+!i)),simpleLog({message:f.join(`
234
- `),stdout:!0})}};const Ni=[R.SUCCEEDED,R.FAILED,R.ABORTED,R.TIMED_OUT];var RunsResurrectCommand=class extends ApifyCommand{static name=`resurrect`;static enableProfileFlag=!0;static description=`Resurrects an aborted or finished Actor Run.`;static examples=[{description:`Resurrect a finished or aborted run.`,command:`apify runs resurrect <runId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-resurrect`;static args={runId:Z.string({required:!0,description:`The run ID to resurrect.`})};static enableJsonFlag=!0;async run(){let{runId:e}=this.args,t=await getLoggedClientOrThrow(),n=await t.run(e).get();if(!n){error({message:`Run with ID "${e}" was not found on your account.`,stdout:!0});return}if(!Ni.includes(n.status)){error({message:`Run with ID "${e}" cannot be resurrected, as it is still running or in the process of aborting.`,stdout:!0});return}try{let n=await t.run(e).resurrect();if(this.flags.json){printJsonToStdout(n);return}success({message:`Run with ID "${e}" was resurrected successfully.`,stdout:!0})}catch(t){let n=t;error({message:`Failed to resurrect run "${e}".\n ${n.message||n}`,stdout:!0})}}};const Pi=[R.SUCCEEDED,R.FAILED,R.ABORTED,R.TIMED_OUT];var RunsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Deletes an Actor Run.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a finished or aborted run (prompts for confirmation).`,command:`apify runs rm <runId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-rm`;static args={runId:Z.string({description:`The run ID to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{runId:e}=this.args,{yes:t}=this.flags,n=await getLoggedClientOrThrow(),r=await n.run(e).get();if(!r){error({message:`Run with ID "${e}" was not found on your account.`});return}if(!Pi.includes(r.status)){error({message:`Run with ID "${e}" cannot be deleted, as it is still running or in the process of aborting.`});return}if(!await X({message:`Are you sure you want to delete this Actor Run?`,providedConfirmFromStdin:t||void 0})){info({message:`Deletion of run "${e}" was canceled.`});return}try{await n.run(e).delete(),success({message:`Run with ID "${e}" was deleted.`})}catch(t){let n=t;error({message:`Failed to delete run "${e}".\n ${n.message||n}`})}}},RunsWaitCommand=class extends ApifyCommand{static name=`wait`;static enableProfileFlag=!0;static description=`Waits for an Actor run to reach a terminal status (SUCCEEDED, FAILED, ABORTED, TIMED-OUT).
232
+ `)}`);let f=`${Kn}${n}`,p=u(i,`${f}.json`);return await writeInputRecord(i,f,t),{tempInputKey:f,tempInputFilePath:p}}return null}};const Oi=[R.READY,R.RUNNING],ki=[R.ABORTING,R.TIMING_OUT];var RunsAbortCommand=class extends ApifyCommand{static name=`abort`;static enableProfileFlag=!0;static description=`Aborts an Actor run.`;static examples=[{description:`Abort a running Actor gracefully (up to 30s drain).`,command:`apify runs abort <runId>`},{description:`Force-abort a running Actor immediately.`,command:`apify runs abort <runId> --force`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-abort`;static args={runId:Z.string({required:!0,description:`The run ID to abort.`})};static flags={force:Y.boolean({description:`Whether to force the run to abort immediately, instead of gracefully.`,default:!1,char:`f`})};static enableJsonFlag=!0;async run(){let{runId:e}=this.args,t=await getLoggedClientOrThrow(),n=await t.run(e).get();if(!n)error({message:`Run with ID "${e}" was not found on your account.`,stdout:!0});else if(!Oi.includes(n.status))ki.includes(n.status)?error({message:`Run with ID "${e}" is already aborting.`,stdout:!0}):error({message:`Run with ID "${e}" is already aborted.`,stdout:!0});else try{let n=await t.run(e).abort({gracefully:!this.flags.force});if(this.flags.json){printJsonToStdout(n);return}this.flags.force?success({message:`Triggered the immediate abort of run "${e}".`,stdout:!0}):success({message:`Triggered the abort of run "${e}", it should finish aborting in up to 30 seconds.`,stdout:!0})}catch(t){let n=t;error({message:`Failed to abort run "${e}".\n ${n.message||n}`,stdout:!0})}}};const Ai=new Q({allColumns:[``,`Unit`,`USD Amount`],mandatoryColumns:[``,`Unit`,`USD Amount`],columnAlignments:{Unit:`right`,"USD Amount":`right`}}),ji={"Actor compute units":`ACTOR_COMPUTE_UNITS`,"Dataset reads":`DATASET_READS`,"Dataset writes":`DATASET_WRITES`,"Key-value store reads":`KEY_VALUE_STORE_READS`,"Key-value store writes":`KEY_VALUE_STORE_WRITES`,"Key-value store lists":`KEY_VALUE_STORE_LISTS`,"Request queue reads":`REQUEST_QUEUE_READS`,"Request queue writes":`REQUEST_QUEUE_WRITES`,"Data transfer internal":`DATA_TRANSFER_INTERNAL_GBYTES`,"Data transfer external":`DATA_TRANSFER_EXTERNAL_GBYTES`,"Proxy residential data transfer":`PROXY_RESIDENTIAL_TRANSFER_GBYTES`,"Proxy SERPs":`PROXY_SERPS`};var RunsInfoCommand=class extends ApifyCommand{static name=`info`;static enableProfileFlag=!0;static description=`Prints information about an Actor run.`;static examples=[{description:`Show a summary of a run.`,command:`apify runs info <runId>`},{description:`Show verbose details including usage breakdown.`,command:`apify runs info <runId> --verbose`},{description:`Emit the full run object as JSON.`,command:`apify runs info <runId> --json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-info`;static args={runId:Z.string({required:!0,description:`The run ID to print information about.`})};static flags={verbose:Y.boolean({char:`v`,description:`Prints more in-depth information about the Actor run.`,default:!1})};static enableJsonFlag=!0;async run(){let{runId:e}=this.args,n=await getLoggedClientOrThrow(),r=await n.run(e).get();if(!r){error({message:`Run with ID "${e}" was not found on your account.`});return}let[i,a,s,c,l]=await Promise.all([n.actor(r.actId).get(),n.build(r.buildId).get(),r.actorTaskId?n.task(r.actorTaskId).get():Promise.resolve(void 0),n.dataset(r.defaultDatasetId).get(),n.requestQueue(r.defaultRequestQueueId).get()]);if(this.flags.json){printJsonToStdout({...r,actor:i,build:a,task:s,defaultDataset:c,defaultRequestQueue:l});return}this.addDetailedUsage(r);let u=i?.username?`${i.username}/${i.name}`:i?.name??`unknown-actor`,f=[`${t.yellow(`Actor`)}: ${u} (${t.grey(r.actId)})`];s?f.push(`└─ ${t.yellow(`Task`)}: ${s.title??s.name} (${t.gray(r.actorTaskId)})`,``):r.actorTaskId?f.push(`└─ ${t.yellow(`Task`)}: unknown-task (${t.gray(r.actorTaskId)})`,``):f.push(``);let p=` (exit code: ${t.gray(r.exitCode===null?`N/A`:r.exitCode)})`;f.push(`${t.yellow(`Status`)}: ${prettyPrintStatus(r.status)}${p}`),r.statusMessage&&f.push(`└─ ${t.yellow(`Status Message:`)} ${r.statusMessage}`);let m=c?.itemCount??0;f.push(`${t.yellow(`Results`)}: ${t.cyan(m.toLocaleString(`en-US`))}`),l?f.push(`${t.yellow(`Requests`)}: ${t.cyan(l.handledRequestCount.toLocaleString(`en-US`))} out of ${t.cyan(l.totalRequestCount.toLocaleString(`en-US`))} handled`):f.push(`${t.yellow(`Requests`)}: ${t.gray(`unknown handled`)}`);let h=this.flags.verbose?``:t.gray(` (run with ${t.yellow(`--verbose`)} for a detailed breakdown)`);if(r.usageTotalUsd?f.push(`${t.yellow(`Usage`)}: ${t.cyan(this.formatUsd(r.usageTotalUsd))}${h}`):f.push(`${t.yellow(`Usage`)}: $${t.gray(`0.000`)}${h}`),this.flags.verbose&&f.push(Ai.render(0)),f.push(``),f.push(`${t.yellow(`Started`)}: ${q.display(r.startedAt)}`),r.finishedAt)f.push(`${t.yellow(`Finished`)}: ${q.display(r.finishedAt)} (took ${t.gray(rr.format(r.stats.durationMillis))})`);else{let e=Date.now()-r.startedAt.getTime();f.push(`${t.yellow(`Finished`)}: ${t.gray(`Running for ${rr.format(e)}`)}`)}if(f.push(``),r.stats.resurrectCount?f.push(`${t.yellow(`Resurrected`)}: Yes, ${t.cyan(r.stats.resurrectCount.toLocaleString(`en-US`))} ${this.pluralString(r.stats.resurrectCount,`time`,`times`)}`):f.push(`${t.yellow(`Resurrected`)}: No`),r.containerUrl&&f.push(`${t.yellow(`Container URL`)}: ${t.blue(r.containerUrl)}`),f.push(`${t.yellow(`Origin`)}: ${r.meta.origin}`),i){let e=r.buildNumber.split(`.`).slice(0,2).join(`.`),n=i.versions.find(t=>t.versionNumber===e),a=Object.entries(i.taggedBuilds??{}).find(([,e])=>e.buildNumber===r.buildNumber)?.[0],s=[`${t.yellow(`Build`)}:`,t.cyan(r.buildNumber)];a?s.push(`(${t.yellow(a)})`):s.push(`(${t.gray(`N/A`)})`),n&&s.push(`| ${t.gray(`Actor version:`)} ${t.cyan(n.versionNumber)} (${t.yellow(n.buildTag)})`),f.push(s.join(` `))}else f.push(`${t.yellow(`Build`)}: ${t.cyan(r.buildNumber)}`);f.push(`${t.yellow(`Timeout`)}: ${r.options.timeoutSecs.toLocaleString(`en-US`)} seconds`),f.push(`${t.yellow(`Memory`)}: ${r.options.memoryMbytes} MB`),f.push(``),f.push(`${t.yellow(`CPU`)}: ${t.gray(`Average:`)} ${r.stats.cpuAvgUsage.toFixed(2)}% | ${t.gray(`Maximum:`)} ${r.stats.cpuMaxUsage.toFixed(2)}%`),f.push(`${t.yellow(`Memory`)}: ${t.gray(`Average:`)} ${prettyPrintBytes({bytes:r.stats.memAvgBytes,shortBytes:!0})} | ${t.gray(`Maximum:`)} ${prettyPrintBytes({bytes:r.stats.memMaxBytes,shortBytes:!0})}`),f.push(``);let g=consoleRunUrl(r.actId,r.id),_=consoleDatasetUrl(r.defaultDatasetId),v=consoleKeyValueStoreUrl(r.defaultKeyValueStoreId);f.push(`${t.blue(`Export results`)}: ${_}`),f.push(`${t.blue(`View saved items`)}: ${v}`),f.push(`${t.blue(`View in Apify Console`)}: ${g}`),simpleLog({message:f.join(`
233
+ `),stdout:!0})}addDetailedUsage(e){let{usage:t,usageUsd:n}=e;if(!t||!n)for(let e of Object.keys(ji))Ai.pushRow({"":e,Unit:`N/A`,"USD Amount":`N/A`});else for(let[e,r]of Object.entries(ji)){let i=t[r]??0,a=n[r]??0;switch(r){case`ACTOR_COMPUTE_UNITS`:Ai.pushRow({"":e,Unit:i.toFixed(4),"USD Amount":this.formatUsd(a)});break;case`DATA_TRANSFER_INTERNAL_GBYTES`:case`DATA_TRANSFER_EXTERNAL_GBYTES`:case`PROXY_RESIDENTIAL_TRANSFER_GBYTES`:Ai.pushRow({"":e,Unit:prettyPrintBytes({bytes:i*1024*1024*1024,shortBytes:!0}),"USD Amount":this.formatUsd(a)});break;default:Ai.pushRow({"":e,Unit:i.toLocaleString(`en-US`),"USD Amount":this.formatUsd(a)})}}}formatUsd(e){return`$${e.toFixed(3)}`}},RunsLogCommand=class extends ApifyCommand{static name=`log`;static enableProfileFlag=!0;static description=`Prints the log of a specific run.`;static examples=[{description:`Print the log of a specific run to stdout.`,command:`apify runs log <runId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-log`;static args={runId:Z.string({required:!0,description:`The run ID to get the log from.`})};async run(){let{runId:e}=this.args,t=await getLoggedClientOrThrow(),n=await t.run(e).get();if(!n)error({message:`Run with ID "${e}" was not found on your account.`,stdout:!0});else{info({message:`Log for run with ID "${e}":\n`,stdout:!0});try{await outputJobLog({job:n,apifyClient:t})}catch(t){error({message:`Failed to get log for run with ID "${e}": ${t.message}`})}}}};const Mi=new Q({allColumns:[`ID`,`Status`,`Results`,`Usage`,`Started At`,`Took`,`Build No.`,`Origin`],mandatoryColumns:[`ID`,`Status`,`Results`,`Usage`,`Started At`,`Took`],columnAlignments:{Results:`right`,Usage:`right`,Took:`right`,"Build No.":`right`}});var RunsLsCommand=class extends ApifyCommand{static name=`ls`;static enableProfileFlag=!0;static description=`Lists all runs of the Actor.`;static examples=[{description:`List runs of the Actor in the current directory.`,command:`apify runs ls`},{description:`List runs of a specific Actor.`,command:`apify runs ls apify/hello-world`},{description:`List the 50 most recent runs in descending order.`,command:`apify runs ls --limit 50 --desc`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-ls`;static flags={offset:Y.integer({description:`Number of runs that will be skipped.`,default:0}),limit:Y.integer({description:`Number of runs that will be listed.`,default:10}),desc:Y.boolean({description:`Sort runs in descending order.`,default:!1}),compact:Y.boolean({description:`Display a compact table.`,default:!1,char:`c`})};static args={actorId:Z.string({description:`Optional Actor ID or Name to list runs for. By default, it will use the Actor from the current directory.`})};static enableJsonFlag=!0;async run(){let{desc:e,limit:n,offset:r,compact:i,json:a}=this.flags,{actorId:s}=this.args,c=await getLoggedClientOrThrow(),l=await resolveActorContext({providedActorNameOrId:s,client:c});if(!l.valid){error({message:`${l.reason}. Please run this command in an Actor directory, or specify the Actor ID.`});return}let u=await c.actor(l.id).runs().list({desc:e,limit:n,offset:r});if(a){printJsonToStdout(u);return}if(!u.items.length){simpleLog({message:`There are no recent runs found for this Actor.`});return}let f=[`${t.reset(`Showing`)} ${t.yellow(u.items.length)} out of ${t.yellow(u.total)} runs for Actor ${t.yellow(l.userFriendlyId)} (${t.gray(l.id)})`],p=new Map(await Promise.all(u.items.map(async e=>c.dataset(e.defaultDatasetId).get().then(n=>[e.id,t.yellow(n?.itemCount??0)],()=>[e.id,t.gray(`N/A`)]))));for(let e of u.items){let n;if(e.finishedAt){let r=e.finishedAt.getTime()-e.startedAt.getTime();n=t.gray(`${rr.format(r,void 0,{left:``})}`)}else{let r=Date.now()-e.startedAt.getTime();n=t.gray(`Running for ${rr.format(r,void 0,{left:``})}`)}Mi.pushRow({ID:t.gray(e.id),Status:prettyPrintStatus(e.status),Results:p.get(e.id)||t.gray(`N/A`),Usage:t.cyan(`$${(e.usageTotalUsd??0).toFixed(3)}`),"Started At":er.display(e.startedAt),Took:n,"Build No.":e.buildNumber,Origin:e.meta.origin??`UNKNOWN`})}f.push(Mi.render(+!i)),simpleLog({message:f.join(`
234
+ `),stdout:!0})}};const Ni=[R.SUCCEEDED,R.FAILED,R.ABORTED,R.TIMED_OUT];var RunsResurrectCommand=class extends ApifyCommand{static name=`resurrect`;static enableProfileFlag=!0;static description=`Resurrects an aborted or finished Actor Run.`;static examples=[{description:`Resurrect a finished or aborted run.`,command:`apify runs resurrect <runId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-resurrect`;static args={runId:Z.string({required:!0,description:`The run ID to resurrect.`})};static enableJsonFlag=!0;async run(){let{runId:e}=this.args,t=await getLoggedClientOrThrow(),n=await t.run(e).get();if(!n)error({message:`Run with ID "${e}" was not found on your account.`,stdout:!0});else if(!Ni.includes(n.status))error({message:`Run with ID "${e}" cannot be resurrected, as it is still running or in the process of aborting.`,stdout:!0});else try{let n=await t.run(e).resurrect();if(this.flags.json){printJsonToStdout(n);return}success({message:`Run with ID "${e}" was resurrected successfully.`,stdout:!0})}catch(t){let n=t;error({message:`Failed to resurrect run "${e}".\n ${n.message||n}`,stdout:!0})}}};const Pi=[R.SUCCEEDED,R.FAILED,R.ABORTED,R.TIMED_OUT];var RunsRmCommand=class extends ApifyCommand{static name=`rm`;static enableProfileFlag=!0;static description=`Deletes an Actor Run.`;static interactive=!0;static interactiveNote=`Prompts for confirmation before deleting. Cannot be bypassed; deletion is irreversible.`;static examples=[{description:`Delete a finished or aborted run (prompts for confirmation).`,command:`apify runs rm <runId>`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-rm`;static args={runId:Z.string({description:`The run ID to delete.`,required:!0})};static flags={...YesFlag()};async run(){let{runId:e}=this.args,{yes:t}=this.flags,n=await getLoggedClientOrThrow(),r=await n.run(e).get();if(!r)error({message:`Run with ID "${e}" was not found on your account.`});else if(!Pi.includes(r.status))error({message:`Run with ID "${e}" cannot be deleted, as it is still running or in the process of aborting.`});else if(!await X({message:`Are you sure you want to delete this Actor Run?`,providedConfirmFromStdin:t||void 0}))info({message:`Deletion of run "${e}" was canceled.`});else try{await n.run(e).delete(),success({message:`Run with ID "${e}" was deleted.`})}catch(t){let n=t;error({message:`Failed to delete run "${e}".\n ${n.message||n}`})}}},RunsWaitCommand=class extends ApifyCommand{static name=`wait`;static enableProfileFlag=!0;static description=`Waits for an Actor run to reach a terminal status (SUCCEEDED, FAILED, ABORTED, TIMED-OUT).
235
235
  Returns exit code 0 only when the run SUCCEEDED. Designed for CI and agentic workflows.`;static examples=[{description:`Wait for a run to finish and return a non-zero exit code on failure.`,command:`apify runs wait <runId>`},{description:`Wait for a run and emit a structured JSON result.`,command:`apify runs wait <runId> --json`},{description:`Give up waiting after 5 minutes. Reports the real current status and exits with code 6 if the run is still running.`,command:`apify runs wait <runId> --timeout 300`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs-wait`;static enableJsonFlag=!0;static args={runId:Z.string({required:!0,description:`The run ID to wait for.`})};static flags={timeout:Y.integer({char:`t`,description:`Maximum seconds to wait before giving up. Without this flag the command waits indefinitely.`,required:!1}),"poll-interval":Y.integer({description:`How often to poll the platform, in seconds. Defaults to 2.`,required:!1})};async run(){let{runId:t}=this.args,{timeout:n,pollInterval:r,json:i}=this.flags,a=await getLoggedClientOrThrow(),{job:s,timedOutWaiting:c}=await waitForTerminalStatus({apifyClient:a,jobId:t,kind:z.RUN,maxWaitMillis:n?n*1e3:void 0,pollIntervalMillis:r?r*1e3:void 0}),l=s,u=consoleRunUrl(l.actId,l.id),f=l.status===R.SUCCEEDED,p=exitCodeForWaitResult({job:s,timedOutWaiting:c},z.RUN),m=`Gave up waiting after ${n}s; run is still ${l.status}`,h=[];if(f||(h=await fetchLogTail(a,l.id)),i){printJsonToStdout({ok:f,operation:`runs.wait`,timedOutWaiting:c,run:{id:l.id,status:l.status,exitCode:l.exitCode??null,url:u},...f?{}:{error:{phase:`run`,message:c?m:`Actor run did not succeed`,logTail:h}},exitCode:p}),e.exitCode=p;return}let g=[{label:`Run`,value:l.status},{label:`Run ID`,value:l.id},{label:`Actor ID`,value:l.actId}];l.buildNumber&&g.push({label:`Build number`,value:l.buildNumber}),typeof l.exitCode==`number`&&g.push({label:`Exit code`,value:String(l.exitCode)});let _=[{label:`Run URL`,url:u}];simpleLog({message:formatResultSummary({resultLabel:`Apify run result`,overallStatus:l.status,lines:g,links:_,errorReason:f?void 0:h}),stdout:!0}),c?error({message:`${m}.`}):f||error({message:`Run ended with status ${l.status}.`}),e.exitCode=p}},RunsIndexCommand=class extends ApifyCommand{static name=`runs`;static description=`Inspect, abort, resurrect, or delete existing Actor runs.
236
- Does not start new runs — use 'apify call' (synchronous) or 'apify actors start' (asynchronous) for that.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs`;static subcommands=[RunsAbortCommand,RunsInfoCommand,RunsLogCommand,RunsLsCommand,RunsResurrectCommand,RunsRmCommand,RunsWaitCommand];async run(){this.printHelp()}},SecretsAddCommand=class extends ApifyCommand{static name=`add`;static description=`Adds a new secret to '~/.apify' for use in Actor environment variables.`;static examples=[{description:`Add a secret named "mySecret". Reference it in .actor/actor.json as "@mySecret".`,command:`apify secrets add mySecret TopSecretValue123`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets-add`;static args={name:Z.string({required:!0,description:`Name of the secret.`}),value:Z.string({required:!0,description:`Value of the secret.`})};async run(){let{name:e,value:t}=this.args;addSecret(e,t)}};const Fi=new Q({allColumns:[`Secret Name`],mandatoryColumns:[`Secret Name`],columnAlignments:{"Secret Name":`left`}});var SecretsLsCommand=class extends ApifyCommand{static name=`ls`;static description=`Lists all secret keys stored in your local configuration.`;static examples=[{description:`List the names of all locally stored secrets.`,command:`apify secrets ls`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets-ls`;static enableJsonFlag=!0;async run(){let{json:e}=this.flags,n=getSecretsFile(),r=Object.keys(n);if(e){printJsonToStdout({keys:r});return}if(r.length===0){info({message:`You don't have any secrets stored locally. Use 'apify secrets add' to add a secret.`,stdout:!0});return}for(let e of r)Fi.pushRow({"Secret Name":t.cyan(e)});simpleLog({message:Fi.render(1),stdout:!0})}},SecretsRmCommand=class extends ApifyCommand{static name=`rm`;static description=`Permanently deletes a secret from your stored credentials.`;static examples=[{description:`Delete a locally stored secret by name.`,command:`apify secrets rm mySecret`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets-rm`;static args={name:Z.string({required:!0,description:`Name of the secret.`})};async run(){let{name:e}=this.args;removeSecret(e)}},SecretsIndexCommand=class extends ApifyCommand{static name=`secrets`;static description=`Manage locally stored secrets that can be referenced from '${K}' environment variables using the "@" prefix (e.g. "@mySecret"). Secrets are uploaded alongside the Actor and stored encrypted on the Apify platform.`;static group=`Authentication`;static examples=[{description:`Store a secret called "mySecret".`,command:`apify secrets add mySecret TopSecretValue123`},{description:`Reference the secret from .actor/actor.json using the "@" prefix, e.g. "environmentVariables": { "SECRET_ENV_VAR": "@mySecret" }, then push as usual.`,command:`apify push`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets`;static subcommands=[SecretsAddCommand,SecretsLsCommand,SecretsRmCommand];async run(){this.printHelp()}},TaskPublishCommand=class extends ApifyCommand{static name=`publish`;static enableProfileFlag=!0;static description=`Publishes the task on its public landing page.
237
- The task must belong to a public Actor and have its public display configuration set up on the task Publication tab in Apify Console. Requires write access to the task and to its Actor.`;static examples=[{description:`Publish a task by name.`,command:`apify task publish my-task`},{description:`Publish a task by full name.`,command:`apify task publish username/my-task`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-task-publish`;static args={taskId:Z.string({required:!0,description:`Name of the task to publish. For example, "my-task" or "username/my-task".`})};async run(){let n=await getLoggedClientOrThrow(),r=await getCurrentUserInfo(),i=r.username||r.id,{taskId:a}=this.args,s=a.includes(`/`)?a:`${i}/${a.toLowerCase()}`,c=n.task(s),l=await c.get();if(!l){error({message:`Cannot find Task with name '${a}' in your account.`}),e.exitCode=250;return}try{await c.publish(),success({message:`Task ${t.yellow(l.name)} has been published.`,stdout:!0})}catch(n){let r=n;error({message:`Failed to publish task ${t.yellow(l.name)}\n ${r.message||r}`}),e.exitCode=1}}},TaskRunCommand=class extends ApifyCommand{static name=`run`;static enableProfileFlag=!0;static description=`Executes predefined Actor task remotely using local key-value store for input.
236
+ Does not start new runs — use 'apify call' (synchronous) or 'apify actors start' (asynchronous) for that.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-runs`;static subcommands=[RunsAbortCommand,RunsInfoCommand,RunsLogCommand,RunsLsCommand,RunsResurrectCommand,RunsRmCommand,RunsWaitCommand];async run(){this.printHelp()}},SecretsAddCommand=class extends ApifyCommand{static name=`add`;static description=`Adds a new secret to '~/.apify' for use in Actor environment variables.`;static examples=[{description:`Add a secret named "mySecret". Reference it in .actor/actor.json as "@mySecret".`,command:`apify secrets add mySecret TopSecretValue123`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets-add`;static args={name:Z.string({required:!0,description:`Name of the secret.`}),value:Z.string({required:!0,description:`Value of the secret.`})};async run(){let{name:e,value:t}=this.args;addSecret(e,t)}};const Fi=new Q({allColumns:[`Secret Name`],mandatoryColumns:[`Secret Name`],columnAlignments:{"Secret Name":`left`}});var SecretsLsCommand=class extends ApifyCommand{static name=`ls`;static description=`Lists all secret keys stored in your local configuration.`;static examples=[{description:`List the names of all locally stored secrets.`,command:`apify secrets ls`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets-ls`;static enableJsonFlag=!0;async run(){let{json:e}=this.flags,n=getSecretsFile(),r=Object.keys(n);if(e)printJsonToStdout({keys:r});else if(r.length===0)info({message:`You don't have any secrets stored locally. Use 'apify secrets add' to add a secret.`,stdout:!0});else{for(let e of r)Fi.pushRow({"Secret Name":t.cyan(e)});simpleLog({message:Fi.render(1),stdout:!0})}}},SecretsRmCommand=class extends ApifyCommand{static name=`rm`;static description=`Permanently deletes a secret from your stored credentials.`;static examples=[{description:`Delete a locally stored secret by name.`,command:`apify secrets rm mySecret`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets-rm`;static args={name:Z.string({required:!0,description:`Name of the secret.`})};async run(){let{name:e}=this.args;removeSecret(e)}},SecretsIndexCommand=class extends ApifyCommand{static name=`secrets`;static description=`Manage locally stored secrets that can be referenced from '${K}' environment variables using the "@" prefix (e.g. "@mySecret"). Secrets are uploaded alongside the Actor and stored encrypted on the Apify platform.`;static group=`Authentication`;static examples=[{description:`Store a secret called "mySecret".`,command:`apify secrets add mySecret TopSecretValue123`},{description:`Reference the secret from .actor/actor.json using the "@" prefix, e.g. "environmentVariables": { "SECRET_ENV_VAR": "@mySecret" }, then push as usual.`,command:`apify push`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-secrets`;static subcommands=[SecretsAddCommand,SecretsLsCommand,SecretsRmCommand];async run(){this.printHelp()}},TaskPublishCommand=class extends ApifyCommand{static name=`publish`;static enableProfileFlag=!0;static description=`Publishes the task on its public landing page.
237
+ The task must belong to a public Actor and have its public display configuration set up on the task Publication tab in Apify Console. Requires write access to the task and to its Actor.`;static examples=[{description:`Publish a task by name.`,command:`apify task publish my-task`},{description:`Publish a task by full name.`,command:`apify task publish username/my-task`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-task-publish`;static args={taskId:Z.string({required:!0,description:`Name of the task to publish. For example, "my-task" or "username/my-task".`})};async run(){let n=await getLoggedClientOrThrow(),r=await getCurrentUserInfo(),i=r.username||r.id,{taskId:a}=this.args,s=a.includes(`/`)?a:`${i}/${a.toLowerCase()}`,c=n.task(s),l=await c.get();if(!l)error({message:`Cannot find Task with name '${a}' in your account.`}),e.exitCode=250;else try{await c.publish(),success({message:`Task ${t.yellow(l.name)} has been published.`,stdout:!0})}catch(n){let r=n;error({message:`Failed to publish task ${t.yellow(l.name)}\n ${r.message||r}`}),e.exitCode=1}}},TaskRunCommand=class extends ApifyCommand{static name=`run`;static enableProfileFlag=!0;static description=`Executes predefined Actor task remotely using local key-value store for input.
238
238
  Customize with --memory and --timeout flags.
239
239
  `;static examples=[{description:`Run a task by name.`,command:`apify task run my-task`},{description:`Run a task by full ID with custom memory and timeout.`,command:`apify task run username/my-task --memory 4096 --timeout 600`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-task-run`;static flags=SharedRunOnCloudFlags(`Task`);static enableJsonFlag=!0;static args={taskId:Z.string({required:!0,description:`Name or ID of the Task to run (e.g. "my-task" or "E2jjCZBezvAZnX8Rb").`})};async run(){let e=await getLoggedClientOrThrow(),t=await getCurrentUserInfo(),n=t.username||t.id,{id:r,userFriendlyId:i,title:a}=await this.resolveTaskId(e,n),s={waitForFinish:2};this.flags.build&&(s.build=this.flags.build),this.flags.timeout!==void 0&&(s.timeout=this.flags.timeout),this.flags.memory&&(s.memory=this.flags.memory);let c,l=runActorOrTaskOnCloud(e,{actorOrTaskData:{id:r,userFriendlyId:i,title:a},runOptions:s,type:`Task`,waitForRunToFinish:!0,printRunLogs:!0,suppressFinalStatus:!0});for await(let e of l)c=e;await finalizeRun({apifyClient:e,run:c,operation:`task-run`,json:this.flags.json})}async resolveTaskId(e,t){let{taskId:n}=this.args;if(n?.includes(`/`)){let r=await e.task(n).get();if(!r)throw Error(`Cannot find Task with ID '${n}' in your account.`);return{id:r.id,userFriendlyId:`${t}/${r.name}`,title:r.title,task:r}}if(n){let r=await e.task(`${t}/${n.toLowerCase()}`).get();if(!r)throw Error(`Cannot find Task with name '${n}' in your account.`);return{id:r.id,userFriendlyId:`${t}/${r.name}`,title:r.title,task:r}}throw Error(`Please provide a valid Task ID or name.`)}},TaskUnpublishCommand=class extends ApifyCommand{static name=`unpublish`;static enableProfileFlag=!0;static description=`Unpublishes the task from its public landing page.
240
- The public display configuration is preserved, so the task can be published again later. Requires write access to the task and to its Actor.`;static examples=[{description:`Unpublish a task by name.`,command:`apify task unpublish my-task`},{description:`Unpublish a task by full name.`,command:`apify task unpublish username/my-task`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-task-unpublish`;static args={taskId:Z.string({required:!0,description:`Name of the task to unpublish. For example, "my-task" or "username/my-task".`})};async run(){let n=await getLoggedClientOrThrow(),r=await getCurrentUserInfo(),i=r.username||r.id,{taskId:a}=this.args,s=a.includes(`/`)?a:`${i}/${a.toLowerCase()}`,c=n.task(s),l=await c.get();if(!l){error({message:`Cannot find Task with name '${a}' in your account.`}),e.exitCode=250;return}try{await c.unpublish(),success({message:`Task ${t.yellow(l.name)} has been unpublished.`,stdout:!0})}catch(n){let r=n;error({message:`Failed to unpublish task ${t.yellow(l.name)}\n ${r.message||r}`}),e.exitCode=1}}},TasksIndexCommand=class extends ApifyCommand{static name=`task`;static description=`Run and publish saved Apify tasks (named Actor configurations). Create and manage tasks in Apify Console.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-task`;static subcommands=[TaskRunCommand,TaskPublishCommand,TaskUnpublishCommand];async run(){this.printHelp()}},TelemetryDisableCommand=class extends ApifyCommand{static name=`disable`;static description=`Disables telemetry.`;static examples=[{description:`Opt out of anonymous telemetry.`,command:`apify telemetry disable`}];static docsUrl=`https://docs.apify.com/cli/docs/telemetry`;async run(){(await useTelemetryState()).enabled?(await updateTelemetryEnabled(!1),success({message:`Telemetry disabled.`})):info({message:`Telemetry is already disabled.`})}},TelemetryEnableCommand=class extends ApifyCommand{static name=`enable`;static description=`Enables telemetry.`;static examples=[{description:`Opt in to anonymous telemetry.`,command:`apify telemetry enable`}];static docsUrl=`https://docs.apify.com/cli/docs/telemetry`;async run(){(await useTelemetryState()).enabled?info({message:`Telemetry is already enabled.`}):(await updateTelemetryEnabled(!0),success({message:`Telemetry enabled.`}))}},TelemetryIndexCommand=class extends ApifyCommand{static name=`telemetry`;static description=`Enable or disable anonymous telemetry. We use this data to improve the CLI and the Apify platform.`;static group=`Utilities`;static docsUrl=`https://docs.apify.com/cli/docs/telemetry`;static subcommands=[TelemetryEnableCommand,TelemetryDisableCommand];async run(){this.printHelp()}};const Ii=new Q({allColumns:[`Template`,`Label`,`Language`,`Use cases`],mandatoryColumns:[`Template`,`Language`,`Use cases`]});var TemplatesLsCommand=class extends ApifyCommand{static name=`ls`;static description=`Prints all available Actor templates, including the use cases and language each one supports.`;static examples=[{description:`List all available templates.`,command:`apify templates ls`},{description:`List templates as JSON (includes the use-case tags for scripting).`,command:`apify templates ls --json`}];static enableJsonFlag=!0;async run(){let{json:e}=this.flags,t=await Ot().catch(e=>{throw Error(`Could not fetch template list from server. Cause: ${e?.message}`)});if(e){printJsonToStdout(t.templates);return}if(t.templates.length===0){info({message:`There are no templates available.`,stdout:!0});return}for(let e of t.templates)Ii.pushRow({Template:e.name,Label:e.label,Language:languageLabel(e.category),"Use cases":(e.useCases??[]).join(`, `)});simpleLog({message:Ii.render(1),stdout:!0})}},TemplatesIndexCommand=class extends ApifyCommand{static name=`templates`;static description=`Explore the Actor templates used by "apify create".`;static group=`Local Actor Development`;static subcommands=[TemplatesLsCommand];async run(){this.printHelp()}},ValidateSchemaCommand=class extends ApifyCommand{static name=`validate-schema`;static description=`Validates Actor schemas.
240
+ The public display configuration is preserved, so the task can be published again later. Requires write access to the task and to its Actor.`;static examples=[{description:`Unpublish a task by name.`,command:`apify task unpublish my-task`},{description:`Unpublish a task by full name.`,command:`apify task unpublish username/my-task`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-task-unpublish`;static args={taskId:Z.string({required:!0,description:`Name of the task to unpublish. For example, "my-task" or "username/my-task".`})};async run(){let n=await getLoggedClientOrThrow(),r=await getCurrentUserInfo(),i=r.username||r.id,{taskId:a}=this.args,s=a.includes(`/`)?a:`${i}/${a.toLowerCase()}`,c=n.task(s),l=await c.get();if(!l)error({message:`Cannot find Task with name '${a}' in your account.`}),e.exitCode=250;else try{await c.unpublish(),success({message:`Task ${t.yellow(l.name)} has been unpublished.`,stdout:!0})}catch(n){let r=n;error({message:`Failed to unpublish task ${t.yellow(l.name)}\n ${r.message||r}`}),e.exitCode=1}}},TasksIndexCommand=class extends ApifyCommand{static name=`task`;static description=`Run and publish saved Apify tasks (named Actor configurations). Create and manage tasks in Apify Console.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-task`;static subcommands=[TaskRunCommand,TaskPublishCommand,TaskUnpublishCommand];async run(){this.printHelp()}},TelemetryDisableCommand=class extends ApifyCommand{static name=`disable`;static description=`Disables telemetry.`;static examples=[{description:`Opt out of anonymous telemetry.`,command:`apify telemetry disable`}];static docsUrl=`https://docs.apify.com/cli/docs/telemetry`;async run(){(await useTelemetryState()).enabled?(await updateTelemetryEnabled(!1),success({message:`Telemetry disabled.`})):info({message:`Telemetry is already disabled.`})}},TelemetryEnableCommand=class extends ApifyCommand{static name=`enable`;static description=`Enables telemetry.`;static examples=[{description:`Opt in to anonymous telemetry.`,command:`apify telemetry enable`}];static docsUrl=`https://docs.apify.com/cli/docs/telemetry`;async run(){(await useTelemetryState()).enabled?info({message:`Telemetry is already enabled.`}):(await updateTelemetryEnabled(!0),success({message:`Telemetry enabled.`}))}},TelemetryIndexCommand=class extends ApifyCommand{static name=`telemetry`;static description=`Enable or disable anonymous telemetry. We use this data to improve the CLI and the Apify platform.`;static group=`Utilities`;static docsUrl=`https://docs.apify.com/cli/docs/telemetry`;static subcommands=[TelemetryEnableCommand,TelemetryDisableCommand];async run(){this.printHelp()}};const Ii=new Q({allColumns:[`Template`,`Label`,`Language`,`Use cases`],mandatoryColumns:[`Template`,`Language`,`Use cases`]});var TemplatesLsCommand=class extends ApifyCommand{static name=`ls`;static description=`Prints all available Actor templates, including the use cases and language each one supports.`;static examples=[{description:`List all available templates.`,command:`apify templates ls`},{description:`List templates as JSON (includes the use-case tags for scripting).`,command:`apify templates ls --json`}];static enableJsonFlag=!0;async run(){let{json:e}=this.flags,t=await Ot().catch(e=>{throw Error(`Could not fetch template list from server. Cause: ${e?.message}`)});if(e)printJsonToStdout(t.templates);else if(t.templates.length===0)info({message:`There are no templates available.`,stdout:!0});else{for(let e of t.templates)Ii.pushRow({Template:e.name,Label:e.label,Language:languageLabel(e.category),"Use cases":(e.useCases??[]).join(`, `)});simpleLog({message:Ii.render(1),stdout:!0})}}},TemplatesIndexCommand=class extends ApifyCommand{static name=`templates`;static description=`Explore the Actor templates used by "apify create".`;static group=`Local Actor Development`;static subcommands=[TemplatesLsCommand];async run(){this.printHelp()}},ValidateSchemaCommand=class extends ApifyCommand{static name=`validate-schema`;static description=`Validates Actor schemas.
241
241
 
242
242
  When a path argument is provided, validates only the input schema at that path.
243
243
 
@@ -245,5 +245,5 @@ When no path is provided, validates all schemas found in '${K}':
245
245
  - Input schema (from "input" key or default locations)
246
246
  - Dataset schema (from "storages.dataset")
247
247
  - Output schema (from "output")
248
- - Key-Value Store schema (from "storages.keyValueStore")`;static group=`Local Actor Development`;static examples=[{description:`Validate the input schema discovered from the default locations.`,command:`apify validate-schema`},{description:`Validate a specific INPUT_SCHEMA.json file.`,command:`apify validate-schema ./my-schema.json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-validate-schema`;static args={path:Z.string({required:!1,description:`Optional path to your INPUT_SCHEMA.json file. If not provided, validates all schemas in '${K}'.`})};static hiddenAliases=[`vis`];async run(){if(this.args.path){await this.validateInputSchemaAtPath(this.args.path);return}await this.validateAllSchemas()}async validateInputSchemaAtPath(t){await readAndValidateInputSchema({forcePath:t,cwd:e.cwd(),getMessage:e=>`Validating input schema at ${e??t}`}),success({message:`Input schema is valid.`})}async validateAllSchemas(){let t=e.cwd(),n=!1,r=!1;try{let{inputSchema:e,inputSchemaPath:r}=await readInputSchema({cwd:t,throwOnMissing:!0});if(e){n=!0,info({message:`Validating input schema ${r?`at ${r}`:`embedded in '${K}'`}`});let t=new Xn({strict:!1});_t(t,e),success({message:`Input schema is valid.`})}}catch(e){n=!0,r=!0,error({message:e.message})}let i=[{label:`Dataset`,read:()=>readStorageSchema({cwd:t,key:`dataset`,label:`Dataset`,throwOnMissing:!0}),validate:validateDatasetSchema},{label:`Output`,read:()=>readStorageSchema({cwd:t,key:`output`,label:`Output`,getRef:e=>e?.output,throwOnMissing:!0}),validate:validateOutputSchema},{label:`Key-Value Store`,read:()=>readStorageSchema({cwd:t,key:`keyValueStore`,label:`Key-Value Store`,throwOnMissing:!0}),validate:validateKvsSchema}];for(let{label:e,read:t,validate:a}of i)try{let r=t();r&&(n=!0,info({message:`Validating ${e} schema ${r.schemaPath?`at ${r.schemaPath}`:`embedded in '${K}'`}`}),a(r.schema),success({message:`${e} schema is valid.`}))}catch(e){n=!0,r=!0,error({message:e.message})}if(!n)throw Error(`No schemas found. Make sure '${K}' exists and defines at least one schema.`);r&&(e.exitCode=5)}};const Li=[ActorIndexCommand,ActorsIndexCommand,AuthIndexCommand,BuildsIndexCommand,DatasetsIndexCommand,KeyValueStoresIndexCommand,MCPIndexCommand,RequestQueuesIndexCommand,RunsIndexCommand,SecretsIndexCommand,TasksIndexCommand,TelemetryIndexCommand,TemplatesIndexCommand,ApiCommand,TopLevelCallCommand,UpgradeCommand,InstallCommand,CreateCommand,EditInputSchemaCommand,InfoCommand,WrapScrapyCommand,InitCommand,LoginCommand,LogoutCommand,TopLevelPullCommand,ToplevelPushCommand,RunCommand,ValidateSchemaCommand,HelpCommand],Ri=[ActorSetValueCommand,ActorPushDataCommand,ActorGetValueCommand,ActorGetPublicUrlCommand,ActorGetInputCommand,ActorChargeCommand,ActorCalculateMemoryCommand,ActorGenerateSchemaTypesCommand,HelpCommand,UpgradeCommand,InstallCommand,TelemetryIndexCommand];export{runCLI as i,Li as n,processVersionCheck as r,Ri as t};
249
- //# sourceMappingURL=_register-DKn0lYv0.js.map
248
+ - Key-Value Store schema (from "storages.keyValueStore")`;static group=`Local Actor Development`;static examples=[{description:`Validate the input schema discovered from the default locations.`,command:`apify validate-schema`},{description:`Validate a specific INPUT_SCHEMA.json file.`,command:`apify validate-schema ./my-schema.json`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-validate-schema`;static args={path:Z.string({required:!1,description:`Optional path to your INPUT_SCHEMA.json file. If not provided, validates all schemas in '${K}'.`})};static hiddenAliases=[`vis`];async run(){this.args.path?await this.validateInputSchemaAtPath(this.args.path):await this.validateAllSchemas()}async validateInputSchemaAtPath(t){await readAndValidateInputSchema({forcePath:t,cwd:e.cwd(),getMessage:e=>`Validating input schema at ${e??t}`}),success({message:`Input schema is valid.`})}async validateAllSchemas(){let t=e.cwd(),n=!1,r=!1;try{let{inputSchema:e,inputSchemaPath:r}=await readInputSchema({cwd:t,throwOnMissing:!0});if(e){n=!0,info({message:`Validating input schema ${r?`at ${r}`:`embedded in '${K}'`}`});let t=new Xn({strict:!1});_t(t,e),success({message:`Input schema is valid.`})}}catch(e){n=!0,r=!0,error({message:e.message})}let i=[{label:`Dataset`,read:()=>readStorageSchema({cwd:t,key:`dataset`,label:`Dataset`,throwOnMissing:!0}),validate:validateDatasetSchema},{label:`Output`,read:()=>readStorageSchema({cwd:t,key:`output`,label:`Output`,getRef:e=>e?.output,throwOnMissing:!0}),validate:validateOutputSchema},{label:`Key-Value Store`,read:()=>readStorageSchema({cwd:t,key:`keyValueStore`,label:`Key-Value Store`,throwOnMissing:!0}),validate:validateKvsSchema}];for(let{label:e,read:t,validate:a}of i)try{let r=t();r&&(n=!0,info({message:`Validating ${e} schema ${r.schemaPath?`at ${r.schemaPath}`:`embedded in '${K}'`}`}),a(r.schema),success({message:`${e} schema is valid.`}))}catch(e){n=!0,r=!0,error({message:e.message})}if(!n)throw Error(`No schemas found. Make sure '${K}' exists and defines at least one schema.`);r&&(e.exitCode=5)}};const Li=[ActorIndexCommand,ActorsIndexCommand,AuthIndexCommand,BuildsIndexCommand,DatasetsIndexCommand,KeyValueStoresIndexCommand,MCPIndexCommand,RequestQueuesIndexCommand,RunsIndexCommand,SecretsIndexCommand,TasksIndexCommand,TelemetryIndexCommand,TemplatesIndexCommand,ApiCommand,TopLevelCallCommand,UpgradeCommand,InstallCommand,CreateCommand,EditInputSchemaCommand,InfoCommand,WrapScrapyCommand,InitCommand,LoginCommand,LogoutCommand,TopLevelPullCommand,ToplevelPushCommand,RunCommand,ValidateSchemaCommand,HelpCommand],Ri=[ActorSetValueCommand,ActorPushDataCommand,ActorGetValueCommand,ActorGetPublicUrlCommand,ActorGetInputCommand,ActorChargeCommand,ActorCalculateMemoryCommand,ActorGenerateSchemaTypesCommand,HelpCommand,UpgradeCommand,InstallCommand,TelemetryIndexCommand];export{runCLI as i,Li as n,processVersionCheck as r,Ri as t};
249
+ //# sourceMappingURL=_register-KqqemAf5.js.map