Skip to content

feat: add actors search command to search Apify Store#1047

Merged
l2ysho merged 8 commits intomasterfrom
feat/actors-search-command
Mar 25, 2026
Merged

feat: add actors search command to search Apify Store#1047
l2ysho merged 8 commits intomasterfrom
feat/actors-search-command

Conversation

@patrikbraborec
Copy link
Contributor

Summary

  • Adds apify actors search subcommand that searches the Apify Store for Actors matching a query
  • Supports filtering by category, author username, pricing model, and sort order
  • Uses apify-client SDK (StoreCollectionClient) instead of raw fetch for consistency with all other commands
  • Does not require authentication
  • Supports --json output flag

Test plan

  • Run yarn dev:apify actors search "web scraper" and verify table output
  • Run yarn dev:apify actors search --category AI --limit 5 --json and verify JSON output
  • Run yarn dev:apify actors search --username apify --pricing-model FREE and verify filtering
  • Run yarn dev:apify actors search "nonexistent-query-xyz" and verify empty result message
  • Verify command works without being logged in (no authentication required)

🤖 Generated with Claude Code

Adds a new `actors search` subcommand that searches the Apify Store for
Actors by query, category, author, pricing model, and more. Uses the
apify-client SDK's StoreCollectionClient for consistency with all other
commands. Does not require authentication.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions bot added the t-c&c Team covering store and finance matters. label Mar 24, 2026
@patrikbraborec patrikbraborec requested a review from l2ysho March 24, 2026 10:33
Copy link
Contributor

@l2ysho l2ysho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GJ, so far so good, just 2 small nits from me and we should also add some tests.

process.exitCode = CommandExitCodes.RunFailed;
error({
message: `Failed to search Apify Store: ${err instanceof Error ? err.message : String(err)}`,
stdout: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vladfrangu stdout or stderr ? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm, depends if we run this with --json i'd say. stdout for json=false, stderr for json=true + error object on stdout (or empty array)

patrikbraborec and others added 2 commits March 25, 2026 09:48
Co-authored-by: Richard Solar <solar.richard@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions bot added the tested Temporary label used only programatically for some analytics. label Mar 25, 2026
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@patrikbraborec
Copy link
Contributor Author

@l2ysho Thanks for the review. I added tests. :)

Copy link
Contributor

@l2ysho l2ysho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, @patrikbraborec I found one corner case when testing, not sure how big problem it is so It is up to you if you want to tackle it here or we create separate issue. cc @vladfrangu

const { query } = this.args;
const { json, sortBy, category, username, pricingModel, limit, offset } = this.flags;

const client = new ApifyClient(getApifyClientOptions());
Copy link
Contributor

@l2ysho l2ysho Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one sneaky problem here (as this is first non-auth API related command ). If user is authorised but his token is invalid (expired, revoked, ...) this command fail on 401.

example of test which should succeed but currently fail

	describe('with expired/invalid token', () => {
		useAuthSetup({ cleanup: true, perTest: true });

		it('should still succeed when an invalid token is stored (no auth required)', async () => {
			// Write a fake expired token to the auth file
			const authPath = AUTH_FILE_PATH();
			mkdirSync(dirname(authPath), { recursive: true });
			writeFileSync(authPath, JSON.stringify({ token: 'fake-expired-token-12345' }));

			await testRunCommand(ActorsSearchCommand, {
				args_query: 'web scraper',
				flags_json: true,
				flags_limit: 1,
			});

			// This command should succeed without auth — but currently fails
			// because getApifyClientOptions() injects the invalid token
			expect(process.exitCode).toBeUndefined();

			const output = lastLogMessage();
			const parsed = JSON.parse(output);
			expect(parsed).toHaveProperty('items');
		});
	});

this should be probably fixed inside of getApifyClientOptions but it may be to much noise for this PR and this hotfix is enough here:

const clientOptions = getApifyClientOptions();                                                                                                                         
delete clientOptions.token;                                                                                                                                            
const client = new ApifyClient(clientOptions);     

As I am not sure how long token lasts, this may not be so big problem but it is worth to know this can happen.

@patrikbraborec
Copy link
Contributor Author

@l2ysho thanks! I created the issue: #1051. I think we can merge it. Or do you want someone else to check it?

@l2ysho l2ysho merged commit ada9674 into master Mar 25, 2026
22 checks passed
@l2ysho l2ysho deleted the feat/actors-search-command branch March 25, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-c&c Team covering store and finance matters. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants