@crawlee-cloud/cli 0.2.1 → 0.8.5

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,46 +1,159 @@
1
1
  /**
2
2
  * Configuration utilities for CLI.
3
+ *
4
+ * The config file supports multiple named "profiles" — separate API URL +
5
+ * token sets for different environments (local / staging / prod / per-team).
6
+ * One profile is active at a time; `getConfig()` returns its values so the
7
+ * rest of the CLI doesn't need to know about profiles at all.
8
+ *
9
+ * Persisted shape (~/.crawlee-cloud/config.json):
10
+ * {
11
+ * "activeProfile": "default",
12
+ * "profiles": {
13
+ * "default": { "apiBaseUrl": "...", "token": "...", "registryUrl": "..." },
14
+ * "prod": { ... },
15
+ * "staging": { ... }
16
+ * }
17
+ * }
18
+ *
19
+ * Backwards-compat: if the file is in the OLD flat shape
20
+ * { "apiBaseUrl": "...", "token": "..." }
21
+ * we migrate it on first read into a `default` profile, transparently.
22
+ *
23
+ * Profile selection precedence (highest wins):
24
+ * 1. CRAWLEE_CLOUD_PROFILE env var (per-invocation override)
25
+ * 2. activeProfile in config.json
26
+ * 3. "default"
27
+ *
28
+ * Env-var overrides for the active profile's fields still apply
29
+ * (CRAWLEE_CLOUD_API_URL, CRAWLEE_CLOUD_TOKEN, etc.) — useful for CI.
3
30
  */
4
31
  import fs from 'fs-extra';
5
32
  import path from 'path';
6
33
  import os from 'os';
7
34
  const CONFIG_DIR = path.join(os.homedir(), '.crawlee-cloud');
8
35
  const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
36
+ const DEFAULT_PROFILE = 'default';
37
+ /** Read the on-disk file, migrating the old flat shape if needed. */
38
+ async function readProfileFile() {
39
+ if (!(await fs.pathExists(CONFIG_FILE)))
40
+ return {};
41
+ const raw = (await fs.readJson(CONFIG_FILE));
42
+ // Already in profile shape: it has a `profiles` object.
43
+ if (raw && typeof raw === 'object' && 'profiles' in raw) {
44
+ return raw;
45
+ }
46
+ // Legacy flat shape: { apiBaseUrl, token, registryUrl }. Wrap it as the
47
+ // default profile so the new code paths see a consistent layout. We
48
+ // don't write the migrated file back here — saveConfig() does that on
49
+ // the next mutation, so reading is non-destructive.
50
+ if (raw && typeof raw === 'object' && ('token' in raw || 'apiBaseUrl' in raw)) {
51
+ return {
52
+ activeProfile: DEFAULT_PROFILE,
53
+ profiles: { [DEFAULT_PROFILE]: raw },
54
+ };
55
+ }
56
+ return {};
57
+ }
58
+ /**
59
+ * Resolve which profile to use for this invocation.
60
+ * Looks at CRAWLEE_CLOUD_PROFILE env var first (per-invocation override),
61
+ * then the file's activeProfile, then "default".
62
+ */
63
+ function activeProfileName(file) {
64
+ return process.env.CRAWLEE_CLOUD_PROFILE || file.activeProfile || DEFAULT_PROFILE;
65
+ }
9
66
  /**
10
- * Get CLI configuration.
67
+ * Get the effective CLI configuration for the active profile.
68
+ *
69
+ * Resolution order per field (highest wins):
70
+ * 1. Direct env var (CRAWLEE_CLOUD_API_URL, CRAWLEE_CLOUD_TOKEN, ...)
71
+ * 2. Active profile in config.json
72
+ * 3. Hard-coded defaults
11
73
  */
12
74
  export async function getConfig() {
13
- // Check environment variables first
14
75
  const envConfig = {
15
- apiBaseUrl: process.env.CRAWLEE_CLOUD_API_URL || process.env.APIFY_API_BASE_URL?.replace('/v2', '') || 'http://localhost:3000',
16
- token: process.env.CRAWLEE_CLOUD_TOKEN || process.env.APIFY_TOKEN || '',
76
+ apiBaseUrl: process.env.CRAWLEE_CLOUD_API_URL ||
77
+ process.env.APIFY_API_BASE_URL?.replace('/v2', '') ||
78
+ undefined,
79
+ token: process.env.CRAWLEE_CLOUD_TOKEN || process.env.APIFY_TOKEN || undefined,
17
80
  registryUrl: process.env.CRAWLEE_CLOUD_REGISTRY_URL,
18
81
  };
19
- // Load from file if exists
20
- if (await fs.pathExists(CONFIG_FILE)) {
21
- const fileConfig = await fs.readJson(CONFIG_FILE);
22
- return {
23
- ...envConfig,
24
- ...fileConfig,
25
- };
26
- }
27
- return envConfig;
82
+ const file = await readProfileFile();
83
+ const name = activeProfileName(file);
84
+ const fromFile = file.profiles?.[name];
85
+ return {
86
+ apiBaseUrl: envConfig.apiBaseUrl ?? fromFile?.apiBaseUrl ?? 'http://localhost:3000',
87
+ token: envConfig.token ?? fromFile?.token ?? '',
88
+ registryUrl: envConfig.registryUrl ?? fromFile?.registryUrl,
89
+ };
28
90
  }
