apify-cli 0.16.2 → 0.17.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -70,7 +70,7 @@ which should print something like:
70
70
  apify-cli/0.10.0 darwin-x64 node-v16.14.2
71
71
  ```
72
72
 
73
- > You can also skip the manual global installation altogether and use `npx apify-cli` with all the following commands instead.
73
+ > You can also skip the manual global installation altogether and use `npx apify-cli` with all the following commands instead.
74
74
 
75
75
  ## Basic usage
76
76
 
@@ -299,7 +299,7 @@ USAGE
299
299
  $ apify actor
300
300
  ```
301
301
 
302
- _See code: [src/commands/actor/index.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/actor/index.js)_
302
+ _See code: [src/commands/actor/index.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/actor/index.js)_
303
303
 
304
304
  ## `apify actor:get-input`
305
305
 
@@ -310,7 +310,7 @@ USAGE
310
310
  $ apify actor:get-input
311
311
  ```
312
312
 
313
- _See code: [src/commands/actor/get-input.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/actor/get-input.js)_
313
+ _See code: [src/commands/actor/get-input.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/actor/get-input.js)_
314
314
 
315
315
  ## `apify actor:get-value KEY`
316
316
 
@@ -324,7 +324,7 @@ ARGUMENTS
324
324
  KEY Key of the record in key-value store
325
325
  ```
326
326
 
327
- _See code: [src/commands/actor/get-value.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/actor/get-value.js)_
327
+ _See code: [src/commands/actor/get-value.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/actor/get-value.js)_
328
328
 
329
329
  ## `apify actor:push-data [ITEM]`
330
330
 
@@ -345,7 +345,7 @@ DESCRIPTION
345
345
  $ cat ./test.json | apify actor:push-data
346
346
  ```
347
347
 
348
- _See code: [src/commands/actor/push-data.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/actor/push-data.js)_
348
+ _See code: [src/commands/actor/push-data.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/actor/push-data.js)_
349
349
 
350
350
  ## `apify actor:set-value KEY [VALUE]`
351
351
 
@@ -375,7 +375,7 @@ DESCRIPTION
375
375
  $ cat ./my-text-file.txt | apify actor:set-value KEY --contentType text/plain
376
376
  ```
377
377
 
378
- _See code: [src/commands/actor/set-value.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/actor/set-value.js)_
378
+ _See code: [src/commands/actor/set-value.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/actor/set-value.js)_
379
379
 
380
380
  ## `apify call [ACTID]`
381
381
 
@@ -396,11 +396,11 @@ OPTIONS
396
396
  -w, --wait-for-finish=wait-for-finish Seconds for waiting to run to finish, if no value passed, it waits forever.
397
397
 
398
398
  DESCRIPTION
399
- The actor is run under your current Apify account. Therefore you need to be logged in by calling "apify login". It
400
- takes input for the actor from the default local key-value store by default.
399
+ The Actor is run under your current Apify account. Therefore you need to be logged in by calling "apify login". It
400
+ takes input for the Actor from the default local key-value store by default.
401
401
  ```
402
402
 
403
- _See code: [src/commands/call.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/call.js)_
403
+ _See code: [src/commands/call.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/call.js)_
404
404
 
405
405
  ## `apify create [ACTORNAME]`
406
406
 
@@ -422,7 +422,7 @@ OPTIONS
422
422
  --skip-dependency-install Skip installing actor dependencies.
423
423
  ```
424
424
 
425
- _See code: [src/commands/create.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/create.js)_
425
+ _See code: [src/commands/create.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/create.js)_
426
426
 
427
427
  ## `apify info`
428
428
 
@@ -436,7 +436,7 @@ DESCRIPTION
436
436
  The information is printed to the console.
437
437
  ```
438
438
 
439
- _See code: [src/commands/info.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/info.js)_
439
+ _See code: [src/commands/info.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/info.js)_
440
440
 
441
441
  ## `apify init [ACTORNAME]`
442
442
 
@@ -456,7 +456,7 @@ DESCRIPTION
456
456
  WARNING: The directory at "storage" will be overwritten if it already exists.
457
457
  ```
458
458
 
459
- _See code: [src/commands/init.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/init.js)_
459
+ _See code: [src/commands/init.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/init.js)_
460
460
 
461
461
  ## `apify login`
462
462
 
@@ -474,7 +474,7 @@ DESCRIPTION
474
474
  "apify" commands. To log out, call "apify logout".
475
475
  ```
476
476
 
477
- _See code: [src/commands/login.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/login.js)_
477
+ _See code: [src/commands/login.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/login.js)_
478
478
 
479
479
  ## `apify logout`
480
480
 
@@ -489,7 +489,7 @@ DESCRIPTION
489
489
  call "apify login".
490
490
  ```
491
491
 
492
- _See code: [src/commands/logout.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/logout.js)_
492
+ _See code: [src/commands/logout.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/logout.js)_
493
493
 
494
494
  ## `apify pull [ACTORID]`
495
495
 
@@ -507,7 +507,7 @@ OPTIONS
507
507
  -v, --version=version Actor version number which will be pulled, e.g. 1.2. Default: the highest version
508
508
  ```
509
509
 
510
- _See code: [src/commands/pull.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/pull.js)_
510
+ _See code: [src/commands/pull.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/pull.js)_
511
511
 
512
512
  ## `apify push [ACTORID]`
513
513
 
@@ -537,7 +537,7 @@ OPTIONS
537
537
  should be pushed. By default, it is taken from the ".actor/actor.json" file.
538
538
 
539
539
  DESCRIPTION
540
- The actor settings are read from the ".actor/actor.json" file in the current directory, but they can be overridden
540
+ The Actor settings are read from the ".actor/actor.json" file in the current directory, but they can be overridden
541
541
  using command-line options.
542
542
  NOTE: If the source files are smaller than 3 MB then they are uploaded as
543
543
  "Multiple source files", otherwise they are uploaded as "Zip file".
@@ -545,7 +545,7 @@ DESCRIPTION
545
545
  WARNING: If the target Actor already exists in your Apify account, it will be overwritten!
546
546
  ```
547
547
 
548
- _See code: [src/commands/push.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/push.js)_
548
+ _See code: [src/commands/push.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/push.js)_
549
549
 
550
550
  ## `apify run`
551
551
 
@@ -575,7 +575,7 @@ DESCRIPTION
575
575
  package.json file. You can set up your own main file or environment variables by changing it.
576
576
  ```
577
577
 
578
- _See code: [src/commands/run.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/run.js)_
578
+ _See code: [src/commands/run.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/run.js)_
579
579
 
580
580
  ## `apify secrets`
581
581
 
@@ -603,7 +603,7 @@ DESCRIPTION
603
603
  of the actor.
604
604
  ```
605
605
 
606
- _See code: [src/commands/secrets/index.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/secrets/index.js)_
606
+ _See code: [src/commands/secrets/index.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/secrets/index.js)_
607
607
 
608
608
  ## `apify secrets:add NAME VALUE`
609
609
 
@@ -621,7 +621,7 @@ DESCRIPTION
621
621
  The secrets are stored to a file at ~/.apify
622
622
  ```
623
623
 
624
- _See code: [src/commands/secrets/add.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/secrets/add.js)_
624
+ _See code: [src/commands/secrets/add.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/secrets/add.js)_
625
625
 
626
626
  ## `apify secrets:rm NAME`
627
627
 
@@ -635,7 +635,7 @@ ARGUMENTS
635
635
  NAME Name of the secret
636
636
  ```
637
637
 
638
- _See code: [src/commands/secrets/rm.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/secrets/rm.js)_
638
+ _See code: [src/commands/secrets/rm.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/secrets/rm.js)_
639
639
 
640
640
  ## `apify vis [PATH]`
641
641
 
@@ -659,5 +659,5 @@ DESCRIPTION
659
659
  You can also pass any custom path to your input schema to have it validated instead.
