apify-cli 1.10.1-beta.25 → 1.10.1-beta.26
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,constants as w,copyFileSync as T,createWriteStream as E,existsSync as D,fstat as O,mkdirSync as k,openSync as A,readFileSync as j,readdirSync as ee,realpathSync as M,renameSync as N,rmSync as P,statSync as te,unlinkSync as ne,writeFileSync as F}from"node:fs";import re from"string-width";import ie from"strip-ansi";import{once as ae}from"node:events";import{homedir as oe,platform as se}from"node:os";import ce,{isCI as le}from"ci-info";import{ACTOR_ENV_VARS as I,ACTOR_JOB_STATUSES as L,ACTOR_JOB_TERMINAL_STATUSES as ue,ACTOR_NAME as de,ACTOR_SOURCE_TYPES as fe,APIFY_ENV_VARS as R,KEY_VALUE_STORE_KEYS as pe,LOCAL_ACTOR_ENV_VARS as me,LOCAL_STORAGE_SUBDIRS as he,MAX_MULTIFILE_BYTES as ge,META_ORIGINS as _e,SOURCE_FILE_FORMATS as ve}from"@apify/consts";import{jaroWinkler as ye}from"@skyra/jaro-winkler";import be from"js-levenshtein";import{Result as xe,err as Se,none as Ce,ok as we,some as Te}from"@sapphire/result";import{execa as Ee}from"execa";import{access as De,appendFile as Oe,mkdir as z,readFile as B,readdir as ke,rename as Ae,rm as je,stat as V,symlink as Me,unlink as Ne,writeFile as H}from"node:fs/promises";import Pe from"configparser";import Fe from"@inquirer/input";import Ie from"which";import{createHmacSignature as Le,cryptoRandomObjectId as Re}from"@apify/utilities";import{execSync as ze,spawn as Be}from"node:child_process";import{DurationFormatter as Ve,Time as He,TimeTypes as Ue}from"@sapphire/duration";import{Timestamp as We}from"@sapphire/timestamp";import Ge from"adm-zip";import Ke from"ajv/dist/2019.js";import{ApifyApiError as qe,ApifyClient as Je,DownloadItemsFormat as U}from"apify-client";import{ZipArchive as Ye}from"archiver";import Xe,{AxiosHeaders as Ze}from"axios";import Qe from"escape-string-regexp";import $e from"ignore";import{getEncoding as et}from"istextorbinary";import tt,{Mime as nt}from"mime";import rt from"mime/types/other.js";import it from"mime/types/standard.js";import{glob as at}from"tinyglobby";import{calculateRunDynamicMemory as ot}from"@apify/actor-memory-expression";import{Separator as st,createPrompt as ct,isEnterKey as lt,makeTheme as ut,useKeypress as dt,usePrefix as ft,useState as pt}from"@inquirer/core";import{compile as mt}from"json-schema-to-typescript";import{validateInputSchema as ht,validateInputUsingValidator as gt}from"@apify/input_schema";import{getDatasetSchemaValidator as _t,getKeyValueStoreSchemaValidator as vt,getOutputSchemaValidator as yt}from"@apify/json_schemas";import{pipeline as bt}from"node:stream/promises";import{MemoryStorage as xt}from"@crawlee/memory-storage";import St from"cli-table3";import{downloadTemplate as Ct}from"giget";import wt from"jju";import Tt from"open";import{fetchManifest as Et,manifestUrl as Dt,wrapperManifestUrl as Ot}from"@apify/actor-templates";import kt from"computer-name";import At from"@inquirer/password";import jt from"@inquirer/select";import{createServer as Mt}from"node:http";import Nt from"node:assert";import{ReadStream as Pt}from"node:tty";import{setTimeout as Ft}from"node:timers/promises";import It from"detect-indent";import{fileURLToPath as Lt}from"node:url";import Rt from"@root/walk";import zt 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=M(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 Bt=null;function useCLIMetadata(){if(Bt)return Bt;let e=detectInstallMethod(),t=getRuntimeInfo();return Bt={version:`1.10.1-beta.
|
|
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,constants as w,copyFileSync as T,createWriteStream as E,existsSync as D,fstat as O,mkdirSync as k,openSync as A,readFileSync as j,readdirSync as ee,realpathSync as M,renameSync as N,rmSync as P,statSync as te,unlinkSync as ne,writeFileSync as F}from"node:fs";import re from"string-width";import ie from"strip-ansi";import{once as ae}from"node:events";import{homedir as oe,platform as se}from"node:os";import ce,{isCI as le}from"ci-info";import{ACTOR_ENV_VARS as I,ACTOR_JOB_STATUSES as L,ACTOR_JOB_TERMINAL_STATUSES as ue,ACTOR_NAME as de,ACTOR_SOURCE_TYPES as fe,APIFY_ENV_VARS as R,KEY_VALUE_STORE_KEYS as pe,LOCAL_ACTOR_ENV_VARS as me,LOCAL_STORAGE_SUBDIRS as he,MAX_MULTIFILE_BYTES as ge,META_ORIGINS as _e,SOURCE_FILE_FORMATS as ve}from"@apify/consts";import{jaroWinkler as ye}from"@skyra/jaro-winkler";import be from"js-levenshtein";import{Result as xe,err as Se,none as Ce,ok as we,some as Te}from"@sapphire/result";import{execa as Ee}from"execa";import{access as De,appendFile as Oe,mkdir as z,readFile as B,readdir as ke,rename as Ae,rm as je,stat as V,symlink as Me,unlink as Ne,writeFile as H}from"node:fs/promises";import Pe from"configparser";import Fe from"@inquirer/input";import Ie from"which";import{createHmacSignature as Le,cryptoRandomObjectId as Re}from"@apify/utilities";import{execSync as ze,spawn as Be}from"node:child_process";import{DurationFormatter as Ve,Time as He,TimeTypes as Ue}from"@sapphire/duration";import{Timestamp as We}from"@sapphire/timestamp";import Ge from"adm-zip";import Ke from"ajv/dist/2019.js";import{ApifyApiError as qe,ApifyClient as Je,DownloadItemsFormat as U}from"apify-client";import{ZipArchive as Ye}from"archiver";import Xe,{AxiosHeaders as Ze}from"axios";import Qe from"escape-string-regexp";import $e from"ignore";import{getEncoding as et}from"istextorbinary";import tt,{Mime as nt}from"mime";import rt from"mime/types/other.js";import it from"mime/types/standard.js";import{glob as at}from"tinyglobby";import{calculateRunDynamicMemory as ot}from"@apify/actor-memory-expression";import{Separator as st,createPrompt as ct,isEnterKey as lt,makeTheme as ut,useKeypress as dt,usePrefix as ft,useState as pt}from"@inquirer/core";import{compile as mt}from"json-schema-to-typescript";import{validateInputSchema as ht,validateInputUsingValidator as gt}from"@apify/input_schema";import{getDatasetSchemaValidator as _t,getKeyValueStoreSchemaValidator as vt,getOutputSchemaValidator as yt}from"@apify/json_schemas";import{pipeline as bt}from"node:stream/promises";import{MemoryStorage as xt}from"@crawlee/memory-storage";import St from"cli-table3";import{downloadTemplate as Ct}from"giget";import wt from"jju";import Tt from"open";import{fetchManifest as Et,manifestUrl as Dt,wrapperManifestUrl as Ot}from"@apify/actor-templates";import kt from"computer-name";import At from"@inquirer/password";import jt from"@inquirer/select";import{createServer as Mt}from"node:http";import Nt from"node:assert";import{ReadStream as Pt}from"node:tty";import{setTimeout as Ft}from"node:timers/promises";import It from"detect-indent";import{fileURLToPath as Lt}from"node:url";import Rt from"@root/walk";import zt 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=M(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 Bt=null;function useCLIMetadata(){if(Bt)return Bt;let e=detectInstallMethod(),t=getRuntimeInfo();return Bt={version:`1.10.1-beta.26`,hash:`85a9a0b9cab4f0e75583197d7af9b2aa4a7f15ba`,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`&&(Bt.installPath=c(process.execPath)),Bt}function cliDebugPrint(e,...n){process.env.APIFY_CLI_DEBUG&&console.error(t.gray(`[${e}]`),...n)}const Vt=[`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{F(i,n),r!==void 0&&C(i,r),N(i,t)}catch(e){try{P(i,{force:!0})}catch{}throw e}}function atomicCopySync(t,n,r){let i=`${n}.${e.pid}.tmp`;try{T(t,i),r!==void 0&&C(i,r),N(i,n)}catch(e){try{P(i,{force:!0})}catch{}throw e}}function writeEntrypointShims(e,t){for(let n of Vt)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 Vt){let t=u(r,`${e}.exe.old`);if(D(t))try{P(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`||!Vt.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 Vt){let n=u(r,`${t}.exe`);if(D(n))try{p(n)===p(e.execPath)?(N(n,`${n}.old`),cliDebugPrint(`[migration] renamed running legacy binary`,n)):P(n,{force:!0})}catch(e){try{N(n,`${n}.old`)}catch{}cliDebugPrint(`[migration] failed to remove legacy binary`,{legacyBinaryPath:n,err:e})}}let t=u(r,`upgrade.ps1`);try{P(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 Ht;function getMaxLineWidth(){if(Ht)return Ht;let e=Number(process.env.APIFY_CLI_MAX_LINE_WIDTH);if(!Number.isNaN(e))Ht=e;else if(!process.stdout.isTTY)Ht=80;else{let e=process.stdout.getWindowSize?.()[0]??-1;Ht=e<1?80:e<40?40:e}return Ht}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(`
|
|
@@ -8,27 +8,27 @@ import e from"node:process";import t from"chalk";import n from"indent-string";im
|
|
|
8
8
|
`).at(-1)||``)+n+re(t)>getMaxLineWidth()&&e.push(`
|
|
9
9
|
`),e.push(t)}kebabFlagName(e){return kebabCaseString(camelCaseToKebabCase(e)).toLowerCase()}makeFlagString(e,t){let n=this.kebabFlagName(e),r=t.char?`-${t.char}`:`--${n}`;switch(t.flagTag){case`boolean`:return r;case`string`:case`integer`:return`${r} ${t.choices?.length?`${t.choices.join(`|`)}`:`<value>`}`;default:throw RangeError(`Unhandled flag type: ${t.flagTag}`)}}},CommandHelp=class extends BaseCommandRenderer{render(){let e=[];return this.pushShortDescription(e),this.pushUsageString(e),this.command.description&&this.pushDescription(e),this.pushExamples(e),this.pushInteractiveNote(e),this.pushLearnMore(e),e.join(`
|
|
10
10
|
`).trim()}selectiveRender(e){let t=[];return e.showShortDescription&&this.pushShortDescription(t),e.showUsageString&&this.pushUsageString(t),e.showDescription&&this.command.description&&this.pushDescription(t),e.showExamples&&this.pushExamples(t),e.showLearnMore&&this.pushLearnMore(t),t.join(`
|
|
11
|
-
`).trim()}pushUsageString(e){e.push(t.bold(`USAGE`));let r=`$ ${this.entrypoint} ${this.command.name}`,a=2+re(r),s=[r],c=Object.entries(this.command.args??{});if(c.length)for(let[e,t]of c){if(typeof t==`string`)throw RangeError(`This is a type-check only value, do not actually use it`);this.pushNewLineBeforeNewEntryIfLengthIsPastTheLimit({state:s,itemToAdd:t.required?`<${e}>`:`[${e}]`,indentSize:a})}let l=Object.entries(this.command.flags??{}).filter(([,e])=>{if(typeof e==`string`)throw RangeError(`This is a type-check only value, do not actually use it`);return!e.hidden});this.command.enableJsonFlag&&l.push([`json`,{choices:null,flagTag:`boolean`,hasDefault:!1,required:!1,stdin:null,builder:null,aliases:void 0,char:void 0,description:`Format the command output as JSON.`,hidden:void 0,exclusive:void 0}]);let u=new Map(l.sort((e,t)=>{if(typeof e[1]==`string`||typeof t[1]==`string`)throw RangeError(`This is a type-check only value, do not actually use it`);return e[1].required&&!t[1].required?-1:!e[1].required&&t[1].required?1:e[0].localeCompare(t[0])})),f
|
|
12
|
-
`));for(let[t,r]of a){let a=`${t.padEnd(s)} ${r.description}`,c=i(a,getMaxLineWidth()-s-2),l=n(c,s+2+2).trim();e.push(` ${l}`)}e.push(``)}pushFlags(e,a){if(!a.size)return;e.push(t.bold(`FLAGS`));let s
|
|
11
|
+
`).trim()}pushUsageString(e){e.push(t.bold(`USAGE`));let r=`$ ${this.entrypoint} ${this.command.name}`,a=2+re(r),s=[r],c=Object.entries(this.command.args??{});if(c.length)for(let[e,t]of c){if(typeof t==`string`)throw RangeError(`This is a type-check only value, do not actually use it`);this.pushNewLineBeforeNewEntryIfLengthIsPastTheLimit({state:s,itemToAdd:t.required?`<${e}>`:`[${e}]`,indentSize:a})}let l=Object.entries(this.command.flags??{}).filter(([,e])=>{if(typeof e==`string`)throw RangeError(`This is a type-check only value, do not actually use it`);return!e.hidden});this.command.enableJsonFlag&&l.push([`json`,{choices:null,flagTag:`boolean`,hasDefault:!1,required:!1,stdin:null,builder:null,aliases:void 0,char:void 0,description:`Format the command output as JSON.`,hidden:void 0,exclusive:void 0}]);let u=new Map(l.sort((e,t)=>{if(typeof e[1]==`string`||typeof t[1]==`string`)throw RangeError(`This is a type-check only value, do not actually use it`);return e[1].required&&!t[1].required?-1:!e[1].required&&t[1].required?1:e[0].localeCompare(t[0])})),f=/* @__PURE__ */ new Set;if(l.length)for(let[e,t]of u){if(typeof t==`string`)throw RangeError(`This is a type-check only value, do not actually use it`);if(f.has(e))continue;let n=t.required,r=[this.makeFlagString(e,t)];if(t.exclusive?.length)for(let e of t.exclusive){f.add(e);let t=u.get(e),i=this.makeFlagString(e,t);r.push(i),t.required&&(n=!0)}this.pushNewLineBeforeNewEntryIfLengthIsPastTheLimit({state:s,itemToAdd:n?r.join(` | `):`[${r.join(` | `)}]`,indentSize:a})}let p=i(s.join(` `),getMaxLineWidth()-a),m=n(p,a+1).trim();e.push(` ${m}`,``),c.length&&this.pushArguments(e,c),l.length&&this.pushFlags(e,u)}pushArguments(e,a){if(!a.length)return;e.push(t.bold(`ARGUMENTS`));let s=r(a.map(([e])=>e).join(`
|
|
12
|
+
`));for(let[t,r]of a){let a=`${t.padEnd(s)} ${r.description}`,c=i(a,getMaxLineWidth()-s-2),l=n(c,s+2+2).trim();e.push(` ${l}`)}e.push(``)}pushFlags(e,a){if(!a.size)return;e.push(t.bold(`FLAGS`));let s=/* @__PURE__ */ new Map;for(let[e,n]of a){let r=[];switch(n.char?r.push(`-${n.char},`):r.push(` `.repeat(3)),n.flagTag){case`boolean`:r.push(`--${this.kebabFlagName(e)}`);break;case`string`:case`integer`:{let i=n.choices?`<option>`:`<value>`;r.push(`--${this.kebabFlagName(e)}=${t.underline(i)}`);break}default:throw Error(`Unhandled flag tag: ${n.flagTag}`)}s.set(r.join(` `),n)}let c=r([...s.keys()].map(ie).join(`
|
|
13
13
|
`));for(let[t,r]of s){let a=c-ie(t).length,s=`${t}${` `.repeat(a)} ${r.description??``}`;r.choices?.length&&(s+=`\n<options: ${r.choices.join(`|`)}>`);let l=i(s,getMaxLineWidth()-c),u=n(l,c).trim().split(`
|
|
14
14
|
`).map(e=>/^-[a-z]/.test(e.trim())?e:` ${e}`).join(`
|
|
15
15
|
`);e.push(` ${u}`)}e.push(``)}},CommandWithSubcommandsHelp=class extends BaseCommandRenderer{render(){let e=[];return this.pushShortDescription(e),this.command.description&&this.pushDescription(e),this.pushSubcommands(e),this.pushExamples(e),this.pushInteractiveNote(e),this.pushLearnMore(e),e.join(`
|
|
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 Ut
|
|
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 Ut=/* @__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){Ut.set(t,new CommandWithSubcommandsHelp(e,t));for(let n of t.subcommands)registerCommandForHelpGeneration(`${e} ${t.name}`,n)}else Ut.set(t,new CommandHelp(e,t))}function renderHelpForCommand(e){let t=Ut.get(e);if(!t)throw Error(`No help renderer found for command ${e.name}`);return t.render()}function selectiveRenderHelpForCommand(e,t){let n=Ut.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 Wt=[`Local Actor Development`,`Apify Console`,`Authentication`,`Utilities`],Gt=`Other`,Kt=[{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"`}],qt=[{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 Ut)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||Gt;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 Wt)l.has(e)&&u.push(e);let f=[...l.keys()].filter(e=>!Wt.includes(e)&&e!==Gt).sort();u.push(...f),l.has(Gt)&&u.push(Gt);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`?qt:Kt;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(`
|
|
23
23
|
`);s.push(t.dim(n(a,2)))}s.push(` $ ${r.command}`),r.description&&e<h.length-1&&s.push(``)}s.push(``)}return s.push(t.bold(`LEARN MORE`),` Use '${e} <command> --help' for more information about a command.`,` Read the docs at https://docs.apify.com/cli.`,` Run '${e} help --skill' to print the Apify CLI agent skill (guidance for driving 'apify' from agents).`,``),s.push(t.bold(`TROUBLESHOOTING`),` For general support, reach out to us at https://apify.com/contact.`,` If you believe you are encountering a bug, file it at https://github.com/apify/apify-cli/issues/new.`),s.join(`
|
|
24
|
-
`).trim()}let Jt
|
|
24
|
+
`).trim()}let Jt=/* @__PURE__ */ function(e){return e[e.NODEJS_ERR_PARSE_ARGS_INVALID_OPTION_VALUE=0]=`NODEJS_ERR_PARSE_ARGS_INVALID_OPTION_VALUE`,e[e.NODEJS_ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL=1]=`NODEJS_ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL`,e[e.NODEJS_ERR_PARSE_ARGS_UNKNOWN_OPTION=2]=`NODEJS_ERR_PARSE_ARGS_UNKNOWN_OPTION`,e[e.APIFY_FLAG_PROVIDED_MULTIPLE_TIMES=3]=`APIFY_FLAG_PROVIDED_MULTIPLE_TIMES`,e[e.APIFY_INVALID_FLAG_INTEGER_VALUE=4]=`APIFY_INVALID_FLAG_INTEGER_VALUE`,e[e.APIFY_INVALID_CHOICE=5]=`APIFY_INVALID_CHOICE`,e[e.APIFY_MISSING_FLAG=6]=`APIFY_MISSING_FLAG`,e[e.APIFY_FLAG_IS_EXCLUSIVE_WITH_ANOTHER_FLAG=7]=`APIFY_FLAG_IS_EXCLUSIVE_WITH_ANOTHER_FLAG`,e[e.APIFY_TOO_MANY_REQUESTERS_OF_STDIN=8]=`APIFY_TOO_MANY_REQUESTERS_OF_STDIN`,e[e.APIFY_UNKNOWN_ERROR=9]=`APIFY_UNKNOWN_ERROR`,e}({});var W=class CommandError extends Error{code;command;metadata;constructor({code:e,message:t=``,metadata:n={},command:r}){super(t||String(Jt[e])),this.code=e,this.metadata=n,this.command=r}extractFlagNameFromMessage(){switch(this.code){case 0:{let e=/'(?:-[a-z], )?-?-(?<flagName>[a-zA-Z-]+)(?: <value>)?' (?<noArg>does not take)?(?<missingArg>argument missing)?(?<ambiguous>argument is ambiguous\.(?<ambiguousMessage>\s*.*\s*.*)?)?/gi.exec(this.message);if(!e)throw Error(`Encountered unparsable error message from argument parser: ${this.message}.\n\nPlease report this issue at https://github.com/apify/apify-cli/issues`);return{name:e.groups.flagName,expectsValue:e.groups.noArg===void 0,ambiguousFlag:e.groups.ambiguous?e.groups.ambiguous:void 0,ambiguousMessage:e.groups.ambiguousMessage?e.groups.ambiguousMessage.trim():void 0}}case 2:{let e=/Unknown option '-(?<longForm>-)?(?<optionName>.+)'\.(?<nodeSuggestion>.*)/gi.exec(this.message);if(!e)throw Error(`Encountered unparsable error message from argument parser: ${this.message}.\n\nPlease report this issue at https://github.com/apify/apify-cli/issues`);return{name:e.groups.optionName,expectsValue:!1,unknownOptionSuggestion:e.groups.nodeSuggestion,shortForm:!e.groups.longForm}}default:throw Error(`Not implemented`)}}getPrettyMessage(){switch(this.code){case 0:{let e=this.extractFlagNameFromMessage();return CommandError.buildMessageFromFlagData(e)}case 2:{let e=this.extractFlagNameFromMessage(),n=selectiveRenderHelpForCommand(this.command,{showUsageString:!0});return[t.gray(`Unknown flag provided: ${t.white.bold(e.shortForm?`-${e.name}`:`--${e.name}`)}`),e.unknownOptionSuggestion?t.gray(` ${e.unknownOptionSuggestion.trim()}`):null,``,n].filter(e=>e!==null).join(`
|
|
25
25
|
`)}case 3:{let e=`--${this.metadata.flag}`;return t.gray(`Flag ${t.white.bold(e)} can only be specified once.`)}case 4:{let e=`--${this.metadata.flag}`,n=t.whiteBright(String(this.metadata.value));return t.gray(`The provided value for the '${t.white.bold(e)}' flag could not be processed as an integer. Received: ${n}.`)}case 6:{let{flag:e,matcher:n,providedButReceivedNoValue:r}=this.metadata,i=`'${t.white.bold(`--${e}`)}'`;return n&&(i=`${i} (alias used: '${t.white.bold(`--${n}`)}')`),r?t.gray(`Flag ${i} was provided, but no value was received. Did you mean to pass the value as an argument or through standard input?`):t.gray(`Flag ${i} is required, but was not provided.`)}case 7:{let{flagPairs:e}=this.metadata,n=[t.gray(`The following errors occurred:`)],r=t.red(` > `);for(let[i,a]of e)n.push(t.gray(`${r}${t.white.bold(i)} cannot also be provided when using ${t.white.bold(a)}`));return n.push(t.gray(`${r}See more help with ${t.white.bold(`--help`)}`)),n.join(`
|
|
26
26
|
`)}case 8:{let{firstUse:e,secondUse:n}=this.metadata;return t.gray(`Flag ${t.white.bold(`--${e}`)} and ${t.white.bold(`--${n}`)} cannot both request that their value comes from standard input at the same time.`)}case 5:{let e=`--${this.metadata.flag}`,n=this.metadata.choices;return t.gray(`Invalid value for flag ${t.white.bold(e)}. Expected one of: ${n}`)}default:{let e=useCLIMetadata();return[`The CLI encountered an unhandled argument parsing error!`,`Please report this issue at https://github.com/apify/apify-cli/issues, and provide the following information:`,``,`- Error code: ${this.code} (${Jt[this.code]})`,`- Error metadata: ${JSON.stringify(this.metadata)}`,``,`- Stack:\n${this.stack}`,``,`- Arguments (!!!only provide these as is if there is no sensitive information!!!):`,` ${JSON.stringify(process.argv.slice(2))}`,``,`- CLI version: \`${e.fullVersionString}\``,`- CLI debug logs (process.env.APIFY_CLI_DEBUG): ${process.env.APIFY_CLI_DEBUG?`Enabled`:`Disabled`}`,`- Stdin data? ${fn?`Yes`:`No`}`].join(`
|
|
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 Yt=_(O);let Xt;async function useStdin(){if(Xt)return Xt;let t=e.stdin,n={isTTY:t.isTTY,hasData:!1,waitDelay:0,stream:t},r=await Yt(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&w.S_IFIFO)===w.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),Xt=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 ae(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 Zt={node:`>=22`};const Qt=`storage`,$t={actorSpecification:1,name:null,version:`0.0`,buildTag:`latest`,environmentVariables:{}},en=Date.UTC(2026,9,1),tn=[`SIGINT`,`SIGTERM`,`SIGHUP`],GLOBAL_CONFIGS_FOLDER=()=>{let t=u(oe(),`.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`),nn=`.actor`,G=u(nn,`actor.json`),rn=Zt.node,an=ce.GITHUB_ACTIONS?`${e.env.GITHUB_SERVER_URL}/${e.env.GITHUB_REPOSITORY}/actions/runs/${e.env.GITHUB_RUN_ID}`:void 0,on={"X-Apify-Request-Origin":ce.isCI?_e.CI:_e.CLI,...an&&{"X-Apify-Github-Actions-Run-Url":an}},sn=`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 cn={version:1};function useLocalState(){let e=STATE_FILE_PATH();if(!D(e))return cn;let t=JSON.parse(j(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);k(i,{recursive:!0}),F(STATE_FILE_PATH(),JSON.stringify(n,null,` `))}const ln=useCLIMetadata(),un=`Apify CLI/${ln.version} (https://github.com/apify/apify-cli)`,dn=[`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(dn.map(async e=>fetch(e,{signal:t.signal,headers:{"User-Agent":un},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":un}});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:ln.version,latestVersion:`unknown`,shouldUpdate:!1,cacheHit:!1};let a=v(i,ln.version);return{currentVersion:ln.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=be(n,r),l=ye(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 fn=await readStdin(),pn=useCLIMetadata(),mn=`Apify CLI/${pn.version} (https://github.com/apify/apify-cli)`;function processVersionCheck(t){pn.installMethod!==`bundle`&&(x(e.version,rn)||(error({message:`${t} CLI requires Node.js version ${rn}. Your current version is ${e.version}.`}),e.exit(1)))}function printCLIVersionAndExitIfFlagUsed(t){t.values.version===!0&&t.positionals.length===0&&(console.log(pn.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
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`,{...pn,fullVersionString:pn.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:W.into(t,u).getPrettyMessage()}),e.exit(1)}}const hn={output:e.stderr},gn=`confirm`,_n=`no-${gn}`;function stdinCheckWrapper(e,{errorMessageForStdin:t=`Please use the --${gn}/--${_n} flags to confirm the action.`}={}){return async(n,...r)=>{let{isTTY:i,hasData:a}=await useStdin(),s=n;if(le||!i&&!a){if(s.providedConfirmFromStdin===void 0)throw Error(s.errorMessageForStdin??t);return s.providedConfirmFromStdin}return await e(n,...r)}}const vn=stdinCheckWrapper(async({message:e,validate:t,default:n})=>await Fe({message:e,validate:t,default:n},hn),{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=j(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 D(u(e,`scrapy.cfg`))}async init(){await this.loadSettings()}loadScrapyCfg(){let e=new Pe,t=p(u(this.pathname,`scrapy.cfg`));if(!D(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 vn({message:`Enter the Scrapy BOT_NAME (see settings.py):`,default:e}),n=await vn({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=ee(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 yn
|
|
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 vn({message:`Enter the Scrapy BOT_NAME (see settings.py):`,default:e}),n=await vn({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=ee(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 yn=/* @__PURE__ */ new Map,bn={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 Ee(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 Ee(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=yn.get(t);if(n)return cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!0,cwd:t,runtime:n.unwrapOr(null)}),n;for(let[e,n]of Object.entries(bn))try{let r=normalizeExecutablePath(await Ie(e)),i=await getRuntimeVersion(r,n);if(i){let n={executablePath:r,version:i};if(e===`node`){let e=normalizeExecutablePath(await Ie(`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 yn.set(t,Te(n)),cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!1,cwd:t,runtime:yn.get(t)?.unwrap()}),Te(n)}}catch{}return yn.set(t,Ce),cliDebugPrint(`useJavaScriptRuntime`,{cacheHit:!1,cwd:t,runtime:null}),Ce}const xn=/* @__PURE__ */ new Map;async function getPythonVersion(t){try{let n=await Ee(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=xn.get(t);if(r&&!n)return cliDebugPrint(`usePythonRuntime`,{cacheHit:!0,cwd:t,runtime:r.unwrapOr(null)}),r;let i=se()===`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 xn.set(t,Te({executablePath:s,version:e})),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:xn.get(t)?.unwrap()}),xn.get(t)}catch{}let c=[`python3`,`python`,...i?[`python3.exe`,`python.exe`]:[]];for(let e of c)try{let n=normalizeExecutablePath(await Ie(e)),r=await getPythonVersion(n);if(r)return xn.set(t,Te({executablePath:n,version:r})),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:xn.get(t)?.unwrap()}),xn.get(t)}catch{}return xn.set(t,Ce),cliDebugPrint(`usePythonRuntime`,{cacheHit:!1,cwd:t,runtime:null}),Ce}const Sn=/* @__PURE__ */ new Map;async function useCwdProject({cwd:t=e.cwd()}={}){let n=Sn.get(t);if(n)return cliDebugPrint(`useCwdProject`,{cacheHit:!0,project:n}),we(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 Se({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 we(r)},i=await check();return i?.isErr()?(cliDebugPrint(`useCwdProject`,{cacheHit:!1,error:i}),i):(cliDebugPrint(`useCwdProject`,{cacheHit:!1,project:r}),Sn.set(t,r),we(r))}async function checkNodeProject(e){let t=u(e,`package.json`);try{let n=await B(t,`utf-8`),r=JSON.parse(n);if(r.scripts?.start)return{type:`script`,script:`start`};if(r.main)try{return await De(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 De(e),{path:e,type:`file`}}catch{}return null}async function fileExists(e){try{return await De(e),!0}catch{return!1}}async function dirExists(e){try{return(await V(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 ke(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 ke(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 ke(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 ke(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 ke(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 ke(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(`
|
|
@@ -45,16 +45,16 @@ Common package structures:
|
|
|
45
45
|
src/
|
|
46
46
|
my_package/
|
|
47
47
|
__init__.py
|
|
48
|
-
main.py`);return null}async function checkScrapyProject(e){return ScrapyProjectAnalyzer.isApplicable(e)}function normalizeExecutablePath(e){return e?e.startsWith(`"`)?e:l(e)&&e.includes(` `)?`"${e}"`:e:null}async function getInstallCommandSuggestion(e){let t=null;return await(await useCwdProject({cwd:e})).inspectAsync(async n=>{if(n.type===0){let[r,i,a,s]=await Promise.all([V(u(e,`yarn.lock`)).then(()=>!0).catch(()=>!1),V(u(e,`pnpm-lock.yaml`)).then(()=>!0).catch(()=>!1),V(u(e,`bun.lockb`)).then(()=>!0).catch(()=>!1),V(u(e,`bun.lock`)).then(()=>!0).catch(()=>!1)]);t=r?`yarn install`:i?`pnpm install`:a||s||n.runtime?.pmName===`bun`?`bun install`:n.runtime?.pmName===`deno`?`deno install --node-modules-dir`:`npm install`}else(n.type===1||n.type===2)&&(t=n.packageManager===`uv`?`uv sync`:`python -m pip install -r requirements.txt`)}),t}let Cn=`inherit`;function keepStdoutClean(){Cn=e.stderr}const spawnPromised=async(t,n,r,{forwardSignals:i}={})=>{let a=normalizeExecutablePath(t);cliDebugPrint(`spawnPromised`,{escapedCommand:a,args:n,opts:r,forwardSignals:i});let s=Ee(a,n,{shell:!0,windowsHide:!0,env:r.env,cwd:r.cwd,stdout:e.env.APIFY_NO_LOGS_IN_TESTS?[`pipe`]:[`pipe`,Cn],stderr:e.env.APIFY_NO_LOGS_IN_TESTS?[`pipe`]:[`pipe`,`inherit`],verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0}),c=[];if(i?.length)for(let t of i){let handler=()=>{s.kill(t)};e.on(t,handler),c.push(()=>e.off(t,handler))}try{return await xe.fromAsync(s.catch(e=>{let n;throw n=e.exitCode==null?e.signal?`${t} exited due to signal ${e.signal}`:e.shortMessage:`${t} exited with code ${e.exitCode}`,Error(n,{cause:e})}))}finally{for(let e of c)e()}};async function execWithLog({cmd:e,args:t=[],opts:n={},overrideCommand:r,forwardSignals:i}){run({message:`${r||e} ${t.join(` `)}`});let a=await spawnPromised(e,t,n,{forwardSignals:i});if(a.isErr()){let e=a.unwrapErr();if(error({message:e.message}),e.cause)throw e.cause}}const wn=[[`CLAUDECODE`,`claude_code`],[`CLAUDE_CODE_ENTRYPOINT`,`claude_code`],[`CURSOR_AGENT`,`cursor`],[`CLINE_ACTIVE`,`cline`],[`CODEX_SANDBOX`,`codex_cli`],[`CODEX_THREAD_ID`,`codex_cli`],[`GEMINI_CLI`,`gemini_cli`],[`OPENCODE`,`open_code`],[`OPENCLAW_SHELL`,`openclaw`]];function detectAiAgent(){for(let[e,t]of wn)if(process.env[e])return t}function detectCi(){return ce.isCI?{isCi:!0,ciProvider:ce.id?.toLowerCase()??`unknown`}:{isCi:!1,ciProvider:void 0}}function detectIsInteractive(){return!!process.stdin.isTTY&&!!process.stdout.isTTY}const updateLocalJson=async(e,t={},n=null)=>{let r=await B(e,`utf-8`),i=JSON.parse(r),a;n?(a=i,a[n]={...i[n],...t}):a={...i,...t},await H(e,JSON.stringify(a,null,` `))},ensureFolderExistsSync=(e,t)=>{t||(t=e,e=`.`),t.split(m).reduce((e,t)=>(e=u(e,t),D(e)||k(e),e),e)},rimrafPromised=async e=>{let t=Array.isArray(e)?e:[e];await Promise.all(t.map(async e=>je(e,{recursive:!0,force:!0,maxRetries:10,retryDelay:100})))},deleteFile=async e=>{(await V(e)).isFile()&&await Ne(e)};function ensureApifyDirectory(e){let t=c(e);k(t,{recursive:!0})}const sumFilesSizeInBytes=async(e,t)=>(await Promise.all(e.map(async e=>V(u(t,e))))).map(e=>e.size).reduce((e,t)=>e+t,0),Tn=`token`,En=`proxy-password`;let Dn,On,kn;async function loadKeyringModule(){return Dn===void 0&&(Dn=await importKeyringModule()),Dn}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 On||(On=(async()=>e.env.APIFY_DISABLE_KEYRING===`1`||readAuthFile().secretsBackend===`file`?`file`:await loadKeyringModule()?`keyring`:`file`)(),On)}function downgradeBackendToFile(){On=Promise.resolve(`file`)}function readAuthFile(){if(!D(AUTH_FILE_PATH()))return{};try{let e=j(AUTH_FILE_PATH(),`utf-8`);return JSON.parse(e)}catch{return{}}}function stripProxyPassword(e){e.proxy&&(delete e.proxy.password,Object.keys(e.proxy).length===0&&delete e.proxy)}function writeAuthFile(e){ensureApifyDirectory(AUTH_FILE_PATH()),F(AUTH_FILE_PATH(),JSON.stringify(e,null,` `),{mode:384})}async function getKeyringEntry(e){let t=await loadKeyringModule();return t?new t.Entry(`com.apify.cli`,e):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} 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);if(!t)return;t.deletePassword()}catch(t){cliDebugPrint(`credentials`,`failed to delete ${e} from keyring`,t)}}async function getToken(){return await getBackend()===`keyring`?readKeyring(Tn):readAuthFile().token}async function getProxyPassword(){return await getBackend()===`keyring`?readKeyring(En):readAuthFile().proxy?.password}async function setToken(e,t={}){let n=await getBackend();if(t.skipIfUnchanged&&(n===`keyring`?await readKeyring(Tn):readAuthFile().token)===e)return;if(n===`keyring`)try{await writeKeyring(Tn,e);return}catch(e){cliDebugPrint(`credentials`,`keyring write failed; falling back to file`,e),downgradeBackendToFile()}let r=readAuthFile();r.token=e,r.secretsBackend=`file`,writeAuthFile(r)}async function setProxyPassword(e,t={}){let n=await getBackend();if(t.skipIfUnchanged&&(n===`keyring`?await readKeyring(En):readAuthFile().proxy?.password)===e)return;if(n===`keyring`)try{await writeKeyring(En,e);return}catch(e){cliDebugPrint(`credentials`,`keyring write failed; falling back to file`,e),downgradeBackendToFile()}let r=readAuthFile();r.proxy={...r.proxy,password:e},r.secretsBackend=`file`,writeAuthFile(r)}async function deleteProxyPassword(){if(await getBackend()===`keyring`){await deleteKeyring(En);return}let e=readAuthFile();e.proxy?.password&&(stripProxyPassword(e),writeAuthFile(e))}async function clearKeyringSecrets(){await deleteKeyring(Tn),await deleteKeyring(En)}async function ensureMigrated(){return kn||(kn=(async()=>{try{let e=readAuthFile();if(e.secretsBackend||!e.token&&!e.proxy?.password)return;if(await getBackend()===`file`){e.secretsBackend=`file`,writeAuthFile(e);return}try{e.token&&await writeKeyring(Tn,e.token),e.proxy?.password&&await writeKeyring(En,e.proxy.password)}catch(t){cliDebugPrint(`credentials`,`keyring write failed during migration; falling back to file`,t),downgradeBackendToFile(),e.secretsBackend=`file`,writeAuthFile(e);return}delete e.token,stripProxyPassword(e),e.secretsBackend=`keyring`,writeAuthFile(e)}catch(e){cliDebugPrint(`credentials`,`migration failed`,e)}})(),kn)}const An=new Set([`undefined`,`null`,`nil`,`none`,`nan`,`false`,`0`,`-`]);function readEnvToken(){let t=e.env[R.TOKEN]?.trim();return t?An.has(t.toLowerCase())?{kind:`invalid`,raw:t}:{kind:`token`,token:t}:{kind:`unset`}}function invalidEnvTokenMessage(e){return`${R.TOKEN} is set to "${e}", which is not an API token. Unset ${R.TOKEN} and try again.`}const jn={env:`${R.TOKEN} environment variable`,stored:`apify login`};let Mn;const resolveAuth=async()=>{Mn??=(async()=>{await ensureMigrated();let t=readEnvToken();if(t.kind===`invalid`)throw e.exitCode=5,Error(invalidEnvTokenMessage(t.raw));if(t.kind===`token`)return D(AUTH_FILE_PATH())&&warning({message:`Using the API token from ${R.TOKEN}.`}),{token:t.token,source:`env`};let n=await getToken();return n?{token:n,source:`stored`}:void 0})();try{return await Mn}catch(e){throw Mn=void 0,e}};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 qe?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 ${R.TOKEN} was rejected. Unset it to use your stored login instead.`;default:return`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 Ze;for(let[t,n]of Object.entries(on))e.headers[t]=n;return e}]}),getApifyClientOptionsForToken=(e,t)=>({...getAnonymousApifyClientOptions(t),token:e});async function loginWithToken(e,t){let n=new Je(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}let i=r.proxy?.password,a={...r,secretsBackend:await getBackend()};return stripProxyPassword(a),ensureApifyDirectory(AUTH_FILE_PATH()),F(AUTH_FILE_PATH(),JSON.stringify(a,null,` `),{mode:384}),await setToken(e,{skipIfUnchanged:!0}),i?await setProxyPassword(i,{skipIfUnchanged:!0}):await deleteProxyPassword(),{client:n,userInfo:r}}const Nn=`__CLI_`;function resolveInputKey(){return process.env[I.INPUT_KEY]||process.env[R.INPUT_KEY]||process.env.CRAWLEE_INPUT_KEY||`INPUT`}function inputFileRegExp(e){return RegExp(`(^${Qe(e)}(?:\\.[^.]+)?$)`)}const Pn=`__metadata__.json`,Fn=`.${Pn}`;function encodeRecordKey(e){return encodeURIComponent(e).replaceAll(/[!'()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}const recordMetadataFileName=e=>`${encodeRecordKey(e)}${Fn}`;async function writeKvsRecord({storePath:e,key:t,fileName:n,contentType:r,body:i}){let a={key:t,contentType:r};n!==encodeRecordKey(t)&&(a.filename=n),await Promise.all([H(u(e,n),i),H(u(e,recordMetadataFileName(t)),JSON.stringify(a,null,2))])}function readKvsRecordMetadata(e,t){let n;try{n=JSON.parse(j(u(e,recordMetadataFileName(t)),`utf8`))}catch{return}if(typeof n?.contentType!=`string`)return;let{filename:r}=n;return r===void 0||typeof r==`string`&&![``,`.`,`..`].includes(r)&&s(r)===r&&r!==Pn&&!r.endsWith(Fn)?n:void 0}async function deleteKvsRecord(e,t){await Promise.all([je(e,{force:!0}),je(u(c(e),recordMetadataFileName(t)),{force:!0})])}const In=$e,Ln=Ke,getLocalStorageDir=()=>{let t=R.LOCAL_STORAGE_DIR;return e.env[t]||e.env.CRAWLEE_STORAGE_DIR||`storage`},getLocalKeyValueStorePath=t=>{let n=I.DEFAULT_KEY_VALUE_STORE_ID,r=t||e.env[n]||me[n];return u(getLocalStorageDir(),he.keyValueStores,r)},getLocalDatasetPath=t=>{let n=I.DEFAULT_DATASET_ID,r=t||e.env[n]||me[n];return u(getLocalStorageDir(),he.datasets,r)},getLocalRequestQueuePath=t=>{let n=I.DEFAULT_REQUEST_QUEUE_ID,r=t||e.env[n]||me[n];return u(getLocalStorageDir(),he.requestQueues,r)},getLocalUserInfo=async()=>{await ensureMigrated();let e={};try{let t=await B(AUTH_FILE_PATH(),`utf-8`);e=JSON.parse(t)}catch{}if(await getBackend()===`keyring`){let t=await getToken();t&&(e.token=t);let n=await getProxyPassword();n&&(e.proxy={...e.proxy,password:n})}let t=!!(e.username||e.id);if(!(t||e.token))return{};if(!t)throw Error(`Stale credentials found without user metadata. Please run "apify login" again.`);return e};async function getLoggedClientOrThrow(){let{client:t,auth:n,error:r}=await getLoggedClient();if(!t)throw e.exitCode=1,Error(describeAuthFailure(n,r));return t}let Rn;async function getLoggedClient(){let e=await resolveAuth();if(!e)return{client:null};let t=new Je(getApifyClientOptionsForToken(e.token));try{let n=await t.user(`me`).get();Rn={token:e.token,userInfo:n}}catch(t){return cliDebugPrint(`[getLoggedClient] error getting user info`,{error:t}),{client:null,auth:e,error:t}}return{client:t,auth:e}}async function getCurrentUserInfo(){let e=await resolveAuth();if(!e)return getLocalUserInfo();if(Rn?.token===e.token)return Rn.userInfo;if(e.source===`stored`)return getLocalUserInfo();let t=await new Je({...getApifyClientOptionsForToken(e.token),maxRetries:1,timeoutSecs:10}).user(`me`).get();return Rn={token:e.token,userInfo:t},t}const getLocalConfigPath=e=>u(e,G),getJsonFileContent=e=>{if(D(e))return JSON.parse(j(e,{encoding:`utf-8`}))},getLocalConfig=e=>getJsonFileContent(getLocalConfigPath(e)),setLocalConfig=async(t,n)=>{let r=u(n||e.cwd(),G);await z(c(r),{recursive:!0}),F(r,JSON.stringify(t,null,` `))},zn=[getLocalStorageDir(),`node_modules`,`.venv`],setLocalEnv=async e=>{let t=getLocalKeyValueStorePath();ensureFolderExistsSync(e,getLocalDatasetPath()),ensureFolderExistsSync(e,getLocalRequestQueuePath()),ensureFolderExistsSync(e,t);let n=u(e,`.gitignore`),r=``;D(n)&&(r=j(n,{encoding:`utf-8`}));let i=[];for(let e of zn)RegExp(`^${Qe(e)}$`,`mg`).test(r)||i.push(e);i.length>0&&(r.length>0?(i.unshift(`# Added by Apify CLI`),F(n,`\n${i.join(`
|
|
48
|
+
main.py`);return null}async function checkScrapyProject(e){return ScrapyProjectAnalyzer.isApplicable(e)}function normalizeExecutablePath(e){return e?e.startsWith(`"`)?e:l(e)&&e.includes(` `)?`"${e}"`:e:null}async function getInstallCommandSuggestion(e){let t=null;return await(await useCwdProject({cwd:e})).inspectAsync(async n=>{if(n.type===0){let[r,i,a,s]=await Promise.all([V(u(e,`yarn.lock`)).then(()=>!0).catch(()=>!1),V(u(e,`pnpm-lock.yaml`)).then(()=>!0).catch(()=>!1),V(u(e,`bun.lockb`)).then(()=>!0).catch(()=>!1),V(u(e,`bun.lock`)).then(()=>!0).catch(()=>!1)]);t=r?`yarn install`:i?`pnpm install`:a||s||n.runtime?.pmName===`bun`?`bun install`:n.runtime?.pmName===`deno`?`deno install --node-modules-dir`:`npm install`}else(n.type===1||n.type===2)&&(t=n.packageManager===`uv`?`uv sync`:`python -m pip install -r requirements.txt`)}),t}let Cn=`inherit`;function keepStdoutClean(){Cn=e.stderr}const spawnPromised=async(t,n,r,{forwardSignals:i}={})=>{let a=normalizeExecutablePath(t);cliDebugPrint(`spawnPromised`,{escapedCommand:a,args:n,opts:r,forwardSignals:i});let s=Ee(a,n,{shell:!0,windowsHide:!0,env:r.env,cwd:r.cwd,stdout:e.env.APIFY_NO_LOGS_IN_TESTS?[`pipe`]:[`pipe`,Cn],stderr:e.env.APIFY_NO_LOGS_IN_TESTS?[`pipe`]:[`pipe`,`inherit`],verbose:e.env.APIFY_CLI_DEBUG?`full`:void 0}),c=[];if(i?.length)for(let t of i){let handler=()=>{s.kill(t)};e.on(t,handler),c.push(()=>e.off(t,handler))}try{return await xe.fromAsync(s.catch(e=>{let n;throw n=e.exitCode==null?e.signal?`${t} exited due to signal ${e.signal}`:e.shortMessage:`${t} exited with code ${e.exitCode}`,Error(n,{cause:e})}))}finally{for(let e of c)e()}};async function execWithLog({cmd:e,args:t=[],opts:n={},overrideCommand:r,forwardSignals:i}){run({message:`${r||e} ${t.join(` `)}`});let a=await spawnPromised(e,t,n,{forwardSignals:i});if(a.isErr()){let e=a.unwrapErr();if(error({message:e.message}),e.cause)throw e.cause}}const wn=[[`CLAUDECODE`,`claude_code`],[`CLAUDE_CODE_ENTRYPOINT`,`claude_code`],[`CURSOR_AGENT`,`cursor`],[`CLINE_ACTIVE`,`cline`],[`CODEX_SANDBOX`,`codex_cli`],[`CODEX_THREAD_ID`,`codex_cli`],[`GEMINI_CLI`,`gemini_cli`],[`OPENCODE`,`open_code`],[`OPENCLAW_SHELL`,`openclaw`]];function detectAiAgent(){for(let[e,t]of wn)if(process.env[e])return t}function detectCi(){return ce.isCI?{isCi:!0,ciProvider:ce.id?.toLowerCase()??`unknown`}:{isCi:!1,ciProvider:void 0}}function detectIsInteractive(){return!!process.stdin.isTTY&&!!process.stdout.isTTY}const updateLocalJson=async(e,t={},n=null)=>{let r=await B(e,`utf-8`),i=JSON.parse(r),a;n?(a=i,a[n]={...i[n],...t}):a={...i,...t},await H(e,JSON.stringify(a,null,` `))},ensureFolderExistsSync=(e,t)=>{t||(t=e,e=`.`),t.split(m).reduce((e,t)=>(e=u(e,t),D(e)||k(e),e),e)},rimrafPromised=async e=>{let t=Array.isArray(e)?e:[e];await Promise.all(t.map(async e=>je(e,{recursive:!0,force:!0,maxRetries:10,retryDelay:100})))},deleteFile=async e=>{(await V(e)).isFile()&&await Ne(e)};function ensureApifyDirectory(e){let t=c(e);k(t,{recursive:!0})}const sumFilesSizeInBytes=async(e,t)=>(await Promise.all(e.map(async e=>V(u(t,e))))).map(e=>e.size).reduce((e,t)=>e+t,0),Tn=`token`,En=`proxy-password`;let Dn,On,kn;async function loadKeyringModule(){return Dn===void 0&&(Dn=await importKeyringModule()),Dn}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 On||(On=(async()=>e.env.APIFY_DISABLE_KEYRING===`1`||readAuthFile().secretsBackend===`file`?`file`:await loadKeyringModule()?`keyring`:`file`)(),On)}function downgradeBackendToFile(){On=Promise.resolve(`file`)}function readAuthFile(){if(!D(AUTH_FILE_PATH()))return{};try{let e=j(AUTH_FILE_PATH(),`utf-8`);return JSON.parse(e)}catch{return{}}}function stripProxyPassword(e){e.proxy&&(delete e.proxy.password,Object.keys(e.proxy).length===0&&delete e.proxy)}function writeAuthFile(e){ensureApifyDirectory(AUTH_FILE_PATH()),F(AUTH_FILE_PATH(),JSON.stringify(e,null,` `),{mode:384})}async function getKeyringEntry(e){let t=await loadKeyringModule();return t?new t.Entry(`com.apify.cli`,e):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} 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);if(!t)return;t.deletePassword()}catch(t){cliDebugPrint(`credentials`,`failed to delete ${e} from keyring`,t)}}async function getToken(){return await getBackend()===`keyring`?readKeyring(Tn):readAuthFile().token}async function getProxyPassword(){return await getBackend()===`keyring`?readKeyring(En):readAuthFile().proxy?.password}async function setToken(e,t={}){let n=await getBackend();if(t.skipIfUnchanged&&(n===`keyring`?await readKeyring(Tn):readAuthFile().token)===e)return;if(n===`keyring`)try{await writeKeyring(Tn,e);return}catch(e){cliDebugPrint(`credentials`,`keyring write failed; falling back to file`,e),downgradeBackendToFile()}let r=readAuthFile();r.token=e,r.secretsBackend=`file`,writeAuthFile(r)}async function setProxyPassword(e,t={}){let n=await getBackend();if(t.skipIfUnchanged&&(n===`keyring`?await readKeyring(En):readAuthFile().proxy?.password)===e)return;if(n===`keyring`)try{await writeKeyring(En,e);return}catch(e){cliDebugPrint(`credentials`,`keyring write failed; falling back to file`,e),downgradeBackendToFile()}let r=readAuthFile();r.proxy={...r.proxy,password:e},r.secretsBackend=`file`,writeAuthFile(r)}async function deleteProxyPassword(){if(await getBackend()===`keyring`){await deleteKeyring(En);return}let e=readAuthFile();e.proxy?.password&&(stripProxyPassword(e),writeAuthFile(e))}async function clearKeyringSecrets(){await deleteKeyring(Tn),await deleteKeyring(En)}async function ensureMigrated(){return kn||(kn=(async()=>{try{let e=readAuthFile();if(e.secretsBackend||!e.token&&!e.proxy?.password)return;if(await getBackend()===`file`){e.secretsBackend=`file`,writeAuthFile(e);return}try{e.token&&await writeKeyring(Tn,e.token),e.proxy?.password&&await writeKeyring(En,e.proxy.password)}catch(t){cliDebugPrint(`credentials`,`keyring write failed during migration; falling back to file`,t),downgradeBackendToFile(),e.secretsBackend=`file`,writeAuthFile(e);return}delete e.token,stripProxyPassword(e),e.secretsBackend=`keyring`,writeAuthFile(e)}catch(e){cliDebugPrint(`credentials`,`migration failed`,e)}})(),kn)}const An=/* @__PURE__ */ new Set([`undefined`,`null`,`nil`,`none`,`nan`,`false`,`0`,`-`]);function readEnvToken(){let t=e.env[R.TOKEN]?.trim();return t?An.has(t.toLowerCase())?{kind:`invalid`,raw:t}:{kind:`token`,token:t}:{kind:`unset`}}function invalidEnvTokenMessage(e){return`${R.TOKEN} is set to "${e}", which is not an API token. Unset ${R.TOKEN} and try again.`}const jn={env:`${R.TOKEN} environment variable`,stored:`apify login`};let Mn;const resolveAuth=async()=>{Mn??=(async()=>{await ensureMigrated();let t=readEnvToken();if(t.kind===`invalid`)throw e.exitCode=5,Error(invalidEnvTokenMessage(t.raw));if(t.kind===`token`)return D(AUTH_FILE_PATH())&&warning({message:`Using the API token from ${R.TOKEN}.`}),{token:t.token,source:`env`};let n=await getToken();return n?{token:n,source:`stored`}:void 0})();try{return await Mn}catch(e){throw Mn=void 0,e}};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 qe?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 ${R.TOKEN} was rejected. Unset it to use your stored login instead.`;default:return`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 Ze;for(let[t,n]of Object.entries(on))e.headers[t]=n;return e}]}),getApifyClientOptionsForToken=(e,t)=>({...getAnonymousApifyClientOptions(t),token:e});async function loginWithToken(e,t){let n=new Je(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}let i=r.proxy?.password,a={...r,secretsBackend:await getBackend()};return stripProxyPassword(a),ensureApifyDirectory(AUTH_FILE_PATH()),F(AUTH_FILE_PATH(),JSON.stringify(a,null,` `),{mode:384}),await setToken(e,{skipIfUnchanged:!0}),i?await setProxyPassword(i,{skipIfUnchanged:!0}):await deleteProxyPassword(),{client:n,userInfo:r}}const Nn=`__CLI_`;function resolveInputKey(){return process.env[I.INPUT_KEY]||process.env[R.INPUT_KEY]||process.env.CRAWLEE_INPUT_KEY||`INPUT`}function inputFileRegExp(e){return RegExp(`(^${Qe(e)}(?:\\.[^.]+)?$)`)}const Pn=`__metadata__.json`,Fn=`.${Pn}`;function encodeRecordKey(e){return encodeURIComponent(e).replaceAll(/[!'()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}const recordMetadataFileName=e=>`${encodeRecordKey(e)}${Fn}`;async function writeKvsRecord({storePath:e,key:t,fileName:n,contentType:r,body:i}){let a={key:t,contentType:r};n!==encodeRecordKey(t)&&(a.filename=n),await Promise.all([H(u(e,n),i),H(u(e,recordMetadataFileName(t)),JSON.stringify(a,null,2))])}function readKvsRecordMetadata(e,t){let n;try{n=JSON.parse(j(u(e,recordMetadataFileName(t)),`utf8`))}catch{return}if(typeof n?.contentType!=`string`)return;let{filename:r}=n;return r===void 0||typeof r==`string`&&![``,`.`,`..`].includes(r)&&s(r)===r&&r!==Pn&&!r.endsWith(Fn)?n:void 0}async function deleteKvsRecord(e,t){await Promise.all([je(e,{force:!0}),je(u(c(e),recordMetadataFileName(t)),{force:!0})])}const In=$e,Ln=Ke,getLocalStorageDir=()=>{let t=R.LOCAL_STORAGE_DIR;return e.env[t]||e.env.CRAWLEE_STORAGE_DIR||`storage`},getLocalKeyValueStorePath=t=>{let n=I.DEFAULT_KEY_VALUE_STORE_ID,r=t||e.env[n]||me[n];return u(getLocalStorageDir(),he.keyValueStores,r)},getLocalDatasetPath=t=>{let n=I.DEFAULT_DATASET_ID,r=t||e.env[n]||me[n];return u(getLocalStorageDir(),he.datasets,r)},getLocalRequestQueuePath=t=>{let n=I.DEFAULT_REQUEST_QUEUE_ID,r=t||e.env[n]||me[n];return u(getLocalStorageDir(),he.requestQueues,r)},getLocalUserInfo=async()=>{await ensureMigrated();let e={};try{let t=await B(AUTH_FILE_PATH(),`utf-8`);e=JSON.parse(t)}catch{}if(await getBackend()===`keyring`){let t=await getToken();t&&(e.token=t);let n=await getProxyPassword();n&&(e.proxy={...e.proxy,password:n})}let t=!!(e.username||e.id);if(!(t||e.token))return{};if(!t)throw Error(`Stale credentials found without user metadata. Please run "apify login" again.`);return e};async function getLoggedClientOrThrow(){let{client:t,auth:n,error:r}=await getLoggedClient();if(!t)throw e.exitCode=1,Error(describeAuthFailure(n,r));return t}let Rn;async function getLoggedClient(){let e=await resolveAuth();if(!e)return{client:null};let t=new Je(getApifyClientOptionsForToken(e.token));try{let n=await t.user(`me`).get();Rn={token:e.token,userInfo:n}}catch(t){return cliDebugPrint(`[getLoggedClient] error getting user info`,{error:t}),{client:null,auth:e,error:t}}return{client:t,auth:e}}async function getCurrentUserInfo(){let e=await resolveAuth();if(!e)return getLocalUserInfo();if(Rn?.token===e.token)return Rn.userInfo;if(e.source===`stored`)return getLocalUserInfo();let t=await new Je({...getApifyClientOptionsForToken(e.token),maxRetries:1,timeoutSecs:10}).user(`me`).get();return Rn={token:e.token,userInfo:t},t}const getLocalConfigPath=e=>u(e,G),getJsonFileContent=e=>{if(D(e))return JSON.parse(j(e,{encoding:`utf-8`}))},getLocalConfig=e=>getJsonFileContent(getLocalConfigPath(e)),setLocalConfig=async(t,n)=>{let r=u(n||e.cwd(),G);await z(c(r),{recursive:!0}),F(r,JSON.stringify(t,null,` `))},zn=[getLocalStorageDir(),`node_modules`,`.venv`],setLocalEnv=async e=>{let t=getLocalKeyValueStorePath();ensureFolderExistsSync(e,getLocalDatasetPath()),ensureFolderExistsSync(e,getLocalRequestQueuePath()),ensureFolderExistsSync(e,t);let n=u(e,`.gitignore`),r=``;D(n)&&(r=j(n,{encoding:`utf-8`}));let i=[];for(let e of zn)RegExp(`^${Qe(e)}$`,`mg`).test(r)||i.push(e);i.length>0&&(r.length>0?(i.unshift(`# Added by Apify CLI`),F(n,`\n${i.join(`
|
|
49
49
|
`)}\n`,{flag:`a`})):F(n,`${i.join(`
|
|
50
50
|
`)}\n`,{flag:`w`}))},Bn=new nt(it,rt).define({"application/gzip":[`tgz`],"text/typescript":[`ts`,`tsx`,`mts`]},!0),getSourceFileFormat=(e,t)=>{let n=Bn.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`)?ve.TEXT:ve.BASE64:et(t)===`binary`?ve.BASE64:ve.TEXT},createSourceFiles=async(e,t)=>e.map(e=>{let n=j(u(t,e)),r=getSourceFileFormat(e,n);return{name:e,format:r,content:r===ve.TEXT?n.toString(`utf8`):n.toString(`base64`)}}),getGitignoreFallbackFilter=async e=>{let t=await at(`**/.gitignore`,{dot:!0,cwd:e,ignore:[`.git/**`],expandDirectories:!1}),n=[];for(let r of t){let t=c(r),i=await B(u(e,r),`utf-8`);n.push({dir:t===`.`?``:t,ig:In().add(i)})}let r=c(e);for(;r!==c(r)&&!D(u(r,`.git`));){let t=u(r,`.gitignore`);if(D(t))try{let i=await B(t,`utf-8`),a=f(r,e);n.push({dir:``,ig:In().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(!D(t))return{excludeFilter:null,forceIncludePatterns:[]};let n=(await B(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=In().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=ze(`git ls-files --others --ignored --exclude-standard --directory`,{cwd:n,encoding:`utf-8`,stdio:[`ignore`,`pipe`,`ignore`]}).split(`
|
|
52
52
|
`).filter(Boolean);if(e.length>0){let t=In().add(e);gitIgnoreFilter=e=>e.filter(e=>!t.ignores(e))}}catch{gitIgnoreFilter=await getGitignoreFallbackFilter(n)}let s=await at([`*`,`**/**`],{ignore:r,dot:!0,expandDirectories:!1,cwd:n}),c=gitIgnoreFilter?gitIgnoreFilter(s):s;if(i&&(c=i(c)),a.length>0){let e=In().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)=>{D(e)&&await deleteFile(e);let r=E(e),i=new Ye({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??pe.INPUT,r=p(e,getLocalKeyValueStorePath());if(!D(r))return;let i=readKvsRecordMetadata(r,n);if(i){let e=i.filename??encodeRecordKey(n);if(D(u(r,e)))return{body:j(u(r,e)),contentType:i.contentType,fileName:e}}let a=ee(r).find(e=>!!e.match(inputFileRegExp(n)));return a?{body:j(u(r,a)),contentType:Bn.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(!D(n))return;let r=ee(n),i=t.length>0?t:[pe.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 Je({baseUrl:e.env.APIFY_CLIENT_BASE_URL});if(ue.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||pe.INPUT,r=getLocalStorageDir().replaceAll(`\\`,`/`),i=getLocalKeyValueStorePath().replaceAll(`\\`,`/`);return(await at([`${r}/**`,...[n,`${Nn}${n}`].flatMap(e=>[`!${i}/${e}`,`!${i}/${e}.*`])],{cwd:e.cwd()})).length===0},validateActorName=e=>{if(!de.REGEX.test(e))throw Error(`The Actor name must be a DNS hostname-friendly string (e.g. my-newest-actor).`);if(e.length<de.MIN_LENGTH)throw Error(`The Actor name must be at least 3 characters long.`);if(e.length>de.MAX_LENGTH)throw Error(`The Actor name must be a maximum of 30 characters long.`)},sanitizeActorName=e=>{let t=e.replaceAll(/[^a-zA-Z0-9-]/g,`-`);return t.length<de.MIN_LENGTH&&(t=`${t}-apify-actor`),t=t.replaceAll(/^-+/g,``).replaceAll(/-+$/g,``),t.slice(0,de.MAX_LENGTH)},isPythonVersionSupported=e=>x(e,`^${sn}`),isNodeVersionSupported=e=>{let t=b(rn);return y(e,t)},downloadZip=async e=>{let t=await Xe.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 Ge(n)},downloadAndUnzip=async({url:e,pathTo:t})=>{(await downloadZip(e)).extractAllTo(t,!0)},K=new We(`YYYY-MM-DD [at] HH:mm:ss`),Vn=new We(`YYYY-MM-DD[
|
|
53
53
|
]HH:mm:ss`),Hn=new We(`YYYY-MM-DD`),Un=new Ve,q=new Ve({[Ue.Day]:{DEFAULT:`d`},[Ue.Hour]:{DEFAULT:`h`},[Ue.Minute]:{DEFAULT:`m`},[Ue.Month]:{DEFAULT:`M`},[Ue.Second]:{DEFAULT:`s`},[Ue.Week]:{DEFAULT:`w`},[Ue.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??oe(),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(D(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 Wn=[`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:${Re()}`}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(!D(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:Wn}),useTelemetryState()}let t=JSON.parse(j(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);k(i,{recursive:!0}),F(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 Gn=useCLIMetadata(),Kn=Gn.isBeta?`rT67mFpIQD5qS9bJBoIYSFbZucrt2DZC`:`2uPK6yhPqjC0eNUFhaY78S26cRKyaa6t`;async function trackEvent(e,t){let n=await useTelemetryIdentifiers(),r={anonymousId:n.anonymousId,context:{app:{name:`apify-cli`,version:Gn.version,build:Gn.hash},library:{name:`apify-cli`,version:Gn.version},os:{name:Gn.platform},userAgent:mn,channel:`server`},event:e,properties:{...t,app:`cli`},timestamp:new Date().toISOString(),userId:n.userId,writeKey:Kn};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>=en)}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
|
-
`)}async function getLocalUsername(){try{let e=await B(AUTH_FILE_PATH(),`utf-8`);return JSON.parse(e).username}catch{return}}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 Xe.get(r.href,{params:{username:t,pricingModel:`FLAT_PRICE_PER_MONTH`,limit:1},timeout:3e3,headers:{...on,"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:le,skipEnvValue:e.env.APIFY_CLI_SKIP_RENTAL_SUNSET_NOTICE}))return;let r=await 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 qn={type:`boolean`,multiple:!1,short:`h`},Jn={type:`boolean`,multiple:!1},Yn={type:`string`,multiple:!1},Xn=`user-agent`,Zn
|
|
54
|
+
`);function createAnonymousId(){return`CLI:${Re()}`}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(!D(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:Wn}),useTelemetryState()}let t=JSON.parse(j(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);k(i,{recursive:!0}),F(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 Gn=useCLIMetadata(),Kn=Gn.isBeta?`rT67mFpIQD5qS9bJBoIYSFbZucrt2DZC`:`2uPK6yhPqjC0eNUFhaY78S26cRKyaa6t`;async function trackEvent(e,t){let n=await useTelemetryIdentifiers(),r={anonymousId:n.anonymousId,context:{app:{name:`apify-cli`,version:Gn.version,build:Gn.hash},library:{name:`apify-cli`,version:Gn.version},os:{name:Gn.platform},userAgent:mn,channel:`server`},event:e,properties:{...t,app:`cli`},timestamp:(/* @__PURE__ */ new Date()).toISOString(),userId:n.userId,writeKey:Kn};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>=en)}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
|
+
`)}async function getLocalUsername(){try{let e=await B(AUTH_FILE_PATH(),`utf-8`);return JSON.parse(e).username}catch{return}}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 Xe.get(r.href,{params:{username:t,pricingModel:`FLAT_PRICE_PER_MONTH`,limit:1},timeout:3e3,headers:{...on,"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:le,skipEnvValue:e.env.APIFY_CLI_SKIP_RENTAL_SUNSET_NOTICE}))return;let r=await 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 qn={type:`boolean`,multiple:!1,short:`h`},Jn={type:`boolean`,multiple:!1},Yn={type:`string`,multiple:!1},Xn=`user-agent`,Zn=/* @__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,Qn=[`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 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(),Zn.has(this.entrypoint)){let t=r[Xn],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{await this.run()}catch(t){error({message:t.message}),e.exitCode||=1}finally{!this.telemetryData.actorLanguage&&Qn.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 W({code:3,command:this.ctor,metadata:{flag:l}});let h=e[m[0]];if(h===void 0&&s.required)throw new W({code:6,command:this.ctor,metadata:{flag:l,matcher:m[0]}});if(Array.isArray(h)){if(h.length>1)throw new W({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 W({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 W({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 W({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 W({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 W({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(fn?.toString(`utf8`)??``).trim();default:return fn}}_buildParseArgsOption(){let e={help:qn};Zn.has(this.entrypoint)&&(e[Xn]=Yn);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=Jn),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=`Automatic yes to prompts; assume "yes" as answer to all prompts.`){return{yes:Y.boolean({char:`y`,description:e,default:!1})}}function stringFlag(e){return{flagTag:`string`,builder:t=>{let n=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=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=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 $n=ct((e,t)=>{let n=boolToString,[r,i]=pt(`idle`),[a,s]=pt(``),c=ut(),l=ft({status:r,theme:c});dt((r,c)=>{if(lt(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 $n({message:e,default:t},hn)),getDeprecatedLocalConfigPath=e=>u(e,`apify.json`),er=new Map;async function useActorConfig({cwd:t=e.cwd(),migrateConfig:n=!0,warnAboutOldConfig:r=!0}={cwd:e.cwd(),migrateConfig:!0,warnAboutOldConfig:!0}){let i=er.get(t);if(i)return cliDebugPrint(`useActorConfig`,{cacheHit:!0,config:i}),we(i);let a=getLocalConfigPath(t),s=getDeprecatedLocalConfigPath(t),c,l;try{c=getJsonFileContent(a)}catch(e){return Se({message:`Failed to read local config at path: '${a}':`,cause:e,exists:!1,config:{}})}try{l=getJsonFileContent(s)}catch(e){return Se({message:`Failed to read local config at path: '${s}':`,cause:e,exists:!1,config:{}})}if(c&&l&&r&&await handleBothConfigVersionsFound(s),!c&&!l)return er.set(t,{exists:!1,migrated:!1,config:{}}),we({exists:!1,migrated:!1,config:{}});let u=!1;if(!c&&l&&n){let e=await handleMigrationFlow(l,s,a);if(e.isErr())return Se(e.unwrapErr());c=e.unwrap(),u=!0}return er.set(t,{exists:!0,migrated:u,config:c||l||{}}),cliDebugPrint(`useActorConfig`,{cacheHit:!1,config:er.get(t)}),we({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 Ae(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 tr=[`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,...tr.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 Se({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 z(c(n),{recursive:!0}),await H(n,JSON.stringify(r,null,` `))}catch(e){let t=e;return Se({message:`Failed to write the new "actor.json" file to path: '${n}'.\n ${t.message||t}`,exists:!0,config:r})}try{await Ae(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.`}),we(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 nr=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:nr}),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 ot(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[R.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 rr=[`.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,nn,r.input),i=getJsonFileContent(e);if(!i){if(n)throw Error(`Input schema file not found at ${e} (referenced in '${G}').`);return warning({message:`Input schema file not found at ${e} (referenced in '${G}').`}),{inputSchema:null,inputSchemaPath:e}}return{inputSchema:i,inputSchemaPath:e}}for(let e of rr){let n=u(t,e);if(D(n))return{inputSchema:getJsonFileContent(n),inputSchemaPath:n}}return{inputSchema:null,inputSchemaPath:u(t,rr[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 Ln({strict:!1});return ht(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,nn,s),r=getJsonFileContent(t);if(!r){if(i)throw Error(`${n} schema file not found at ${t} (referenced in '${G}').`);return warning({message:`${n} schema file not found at ${t} (referenced in '${G}').`}),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 Ln({strict:!1});ht(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:pe.INPUT,fileName:`${pe.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(fn?.toString(`utf8`)??``).trim();default:return fn}}_buildParseArgsOption(){let e={help:qn};Zn.has(this.entrypoint)&&(e[Xn]=Yn);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=Jn),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=`Automatic yes to prompts; assume "yes" as answer 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 $n=ct((e,t)=>{let n=boolToString,[r,i]=pt(`idle`),[a,s]=pt(``),c=ut(),l=ft({status:r,theme:c});dt((r,c)=>{if(lt(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 $n({message:e,default:t},hn)),getDeprecatedLocalConfigPath=e=>u(e,`apify.json`),er=/* @__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=er.get(t);if(i)return cliDebugPrint(`useActorConfig`,{cacheHit:!0,config:i}),we(i);let a=getLocalConfigPath(t),s=getDeprecatedLocalConfigPath(t),c,l;try{c=getJsonFileContent(a)}catch(e){return Se({message:`Failed to read local config at path: '${a}':`,cause:e,exists:!1,config:{}})}try{l=getJsonFileContent(s)}catch(e){return Se({message:`Failed to read local config at path: '${s}':`,cause:e,exists:!1,config:{}})}if(c&&l&&r&&await handleBothConfigVersionsFound(s),!c&&!l)return er.set(t,{exists:!1,migrated:!1,config:{}}),we({exists:!1,migrated:!1,config:{}});let u=!1;if(!c&&l&&n){let e=await handleMigrationFlow(l,s,a);if(e.isErr())return Se(e.unwrapErr());c=e.unwrap(),u=!0}return er.set(t,{exists:!0,migrated:u,config:c||l||{}}),cliDebugPrint(`useActorConfig`,{cacheHit:!1,config:er.get(t)}),we({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 Ae(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 tr=[`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,...tr.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 Se({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 z(c(n),{recursive:!0}),await H(n,JSON.stringify(r,null,` `))}catch(e){let t=e;return Se({message:`Failed to write the new "actor.json" file to path: '${n}'.\n ${t.message||t}`,exists:!0,config:r})}try{await Ae(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.`}),we(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 nr=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:nr}),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 ot(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[R.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 rr=[`.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,nn,r.input),i=getJsonFileContent(e);if(!i){if(n)throw Error(`Input schema file not found at ${e} (referenced in '${G}').`);return warning({message:`Input schema file not found at ${e} (referenced in '${G}').`}),{inputSchema:null,inputSchemaPath:e}}return{inputSchema:i,inputSchemaPath:e}}for(let e of rr){let n=u(t,e);if(D(n))return{inputSchema:getJsonFileContent(n),inputSchemaPath:n}}return{inputSchema:null,inputSchemaPath:u(t,rr[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 Ln({strict:!1});return ht(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,nn,s),r=getJsonFileContent(t);if(!r){if(i)throw Error(`${n} schema file not found at ${t} (referenced in '${G}').`);return warning({message:`${n} schema file not found at ${t} (referenced in '${G}').`}),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 Ln({strict:!1});ht(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:pe.INPUT,fileName:`${pe.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=_t();if(!t(e))throw Error(formatSchemaValidationErrors(t.errors,`Dataset`))}function validateOutputSchema(e){let t=yt();if(!t(e))throw Error(formatSchemaValidationErrors(t.errors,`Output`))}function validateKvsSchema(e){let t=vt();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,
|
|
@@ -99,9 +99,9 @@ To inspect the input schema before creating a JSON input, use "apify actors info
|
|
|
99
99
|
`));break}case`FREE`:u.push(`${t.yellow(`Pricing information:`)} ${t.bgGray(`Pay for usage`)}`);break;default:{let n=e.pricingModel;u.push(`${t.yellow(`Pricing information:`)} ${t.bgGray(`Unknown pricing model (${t.yellow(n)})`)}`)}}}else u.push(`${t.yellow(`Pricing information:`)} ${t.bgGray(`Pay for usage`)}`);(c.seoTitle||c.seoDescription)&&(u.push(``,t.yellow(`SEO information:`)),c.seoTitle&&u.push(` ${t.yellow(`Title:`)} ${c.seoTitle}`),c.seoDescription&&u.push(` ${t.yellow(`Description:`)} ${c.seoDescription}`));let{stats:p}=c;if(u.push(``,t.yellow(`Actor stats:`),` ${t.yellow(`Total users:`)} ${t.cyan(`${p.totalUsers}`)}`,` ${t.yellow(`Users (30d):`)} ${t.cyan(`${p.totalUsers30Days}`)}`,` ${t.yellow(`Total runs:`)} ${t.cyan(`${p.totalRuns}`)}`),c.taggedBuilds){u.push(``,t.yellow(`Builds:`));let e=c.taggedBuilds.latest;e&&u.push(` ${t.yellow(`-`)} ${t.cyan(e.buildNumber)} ${t.gray(`/`)} ${t.yellow(`latest`)}`);for(let[e,n]of Object.entries(c.taggedBuilds))e!==`latest`&&u.push(` ${t.yellow(`-`)} ${t.cyan(n.buildNumber)} ${t.gray(`/`)} ${t.yellow(e)}`)}simpleLog({message:u.join(`
|
|
100
100
|
`),stdout:!0})}};function prettyPrintStatus(e){switch(e){case`READY`:return t.green(`Ready`);case`RUNNING`:return t.blue(`Running`);case`SUCCEEDED`:return t.green(`Succeeded`);case`FAILED`:return t.red(`Failed`);case`ABORTING`:return t.yellow(`Aborting`);case`ABORTED`:return t.red(`Aborted`);case`TIMING-OUT`:return t.yellow(`Timing Out`);case`TIMED-OUT`:return t.red(`Timed Out`);default:return t.gray(e.split(`-`).map(e=>e[0].toUpperCase()+e.slice(1).toLowerCase()).join(` `))}}const mr={"TIMED-OUT":t.gray(`after`),"TIMING-OUT":t.gray(`after`),ABORTED:t.gray(`after`),ABORTING:t.gray(`after`),FAILED:t.gray(`after`),READY:t.gray(`for`),RUNNING:t.gray(`for`),SUCCEEDED:t.gray(`after`)},hr=new Q({allColumns:[`Name`,`Runs`,`Last run started at`,`Last run status`,`Last run duration`,`_Small_LastRunText`],mandatoryColumns:[`Name`,`Runs`,`Last run status`,`Last run duration`],columnAlignments:{Runs:`right`,"Last run duration":`right`,Name:`left`,"Last run status":`center`},hiddenColumns:[`_Small_LastRunText`],breakpointOverrides:{small:{"Last run status":{label:`Last run`,valueFrom:`_Small_LastRunText`}}}}),gr=new Q({allColumns:[`Name`,`Modified at`,`Builds`,`Default build`,`Runs`,`Last run`,`Last run status`,`Last run duration`,`_Small_LastRunText`],mandatoryColumns:[`Name`,`Runs`,`Last run`,`Last run duration`],hiddenColumns:[`_Small_LastRunText`],columnAlignments:{Builds:`right`,Runs:`right`,"Last run duration":`right`,Name:`left`,"Last run status":`center`},breakpointOverrides:{small:{"Last run":{label:`Last run`,valueFrom:`_Small_LastRunText`}}}});var ActorsLsCommand=class extends ApifyCommand{static name=`ls`;static description=`Prints a list of recently executed Actors or Actors you own.`;static examples=[{description:`List Actors you recently interacted with.`,command:`apify actors ls`},{description:`List Actors you own, newest first.`,command:`apify actors ls --my --desc`},{description:`List the next page of 50 Actors.`,command:`apify actors ls --limit 50 --offset 50`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-actors-ls`;static flags={my:Y.boolean({description:`Whether to list Actors made by the logged in user.`,default:!1}),offset:Y.integer({description:`Number of Actors that will be skipped.`,default:0}),limit:Y.integer({description:`Number of Actors that will be listed.`,default:20}),desc:Y.boolean({description:`Sort Actors in descending order.`,default:!1})};static enableJsonFlag=!0;async run(){let{desc:e,limit:n,offset:r,my:i,json:a}=this.flags,s=await getLoggedClientOrThrow(),c=await s.actors().list({limit:n,offset:r,desc:e,my:i});if(c.count===0){if(a){printJsonToStdout(c);return}info({message:i?`You don't have any Actors yet!`:`There are no recent Actors used by you.`,stdout:!0});return}let l={...c,items:await Promise.all(c.items.map(async e=>{let t=await s.actor(e.id).get(),n=await s.actor(e.id).runs().list({desc:!0,limit:1}).catch(()=>({count:0,desc:!0,items:[],limit:1,offset:0,total:0}));return{...e,actor:t??null,lastRun:n.items[0]??null}}))};if(l.items=i?this.sortByModifiedAt(l.items):this.sortByLastRun(l.items),a){printJsonToStdout(l);return}let u=i?gr:hr,f=l.items.reduce((e,t)=>{let n=`${t.username}/${t.name}`;return n.length>e?n.length:e},0)+2+6;for(let e of l.items){let n=e.stats.lastRunStartedAt?Vn.display(e.stats.lastRunStartedAt):``,r=e.lastRun?(()=>{if(e.lastRun.finishedAt)return q.format(e.lastRun.finishedAt.getTime()-e.lastRun.startedAt.getTime());let t=Date.now()-e.lastRun.startedAt.getTime();return`${q.format(t)}…`})():``,i=e.actor?(()=>{let n=Object.entries(e.actor.taggedBuilds??{}).find(([t,n])=>n.buildNumber===e.actor.defaultRunOptions.build||t===e.actor.defaultRunOptions.build);return n?`${t.yellow(n[0])} / ${t.cyan(n[1].buildNumber??e.actor.defaultRunOptions.build)}`:t.gray(`Unknown`)})():t.gray(`Unknown`),a=(()=>{if(e.lastRun){let n=[prettyPrintStatus(e.lastRun.status)];if(r&&n.push(mr[e.lastRun.status],t.cyan(r)),e.lastRun.finishedAt){let r=Date.now()-e.lastRun.finishedAt.getTime();r<He.Week?n.push(`
|
|
101
101
|
`,t.gray(`${q.format(r)} ago`)):n.push(`
|
|
102
|
-
`,t.gray(`On`,Hn.display(e.lastRun.finishedAt)))}return n.join(` `)}return``})();u.pushRow({Name:`${e.title}\n${t.gray(`${e.username}/${e.name}`)}`,Runs:Q.isSmallTerminal()&&f>=56?dr:t.cyan(`${e.stats?.totalRuns??0}`),"Last run started at":n,"Last run":n,"Last run status":e.lastRun?prettyPrintStatus(e.lastRun.status):``,"Modified at":Vn.display(e.modifiedAt),Builds:e.actor?t.cyan(e.actor.stats.totalBuilds):t.gray(`Unknown`),"Last run duration":Q.isSmallTerminal()?dr:t.cyan(r),"Default build":i,_Small_LastRunText:a})}simpleLog({message:u.render(1),stdout:!0})}sortByModifiedAt(e){return e.sort((e,t)=>{let n=new Date(e.modifiedAt);return new Date(t.modifiedAt).getTime()-n.getTime()})}sortByLastRun(e){return e.sort((e,t)=>{let n=new Date(e.stats?.lastRunStartedAt??`1970-01-01T00:00Z`);return new Date(t.stats?.lastRunStartedAt??`1970-01-01T00:00Z`).getTime()-n.getTime()})}};const extractGitHubZip=async(e,t)=>{let n=await downloadZip(e);n.extractEntryTo(n.getEntries()[0].entryName,t,!1)};var ActorsPullCommand=class extends ApifyCommand{static name=`pull`;static description=`Download Actor code to current directory. Clones Git repositories or fetches Actor files based on the source type.`;static group=`Local Actor Development`;static examples=[{description:`Pull the Actor linked to the current directory from the Apify platform.`,command:`apify pull`},{description:`Pull a specific Actor by its full name into a target directory.`,command:`apify pull apify/hello-world --dir ./hello-world`},{description:`Pull a specific version of an Actor.`,command:`apify pull apify/hello-world --version 1.2`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-pull`;static flags={version:Y.string({char:`v`,description:`Actor version number which will be pulled, e.g. 1.2. Default: the highest version.`,required:!1}),dir:Y.string({description:`Directory where the Actor should be pulled to.`,required:!1})};static args={actorId:Z.string({required:!1,description:`Name or ID of the Actor to run (e.g. "apify/hello-world" or "E2jjCZBezvAZnX8Rb"). If not provided, the command will update the Actor in the current directory based on its name in ".actor/actor.json" file.`})};async run(){let t=e.cwd(),n=await useActorConfig({cwd:t});if(n.isErr()){error({message:n.unwrapErr().message}),e.exitCode=5;return}let{config:r}=n.unwrap(),i=await getLoggedClientOrThrow(),a=await getCurrentUserInfo(),s=!this.args.actorId,l=a.username||a.id,f=this.args?.actorId||r?.id||(r?.name?`${l}/${r.name}`:void 0);if(!f)throw Error(`Cannot find Actor in this directory.`);let p;try{p=await i.actor(f).get()}catch{throw Error(`Cannot find Actor with ID/name '${f}' in your account.`)}if(!p)throw Error(`Cannot find Actor with ID/name '${f}' in your account.`);let{name:m,versions:h}=p,throwMissingSourceCodeAccessError=()=>{throw Error(`You cannot pull source code of this Actor because you do not have permission to do so.`)};if(!p.versions.length)throw Error(`Actor ${f} has no versions.`);let g=null;if(this.flags.version&&(g=h.find(e=>e.versionNumber===this.flags.version),!g))throw Error(`Cannot find version ${this.flags.version} of Actor ${f}.`);g||=h.reduce((e,t)=>v(`${t.versionNumber}.0`,`${e.versionNumber}.0`)?t:e);let _=s?t:u(t,this.flags.dir??m);if(k(_,{recursive:!0}),!s&&ee(_).length!==0){error({message:`Directory ${_} is not empty. Please empty it or choose another directory.`});return}let{sourceType:y}=g;switch(y){case`TARBALL`:g.tarballUrl||throwMissingSourceCodeAccessError(),await extractGitHubZip(g.tarballUrl,_);break;case`SOURCE_FILES`:{g.sourceFiles||throwMissingSourceCodeAccessError();let{sourceFiles:e}=g;for(let t of e){let e=c(t.name);if(k(`${_}/${e}`,{recursive:!0}),!t.folder){let e=t.format===`BASE64`?Buffer.from(t.content,`base64`).toString():t.content;if(t.name===G){let n=wt.parse(e);n.name=p.name,F(`${_}/${t.name}`,wt.update(e,n))}else F(`${_}/${t.name}`,e)}}break}case`GIT_REPO`:{g.gitRepoUrl||throwMissingSourceCodeAccessError();let{gitRepoUrl:e}=g;try{await Ct(`git:${e}`,{dir:_})}catch(t){throw Error(`Failed to pull Actor from ${e}. ${t.message}`)}break}case`GITHUB_GIST`:g.gitHubGistUrl||throwMissingSourceCodeAccessError(),await extractGitHubZip(`${g.gitHubGistUrl}/archive/master.zip`,_);break;default:throw Error(`Unknown source type: ${y}`)}success({message:s?`Actor ${m} updated at ${_}/`:`Pulled to ${_}/`})}};const _r=5e4,getSecretsFile=()=>{try{return JSON.parse(j(SECRETS_FILE_PATH(),`utf-8`))||{}}catch{return{}}},writeSecretsFile=e=>(ensureApifyDirectory(SECRETS_FILE_PATH()),F(SECRETS_FILE_PATH(),JSON.stringify(e,null,` `)),e),addSecret=(e,t)=>{let n=getSecretsFile();if(n[e])throw Error(`Secret with name ${e} already exists. Call "apify secrets rm ${e}" to remove it.`);if(typeof e!=`string`||e.length>100)throw Error(`Secret name has to be string with maximum length 100.`);if(typeof t!=`string`||t.length>_r)throw Error(`Secret value has to be string with maximum length ${_r}.`);return n[e]=t,writeSecretsFile(n)},removeSecret=e=>{let t=getSecretsFile();if(!t[e])throw Error(`Secret with name ${e} doesn't exist.`);delete t[e],writeSecretsFile(t)},isSecretKey=e=>RegExp(`^@.{1}`).test(e),replaceSecretsValue=(e,t,{allowMissing:n=!1}={})=>{t||=getSecretsFile();let r={},i=[];if(Object.keys(e).forEach(n=>{if(isSecretKey(e[n])){let a=e[n].replace(RegExp(`^@`),``);t[a]?r[n]=t[a]:i.push(a)}else r[n]=e[n]}),i.length>0){let e=i.map(e=>` - ${e}`).join(`
|
|
102
|
+
`,t.gray(`On`,Hn.display(e.lastRun.finishedAt)))}return n.join(` `)}return``})();u.pushRow({Name:`${e.title}\n${t.gray(`${e.username}/${e.name}`)}`,Runs:Q.isSmallTerminal()&&f>=56?dr:t.cyan(`${e.stats?.totalRuns??0}`),"Last run started at":n,"Last run":n,"Last run status":e.lastRun?prettyPrintStatus(e.lastRun.status):``,"Modified at":Vn.display(e.modifiedAt),Builds:e.actor?t.cyan(e.actor.stats.totalBuilds):t.gray(`Unknown`),"Last run duration":Q.isSmallTerminal()?dr:t.cyan(r),"Default build":i,_Small_LastRunText:a})}simpleLog({message:u.render(1),stdout:!0})}sortByModifiedAt(e){return e.sort((e,t)=>{let n=new Date(e.modifiedAt);return new Date(t.modifiedAt).getTime()-n.getTime()})}sortByLastRun(e){return e.sort((e,t)=>{let n=new Date(e.stats?.lastRunStartedAt??`1970-01-01T00:00Z`);return new Date(t.stats?.lastRunStartedAt??`1970-01-01T00:00Z`).getTime()-n.getTime()})}};const extractGitHubZip=async(e,t)=>{let n=await downloadZip(e);n.extractEntryTo(n.getEntries()[0].entryName,t,!1)};var ActorsPullCommand=class extends ApifyCommand{static name=`pull`;static description=`Download Actor code to current directory. Clones Git repositories or fetches Actor files based on the source type.`;static group=`Local Actor Development`;static examples=[{description:`Pull the Actor linked to the current directory from the Apify platform.`,command:`apify pull`},{description:`Pull a specific Actor by its full name into a target directory.`,command:`apify pull apify/hello-world --dir ./hello-world`},{description:`Pull a specific version of an Actor.`,command:`apify pull apify/hello-world --version 1.2`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-pull`;static flags={version:Y.string({char:`v`,description:`Actor version number which will be pulled, e.g. 1.2. Default: the highest version.`,required:!1}),dir:Y.string({description:`Directory where the Actor should be pulled to.`,required:!1})};static args={actorId:Z.string({required:!1,description:`Name or ID of the Actor to run (e.g. "apify/hello-world" or "E2jjCZBezvAZnX8Rb"). If not provided, the command will update the Actor in the current directory based on its name in ".actor/actor.json" file.`})};async run(){let t=e.cwd(),n=await useActorConfig({cwd:t});if(n.isErr()){error({message:n.unwrapErr().message}),e.exitCode=5;return}let{config:r}=n.unwrap(),i=await getLoggedClientOrThrow(),a=await getCurrentUserInfo(),s=!this.args.actorId,l=a.username||a.id,f=this.args?.actorId||r?.id||(r?.name?`${l}/${r.name}`:void 0);if(!f)throw Error(`Cannot find Actor in this directory.`);let p;try{p=await i.actor(f).get()}catch{throw Error(`Cannot find Actor with ID/name '${f}' in your account.`)}if(!p)throw Error(`Cannot find Actor with ID/name '${f}' in your account.`);let{name:m,versions:h}=p,throwMissingSourceCodeAccessError=()=>{throw Error(`You cannot pull source code of this Actor because you do not have permission to do so.`)};if(!p.versions.length)throw Error(`Actor ${f} has no versions.`);let g=null;if(this.flags.version&&(g=h.find(e=>e.versionNumber===this.flags.version),!g))throw Error(`Cannot find version ${this.flags.version} of Actor ${f}.`);g||=h.reduce((e,t)=>v(`${t.versionNumber}.0`,`${e.versionNumber}.0`)?t:e);let _=s?t:u(t,this.flags.dir??m);if(k(_,{recursive:!0}),!s&&ee(_).length!==0){error({message:`Directory ${_} is not empty. Please empty it or choose another directory.`});return}let{sourceType:y}=g;switch(y){case`TARBALL`:g.tarballUrl||throwMissingSourceCodeAccessError(),await extractGitHubZip(g.tarballUrl,_);break;case`SOURCE_FILES`:{g.sourceFiles||throwMissingSourceCodeAccessError();let{sourceFiles:e}=g;for(let t of e){let e=c(t.name);if(k(`${_}/${e}`,{recursive:!0}),!t.folder){let e=t.format===`BASE64`?Buffer.from(t.content,`base64`).toString():t.content;if(t.name===G){let n=wt.parse(e);n.name=p.name,F(`${_}/${t.name}`,wt.update(e,n))}else F(`${_}/${t.name}`,e)}}break}case`GIT_REPO`:{g.gitRepoUrl||throwMissingSourceCodeAccessError();let{gitRepoUrl:e}=g;try{await Ct(`git:${e}`,{dir:_})}catch(t){throw Error(`Failed to pull Actor from ${e}. ${t.message}`)}break}case`GITHUB_GIST`:g.gitHubGistUrl||throwMissingSourceCodeAccessError(),await extractGitHubZip(`${g.gitHubGistUrl}/archive/master.zip`,_);break;default:throw Error(`Unknown source type: ${y}`)}success({message:s?`Actor ${m} updated at ${_}/`:`Pulled to ${_}/`})}};const _r=5e4,getSecretsFile=()=>{try{return JSON.parse(j(SECRETS_FILE_PATH(),`utf-8`))||{}}catch{return{}}},writeSecretsFile=e=>(ensureApifyDirectory(SECRETS_FILE_PATH()),F(SECRETS_FILE_PATH(),JSON.stringify(e,null,` `)),e),addSecret=(e,t)=>{let n=getSecretsFile();if(n[e])throw Error(`Secret with name ${e} already exists. Call "apify secrets rm ${e}" to remove it.`);if(typeof e!=`string`||e.length>100)throw Error(`Secret name has to be string with maximum length 100.`);if(typeof t!=`string`||t.length>_r)throw Error(`Secret value has to be string with maximum length ${_r}.`);return n[e]=t,writeSecretsFile(n)},removeSecret=e=>{let t=getSecretsFile();if(!t[e])throw Error(`Secret with name ${e} doesn't exist.`);delete t[e],writeSecretsFile(t)},isSecretKey=e=>(/* @__PURE__ */ RegExp(`^@.{1}`)).test(e),replaceSecretsValue=(e,t,{allowMissing:n=!1}={})=>{t||=getSecretsFile();let r={},i=[];if(Object.keys(e).forEach(n=>{if(isSecretKey(e[n])){let a=e[n].replace(/* @__PURE__ */ RegExp(`^@`),``);t[a]?r[n]=t[a]:i.push(a)}else r[n]=e[n]}),i.length>0){let e=i.map(e=>` - ${e}`).join(`
|
|
103
103
|
`);if(n)for(let e of i)warning({message:`Value for ${e} not found in local secrets. Set it by calling "apify secrets add ${e} [SECRET_VALUE]"`});else throw Error(`The following secrets are missing:\n${e}\n\nSet them by calling "apify secrets add <SECRET_NAME> <SECRET_VALUE>" for each missing secret.
|
|
104
|
-
If you want to skip missing secrets, run the command with the --allow-missing-secrets flag.`)}return r},transformEnvToEnvVars=(e,t,{allowMissing:n=!1}={})=>{t||=getSecretsFile();let r=[],i=[];if(Object.keys(e).forEach(n=>{if(isSecretKey(e[n])){let a=e[n].replace(RegExp(`^@`),``);t[a]?r.push({name:n,value:t[a],isSecret:!0}):i.push(a)}else r.push({name:n,value:e[n]})}),i.length>0){let e=i.map(e=>` - ${e}`).join(`
|
|
104
|
+
If you want to skip missing secrets, run the command with the --allow-missing-secrets flag.`)}return r},transformEnvToEnvVars=(e,t,{allowMissing:n=!1}={})=>{t||=getSecretsFile();let r=[],i=[];if(Object.keys(e).forEach(n=>{if(isSecretKey(e[n])){let a=e[n].replace(/* @__PURE__ */ RegExp(`^@`),``);t[a]?r.push({name:n,value:t[a],isSecret:!0}):i.push(a)}else r.push({name:n,value:e[n]})}),i.length>0){let e=i.map(e=>` - ${e}`).join(`
|
|
105
105
|
`);if(n)for(let e of i)warning({message:`Value for ${e} not found in local secrets. Set it by calling "apify secrets add ${e} [SECRET_VALUE]"`});else throw Error(`The following secrets are missing:\n${e}\n\nSet them by calling "apify secrets add <SECRET_NAME> <SECRET_VALUE>" for each missing secret.
|
|
106
106
|
If you want to skip missing secrets, run the command with the --allow-missing-secrets flag.`)}return r},vr=`temp_file.zip`,yr={build:`latest`,memoryMbytes:4096,timeoutSecs:3600};function resolvePushOutcome(e){switch(e){case L.SUCCEEDED:return{resultLabel:`SUCCEEDED`,exitCode:0,ok:!0};case L.READY:return{resultLabel:`PENDING`,ok:!0};case L.RUNNING:return{resultLabel:`RUNNING`,ok:!0};case L.ABORTING:return{resultLabel:`ABORTING`,exitCode:3,ok:!1,errorMessage:`Build is aborting`};case L.ABORTED:return{resultLabel:`ABORTED`,exitCode:3,ok:!1,errorMessage:`Build aborted`};case L.TIMING_OUT:return{resultLabel:`TIMING_OUT`,exitCode:2,ok:!1,errorMessage:`Build is timing out`};case L.TIMED_OUT:return{resultLabel:`TIMED_OUT`,exitCode:2,ok:!1,errorMessage:`Build timed out`};case L.FAILED:return{resultLabel:`FAILED`,exitCode:1,ok:!1,errorMessage:`Build failed`};default:return{resultLabel:`UNKNOWN`,exitCode:1,ok:!1,errorMessage:`Build finished with unexpected status "${e}"`}}}const confirmGitSourceSwitch=async({actorName:e,gitRepoUrl:t,force:n})=>(warning({message:[`Actor ${e} builds from a Git repository: ${t}`,`A push replaces that source with the local files and drops the Git connection.`,`To build from the repository, run git push instead. The platform builds on push when automated builds are on.`].join(`
|
|
107
107
|
`)}),n?!0:X({message:`Switch the source to the local files?`,default:!1,errorMessageForStdin:`Actor ${e} builds from a Git repository. To switch the source to the local files, use --force.`}));var ActorsPushCommand=class extends ApifyCommand{static name=`push`;static description=`Deploys Actor to Apify platform using settings from '${G}'.\nFiles under '${ge/1024**2}' MB upload as "Multiple source files"; larger projects upload as ZIP file.
|
|
@@ -115,11 +115,11 @@ Skipping push. Use --force to override.`)}let S=await b.version(g).get();if(S?.s
|
|
|
115
115
|
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 Je(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 description=`Starts Actor remotely and returns run details immediately.
|
|
116
116
|
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 '${G}' 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 cr.resolveActorId({client:i,localActorName:r.name,usernameOrId:s,providedActorNameOrId:this.args.actorId}),f={};this.flags.build&&(f.build=this.flags.build),this.flags.timeout&&(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:`${getConsoleUrl()}/actors/${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(`
|
|
117
117
|
`),stdout:!0})}},ActorsIndexCommand=class extends ApifyCommand{static name=`actors`;static description=`Search, list, deploy, and call Actors on the Apify platform.
|
|
118
|
-
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,cr,ActorsBuildCommand];async run(){this.printHelp()}};const xr=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`],Sr
|
|
118
|
+
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,cr,ActorsBuildCommand];async run(){this.printHelp()}};const xr=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`],Sr=/* @__PURE__ */ new Set([`GET`,`HEAD`]),Cr=`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 wr={GET:t.green,POST:t.yellow,PUT:t.blue,PATCH:t.cyan,DELETE:t.red};function formatEndpointLine(e){let n=(wr[e.method]||t.white)(e.method.padEnd(7)),r=e.summary?t.gray(` ${e.summary}`):``;return`${n} ${e.path}${r}`}const Tr=`Run ${t.cyan(`apify api --list-endpoints`)} to see all available Apify API endpoints.`;function printSuggestions(e){if(e.length>0){simpleLog({message:`
|
|
119
119
|
Did you mean:`,stdout:!1});for(let t of e)simpleLog({message:` ${formatEndpointLine(t)}`,stdout:!1})}simpleLog({message:`\n${Tr}`,stdout:!1})}var ApiCommand=class extends ApifyCommand{cachedEndpoints=null;static name=`api`;static description=`Makes an authenticated HTTP request to the Apify API and prints the response.
|
|
120
120
|
The endpoint can be a relative path (e.g. "acts", "v2/acts", or "/v2/acts"); the "v2/" prefix is added automatically if omitted.
|
|
121
121
|
|
|
122
|
-
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:xr}),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&&xr.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(Sr.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={...on,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=wr[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${Tr}`,stdout:!1})}}};async function fetchEndpoints(){let e;try{e=await fetch(Cr)}catch(e){throw Error(`Failed to download the Apify OpenAPI spec from ${Cr}: ${e.message}`)}if(!e.ok)throw Error(`Failed to download the Apify OpenAPI spec from ${Cr}: ${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))xr.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
|
|
122
|
+
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:xr}),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&&xr.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(Sr.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={...on,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=wr[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${Tr}`,stdout:!1})}}};async function fetchEndpoints(){let e;try{e=await fetch(Cr)}catch(e){throw Error(`Failed to download the Apify OpenAPI spec from ${Cr}: ${e.message}`)}if(!e.ok)throw Error(`Failed to download the Apify OpenAPI spec from ${Cr}: ${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))xr.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 Er=stdinCheckWrapper(async({message:e,mask:t})=>await At({message:e,mask:t??`*`},hn)),Dr=stdinCheckWrapper(async({message:e,choices:t,pageSize:n,loop:r,default:i})=>await jt({message:e,choices:t,pageSize:n,loop:r,default:i},hn),{errorMessageForStdin:`Please provide the selection using the command options.`}),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 Mt(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)})}const tryToLogin=async n=>{let r=await loginWithToken(n,getConsoleUrl().includes(`localhost`)?`http://localhost:3333`:void 0);if(r){let{userInfo:n}=r;await updateUserId(n.id);let i=await getBackend(),a;a=i===`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)`,success({message:`You are logged in to Apify as ${n.username||n.id}. ${t.gray(`Your token is stored in ${a}.`)}`})}else e.exitCode=1,error({message:`Login to Apify failed, the provided API token is not valid.`});return r};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.
|
|
123
123
|
|
|
124
124
|
Run 'apify logout' to remove authentication.`;static group=`Authentication`;static interactive=!0;static interactiveNote=`Prompts for an API token if not provided. To run non-interactively, pass --token <api-token>.`;static examples=[{description:`Log in interactively (prompts to choose a method, then completes the flow accordingly).`,command:`apify login`},{description:`Log in non-interactively with an API token.`,command:`apify login --token apify_api_xxxxx`}];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.`,choices:[`console`,`manual`],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:`${R.TOKEN} is set, so other commands will ignore this login. Unset ${R.TOKEN} and try again.`}),e.exitCode=5;return}if(t){await tryToLogin(t);return}let i=getConsoleUrl(),a=new URL(i).origin,s=getConsoleIntegrationsUrl(),c=n;if(n||(c=await Dr({message:`Choose how you want to log in to Apify`,choices:[{value:`console`,name:`Through Apify Console in your default browser`,short:`Through Apify Console`},{value:`manual`,name:`Enter API token manually`,short:`Manually`}],loop:!0})),c===`console`){let e=Re(),t=createLocalApiServer({corsOrigin:a,authToken:e,routes:{"POST /api/v1/login-token":async(e,n)=>{try{if(e.apiToken)await tryToLogin(e.apiToken);else throw Error(`Request did not contain API token`);n.end()}catch(e){let t=`Login to Apify failed with error: ${e.message}`;error({message:t}),n.status(500),n.send(t)}t.close()},"POST /api/v1/exit":(e,n)=>{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.`}),n.end(),t.close()}}});t.listen(0);let{port:n}=t.address(),r=new URL(s);r.searchParams.set(`localCliCommand`,`login`),r.searchParams.set(`localCliPort`,`${n}`),r.searchParams.set(`localCliToken`,e),r.searchParams.set(`localCliApiVersion`,`v1`);try{r.searchParams.set(`localCliComputerName`,encodeURIComponent(kt()))}catch{}info({message:`Opening Apify Console at "${r.href}"...`}),await Tt(r.href)}else{console.log(`Enter your Apify API token. You can find it at ${s}`);let e=await Er({message:`token:`});await tryToLogin(e)}}},AuthLogoutCommand=class extends ApifyCommand{static name=`logout`;static description=`Removes authentication by deleting your API token and account information from '${tildify(AUTH_FILE_PATH())}'.\nRun 'apify login' to authenticate again.`;static group=`Authentication`;static examples=[{description:`Remove the stored Apify credentials.`,command:`apify logout`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-logout`;async run(){await clearKeyringSecrets(),await rimrafPromised(AUTH_FILE_PATH()),await updateUserId(null),success({message:`You are logged out from your Apify account.`});let e=readEnvToken();e.kind===`token`?warning({message:`${R.TOKEN} is still set, so commands stay authenticated with that token.`}):e.kind===`invalid`&&warning({message:invalidEnvTokenMessage(e.raw)})}},AuthTokenCommand=class extends ApifyCommand{static name=`token`;static description=`Prints the API token the CLI authenticates with, resolved from APIFY_TOKEN or the token from 'apify login'.`;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(),simpleLog({message:(await resolveAuth()).token,stdout:!0})}},AuthIndexCommand=class extends ApifyCommand{static name=`auth`;static description="Log in, log out, and inspect your stored Apify API token. Also available as `apify login` / `apify logout`.";static group=`Authentication`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-auth`;static subcommands=[AuthLoginCommand,AuthLogoutCommand,AuthTokenCommand];async run(){this.printHelp()}},BuildsAddTagCommand=class extends ApifyCommand{static name=`add-tag`;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 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`)}: ${K.display(r.startedAt)}`];if(r.finishedAt)f.push(` ${t.yellow(`Finished`)}: ${K.display(r.finishedAt)} (took ${t.gray(Un.format(r.stats?.durationMillis??0))})`);else{let e=Date.now()-r.startedAt.getTime();f.push(` ${t.yellow(`Finished`)}: ${t.gray(`Running for ${Un.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=`${getConsoleUrl()}/actors/${r.actId}/builds/${r.buildNumber}`;f.push(`${t.blue(`View in Apify Console`)}: ${m}`),simpleLog({message:f.join(`
|
|
125
125
|
`),stdout:!0})}},BuildsLogCommand=class extends ApifyCommand{static name=`log`;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 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(`
|
|
@@ -138,14 +138,14 @@ Returns exit code 0 only when the build SUCCEEDED. Designed for CI and agentic w
|
|
|
138
138
|
`)});return}if(a.platform===`windows`)return this.startUpgradeProcess(t,i,r);await this.handleUnixUpgrade(t,i,r),this.successMessage(i);return}let s=Ar[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=Be(`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(D(n))return;let r=useCLIMetadata(),i=await fetch(Mr,{headers:{"User-Agent":mn}});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: ${Mr}`,`- The status code of the response: ${i.status}`].join(`
|
|
139
139
|
`)}),e.exit(1));let a=await i.arrayBuffer();await H(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":mn}});if(!l.ok){let e=await l.text();cliDebugPrint(`[upgrade] failed to fetch asset`,{asset:s,status:l.status,body:e}),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: ${e}`].join(`
|
|
140
140
|
`)});return}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 H(p,Buffer.from(f),{mode:493}),await Ae(p,c),writeEntrypointShims(n,!1),cliDebugPrint(`[upgrade ${i}] wrote asset to`,c)}catch(e){await je(p,{force:!0}).catch(()=>{}),cliDebugPrint(`[upgrade] failed to write asset`,{error:e}),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: ${e.message}`].join(`
|
|
141
|
-
`)})}}}};const Nr={STARTER:`STARTER`,WEB_SCRAPING:`WEB_SCRAPING`,INTEGRATION:`INTEGRATION`,AUTOMATION:`AUTOMATION`,AI:`AI`},$={JAVASCRIPT:`javascript`,TYPESCRIPT:`typescript`,PYTHON:`python`},Pr=`any-language`,Fr=`any-use-case`,Ir={[$.TYPESCRIPT]:`ts-crawlee-cheerio`,[$.JAVASCRIPT]:`js-crawlee-cheerio`,[$.PYTHON]:`python-crawlee-beautifulsoup`},Lr={[$.TYPESCRIPT]:`ts-empty`,[$.JAVASCRIPT]:`js-empty`,[$.PYTHON]:`python-empty`},Rr=[{cliFlag:`web-scraper`,templateTag:Nr.WEB_SCRAPING,label:`Web scraper`},{cliFlag:`ai-agent`,templateTag:Nr.AI,label:`AI agent`},{cliFlag:`data-pipeline`,templateTag:Nr.INTEGRATION,label:`API & data pipeline`},{cliFlag:`browser-automation`,templateTag:Nr.AUTOMATION,label:`Browser automation`}],zr=[{cliFlag:$.JAVASCRIPT,templateTag:$.JAVASCRIPT,label:`JavaScript`,aliases:[`js`]},{cliFlag:$.TYPESCRIPT,templateTag:$.TYPESCRIPT,label:`TypeScript`,aliases:[`ts`]},{cliFlag:$.PYTHON,templateTag:$.PYTHON,label:`Python`,aliases:[`py`]}],Br=zr.flatMap(e=>[e.cliFlag,...e.aliases]),Vr=Rr.map(e=>e.cliFlag);function useCaseFlagToTag(e){return Rr.find(t=>t.cliFlag===e)?.templateTag}function languageFlagToTag(e){return zr.find(t=>t.cliFlag===e||t.aliases.includes(e))?.templateTag}function useCaseLabel(e){return Rr.find(t=>t.templateTag===e)?.label??e}function languageLabel(e){return e===`any-language`?`any language`:zr.find(t=>t.templateTag===e)?.label??e}function getTemplateRecommendation(e,t,n){let r=n!==Pr,i=t!==Fr,matchesLanguage=e=>!r||e.category===n,matchesUseCase=e=>!i||!!e.useCases?.includes(t),isExactMatch=e=>matchesLanguage(e)&&matchesUseCase(e),a
|
|
141
|
+
`)})}}}};const Nr={STARTER:`STARTER`,WEB_SCRAPING:`WEB_SCRAPING`,INTEGRATION:`INTEGRATION`,AUTOMATION:`AUTOMATION`,AI:`AI`},$={JAVASCRIPT:`javascript`,TYPESCRIPT:`typescript`,PYTHON:`python`},Pr=`any-language`,Fr=`any-use-case`,Ir={[$.TYPESCRIPT]:`ts-crawlee-cheerio`,[$.JAVASCRIPT]:`js-crawlee-cheerio`,[$.PYTHON]:`python-crawlee-beautifulsoup`},Lr={[$.TYPESCRIPT]:`ts-empty`,[$.JAVASCRIPT]:`js-empty`,[$.PYTHON]:`python-empty`},Rr=[{cliFlag:`web-scraper`,templateTag:Nr.WEB_SCRAPING,label:`Web scraper`},{cliFlag:`ai-agent`,templateTag:Nr.AI,label:`AI agent`},{cliFlag:`data-pipeline`,templateTag:Nr.INTEGRATION,label:`API & data pipeline`},{cliFlag:`browser-automation`,templateTag:Nr.AUTOMATION,label:`Browser automation`}],zr=[{cliFlag:$.JAVASCRIPT,templateTag:$.JAVASCRIPT,label:`JavaScript`,aliases:[`js`]},{cliFlag:$.TYPESCRIPT,templateTag:$.TYPESCRIPT,label:`TypeScript`,aliases:[`ts`]},{cliFlag:$.PYTHON,templateTag:$.PYTHON,label:`Python`,aliases:[`py`]}],Br=zr.flatMap(e=>[e.cliFlag,...e.aliases]),Vr=Rr.map(e=>e.cliFlag);function useCaseFlagToTag(e){return Rr.find(t=>t.cliFlag===e)?.templateTag}function languageFlagToTag(e){return zr.find(t=>t.cliFlag===e||t.aliases.includes(e))?.templateTag}function useCaseLabel(e){return Rr.find(t=>t.templateTag===e)?.label??e}function languageLabel(e){return e===`any-language`?`any language`:zr.find(t=>t.templateTag===e)?.label??e}function getTemplateRecommendation(e,t,n){let r=n!==Pr,i=t!==Fr,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(Ir),addCuratedTemplates(Lr),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=zr.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 Xe.get(n.localReadmeSuffixUrl,{responseType:`text`});await Oe(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(`
|
|
142
142
|
`)}`,s?(c+=`\n\n🌱 Connected to ${s.remoteUrl} — Actor ${s.actorId} builds from this repository.`,s.automaticBuilds===`on`?c+=`
|
|
143
143
|
🔁 Every push to this repository rebuilds the Actor.`:s.automaticBuilds===`failed`&&(c+=`
|
|
144
144
|
💡 Tip: Turn on Automatic builds in the Actor's Source settings to rebuild on every push.`)):(c+=`
|
|
145
145
|
|
|
146
146
|
💡 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+=`
|
|
147
|
-
📖 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 vn({message:`Name of your new Actor:`,validate:e=>{try{validateActorName(e)}catch(e){return e.message}return!0}})}async function promptUseCase(){let e=[...Rr.map(e=>({name:e.label,value:e.templateTag})),new st,{name:`Any use case`,value:Fr}];return Dr({message:`What do you want to build?`,choices:e,default:Rr[0].templateTag,loop:!1})}async function promptLanguage(){let e=[...zr.map(e=>({name:e.label,value:e.templateTag})),new st,{name:`Any language`,value:Pr}];return Dr({message:`Choose the programming language of your new Actor:`,choices:e,default:zr[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 st(`── The templates below don't exactly match your selection ──`)),s.push({name:e.label,value:e.template})}),a&&info({message:a,stdout:!1}),Dr({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 Hr=3e5,connectViaConsole=async(e,t,{abortSignal:n,account:r}={})=>{let i=getConsoleUrl(),a=Re(),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 ${Hr/6e4} minutes.`}),Hr);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(kt()))}catch{}info({message:`Connect your ${t} account to Apify: ${p.href}`}),Tt(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()}},Ur=[`apify`,`github`,`gitlab`,`bitbucket`],Wr={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(Wr,e),toGitAccount=({id:e,username:t,organizationOwnerUserId:n})=>({id:e,username:t,organizationOwnerUserId:n}),getGitConnectUrl=(t,n)=>{let{authorize:r}=Wr[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}=Wr[t];return r?r.appInstallUrl.replace(`{app}`,e.env[r.appNameEnvVar]||r.defaultAppName):getConsoleIntegrationsUrl(n)},promptGitSource=async()=>Dr({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".`},...Ur.filter(isGitProvider).map(e=>{let{label:t}=Wr[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}},Gr=2e3,Kr=18e4,pollForWorkspaces=async(e,{timeoutMs:t,abortSignal:n,onState:r})=>{let i=Date.now()+t,a=Gr,s=null;for(;Date.now()<i;){try{await Ft(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}=Wr[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:Hr,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(Kr,Hr-(Date.now()-n));return u<Gr?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 Tt(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:Kr,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 Dr({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 qr=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&&qr.has(p)?new CreateRemoteRepoError(m,`notAuthorized`):p===`invalid-parameter`?new CreateRemoteRepoError(m,`repoNameRejected`):new CreateRemoteRepoError(m,`repoCreateFailed`)},cloneRepo=async(e,t,n)=>{await Ee(`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:fe.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}=Wr[t],_=u?.username?`The Apify account ${u.username}`:`Apify`;if(!h.connected)return stopped(`notAuthorized`,Error(`${_} is not authorized to access your ${g} account.`));if(!h.workspaces.length)return stopped(`noWorkspace`,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,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 vn({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 ${Wr[n].label} account to Apify: ${getGitConnectUrl(n,l)}`,`then re-run apify create`];case`noWorkspace`:return[`Give Apify access to a ${Wr[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(`
|
|
148
|
-
`)}`}))};var CreateCommand=class extends ApifyCommand{static name=`create`;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 ${Dt} 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:Vr,required:!1}),language:Y.string({char:`l`,description:`Filter templates by programming language. Ignored when --template is provided.`,choices:Br,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:[...Ur],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,_=Et().catch(e=>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 V(x).catch(()=>null),n=e&&await ke(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 z(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&&!le&&!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,G));await setLocalConfig(Object.assign(n||$t,{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(rn);if((n.type===1||n.type===2)&&n.packageManager===`uv`){let e=await Ie(`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 ${sn} 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 ${sn} or higher, but you have Python ${i.version}!`}),warning({message:`Please install Python ${sn} 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},ee=await V(u(v,`.git`)).catch(()=>null),M=await V(u(x,`.git`)).catch(()=>null),N=k!==null&&!k.scaffolded,P=!s&&!ee&&!M&&!N;if(P)try{await execWithLog({cmd:`git`,args:[`init`],opts:{cwd:x}})}catch(e){j={success:!1,error:e}}let te=A?null:await getInstallCommandSuggestion(x),ne=P&&j.success||!!M;k?.stopReason&&(e.exitCode=1);let F=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:te}),re=!k?.stopReason;l?printJsonToStdout({dir:x,actorJsonPath:u(x,G),template:C,source:g,nextSteps:F,postCreate:S?.postCreate??null,gitRepositoryInitialized:ne,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}):re&&(simpleLog({message:``}),success({message:formatCreateSuccessMessage({actorName:t,dependenciesInstalled:A,postCreate:S?.postCreate??null,gitRepositoryInitialized:ne,installCommandSuggestion:te,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,F)}};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 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 Jr={[U.JSON]:`application/json`,[U.JSONL]:`application/jsonl`,[U.CSV]:`text/csv`,[U.HTML]:`text/html`,[U.RSS]:`application/rss+xml`,[U.XML]:`application/xml`,[U.XLSX]:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`};var DatasetsGetItems=class extends ApifyCommand{static name=`get-items`;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(Jr),default:U.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:Jr[n]??`application/octet-stream`}),process.stdout.write(c),process.stdout.write(`
|
|
147
|
+
📖 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 vn({message:`Name of your new Actor:`,validate:e=>{try{validateActorName(e)}catch(e){return e.message}return!0}})}async function promptUseCase(){let e=[...Rr.map(e=>({name:e.label,value:e.templateTag})),new st,{name:`Any use case`,value:Fr}];return Dr({message:`What do you want to build?`,choices:e,default:Rr[0].templateTag,loop:!1})}async function promptLanguage(){let e=[...zr.map(e=>({name:e.label,value:e.templateTag})),new st,{name:`Any language`,value:Pr}];return Dr({message:`Choose the programming language of your new Actor:`,choices:e,default:zr[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 st(`── The templates below don't exactly match your selection ──`)),s.push({name:e.label,value:e.template})}),a&&info({message:a,stdout:!1}),Dr({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 Hr=3e5,connectViaConsole=async(e,t,{abortSignal:n,account:r}={})=>{let i=getConsoleUrl(),a=Re(),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 ${Hr/6e4} minutes.`}),Hr);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(kt()))}catch{}info({message:`Connect your ${t} account to Apify: ${p.href}`}),Tt(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()}},Ur=[`apify`,`github`,`gitlab`,`bitbucket`],Wr={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(Wr,e),toGitAccount=({id:e,username:t,organizationOwnerUserId:n})=>({id:e,username:t,organizationOwnerUserId:n}),getGitConnectUrl=(t,n)=>{let{authorize:r}=Wr[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}=Wr[t];return r?r.appInstallUrl.replace(`{app}`,e.env[r.appNameEnvVar]||r.defaultAppName):getConsoleIntegrationsUrl(n)},promptGitSource=async()=>Dr({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".`},...Ur.filter(isGitProvider).map(e=>{let{label:t}=Wr[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}},Gr=2e3,Kr=18e4,pollForWorkspaces=async(e,{timeoutMs:t,abortSignal:n,onState:r})=>{let i=Date.now()+t,a=Gr,s=null;for(;Date.now()<i;){try{await Ft(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}=Wr[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:Hr,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(Kr,Hr-(Date.now()-n));return u<Gr?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 Tt(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:Kr,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 Dr({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 qr=/* @__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&&qr.has(p)?new CreateRemoteRepoError(m,`notAuthorized`):p===`invalid-parameter`?new CreateRemoteRepoError(m,`repoNameRejected`):new CreateRemoteRepoError(m,`repoCreateFailed`)},cloneRepo=async(e,t,n)=>{await Ee(`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:fe.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}=Wr[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 vn({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 ${Wr[n].label} account to Apify: ${getGitConnectUrl(n,l)}`,`then re-run apify create`];case`noWorkspace`:return[`Give Apify access to a ${Wr[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(`
|
|
148
|
+
`)}`}))};var CreateCommand=class extends ApifyCommand{static name=`create`;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 ${Dt} 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:Vr,required:!1}),language:Y.string({char:`l`,description:`Filter templates by programming language. Ignored when --template is provided.`,choices:Br,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:[...Ur],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,_=Et().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 V(x).catch(()=>null),n=e&&await ke(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 z(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&&!le&&!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,G));await setLocalConfig(Object.assign(n||$t,{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(rn);if((n.type===1||n.type===2)&&n.packageManager===`uv`){let e=await Ie(`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 ${sn} 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 ${sn} or higher, but you have Python ${i.version}!`}),warning({message:`Please install Python ${sn} 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},ee=await V(u(v,`.git`)).catch(()=>null),M=await V(u(x,`.git`)).catch(()=>null),N=k!==null&&!k.scaffolded,P=!s&&!ee&&!M&&!N;if(P)try{await execWithLog({cmd:`git`,args:[`init`],opts:{cwd:x}})}catch(e){j={success:!1,error:e}}let te=A?null:await getInstallCommandSuggestion(x),ne=P&&j.success||!!M;k?.stopReason&&(e.exitCode=1);let F=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:te}),re=!k?.stopReason;l?printJsonToStdout({dir:x,actorJsonPath:u(x,G),template:C,source:g,nextSteps:F,postCreate:S?.postCreate??null,gitRepositoryInitialized:ne,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}):re&&(simpleLog({message:``}),success({message:formatCreateSuccessMessage({actorName:t,dependenciesInstalled:A,postCreate:S?.postCreate??null,gitRepositoryInitialized:ne,installCommandSuggestion:te,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,F)}};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 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 Jr={[U.JSON]:`application/json`,[U.JSONL]:`application/jsonl`,[U.CSV]:`text/csv`,[U.HTML]:`text/html`,[U.RSS]:`application/rss+xml`,[U.XML]:`application/xml`,[U.XLSX]:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`};var DatasetsGetItems=class extends ApifyCommand{static name=`get-items`;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(Jr),default:U.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:Jr[n]??`application/octet-stream`}),process.stdout.write(c),process.stdout.write(`
|
|
149
149
|
`)}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 Yr=new Q({allColumns:[`Row1`,`Row2`],mandatoryColumns:[`Row1`,`Row2`]});var DatasetsInfoCommand=class extends ApifyCommand{static name=`info`;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(K.display(i.createdAt))}`,`Modified: ${t.bold(K.display(i.modifiedAt))}`].join(`
|
|
150
150
|
`),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(`
|
|
151
151
|
`);Yr.pushRow({Row1:v,Row2:S});let C=Yr.render(2).split(`
|
|
@@ -176,7 +176,7 @@ Creates the '${G}' file and the '${Qt}' directory in the current directory, but
|
|
|
176
176
|
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=D(t)?await B(t,`utf-8`):``,l=s.trim(),u;if(l){let e;try{e=wt.parse(s)}catch(e){let n=e instanceof Error?e.message.split(`
|
|
177
177
|
`)[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=wt.update(s,e)}else{let e={[n]:{[r]:i}};u=`${wt.stringify(e,{mode:`json`,indent:2})}\n`}await z(c(t),{recursive:!0});let f=`${t}.${e.pid}.tmp`;try{await H(f,u,`utf-8`),await Ae(f,t)}catch(e){throw await je(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 ai=`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(`
|
|
178
178
|
`)})}function isExecaError(e){return typeof e==`object`&&!!e&&`shortMessage`in e&&`command`in e}function describeExecaError(e,t){return isExecaError(e)?e.exitCode==null?e.signal?`${t} exited due to signal ${e.signal}`:e.shortMessage??e.message:`${t} exited with code ${e.exitCode}`:e instanceof Error?e.message:String(e)}async function runCliInstall({binary:t,clientLabel:n,token:r,args:i,maskedCommand:a,missingMessage:s}){if(!await Ie(t,{nothrow:!0}))return error({message:s}),e.exitCode=250,!1;run({message:a});try{await Ee(t,i,{stdio:[`ignore`,`ignore`,`pipe`]})}catch(i){let a=isExecaError(i)?String(i.stderr??``).trim():``;return error({message:maskSecret(`Failed to add the MCP server via ${n}: ${a?`${describeExecaError(i,t)}\n${a}`:describeExecaError(i,t)}`,r)}),e.exitCode=1,!1}return!0}function fileClient({label:t,segments:n,entry:r}){return async({url:i,token:a,yes:s})=>{let c=userHomeDir();if(!c){error({message:`User home directory could not be determined. Set the HOME environment variable and re-run.`}),e.exitCode=5;return}let l=u(c,...n);await mergeServerEntry({filePath:l,topLevelKey:`mcpServers`,entryKey:ai,serverEntry:r(i,a),yes:s})&&printResult({clientLabel:t,serverUrl:i,authDescription:`Bearer ${maskToken(a)}`,configPath:l})}}const claudeCodeHandler=async({url:e,token:t})=>{let command=t=>`claude mcp add --transport http --scope user ${ai} "${e}" --header "Authorization: Bearer ${t}"`;await runCliInstall({binary:`claude`,clientLabel:`Claude Code`,token:t,args:[`mcp`,`add`,`--transport`,`http`,`--scope`,`user`,ai,e,`--header`,`Authorization: Bearer ${t}`],maskedCommand:command(maskToken(t)),missingMessage:`The 'claude' CLI was not found on PATH. Install Claude Code (https://docs.anthropic.com/en/docs/claude-code) and re-run, or add the server manually:\n\n ${command(`<your-token>`)}`})&&printResult({clientLabel:`Claude Code`,serverUrl:e,authDescription:`Bearer ${maskToken(t)} (stored by Claude Code)`})};function vscodeHandler(e,t){return async({url:n,token:r})=>{let serverJson=e=>JSON.stringify({name:ai,type:`http`,url:n,headers:{Authorization:e}});await runCliInstall({binary:e,clientLabel:t,token:r,args:[`--add-mcp`,serverJson(`Bearer ${r}`)],maskedCommand:`${e} --add-mcp '${serverJson(`Bearer ${maskToken(r)}`)}'`,missingMessage:`The '${e}' CLI was not found on PATH. Install ${t} and re-run, or add the server manually:\n\n ${e} --add-mcp '${serverJson(`Bearer <your-token>`)}'`})&&printResult({clientLabel:t,serverUrl:n,authDescription:`Bearer ${maskToken(r)} (stored by ${t})`})}}const codexHandler=async({url:n})=>{let r=userHomeDir();if(!r){error({message:`User home directory could not be determined. Set the HOME environment variable and re-run.`}),e.exitCode=5;return}let i=u(r,`.codex`,`config.toml`),a=[`mcp`,`add`,ai,`--url`,n,`--bearer-token-env-var`,`APIFY_TOKEN`],s=[`[mcp_servers.${ai}]`,`url = "${n}"`,`bearer_token_env_var = "APIFY_TOKEN"`].join(`
|
|
179
|
-
`);await runCliInstall({binary:`codex`,clientLabel:`Codex CLI`,token:``,args:a,maskedCommand:`codex ${a.join(` `)}`,missingMessage:`The 'codex' CLI was not found on PATH. Install Codex (https://developers.openai.com/codex) and re-run, or add this entry manually to ${tildify(i)}:\n\n${s}\n\nThen, before launching codex, export your Apify token in the same shell:\n\n export APIFY_TOKEN=<your-token>`})&&printResult({clientLabel:`Codex CLI`,serverUrl:n,authDescription:`Bearer token from APIFY_TOKEN environment variable`,configPath:i,nextSteps:` ${t.yellow(`Next:`)} Codex reads APIFY_TOKEN from the environment. Before launching codex, run:\n\n export APIFY_TOKEN=<your-token>`})},oi={"claude-code":claudeCodeHandler,cursor:fileClient({label:`Cursor`,segments:[`.cursor`,`mcp.json`],entry:(e,t)=>({url:e,headers:bearer(t)})}),vscode:vscodeHandler(`code`,`VS Code`),"vscode-insiders":vscodeHandler(`code-insiders`,`VS Code Insiders`),codex:codexHandler,kiro:fileClient({label:`Kiro`,segments:[`.kiro`,`settings`,`mcp.json`],entry:(e,t)=>({url:e,headers:bearer(t),disabled:!1,autoApprove:[]})}),antigravity:fileClient({label:`Antigravity`,segments:[`.gemini`,`antigravity`,`mcp_config.json`],entry:(e,t)=>({serverUrl:e,headers:bearer(t)})})},si=Object.keys(oi);function isSupportedClient(e){return e in oi}const ci
|
|
179
|
+
`);await runCliInstall({binary:`codex`,clientLabel:`Codex CLI`,token:``,args:a,maskedCommand:`codex ${a.join(` `)}`,missingMessage:`The 'codex' CLI was not found on PATH. Install Codex (https://developers.openai.com/codex) and re-run, or add this entry manually to ${tildify(i)}:\n\n${s}\n\nThen, before launching codex, export your Apify token in the same shell:\n\n export APIFY_TOKEN=<your-token>`})&&printResult({clientLabel:`Codex CLI`,serverUrl:n,authDescription:`Bearer token from APIFY_TOKEN environment variable`,configPath:i,nextSteps:` ${t.yellow(`Next:`)} Codex reads APIFY_TOKEN from the environment. Before launching codex, run:\n\n export APIFY_TOKEN=<your-token>`})},oi={"claude-code":claudeCodeHandler,cursor:fileClient({label:`Cursor`,segments:[`.cursor`,`mcp.json`],entry:(e,t)=>({url:e,headers:bearer(t)})}),vscode:vscodeHandler(`code`,`VS Code`),"vscode-insiders":vscodeHandler(`code-insiders`,`VS Code Insiders`),codex:codexHandler,kiro:fileClient({label:`Kiro`,segments:[`.kiro`,`settings`,`mcp.json`],entry:(e,t)=>({url:e,headers:bearer(t),disabled:!1,autoApprove:[]})}),antigravity:fileClient({label:`Antigravity`,segments:[`.gemini`,`antigravity`,`mcp_config.json`],entry:(e,t)=>({serverUrl:e,headers:bearer(t)})})},si=Object.keys(oi);function isSupportedClient(e){return e in oi}const ci=/* @__PURE__ */ new Set([`codex`]);function clientNeedsToken(e){return!ci.has(e)}function getClientHandler(e){return oi[e]}var MCPInstallCommand=class extends ApifyCommand{static name=`install`;static description=`Configure a local MCP client to use the Apify MCP server. Writes or merges a server entry named 'apify' into the client's config file, or runs the client's own 'mcp add' command when available.`;static group=`MCP`;static interactive=!0;static interactiveNote=`Prompts before overwriting an existing JSON config entry (cursor, kiro, antigravity). Pass --yes to overwrite without prompting. For clients delegated to their own CLI (claude-code, vscode, vscode-insiders, codex), overwrite behavior is controlled by that CLI.`;static examples=[{description:`Add Apify to Claude Code using the stored API token.`,command:`apify mcp install claude-code`},{description:`Add Apify to Cursor.`,command:`apify mcp install cursor`},{description:`Add only the 'search-actors' tool and the 'apify/rag-web-browser' Actor to VS Code.`,command:`apify mcp install vscode --tools search-actors,apify/rag-web-browser`},{description:`Add Apify to Codex CLI with an explicit token (non-interactive).`,command:`apify mcp install codex --token apify_api_xxxxx --yes`}];static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-mcp-install`;static args={client:Z.string({required:!0,description:`Target MCP client. One of: ${si.join(`, `)}.`})};static flags={...YesFlag(`Overwrite an existing 'apify' entry without prompting.`),token:Y.string({char:`t`,description:`Apify API token to embed in the config. Defaults to APIFY_TOKEN, then the token from 'apify login'.`}),url:Y.string({description:`Apify MCP server URL.`,default:`https://mcp.apify.com`}),tools:Y.string({description:`Comma-separated tool IDs or Actor full names to expose. Forwarded as a '?tools=' query parameter.`})};async run(){let{client:t}=this.args,{token:n,url:r,tools:i,yes:a}=this.flags;if(!isSupportedClient(t)){error({message:`Unknown MCP client '${t}'. Supported clients: ${si.join(`, `)}.`}),e.exitCode=5;return}let s=``;if(clientNeedsToken(t)){let t=n?{token:n}:await resolveAuth();if(!t){error({message:`You are not logged in to Apify. Run 'apify login' first, or pass --token <api-token>.`}),e.exitCode=1;return}s=t.token}await getClientHandler(t)({url:buildMcpUrl(r,i),token:s,yes:a})}},MCPIndexCommand=class extends ApifyCommand{static name=`mcp`;static description=`Configure the Apify MCP server in your AI client: Claude Code, Cursor, VS Code, Codex CLI, Kiro, or Antigravity.`;static group=`MCP`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-mcp`;static subcommands=[MCPInstallCommand];async run(){this.printHelp()}},TopLevelPullCommand=class extends ActorsPullCommand{static name=`pull`},ToplevelPushCommand=class extends ActorsPushCommand{static name=`push`},RequestQueuesIndexCommand=class extends ApifyCommand{static name=`request-queues`;static description=`Manage Apify request queues. No subcommands are available yet.`;static group=`Apify Console`;static docsUrl=`https://docs.apify.com/cli/docs/reference#apify-request-queues`;async run(){this.printHelp()}};const jsScript=e=>`
|
|
180
180
|
(async () => {
|
|
181
181
|
const [nodeModule, process, path, fs] = await Promise.all([
|
|
182
182
|
import('node:module'),
|
|
@@ -241,4 +241,4 @@ When no path is provided, validates all schemas found in '${G}':
|
|
|
241
241
|
- Dataset schema (from "storages.dataset")
|
|
242
242
|
- Output schema (from "output")
|
|
243
243
|
- 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 '${G}'.`})};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 '${G}'`}`});let t=new Ln({strict:!1});ht(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 '${G}'`}`}),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 '${G}' exists and defines at least one schema.`);r&&(e.exitCode=5)}};const yi=[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],bi=[ActorSetValueCommand,ActorPushDataCommand,ActorGetValueCommand,ActorGetPublicUrlCommand,ActorGetInputCommand,ActorChargeCommand,ActorCalculateMemoryCommand,ActorGenerateSchemaTypesCommand,HelpCommand,UpgradeCommand,InstallCommand,TelemetryIndexCommand];export{runCLI as i,yi as n,processVersionCheck as r,bi as t};
|
|
244
|
-
//# sourceMappingURL=_register-
|
|
244
|
+
//# sourceMappingURL=_register-DJntAWNn.js.map
|