29
91
  /**
30
- * Save CLI configuration.
92
+ * Save (merge) into the active profile. Used by `crc login` to persist
93
+ * after a successful auth handshake.
94
+ *
95
+ * If `profile` is passed, that named profile is updated/created instead
96
+ * of the active one — this is how `crc login --profile prod` adds a new
97
+ * profile without disturbing the active selection.
31
98
  */
32
- export async function saveConfig(config) {
99
+ export async function saveConfig(config, options = {}) {
33
100
  await fs.ensureDir(CONFIG_DIR);
34
- const existing = await getConfig();
35
- const merged = { ...existing, ...config };
36
- await fs.writeJson(CONFIG_FILE, merged, { spaces: 2, mode: 0o600 });
101
+ const file = await readProfileFile();
102
+ const name = options.profile ?? activeProfileName(file);
103
+ const profiles = file.profiles ?? {};
104
+ const existing = profiles[name] ?? { apiBaseUrl: '', token: '' };
105
+ profiles[name] = { ...existing, ...config };
106
+ const next = {
107
+ activeProfile: options.setActive ? name : (file.activeProfile ?? name),
108
+ profiles,
109
+ };
110
+ await fs.writeJson(CONFIG_FILE, next, { spaces: 2, mode: 0o600 });
37
111
  }
38
- /**
39
- * Clear CLI configuration.
40
- */
112
+ /** Delete every persisted profile + reset active. Used in test cleanup. */
41
113
  export async function clearConfig() {
42
114
  if (await fs.pathExists(CONFIG_FILE)) {
43
115
  await fs.remove(CONFIG_FILE);
44
116
  }
45
117
  }
118
+ /** List every persisted profile with its API URL and a masked token preview. */
119
+ export async function listProfiles() {
120
+ const file = await readProfileFile();
121
+ const active = activeProfileName(file);
122
+ const profiles = file.profiles ?? {};
123
+ return Object.entries(profiles).map(([name, p]) => ({
124
+ name,
125
+ apiBaseUrl: p.apiBaseUrl,
126
+ tokenPreview: p.token ? `${p.token.slice(0, 12)}...` : '(no token)',
127
+ active: name === active,
128
+ }));
129
+ }
130
+ /** Set the active profile. Throws if the named profile doesn't exist. */
131
+ export async function useProfile(name) {
132
+ const file = await readProfileFile();
133
+ if (!file.profiles?.[name]) {
134
+ throw new Error(`Profile "${name}" not found. Run \`crc profile list\` to see available profiles.`);
135
+ }
136
+ await fs.writeJson(CONFIG_FILE, { ...file, activeProfile: name }, { spaces: 2, mode: 0o600 });
137
+ }
138
+ /** Remove a named profile. If it was active, fall back to "default" or first. */
139
+ export async function removeProfile(name) {
140
+ const file = await readProfileFile();
141
+ if (!file.profiles?.[name]) {
142
+ throw new Error(`Profile "${name}" not found.`);
143
+ }
144
+ delete file.profiles[name];
145
+ // If we removed the active profile, pick a sensible new active so the
146
+ // user isn't left in a "no profile" limbo. Prefer DEFAULT_PROFILE,
147
+ // otherwise the alphabetically first remaining one, otherwise undefined.
148
+ if (file.activeProfile === name) {
149
+ const remaining = Object.keys(file.profiles);
150
+ file.activeProfile = file.profiles[DEFAULT_PROFILE] ? DEFAULT_PROFILE : remaining.sort()[0];
151
+ }
152
+ await fs.writeJson(CONFIG_FILE, file, { spaces: 2, mode: 0o600 });
153
+ }
154
+ /** Get the currently-active profile's name (after env-var override). */
155
+ export async function getActiveProfileName() {
156
+ const file = await readProfileFile();
157
+ return activeProfileName(file);
158
+ }
46
159
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAQpB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,oCAAoC;IACpC,MAAM,SAAS,GAAc;QAC3B,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,uBAAuB;QAC9H,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE;QACvE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B;KACpD,CAAC;IAEF,2BAA2B;IAC3B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClD,OAAO;YACL,GAAG,SAAS;YACZ,GAAG,UAAU;SACd,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAA0B;IACzD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAE/B,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IAE1C,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee-cloud/cli",
3
- "version": "0.2.1",
3
+ "version": "0.8.5",
4
4
  "description": "CLI for Crawlee Cloud - run and deploy Actors",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,8 @@
13
13
  "build": "tsc",
14
14
  "dev": "tsx src/bin.ts",
15
15
  "clean": "rm -rf dist",
16
- "typecheck": "tsc --noEmit"
16
+ "typecheck": "tsc --noEmit",
17
+ "test:integration": "vitest run --config vitest.integration.config.ts"
17
18
  },