660
660
  ```
661
661
 
662
- _See code: [src/commands/vis.js](https://github.com/apify/apify-cli/blob/v0.16.2/src/commands/vis.js)_
662
+ _See code: [src/commands/vis.js](https://github.com/apify/apify-cli/blob/v0.17.0/src/commands/vis.js)_
663
663
  <!-- commandsstop -->
@@ -39,6 +39,7 @@
39
39
  "jju": "^1.4.0",
40
40
  "load-json-file": "^6.2.0",
41
41
  "mime": "^2.6.0",
42
+ "mixpanel": "^0.17.0",
42
43
  "open": "^8.4.0",
43
44
  "ow": "^0.28.1",
44
45
  "rimraf": "^3.0.2",
@@ -5441,6 +5442,17 @@
5441
5442
  "node": ">=8"
5442
5443
  }
5443
5444
  },
5445
+ "node_modules/mixpanel": {
5446
+ "version": "0.17.0",
5447
+ "resolved": "https://registry.npmjs.org/mixpanel/-/mixpanel-0.17.0.tgz",
5448
+ "integrity": "sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g==",
5449
+ "dependencies": {
5450
+ "https-proxy-agent": "5.0.0"
5451
+ },
5452
+ "engines": {
5453
+ "node": ">=10.0"
5454
+ }
5455
+ },
5444
5456
  "node_modules/mkdirp-classic": {
5445
5457
  "version": "0.5.3",
5446
5458
  "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
@@ -12175,6 +12187,14 @@
12175
12187
  }
12176
12188
  }
12177
12189
  },
12190
+ "mixpanel": {
12191
+ "version": "0.17.0",
12192
+ "resolved": "https://registry.npmjs.org/mixpanel/-/mixpanel-0.17.0.tgz",
12193
+ "integrity": "sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g==",
12194
+ "requires": {
12195
+ "https-proxy-agent": "5.0.0"
12196
+ }
12197
+ },
12178
12198
  "mkdirp-classic": {
12179
12199
  "version": "0.5.3",
12180
12200
  "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
@@ -1 +1 @@
1
- {"version":"0.16.2","commands":{"call":{"id":"call","description":"Runs a specific actor remotely on the Apify cloud platform.\nThe actor is run under your current Apify account. Therefore you need to be logged in by calling \"apify login\". It takes input for the actor from the default local key-value store by default.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"build":{"name":"build","type":"option","char":"b","description":"Tag or number of the build to run (e.g. \"latest\" or \"1.2.34\").","required":false},"timeout":{"name":"timeout","type":"option","char":"t","description":"Timeout for the actor run in seconds. Zero value means there is no timeout.","required":false},"memory":{"name":"memory","type":"option","char":"m","description":"Amount of memory allocated for the actor run, in megabytes.","required":false},"wait-for-finish":{"name":"wait-for-finish","type":"option","char":"w","description":"Seconds for waiting to run to finish, if no value passed, it waits forever.","required":false}},"args":[{"name":"actId","description":"Name or ID of the actor to run (e.g. \"apify/hello-world\" or \"E2jjCZBezvAZnX8Rb\"). If not provided, the command runs the remote actor specified in the \".actor/actor.json\" file.","required":false}]},"check-version":{"id":"check-version","description":"Checks that installed Apify CLI version is up to date.","pluginName":"apify-cli","pluginType":"core","hidden":true,"aliases":["cv"],"flags":{"enforce-update":{"name":"enforce-update","type":"boolean","char":"e","description":"[Optional] Enforce version update from NPM","required":false,"allowNo":false}},"args":[]},"create":{"id":"create","description":"Creates a new actor project directory from a selected boilerplate template.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"template":{"name":"template","type":"option","char":"t","description":"Template for the actor. If not provided, the command will prompt for it.\nVisit https://raw.githubusercontent.com/apify/actor-templates/master/templates/manifest.json to find available template names.","required":false},"skip-dependency-install":{"name":"skip-dependency-install","type":"boolean","description":"Skip installing actor dependencies.","required":false,"allowNo":false},"template-archive-url":{"name":"template-archive-url","type":"option","description":"Actor template archive url. Useful for developing new templates.","hidden":true,"required":false}},"args":[{"name":"actorName","description":"Name of the actor and its directory","required":false}]},"edit-input-schema":{"id":"edit-input-schema","description":"Lets you edit your input schema that would be used on the platform in a visual input schema editor.","pluginName":"apify-cli","pluginType":"core","hidden":true,"aliases":["eis"],"flags":{},"args":[{"name":"path","description":"Optional path to your INPUT_SCHEMA.json file. If not provided default platform location for input schema is used.","required":false}]},"info":{"id":"info","description":"Displays information about the currently active Apify account.\nThe information is printed to the console.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"init":{"id":"init","description":"Initializes a new actor project in an existing directory.\nThe command only creates the \".actor/actor.json\" file and the \"storage\" directory in the current directory, but will not touch anything else.\n\nWARNING: The directory at \"storage\" will be overwritten if it already exists.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"actorName","description":"Name of the actor. If not provided, you will be prompted for it.","required":false}]},"login-new":{"id":"login-new","description":"Logs in to your Apify account using your API token.\nThe API token and other account information is stored in the ~/.apify directory, from where it is read by all other \"apify\" commands. To log out, call \"apify logout\".","pluginName":"apify-cli","pluginType":"core","hidden":true,"aliases":[],"flags":{"token":{"name":"token","type":"option","char":"t","description":"[Optional] Apify API token","required":false}},"args":[]},"login":{"id":"login","description":"Logs in to your Apify account using a provided API token.\nThe API token and other account information is stored in the ~/.apify directory, from where it is read by all other \"apify\" commands. To log out, call \"apify logout\".","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"token":{"name":"token","type":"option","char":"t","description":"[Optional] Apify API token","required":false}},"args":[]},"logout":{"id":"logout","description":"Logs out of your Apify account.\nThe command deletes the API token and all other account information stored in the ~/.apify directory. To log in again, call \"apify login\".","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"pull":{"id":"pull","description":"Pulls an Actor from the Apify platform to the current directory. If it is defined as Git repository, it will be cloned. If it is defined as Web IDE, it will fetch the files.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"version":{"name":"version","type":"option","char":"v","description":"Actor version number which will be pulled, e.g. 1.2. Default: the highest version","required":false}},"args":[{"name":"actorId","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.","required":false}]},"push":{"id":"push","description":"Uploads the actor to the Apify platform and builds it there.\nThe actor settings are read from the \".actor/actor.json\" file in the current directory, but they can be overridden using command-line options.\nNOTE: If the source files are smaller than 3 MB then they are uploaded as \n\"Multiple source files\", otherwise they are uploaded as \"Zip file\".\n\nWARNING: If the target Actor already exists in your Apify account, it will be overwritten!","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"version-number":{"name":"version-number","type":"option","description":"DEPRECATED: Use flag version instead. Actor version number to which the files should be pushed. By default, it is taken from the \".actor/actor.json\" file.","required":false},"version":{"name":"version","type":"option","char":"v","description":"Actor version number to which the files should be pushed. By default, it is taken from the \".actor/actor.json\" file.","required":false},"build-tag":{"name":"build-tag","type":"option","char":"b","description":"Build tag to be applied to the successful Actor build. By default, it is taken from the \".actor/actor.json\" file","required":false},"wait-for-finish":{"name":"wait-for-finish","type":"option","char":"w","description":"Seconds for waiting to build to finish, if no value passed, it waits forever.","required":false},"no-prompt":{"name":"no-prompt","type":"boolean","description":"Do not prompt for opening the actor details in a browser. This will also not open the browser automatically.","required":false,"allowNo":false}},"args":[{"name":"actorId","description":"Name or ID of the Actor to push (e.g. \"apify/hello-world\" or \"E2jjCZBezvAZnX8Rb\"). If not provided, the command will create or modify the actor with the name specified in \".actor/actor.json\" file.","required":false}]},"run":{"id":"run","description":"Runs the actor locally in the current directory.\nIt sets various APIFY_XYZ environment variables in order to provide a working execution environment for the actor. For example, this causes the actor input, as well as all other data in key-value stores, datasets or request queues to be stored in the \"storage\" directory, rather than on the Apify platform.\n\nNOTE: You can override the command's default behavior for Node.js actors by overriding the \"start\" script in the package.json file. You can set up your own main file or environment variables by changing it.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"purge":{"name":"purge","type":"boolean","char":"p","description":"Shortcut that combines the --purge-queue, --purge-dataset and --purge-key-value-store options.","required":false,"allowNo":false},"purge-queue":{"name":"purge-queue","type":"boolean","description":"Deletes the local directory containing the default request queue before the run starts.","required":false,"allowNo":false},"purge-dataset":{"name":"purge-dataset","type":"boolean","description":"Deletes the local directory containing the default dataset before the run starts.","required":false,"allowNo":false},"purge-key-value-store":{"name":"purge-key-value-store","type":"boolean","description":"Deletes all records from the default key-value store in the local directory before the run starts, except for the \"INPUT\" key.","required":false,"allowNo":false}},"args":[]},"vis":{"id":"vis","description":"Validates input schema and prints errors found.\nThe input schema for the actor is used from these locations in order of preference.\nThe first one found is validated as it would be the one used on the Apify platform.\n1. Directly embedded object in \".actor/actor.json\" under 'input' key\n2. Path to JSON file referenced in \".actor/actor.json\" under 'input' key\n3. JSON file at .actor/INPUT_SCHEMA.json\n4. JSON file at INPUT_SCHEMA.json\n\nYou can also pass any custom path to your input schema to have it validated instead.\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"path","description":"Optional path to your INPUT_SCHEMA.json file. If not provided ./INPUT_SCHEMA.json is used.","required":false}]},"actor:get-input":{"id":"actor:get-input","description":"Gets the actor input value from the default key-value store associated with the actor run.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"actor:get-value":{"id":"actor:get-value","description":"Gets a value from the default key-value store associated with the actor run.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"key","description":"Key of the record in key-value store","required":true}]},"actor":{"id":"actor","description":"Commands are designed to be used in actor runs. All commands are in PoC state, do not use in production environments.\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"actor:push-data":{"id":"actor:push-data","description":"Stores an object or an array of objects to the default dataset of the actor run.\nIt is possible to pass data using item argument or stdin.\nPassing data using argument:\n$ apify actor:push-data {\"foo\": \"bar\"}\nPassing data using stdin with pipe:\n$ cat ./test.json | apify actor:push-data\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"item","description":"JSON string with one object or array of objects containing data to be stored in the default dataset.","required":false}]},"actor:set-value":{"id":"actor:set-value","description":"Sets or removes record into the default KeyValueStore associated with the actor run.\nIt is possible to pass data using argument or stdin.\nPassing data using argument:\n$ apify actor:set-value KEY my-value\nPassing data using stdin with pipe:\n$ cat ./my-text-file.txt | apify actor:set-value KEY --contentType text/plain\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"contentType":{"name":"contentType","type":"option","char":"c","description":"Specifies a custom MIME content type of the record. By default \"application/json\" is used.","required":false}},"args":[{"name":"key","description":"Key of the record in key-value store.","required":true},{"name":"value","description":"Record data, which can be one of the following values:\n- If empty, the record in the key-value store is deleted.\n- If no `contentType` flag is specified, value is expected to be any JSON string value.\n- If options.contentType is set, value is taken as is.","required":false}]},"secrets:add":{"id":"secrets:add","description":"Adds a new secret value.\nThe secrets are stored to a file at ~/.apify","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"name","description":"Name of the secret","required":true},{"name":"value","description":"Value of the secret","required":true}]},"secrets":{"id":"secrets","description":"Manages secret values for actor environment variables.\n\nExample:\n$ apify secrets:add mySecret TopSecretValue123\n\nNow the \"mySecret\" value can be used in an environment variable defined in \".actor/actor.json\" file by adding the \"@\" prefix:\n\n{\n \"actorSpecification\": 1,\n \"name\": \"my_actor\",\n \"environmentVariables\": { \"SECRET_ENV_VAR\": \"@mySecret\" },\n \"version\": \"0.1\n}\n\nWhen the actor is pushed to Apify cloud, the \"SECRET_ENV_VAR\" and its value is stored as a secret environment variable of the actor.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"secrets:rm":{"id":"secrets:rm","description":"Removes the secret.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"name","description":"Name of the secret","required":true}]}}}
1
+ {"version":"0.17.0","commands":{"call":{"id":"call","description":"Runs a specific actor remotely on the Apify cloud platform.\nThe Actor is run under your current Apify account. Therefore you need to be logged in by calling \"apify login\". It takes input for the Actor from the default local key-value store by default.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"build":{"name":"build","type":"option","char":"b","description":"Tag or number of the build to run (e.g. \"latest\" or \"1.2.34\").","required":false},"timeout":{"name":"timeout","type":"option","char":"t","description":"Timeout for the actor run in seconds. Zero value means there is no timeout.","required":false},"memory":{"name":"memory","type":"option","char":"m","description":"Amount of memory allocated for the actor run, in megabytes.","required":false},"wait-for-finish":{"name":"wait-for-finish","type":"option","char":"w","description":"Seconds for waiting to run to finish, if no value passed, it waits forever.","required":false}},"args":[{"name":"actId","description":"Name or ID of the actor to run (e.g. \"apify/hello-world\" or \"E2jjCZBezvAZnX8Rb\"). If not provided, the command runs the remote actor specified in the \".actor/actor.json\" file.","required":false}]},"check-version":{"id":"check-version","description":"Checks that installed Apify CLI version is up to date.","pluginName":"apify-cli","pluginType":"core","hidden":true,"aliases":["cv"],"flags":{"enforce-update":{"name":"enforce-update","type":"boolean","char":"e","description":"[Optional] Enforce version update from NPM","required":false,"allowNo":false}},"args":[]},"create":{"id":"create","description":"Creates a new actor project directory from a selected boilerplate template.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"template":{"name":"template","type":"option","char":"t","description":"Template for the actor. If not provided, the command will prompt for it.\nVisit https://raw.githubusercontent.com/apify/actor-templates/master/templates/manifest.json to find available template names.","required":false},"skip-dependency-install":{"name":"skip-dependency-install","type":"boolean","description":"Skip installing actor dependencies.","required":false,"allowNo":false},"template-archive-url":{"name":"template-archive-url","type":"option","description":"Actor template archive url. Useful for developing new templates.","hidden":true,"required":false}},"args":[{"name":"actorName","description":"Name of the actor and its directory","required":false}]},"edit-input-schema":{"id":"edit-input-schema","description":"Lets you edit your input schema that would be used on the platform in a visual input schema editor.","pluginName":"apify-cli","pluginType":"core","hidden":true,"aliases":["eis"],"flags":{},"args":[{"name":"path","description":"Optional path to your INPUT_SCHEMA.json file. If not provided default platform location for input schema is used.","required":false}]},"info":{"id":"info","description":"Displays information about the currently active Apify account.\nThe information is printed to the console.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"init":{"id":"init","description":"Initializes a new actor project in an existing directory.\nThe command only creates the \".actor/actor.json\" file and the \"storage\" directory in the current directory, but will not touch anything else.\n\nWARNING: The directory at \"storage\" will be overwritten if it already exists.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"actorName","description":"Name of the actor. If not provided, you will be prompted for it.","required":false}]},"login-new":{"id":"login-new","description":"Logs in to your Apify account using your API token.\nThe API token and other account information is stored in the ~/.apify directory, from where it is read by all other \"apify\" commands. To log out, call \"apify logout\".","pluginName":"apify-cli","pluginType":"core","hidden":true,"aliases":[],"flags":{"token":{"name":"token","type":"option","char":"t","description":"[Optional] Apify API token","required":false}},"args":[]},"login":{"id":"login","description":"Logs in to your Apify account using a provided API token.\nThe API token and other account information is stored in the ~/.apify directory, from where it is read by all other \"apify\" commands. To log out, call \"apify logout\".","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"token":{"name":"token","type":"option","char":"t","description":"[Optional] Apify API token","required":false}},"args":[]},"logout":{"id":"logout","description":"Logs out of your Apify account.\nThe command deletes the API token and all other account information stored in the ~/.apify directory. To log in again, call \"apify login\".","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"pull":{"id":"pull","description":"Pulls an Actor from the Apify platform to the current directory. If it is defined as Git repository, it will be cloned. If it is defined as Web IDE, it will fetch the files.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"version":{"name":"version","type":"option","char":"v","description":"Actor version number which will be pulled, e.g. 1.2. Default: the highest version","required":false}},"args":[{"name":"actorId","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.","required":false}]},"push":{"id":"push","description":"Uploads the actor to the Apify platform and builds it there.\nThe Actor settings are read from the \".actor/actor.json\" file in the current directory, but they can be overridden using command-line options.\nNOTE: If the source files are smaller than 3 MB then they are uploaded as \n\"Multiple source files\", otherwise they are uploaded as \"Zip file\".\n\nWARNING: If the target Actor already exists in your Apify account, it will be overwritten!","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"version-number":{"name":"version-number","type":"option","description":"DEPRECATED: Use flag version instead. Actor version number to which the files should be pushed. By default, it is taken from the \".actor/actor.json\" file.","required":false},"version":{"name":"version","type":"option","char":"v","description":"Actor version number to which the files should be pushed. By default, it is taken from the \".actor/actor.json\" file.","required":false},"build-tag":{"name":"build-tag","type":"option","char":"b","description":"Build tag to be applied to the successful Actor build. By default, it is taken from the \".actor/actor.json\" file","required":false},"wait-for-finish":{"name":"wait-for-finish","type":"option","char":"w","description":"Seconds for waiting to build to finish, if no value passed, it waits forever.","required":false},"no-prompt":{"name":"no-prompt","type":"boolean","description":"Do not prompt for opening the actor details in a browser. This will also not open the browser automatically.","required":false,"allowNo":false}},"args":[{"name":"actorId","description":"Name or ID of the Actor to push (e.g. \"apify/hello-world\" or \"E2jjCZBezvAZnX8Rb\"). If not provided, the command will create or modify the actor with the name specified in \".actor/actor.json\" file.","required":false}]},"run":{"id":"run","description":"Runs the actor locally in the current directory.\nIt sets various APIFY_XYZ environment variables in order to provide a working execution environment for the actor. For example, this causes the actor input, as well as all other data in key-value stores, datasets or request queues to be stored in the \"storage\" directory, rather than on the Apify platform.\n\nNOTE: You can override the command's default behavior for Node.js actors by overriding the \"start\" script in the package.json file. You can set up your own main file or environment variables by changing it.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"purge":{"name":"purge","type":"boolean","char":"p","description":"Shortcut that combines the --purge-queue, --purge-dataset and --purge-key-value-store options.","required":false,"allowNo":false},"purge-queue":{"name":"purge-queue","type":"boolean","description":"Deletes the local directory containing the default request queue before the run starts.","required":false,"allowNo":false},"purge-dataset":{"name":"purge-dataset","type":"boolean","description":"Deletes the local directory containing the default dataset before the run starts.","required":false,"allowNo":false},"purge-key-value-store":{"name":"purge-key-value-store","type":"boolean","description":"Deletes all records from the default key-value store in the local directory before the run starts, except for the \"INPUT\" key.","required":false,"allowNo":false}},"args":[]},"vis":{"id":"vis","description":"Validates input schema and prints errors found.\nThe input schema for the actor is used from these locations in order of preference.\nThe first one found is validated as it would be the one used on the Apify platform.\n1. Directly embedded object in \".actor/actor.json\" under 'input' key\n2. Path to JSON file referenced in \".actor/actor.json\" under 'input' key\n3. JSON file at .actor/INPUT_SCHEMA.json\n4. JSON file at INPUT_SCHEMA.json\n\nYou can also pass any custom path to your input schema to have it validated instead.\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"path","description":"Optional path to your INPUT_SCHEMA.json file. If not provided ./INPUT_SCHEMA.json is used.","required":false}]},"actor:get-input":{"id":"actor:get-input","description":"Gets the actor input value from the default key-value store associated with the actor run.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"actor:get-value":{"id":"actor:get-value","description":"Gets a value from the default key-value store associated with the actor run.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"key","description":"Key of the record in key-value store","required":true}]},"actor":{"id":"actor","description":"Commands are designed to be used in actor runs. All commands are in PoC state, do not use in production environments.\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"actor:push-data":{"id":"actor:push-data","description":"Stores an object or an array of objects to the default dataset of the actor run.\nIt is possible to pass data using item argument or stdin.\nPassing data using argument:\n$ apify actor:push-data {\"foo\": \"bar\"}\nPassing data using stdin with pipe:\n$ cat ./test.json | apify actor:push-data\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"item","description":"JSON string with one object or array of objects containing data to be stored in the default dataset.","required":false}]},"actor:set-value":{"id":"actor:set-value","description":"Sets or removes record into the default KeyValueStore associated with the actor run.\nIt is possible to pass data using argument or stdin.\nPassing data using argument:\n$ apify actor:set-value KEY my-value\nPassing data using stdin with pipe:\n$ cat ./my-text-file.txt | apify actor:set-value KEY --contentType text/plain\n","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{"contentType":{"name":"contentType","type":"option","char":"c","description":"Specifies a custom MIME content type of the record. By default \"application/json\" is used.","required":false}},"args":[{"name":"key","description":"Key of the record in key-value store.","required":true},{"name":"value","description":"Record data, which can be one of the following values:\n- If empty, the record in the key-value store is deleted.\n- If no `contentType` flag is specified, value is expected to be any JSON string value.\n- If options.contentType is set, value is taken as is.","required":false}]},"secrets:add":{"id":"secrets:add","description":"Adds a new secret value.\nThe secrets are stored to a file at ~/.apify","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"name","description":"Name of the secret","required":true},{"name":"value","description":"Value of the secret","required":true}]},"secrets":{"id":"secrets","description":"Manages secret values for actor environment variables.\n\nExample:\n$ apify secrets:add mySecret TopSecretValue123\n\nNow the \"mySecret\" value can be used in an environment variable defined in \".actor/actor.json\" file by adding the \"@\" prefix:\n\n{\n \"actorSpecification\": 1,\n \"name\": \"my_actor\",\n \"environmentVariables\": { \"SECRET_ENV_VAR\": \"@mySecret\" },\n \"version\": \"0.1\n}\n\nWhen the actor is pushed to Apify cloud, the \"SECRET_ENV_VAR\" and its value is stored as a secret environment variable of the actor.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[]},"secrets:rm":{"id":"secrets:rm","description":"Removes the secret.","pluginName":"apify-cli","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"name","description":"Name of the secret","required":true}]}}}
package/package.json CHANGED
@@ -1,113 +1,114 @@
1
1
  {
2
- "name": "apify-cli",
3
- "version": "0.16.2",
4
- "description": "Apify command-line interface helps you create, develop, build and run Apify actors, and manage the Apify cloud platform.",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "cross-env APIFY_CLI_SKIP_UPDATE_CHECK=1 mocha --timeout 180000 --recursive",
8
- "test-python": "npm run test -- --grep '\\[python\\]'",
9
- "lint": "eslint src test",
10
- "lint:fix": "eslint src test --fix",
11
- "commands-md": "npm run manifest && oclif-dev readme",
12
- "prepare-release": "npm run commands-md && npm run prod-shrinkwrap",
13
- "prod-shrinkwrap": "rm -rf node_modules && npm install --production && npm shrinkwrap",
14
- "manifest": "rm -f oclif.manifest.json && oclif-dev manifest",
15
- "postinstall": "node \"./src/bin/run\" check-version && node ./src/lib/community"
16
- },
17
- "files": [
18
- "src",
19
- "oclif.manifest.json",
20
- "index.js",
21
- "package.json"
22
- ],
23
- "bin": {
24
- "apify": "./src/bin/run"
25
- },
26
- "contributors": [
27
- "Jakub Drobník <jakub.drobnik@apify.com>",
28
- "Jan Curn <jan@apify.com>"
29
- ],
30
- "repository": {
31
- "type": "git",
32
- "url": "git+https://github.com/apify/apify-cli.git"
33
- },
34
- "keywords": [
35
- "apify",
36
- "client",
37
- "node",
38
- "command",
39
- "line",
40
- "bash"
41
- ],
42
- "author": {
43
- "name": "Apify",
44
- "email": "support@apify.com",
45
- "url": "https://www.apify.com"
46
- },
47
- "license": "Apache-2.0",
48
- "bugs": {
49
- "url": "https://github.com/apify/apify-cli/issues"
50
- },
51
- "homepage": "https://github.com/apify/apify-cli#readme",
52
- "engines": {
53
- "node": ">=16.0.0"
54
- },
55
- "dependencies": {
56
- "@apify/actor-templates": "^0.1.3",
57
- "@apify/consts": "^2.7.0",
58
- "@apify/input_schema": "^3.3.0",
59
- "@apify/utilities": "^2.2.3",
60
- "@crawlee/memory-storage": "^3.0.3",
61
- "@oclif/command": "^1.8.16",
62
- "@oclif/config": "^1.18.3",
63
- "@oclif/errors": "^1.3.5",
64
- "@oclif/plugin-commands": "^2.1.0",
65
- "@oclif/plugin-help": "^5.1.12",
66
- "adm-zip": "^0.5.10",
67
- "ajv": "^8.10.0",
68
- "apify-client": "^2.2.0",
69
- "archiver-promise": "^1.0.0",
70
- "axios": "^0.21.1",
71
- "chalk": "^4.1.2",
72
- "computer-name": "^0.1.0",
73
- "cors": "^2.8.5",
74
- "detect-indent": "^6.1.0",
75
- "escape-string-regexp": "^4.0.0",
76
- "express": "^4.18.2",
77
- "globby": "^11.1.0",
78
- "inquirer": "^7.3.3",
79
- "is-ci": "^3.0.1",
80
- "is-online": "^10.0.0",
81
- "istextorbinary": "^6.0.0",
82
- "jju": "^1.4.0",
83
- "load-json-file": "^6.2.0",
84
- "mime": "^2.6.0",
85
- "open": "^8.4.0",
86
- "ow": "^0.28.1",
87
- "rimraf": "^3.0.2",
88
- "semver": "^7.3.5",
89
- "tiged": "^2.12.4",
90
- "underscore": "^1.13.2",
91
- "write-json-file": "^4.3.0"
92
- },
93
- "devDependencies": {
94
- "@apify/eslint-config": "^0.2.3",
95
- "@oclif/dev-cli": "^1.26.0",
96
- "@oclif/test": "^2.1.0",
97
- "chai": "^4.3.4",
98
- "chai-match": "^1.1.1",
99
- "cross-env": "^7.0.3",
100
- "eslint": "^8.11.0",
101
- "mocha": "^10.0.0",
102
- "sinon": "^9.2.4"
103
- },
104
- "oclif": {
105
- "bin": "apify",
106
- "commands": "./src/commands",
107
- "hooks": {
108
- "init": [
109
- "./src/hooks/init"
110
- ]
111
- }
2
+ "name": "apify-cli",
3
+ "version": "0.17.0-beta.0",
4
+ "description": "Apify command-line interface helps you create, develop, build and run Apify actors, and manage the Apify cloud platform.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "cross-env APIFY_CLI_SKIP_UPDATE_CHECK=1 mocha --timeout 180000 --recursive",
8
+ "test-python": "npm run test -- --grep '\\[python\\]'",
9
+ "lint": "eslint src test",
10
+ "lint:fix": "eslint src test --fix",
11
+ "commands-md": "npm run manifest && oclif-dev readme",
12
+ "prepare-release": "npm run commands-md && npm run prod-shrinkwrap",
13
+ "prod-shrinkwrap": "rm -rf node_modules && npm install --production && npm shrinkwrap",
14
+ "manifest": "rm -f oclif.manifest.json && oclif-dev manifest",
15
+ "postinstall": "node \"./src/bin/run\" check-version && node ./src/lib/community"
16
+ },
17
+ "files": [
18
+ "src",
19
+ "oclif.manifest.json",
20
+ "index.js",
21
+ "package.json"
22
+ ],
23
+ "bin": {
24
+ "apify": "./src/bin/run"
25
+ },
26
+ "contributors": [
27
+ "Jakub Drobník <jakub.drobnik@apify.com>",
28
+ "Jan Curn <jan@apify.com>"
29
+ ],
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/apify/apify-cli.git"
33
+ },
34
+ "keywords": [
35
+ "apify",
36
+ "client",
37
+ "node",
38
+ "command",
39
+ "line",
40
+ "bash"
41
+ ],
42
+ "author": {
43
+ "name": "Apify",
44
+ "email": "support@apify.com",
45
+ "url": "https://www.apify.com"
46
+ },
47
+ "license": "Apache-2.0",
48
+ "bugs": {
49
+ "url": "https://github.com/apify/apify-cli/issues"
50
+ },
51
+ "homepage": "https://github.com/apify/apify-cli#readme",
52
+ "engines": {
53
+ "node": ">=16.0.0"
54
+ },
55
+ "dependencies": {
56
+ "@apify/actor-templates": "^0.1.3",
57
+ "@apify/consts": "^2.7.0",
58
+ "@apify/input_schema": "^3.3.0",
59
+ "@apify/utilities": "^2.2.3",
60
+ "@crawlee/memory-storage": "^3.0.3",
61
+ "@oclif/command": "^1.8.16",
62
+ "@oclif/config": "^1.18.3",
63
+ "@oclif/errors": "^1.3.5",
64
+ "@oclif/plugin-commands": "^2.1.0",
65
+ "@oclif/plugin-help": "^5.1.12",
66
+ "adm-zip": "^0.5.10",
67
+ "ajv": "^8.10.0",
68
+ "apify-client": "^2.2.0",
69
+ "archiver-promise": "^1.0.0",
70
+ "axios": "^0.21.1",
71
+ "chalk": "^4.1.2",
72
+ "computer-name": "^0.1.0",
73
+ "cors": "^2.8.5",
74
+ "detect-indent": "^6.1.0",
75
+ "escape-string-regexp": "^4.0.0",
76
+ "express": "^4.18.2",
77
+ "globby": "^11.1.0",
78
+ "inquirer": "^7.3.3",
79
+ "is-ci": "^3.0.1",
80
+ "is-online": "^10.0.0",
81
+ "istextorbinary": "^6.0.0",
82
+ "jju": "^1.4.0",
83
+ "load-json-file": "^6.2.0",
84
+ "mime": "^2.6.0",
85
+ "mixpanel": "^0.17.0",
86
+ "open": "^8.4.0",
87
+ "ow": "^0.28.1",
88
+ "rimraf": "^3.0.2",
89
+ "semver": "^7.3.5",
90
+ "tiged": "^2.12.4",
91
+ "underscore": "^1.13.2",
92
+ "write-json-file": "^4.3.0"
93
+ },
94
+ "devDependencies": {
95
+ "@apify/eslint-config": "^0.2.3",
96
+ "@oclif/dev-cli": "^1.26.0",
97
+ "@oclif/test": "^2.1.0",
98
+ "chai": "^4.3.4",
99
+ "chai-match": "^1.1.1",
100
+ "cross-env": "^7.0.3",
101
+ "eslint": "^8.11.0",
102
+ "mocha": "^10.0.0",
103
+ "sinon": "^9.2.4"
104
+ },
105
+ "oclif": {
106
+ "bin": "apify",
107
+ "commands": "./src/commands",
108
+ "hooks": {
109
+ "init": [
110
+ "./src/hooks/init"
111
+ ]
112
112
  }
113
+ }
113
114
  }
@@ -2,7 +2,7 @@ const { Command } = require('@oclif/command');
2
2
  const { showHelpForCommand } = require('../../lib/utils');
3
3
 
4
4
  class ActorIndexCommand extends Command {
5
- static async run() {
5
+ async run() {
6
6
  showHelpForCommand('actor');
7
7
  }
8
8
  }
@@ -90,8 +90,8 @@ class CallCommand extends ApifyCommand {
90
90
  }
91
91
 
92
92
  CallCommand.description = 'Runs a specific actor remotely on the Apify cloud platform.\n'
93
- + 'The actor is run under your current Apify account. Therefore you need to be logged in by calling "apify login". '
94
- + 'It takes input for the actor from the default local key-value store by default.';
93
+ + 'The Actor is run under your current Apify account. Therefore you need to be logged in by calling "apify login". '
94
+ + 'It takes input for the Actor from the default local key-value store by default.';
95
95
 
96
96
  CallCommand.flags = {
97
97
  build: flagsHelper.string({
@@ -49,8 +49,13 @@ class CreateCommand extends ApifyCommand {
49
49
 
50
50
  actorName = await ensureValidActorName(actorName);
51
51
  let messages = null;
52
+ this.telemetryData.fromArchiveUrl = !!templateArchiveUrl;
52
53
  if (manifestPromise) {
53
- ({ archiveUrl: templateArchiveUrl, skipOptionalDeps, messages } = await getTemplateDefinition(templateName, manifestPromise));
54
+ const templateDefinition = await getTemplateDefinition(templateName, manifestPromise);
55
+ ({ archiveUrl: templateArchiveUrl, skipOptionalDeps, messages } = templateDefinition);
56
+ this.telemetryData.templateId = templateDefinition.id;
57
+ this.telemetryData.templateName = templateDefinition.name;
58
+ this.telemetryData.templateLanguage = templateDefinition.category;
54
59
  }
55
60
 
56
61
  const cwd = process.cwd();
@@ -3,7 +3,7 @@ const { ApifyCommand } = require('../lib/apify_command');
3
3
  const { getLoggedClientOrThrow, getLocalUserInfo } = require('../lib/utils');
4
4
 
5
5
  class InfoCommand extends ApifyCommand {
6
- static async run() {
6
+ async run() {
7
7
  await getLoggedClientOrThrow();
8
8
  const info = await getLocalUserInfo();
9
9
 
@@ -11,6 +11,7 @@ const { ApifyCommand } = require('../lib/apify_command');
11
11
  const outputs = require('../lib/outputs');
12
12
  const { getLoggedClient } = require('../lib/utils');
13
13
  const { getLocalUserInfo } = require('../lib/utils');
14
+ const { useApifyIdentity } = require('../lib/telemetry');
14
15
 
15
16
  const CONSOLE_BASE_URL = 'https://console.apify.com/account?tab=integrations';
16
17
  // const CONSOLE_BASE_URL = 'http://localhost:3000/account?tab=integrations';
@@ -25,6 +26,7 @@ const tryToLogin = async (token) => {
25
26
  const isUserLogged = await getLoggedClient(token, API_BASE_URL);
26
27
  const userInfo = getLocalUserInfo();
27
28
  if (isUserLogged) {
29
+ await useApifyIdentity(userInfo.id);
28
30
  outputs.success(`You are logged in to Apify as ${userInfo.username || userInfo.id}!`);
29
31
  } else {
30
32
  outputs.error('Login to Apify failed, the provided API token is not valid.');
@@ -4,6 +4,7 @@ const { ApifyCommand } = require('../lib/apify_command');
4
4
  const { success, error } = require('../lib/outputs');
5
5
  const { getLoggedClient } = require('../lib/utils');
6
6
  const { getLocalUserInfo } = require('../lib/utils');
7
+ const { useApifyIdentity } = require('../lib/telemetry');
7
8
 
8
9
  class LoginCommand extends ApifyCommand {
9
10
  async run() {
@@ -16,6 +17,7 @@ class LoginCommand extends ApifyCommand {
16
17
  }
17
18
  const isUserLogged = await getLoggedClient(token);
18
19
  const userInfo = getLocalUserInfo();
20
+ await useApifyIdentity(userInfo.id);
19
21
  return isUserLogged
20
22
  ? success(`You are logged in to Apify as ${userInfo.username || userInfo.id}!`)
21
23
  : error('Login to Apify failed, the provided API token is not valid.');
@@ -1,12 +1,14 @@
1
1
  const { ApifyCommand } = require('../lib/apify_command');
2
- const { GLOBAL_CONFIGS_FOLDER } = require('../lib/consts');
2
+ const { AUTH_FILE_PATH } = require('../lib/consts');
3
3
  const { success } = require('../lib/outputs');
4
4
  const { rimrafPromised } = require('../lib/files');
5
+ const { regenerateLocalDistinctId } = require('../lib/telemetry');
5
6
 
6
7
  class LogoutCommand extends ApifyCommand {
7
- static async run() {
8
- await rimrafPromised(GLOBAL_CONFIGS_FOLDER);
9
- success('You are logged out, all settings in the ~/.apify directory were deleted.');
8
+ async run() {
9
+ await rimrafPromised(AUTH_FILE_PATH);
10
+ regenerateLocalDistinctId();
11
+ success('You are logged out from your Apify account.');
10
12
  }
11
13
  }
12
14
 
@@ -77,7 +77,7 @@ class PullCommand extends ApifyCommand {
77
77
  case 'SOURCE_FILES': {
78
78
  const { sourceFiles } = correctVersion;
79
79
  for (const file of sourceFiles) {
80
- const folderPath = file.folder ? file.folder : path.dirname(file.name);
80
+ const folderPath = path.dirname(file.name);
81
81
  fs.mkdirSync(`${dirpath}/${folderPath}`, { recursive: true }, null);
82
82
 
83
83
  if (!file.folder) {
@@ -187,7 +187,7 @@ class PushCommand extends ApifyCommand {
187
187
  }
188
188
 
189
189
  PushCommand.description = 'Uploads the actor to the Apify platform and builds it there.\n'
190
- + `The actor settings are read from the "${LOCAL_CONFIG_PATH}" file in the current directory, but they can be overridden using command-line options.\n`
190
+ + `The Actor settings are read from the "${LOCAL_CONFIG_PATH}" file in the current directory, but they can be overridden using command-line options.\n`
191
191
  + `NOTE: If the source files are smaller than ${MAX_MULTIFILE_BYTES / (1024 ** 2)} MB then they are uploaded as \n`
192
192
  + '"Multiple source files", otherwise they are uploaded as "Zip file".\n\n'
193
193
  + 'WARNING: If the target Actor already exists in your Apify account, it will be overwritten!';
@@ -5,13 +5,12 @@ const loadJson = require('load-json-file');
5
5
  const { ENV_VARS } = require('@apify/consts');
6
6
  const semver = require('semver');
7
7
  const execWithLog = require('../lib/exec');
8
- const { LEGACY_LOCAL_STORAGE_DIR, DEFAULT_LOCAL_STORAGE_DIR, SUPPORTED_NODEJS_VERSION } = require('../lib/consts');
8
+ const { LEGACY_LOCAL_STORAGE_DIR, DEFAULT_LOCAL_STORAGE_DIR, SUPPORTED_NODEJS_VERSION, LANGUAGE } = require('../lib/consts');
9
9
  const { ApifyCommand } = require('../lib/apify_command');
10
10
  const {
11
11
  getLocalUserInfo, purgeDefaultQueue, purgeDefaultKeyValueStore,
12
12
  purgeDefaultDataset, getLocalConfigOrThrow, getNpmCmd, checkIfStorageIsEmpty,
13
- detectPythonVersion, isPythonVersionSupported, getPythonCommand,
14
- detectNodeVersion, isNodeVersionSupported,
13
+ detectLocalActorLanguage, isPythonVersionSupported, getPythonCommand, isNodeVersionSupported,
15
14
  } = require('../lib/utils');
16
15
  const { error, info, warning } = require('../lib/outputs');
17
16
  const { replaceSecretsValue } = require('../lib/secrets');
@@ -86,8 +85,9 @@ class RunCommand extends ApifyCommand {
86
85
  warning('You are not logged in with your Apify Account. Some features like Apify Proxy will not work. Call "apify login" to fix that.');
87
86
  }
88
87
 
89
- if (packageJsonExists) { // Actor is written in Node.js
90
- const currentNodeVersion = detectNodeVersion();
88
+ const { language, languageVersion } = detectLocalActorLanguage();
89
+ if (language === LANGUAGE.NODEJS) { // Actor is written in Node.js
90
+ const currentNodeVersion = languageVersion;
91
91
  const minimumSupportedNodeVersion = semver.minVersion(SUPPORTED_NODEJS_VERSION);
92
92
  if (currentNodeVersion) {
93
93
  const serverJsFile = path.join(cwd, 'server.js');
@@ -107,12 +107,16 @@ class RunCommand extends ApifyCommand {
107
107
  warning(`You are running Node.js version ${currentNodeVersion}, which is no longer supported. `
108
108
  + `Please upgrade to Node.js version ${minimumSupportedNodeVersion} or later.`);
109
109
  }
110
+ this.telemetryData.actorNodejsVersion = currentNodeVersion;
111
+ this.telemetryData.actorLanguage = LANGUAGE.NODEJS;
110
112
  await execWithLog(getNpmCmd(), ['start'], { env });
111
113
  } else {
112
114
  error(`No Node.js detected! Please install Node.js ${minimumSupportedNodeVersion} or higher to be able to run Node.js actors locally.`);
113
115
  }
114
- } else if (mainPyExists) {
115
- const pythonVersion = detectPythonVersion(cwd);
116
+ } else if (language === LANGUAGE.PYTHON) {
117
+ const pythonVersion = languageVersion;
118
+ this.telemetryData.actorPythonVersion = pythonVersion;
119
+ this.telemetryData.actorLanguage = LANGUAGE.PYTHON;
116
120
  if (pythonVersion) {
117
121
  if (isPythonVersionSupported(pythonVersion)) {
118
122
  const pythonCommand = getPythonCommand(cwd);
@@ -3,7 +3,7 @@ const { LOCAL_CONFIG_PATH } = require('../../lib/consts');
3
3
  const { showHelpForCommand } = require('../../lib/utils');
4
4
 
5
5
  class SecretsIndexCommand extends Command {
6
- static async run() {
6
+ async run() {
7
7
  showHelpForCommand('secrets');
8
8
  }
9
9
  }
@@ -2,18 +2,59 @@ const { Command } = require('@oclif/command');
2
2
  const { finished } = require('stream');
3
3
  const { promisify } = require('util');
4
4
  const { argsToCamelCase } = require('./utils');
5
+ const { maybeTrackTelemetry } = require('./telemetry');
6
+ const { detectInstallationType } = require('./version_check');
7
+ const { detectLocalActorLanguage } = require('./utils');
8
+ const { LANGUAGE, COMMANDS_WITHIN_ACTOR } = require('./consts');
5
9
 
6
10
  /**
7
11
  * Adding parsing flags to oclif Command class
8
12
  */
9
13
  class ApifyCommand extends Command {
14
+ async init() {
15
+ await super.init();
16
+ // Initialize telemetry data, all attributes are tracked in the finally method
17
+ this.telemetryData = {};
18
+ }
19
+
10
20
  parse(cmd) {
11
21
  const { flags, args } = super.parse(cmd);
12
22
  const parsedFlags = argsToCamelCase(flags);
13
- return {
14
- flags: parsedFlags,
15
- args,
23
+ this.telemetryData.flagsUsed = Object.keys(parsedFlags);
24
+ return { flags: parsedFlags, args };
25
+ }
26
+
27
+ async finally(err) {
28
+ const command = this.id;
29
+ const eventData = {
30
+ command,
31
+ $os: this.config.platform,
32
+ shell: this.config.shell,
33
+ arch: this.config.arch,
34
+ apifyCliVersion: this.config.version,
35
+ nodeJsVersion: process.version,
36
+ ...this.telemetryData,
37
+ error: err ? err.message : null,
16
38
  };
39
+ try {
40
+ eventData.installationType = await detectInstallationType();
41
+ if (!this.telemetryData.actorLanguage && command && COMMANDS_WITHIN_ACTOR.includes(command)) {
42
+ const { language, languageVersion } = detectLocalActorLanguage();
43
+ eventData.actorLanguage = language;
44
+ if (language === LANGUAGE.NODEJS) {
45
+ eventData.actorNodejsVersion = languageVersion;
46
+ } else if (language === LANGUAGE.PYTHON) {
47
+ eventData.actorPythonVersion = languageVersion;
48
+ }
49
+ }
50
+ await maybeTrackTelemetry({
51
+ eventName: `cli_command_${command}`,
52
+ eventData,
53
+ });
54
+ } catch (e) {
55
+ // Ignore errors
56
+ }
57
+ return super.finally(err);
17
58
  }
18
59
 
19
60
  /**
package/src/lib/consts.js CHANGED
@@ -16,6 +16,14 @@ exports.EMPTY_LOCAL_CONFIG = {
16
16
  environmentVariables: {},
17
17
  };
18
18
 
19
+ exports.LANGUAGE = {
20
+ NODEJS: 'nodejs',
21
+ PYTHON: 'python',
22
+ UNKNOWN: 'n/a',
23
+ };
24
+
25
+ exports.COMMANDS_WITHIN_ACTOR = ['init', 'run', 'push', 'pull', 'call'];
26
+
19
27
  exports.CHECK_VERSION_EVERY_MILLIS = 24 * 60 * 60 * 1000; // Once a day
20
28
 
21
29
  exports.GLOBAL_CONFIGS_FOLDER = path.join(os.homedir(), '.apify');
@@ -26,6 +34,8 @@ exports.SECRETS_FILE_PATH = path.join(exports.GLOBAL_CONFIGS_FOLDER, 'secrets.js
26
34
 
27
35
  exports.STATE_FILE_PATH = path.join(exports.GLOBAL_CONFIGS_FOLDER, 'state.json');
28
36
 
37
+ exports.TELEMETRY_FILE_PATH = path.join(exports.GLOBAL_CONFIGS_FOLDER, 'telemetry.json');
38
+
29
39
  exports.DEPRECATED_LOCAL_CONFIG_NAME = 'apify.json';
30
40
 
31
41
  exports.ACTOR_SPECIFICATION_FOLDER = '.actor';
@@ -47,3 +57,5 @@ exports.APIFY_CLIENT_DEFAULT_HEADERS = { 'X-Apify-Request-Origin': META_ORIGINS.
47
57
  exports.MINIMUM_SUPPORTED_PYTHON_VERSION = '3.8.0';
48
58
 
49
59
  exports.PYTHON_VENV_PATH = '.venv';
60
+
61
+ exports.MIXPANEL_TOKEN = 'ea75e434d4b4d2405d79ed9d14bfc93b';
@@ -0,0 +1,102 @@
1
+ const Mixpanel = require('mixpanel');
2
+ const { promisify } = require('util');
3
+ const loadJson = require('load-json-file');
4
+ const writeJson = require('write-json-file');
5
+ const { cryptoRandomObjectId } = require('@apify/utilities');
6
+ const { MIXPANEL_TOKEN, TELEMETRY_FILE_PATH } = require('./consts');
7
+ const outputs = require('./outputs');
8
+ const { getLocalUserInfo } = require('./utils');
9
+
10
+ const mixpanel = Mixpanel.init(MIXPANEL_TOKEN, { keepAlive: false });
11
+ const TELEMETRY_WARNING_TEXT = 'Apify collects telemetry data about general usage of Apify CLI to help us improve the product. '
12
+ + 'This feature is enabled by default, and you can disable it by setting the "APIFY_CLI_DISABLE_TELEMETRY" environment variable to "1". '
13
+ + 'You can find more information about our telemetry in https://docs.apify.com/cli/docs/telemetry.';
14
+
15
+ /**
16
+ * Returns distinctId for current local environment.
17
+ * Use CLI prefix to distinguish between id generated by CLI.
18
+ *
19
+ * @returns {string}
20
+ */
21
+ const createLocalDistinctId = () => `CLI:${cryptoRandomObjectId()}`;
22
+
23
+ /**
24
+ * Returns telemetry distinctId for current local environment or creates new one.
25
+ *
26
+ * @returns {string}
27
+ */
28
+ const getOrCreateLocalDistinctId = () => {
29
+ try {
30
+ const telemetry = loadJson.sync(TELEMETRY_FILE_PATH);
31
+ return telemetry.distinctId;
32
+ } catch (e) {
33
+ const userInfo = getLocalUserInfo();
34
+ const distinctId = userInfo.id || createLocalDistinctId();
35
+ // This first time we are tracking telemetry, so we want to notify user about it.
36
+ outputs.info(TELEMETRY_WARNING_TEXT);
37
+ writeJson.sync(TELEMETRY_FILE_PATH, { distinctId });
38
+ return distinctId;
39
+ }
40
+ };
41
+
42
+ const regenerateLocalDistinctId = () => {
43
+ try {
44
+ writeJson.sync(TELEMETRY_FILE_PATH, { distinctId: createLocalDistinctId() });
45
+ } catch (e) {
46
+ // Ignore errors
47
+ }
48
+ };
49
+
50
+ const isTelemetryEnabled = !process.env.APIFY_CLI_DISABLE_TELEMETRY
51
+ || ['false', '0'].includes(process.env.APIFY_CLI_DISABLE_TELEMETRY);
52
+
53
+ /**
54
+ * Tracks telemetry event if telemetry is enabled.
55
+ *
56
+ * @param eventName
57
+ * @param eventData
58
+ * @param distinctId
59
+ */
60
+ const maybeTrackTelemetry = async ({ eventName, eventData }) => {
61
+ if (!isTelemetryEnabled) return;
62
+ try {
63
+ const distinctId = getOrCreateLocalDistinctId();
64
+ await promisify(mixpanel.track.bind(mixpanel))(eventName, {
65
+ distinct_id: distinctId,
66
+ ...eventData,
67
+ });
68
+ } catch (e) {
69
+ // Ignore errors
70
+ }
71
+ };
72
+
73
+ /**
74
+ * Uses Apify identity with local distinctId.
75
+ *
76
+ * @param userId
77
+ * @returns {Promise<void>}
78
+ */
79
+ const useApifyIdentity = async (userId) => {
80
+ if (!isTelemetryEnabled) return;
81
+ try {
82
+ const distinctId = getOrCreateLocalDistinctId();
83
+ writeJson.sync(TELEMETRY_FILE_PATH, { distinctId: userId });
84
+ await maybeTrackTelemetry({
85
+ eventName: '$create_alias',
86
+ eventData: {
87
+ alias: distinctId,
88
+ },
89
+ });
90
+ } catch (e) {
91
+ // Ignore errors
92
+ }
93
+ };
94
+
95
+ module.exports = {
96
+ mixpanel,
97
+ getOrCreateLocalDistinctId,
98
+ isTelemetryEnabled,
99
+ maybeTrackTelemetry,
100
+ useApifyIdentity,
101
+ regenerateLocalDistinctId,
102
+ };
package/src/lib/utils.js CHANGED
@@ -8,7 +8,8 @@ const archiver = require('archiver-promise');
8
8
  const loadJson = require('load-json-file');
9
9
  const writeJson = require('write-json-file');
10
10
  const inquirer = require('inquirer');
11
- const { LOCAL_STORAGE_SUBDIRS,
11
+ const {
12
+ LOCAL_STORAGE_SUBDIRS,
12
13
  ENV_VARS,
13
14
  LOCAL_ENV_VARS,
14
15
  KEY_VALUE_STORE_KEYS,
@@ -35,6 +36,7 @@ const {
35
36
  APIFY_CLIENT_DEFAULT_HEADERS,
36
37
  SUPPORTED_NODEJS_VERSION,
37
38
  MINIMUM_SUPPORTED_PYTHON_VERSION,
39
+ LANGUAGE,
38
40
  } = require('./consts');
39
41
  const {
40
42
  ensureFolderExistsSync,
@@ -503,13 +505,13 @@ const updateLocalConfigStructure = (localConfig) => {
503
505
  */
504
506
  const validateActorName = (actorName) => {
505
507
  if (!ACTOR_NAME.REGEX.test(actorName)) {
506
- throw new Error('The actor name must be a DNS hostname-friendly string (e.g. my-newest-actor).');
508
+ throw new Error('The Actor name must be a DNS hostname-friendly string (e.g. my-newest-actor).');
507
509
  }
508
510
  if (actorName.length < ACTOR_NAME.MIN_LENGTH) {
509
- throw new Error('The actor name must be at least 3 characters long.');
511
+ throw new Error('The Actor name must be at least 3 characters long.');
510
512
  }
511
513
  if (actorName.length > ACTOR_NAME.MAX_LENGTH) {
512
- throw new Error('The actor name must be a maximum of 30 characters long.');
514
+ throw new Error('The Actor name must be a maximum of 30 characters long.');
513
515
  }
514
516
  };
515
517
 
@@ -580,6 +582,23 @@ const detectNpmVersion = () => {
580
582
  }
581
583
  };
582
584
 
585
+ const detectLocalActorLanguage = () => {
586
+ const cwd = process.cwd();
587
+ const isActorInNode = fs.existsSync(path.join(process.cwd(), 'package.json'));
588
+ const isActorInPython = fs.existsSync(path.join(process.cwd(), 'src/__main__.py'));
589
+ const result = {};
590
+ if (isActorInNode) {
591
+ result.language = LANGUAGE.NODEJS;
592
+ result.languageVersion = detectNodeVersion();
593
+ } else if (isActorInPython) {
594
+ result.language = LANGUAGE.PYTHON;
595
+ result.languageVersion = detectPythonVersion(cwd);
596
+ } else {
597
+ result.language = LANGUAGE.UNKNOWN;
598
+ }
599
+ return result;
600
+ };
601
+
583
602
  module.exports = {
584
603
  getLoggedClientOrThrow,
585
604
  getLocalConfig,
@@ -613,4 +632,5 @@ module.exports = {
613
632
  detectNodeVersion,
614
633
  isNodeVersionSupported,
615
634
  detectNpmVersion,
635
+ detectLocalActorLanguage,
616
636
  };
@@ -30,6 +30,8 @@ const SKIP_UPDATE_CHECK = (
30
30
  && !['0', 'false'].includes(process.env.APIFY_CLI_SKIP_UPDATE_CHECK.toLowerCase())
31
31
  );
32
32
 
33
+ const CURRENT_APIFY_CLI_VERSION = require('../../package.json').version;
34
+
33
35
  /**
34
36
  * Detect through which package manager the Apify CLI was installed.
35
37
  * @returns {INSTALLATION_TYPE} The installation type of the CLI.
@@ -102,9 +104,7 @@ const checkLatestVersion = async (enforeUpdate = false) => {
102
104
  ? await getAndCacheLatestNpmVersion()
103
105
  : cachedLatestNpmVersion;
104
106
 
105
- const currentNpmVersion = require('../../package.json').version; // eslint-disable-line
106
-
107
- if (latestNpmVersion && semver.gt(latestNpmVersion, currentNpmVersion)) {
107
+ if (latestNpmVersion && semver.gt(latestNpmVersion, CURRENT_APIFY_CLI_VERSION)) {
108
108
  const installationType = detectInstallationType();
109
109
  const updateCommand = `' ${UPDATE_COMMAND[installationType]} '`;
110
110
  console.log('');
@@ -121,4 +121,6 @@ module.exports = {
121
121
  checkLatestVersion,
122
122
  getLatestNpmVersion,
123
123
  SKIP_UPDATE_CHECK,
124
+ detectInstallationType,
125
+ CURRENT_APIFY_CLI_VERSION,
124
126
  };