18
19
  "keywords": [
19
20
  "crawlee",
@@ -38,7 +39,8 @@
38
39
  "@types/fs-extra": "^11.0.4",
39
40
  "@types/node": "^20.10.0",
40
41
  "tsx": "^4.7.0",
41
- "typescript": "^5.7.2"
42
+ "typescript": "^5.7.2",
43
+ "vitest": "^2.1.9"
42
44
  },
43
45
  "files": [
44
46
  "dist"
@@ -1,9 +0,0 @@
1
- /**
2
- * `crawlee-cloud create` command
3
- *
4
- * Creates a new Actor project using official Apify templates.
5
- * This ensures 100% compatibility with Apify Cloud for zero-code migration.
6
- */
7
- import { Command } from 'commander';
8
- export declare const createCommand: Command;
9
- //# sourceMappingURL=create.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAiEtB,CAAC"}
@@ -1,70 +0,0 @@
1
- /**
2
- * `crawlee-cloud create` command
3
- *
4
- * Creates a new Actor project using official Apify templates.
5
- * This ensures 100% compatibility with Apify Cloud for zero-code migration.
6
- */
7
- import { Command } from 'commander';
8
- import chalk from 'chalk';
9
- import { spawn } from 'child_process';
10
- import { input } from '@inquirer/prompts';
11
- export const createCommand = new Command('create')
12
- .description('Create a new Actor project (uses official Apify templates)')
13
- .argument('[name]', 'Actor name')
14
- .option('-t, --template <template>', 'Template to use (passed to apify-cli)')
15
- .option('--skip-install', 'Skip npm install after creation')
16
- .action(async (name, options) => {
17
- console.log(chalk.bold('\n🚀 Create new Crawlee Cloud Actor\n'));
18
- console.log(chalk.dim('Using official Apify templates for 100% compatibility\n'));
19
- // Get name if not provided
20
- const actorName = name || await input({
21
- message: 'Actor name:',
22
- default: 'my-actor',
23
- validate: (value) => {
24
- if (!/^[a-z0-9-]+$/.test(value)) {
25
- return 'Name must be lowercase letters, numbers, and hyphens only';
26
- }
27
- return true;
28
- },
29
- });
30
- // Build apify-cli create command arguments
31
- const args = ['apify-cli', 'create', actorName];
32
- if (options.template) {
33
- args.push('--template', options.template);
34
- }
35
- if (options.skipInstall) {
36
- args.push('--skip-dependency-install');
37
- }
38
- console.log(chalk.dim(`Running: npx ${args.join(' ')}\n`));
39
- // Run npx apify-cli create
40
- const child = spawn('npx', args, {
41
- stdio: 'inherit',
42
- shell: true,
43
- });
44
- child.on('close', (code) => {
45
- if (code === 0) {
46
- console.log(chalk.green('\n✅ Actor created successfully!'));
47
- console.log(chalk.dim('\nYour Actor is 100% compatible with both:'));
48
- console.log(chalk.cyan(' • Apify Cloud (apify.com)'));
49
- console.log(chalk.cyan(' • Crawlee Cloud (self-hosted)'));
50
- console.log();
51
- console.log(chalk.dim('To run locally:'));
52
- console.log(chalk.cyan(` cd ${actorName}`));
53
- console.log(chalk.cyan(' npm start'));
54
- console.log();
55
- console.log(chalk.dim('To deploy to Crawlee Cloud:'));
56
- console.log(chalk.cyan(' crawlee-cloud push'));
57
- console.log();
58
- }
59
- else {
60
- console.log(chalk.red(`\n❌ Failed to create Actor (exit code: ${code})`));
61
- process.exit(code ?? 1);
62
- }
63
- });
64
- child.on('error', (err) => {
65
- console.error(chalk.red('\n❌ Failed to run apify-cli:'), err.message);
66
- console.log(chalk.dim('\nMake sure you have npx available (comes with npm 5.2+)'));
67
- process.exit(1);
68
- });
69
- });
70
- //# sourceMappingURL=create.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}