primo-cli 0.1.3 → 0.1.4

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.
Files changed (38) hide show
  1. package/README.md +111 -39
  2. package/dist/commands/build.js +488 -272
  3. package/dist/commands/deploy.d.ts +1 -1
  4. package/dist/commands/deploy.js +293 -141
  5. package/dist/commands/dev.d.ts +2 -0
  6. package/dist/commands/dev.js +2007 -150
  7. package/dist/commands/init.d.ts +2 -2
  8. package/dist/commands/init.js +65 -43
  9. package/dist/commands/login.d.ts +1 -2
  10. package/dist/commands/login.js +24 -6
  11. package/dist/commands/new.js +161 -274
  12. package/dist/commands/pull-library.d.ts +7 -0
  13. package/dist/commands/pull-library.js +92 -0
  14. package/dist/commands/pull.d.ts +0 -1
  15. package/dist/commands/pull.js +160 -165
  16. package/dist/commands/push-library.d.ts +7 -0
  17. package/dist/commands/push-library.js +88 -0
  18. package/dist/commands/push.d.ts +2 -0
  19. package/dist/commands/push.js +358 -51
  20. package/dist/commands/validate.d.ts +1 -1
  21. package/dist/commands/validate.js +379 -161
  22. package/dist/index.js +109 -19
  23. package/dist/utils/binary.js +1 -1
  24. package/dist/utils/format.d.ts +12 -0
  25. package/dist/utils/format.js +98 -0
  26. package/dist/utils/head-svelte.d.ts +2 -0
  27. package/dist/utils/head-svelte.js +53 -0
  28. package/dist/utils/server-config.d.ts +19 -0
  29. package/dist/utils/server-config.js +49 -0
  30. package/dist/utils/site-config.d.ts +11 -0
  31. package/dist/utils/site-config.js +14 -0
  32. package/package.json +8 -4
  33. package/dist/commands/export.d.ts +0 -8
  34. package/dist/commands/export.js +0 -163
  35. package/dist/commands/import.d.ts +0 -9
  36. package/dist/commands/import.js +0 -118
  37. package/dist/commands/publish.d.ts +0 -6
  38. package/dist/commands/publish.js +0 -239
@@ -1,5 +1,5 @@
1
1
  interface InitOptions {
2
- port?: string;
2
+ name?: string;
3
3
  }
4
- export declare function init_server(options: InitOptions): Promise<void>;
4
+ export declare function init_workspace(options: InitOptions): Promise<void>;
5
5
  export {};
@@ -2,67 +2,89 @@ import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
  import chalk from 'chalk';
4
4
  import ora from 'ora';
5
- export async function init_server(options) {
6
- const spinner = ora('Initializing Pala server...').start();
5
+ import { SITE_CONFIG_FILE } from '../utils/site-config.js';
6
+ import { SERVER_CONFIG_FILE, read_server_config, write_server_config } from '../utils/server-config.js';
7
+ export async function init_workspace(options) {
8
+ const cwd = process.cwd();
9
+ // Refuse to init inside a site directory
7
10
  try {
8
- const base_dir = process.cwd();
9
- const server_config_path = path.join(base_dir, 'server.json');
10
- // Check if server.json already exists
11
+ await fs.access(path.join(cwd, SITE_CONFIG_FILE));
12
+ console.log(chalk.red(`Found ${SITE_CONFIG_FILE} in the current directory.`));
13
+ console.log(chalk.red('Run `primo init` from outside a site directory.'));
14
+ process.exit(1);
15
+ }
16
+ catch {
17
+ // Not inside a site directory, continue.
18
+ }
19
+ // If a name is provided, create that folder and init inside it.
20
+ // Otherwise, init in cwd.
21
+ let base_dir = cwd;
22
+ if (options.name) {
23
+ if (!/^[a-z0-9.-]+$/i.test(options.name)) {
24
+ console.log(chalk.red('Name must contain only letters, numbers, dots, and hyphens.'));
25
+ process.exit(1);
26
+ }
27
+ base_dir = path.join(cwd, options.name);
11
28
  try {
12
- await fs.access(server_config_path);
13
- spinner.fail('server.json already exists');
29
+ await fs.access(base_dir);
30
+ console.log(chalk.red(`Directory "${options.name}" already exists`));
14
31
  process.exit(1);
15
32
  }
16
33
  catch {
17
- // Good, doesn't exist
34
+ // Directory doesn't exist, good to proceed
18
35
  }
19
- // Check if pala.json exists (single-site mode)
20
- const pala_config_path = path.join(base_dir, 'pala.json');
36
+ }
37
+ const server_config_path = path.join(base_dir, SERVER_CONFIG_FILE);
38
+ // If cwd init, bail if a server is already here.
39
+ if (!options.name) {
21
40
  try {
22
- await fs.access(pala_config_path);
23
- spinner.fail('This directory contains a site (pala.json). Run pala init in a parent directory.');
41
+ await fs.access(server_config_path);
42
+ console.log(chalk.red(`Workspace already initialized (${SERVER_CONFIG_FILE} exists).`));
43
+ console.log(chalk.dim('Run `primo new <site>` to add a site.'));
24
44
  process.exit(1);
25
45
  }
26
46
  catch {
27
- // Good, not a site directory
47
+ // No server config, good to proceed
28
48
  }
29
- const port = options.port ? parseInt(options.port, 10) : 3000;
30
- const server_config = {
31
- port
32
- };
33
- await fs.writeFile(server_config_path, JSON.stringify(server_config, null, 2) + '\n');
34
- // Discover existing sites
35
- const entries = await fs.readdir(base_dir, { withFileTypes: true });
36
- const sites = [];
37
- for (const entry of entries) {
38
- if (entry.isDirectory() && !entry.name.startsWith('.')) {
39
- const site_config = path.join(base_dir, entry.name, 'pala.json');
40
- try {
41
- await fs.access(site_config);
42
- sites.push(entry.name);
43
- }
44
- catch {
45
- // Not a site
49
+ }
50
+ const spinner = ora('Initializing workspace...').start();
51
+ try {
52
+ await fs.mkdir(base_dir, { recursive: true });
53
+ await fs.mkdir(path.join(base_dir, 'sites'), { recursive: true });
54
+ await fs.mkdir(path.join(base_dir, 'library'), { recursive: true });
55
+ await write_server_config(base_dir, {
56
+ port: 3000,
57
+ site_groups: [
58
+ {
59
+ id: 'default',
60
+ name: 'Default',
61
+ index: 0
46
62
  }
47
- }
63
+ ]
64
+ });
65
+ // Re-read and ensure default group is present (normalize round-trip)
66
+ const server_config = await read_server_config(base_dir);
67
+ const site_groups = server_config.site_groups ?? [];
68
+ if (!site_groups.some((group) => group.id === 'default')) {
69
+ site_groups.push({
70
+ id: 'default',
71
+ name: 'Default',
72
+ index: site_groups.length
73
+ });
74
+ await write_server_config(base_dir, { ...server_config, site_groups });
48
75
  }
49
- spinner.succeed('Server initialized');
76
+ spinner.succeed(`Workspace initialized: ${chalk.cyan(base_dir)}`);
77
+ const rel = path.relative(cwd, base_dir) || '.';
50
78
  console.log('');
51
- console.log(` ${chalk.cyan('server.json')} created`);
52
- console.log(` ${chalk.dim('Port:')} ${port}`);
53
- if (sites.length > 0) {
54
- console.log('');
55
- console.log(` ${chalk.dim('Discovered sites:')}`);
56
- for (const site of sites) {
57
- console.log(` ${chalk.dim('•')} ${site}`);
58
- }
79
+ console.log(chalk.dim(' Next steps:'));
80
+ if (rel !== '.') {
81
+ console.log(chalk.dim(` cd ${rel}`));
59
82
  }
83
+ console.log(chalk.dim(' primo new <site-name>'));
60
84
  console.log('');
61
- console.log(chalk.green(' Run `pala new <hostname>` to create a site'));
62
- console.log(chalk.green(' Run `pala dev` to start the server'));
63
85
  }
64
86
  catch (error) {
65
- spinner.fail(`Failed to initialize: ${error instanceof Error ? error.message : error}`);
87
+ spinner.fail(`Failed to initialize workspace: ${error instanceof Error ? error.message : error}`);
66
88
  process.exit(1);
67
89
  }
68
90
  }
@@ -1,7 +1,6 @@
1
1
  interface LoginOptions {
2
- server: string;
2
+ server?: string;
3
3
  email?: string;
4
- password?: string;
5
4
  }
6
5
  export declare function login(options: LoginOptions): Promise<void>;
7
6
  export {};
@@ -1,21 +1,39 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
3
  import readline from 'readline';
4
+ import fs from 'fs/promises';
4
5
  import { save_auth_token } from '../utils/auth.js';
6
+ import { read_server_config, get_server_config_path } from '../utils/server-config.js';
5
7
  export async function login(options) {
6
- const server = normalize_server_url(options.server);
8
+ let server_url = options.server;
9
+ if (!server_url) {
10
+ // Fall back to `server:` in server.yaml when run from a workspace.
11
+ try {
12
+ await fs.access(get_server_config_path(process.cwd()));
13
+ const config = await read_server_config(process.cwd());
14
+ if (config.server)
15
+ server_url = config.server;
16
+ }
17
+ catch {
18
+ // not in a workspace, fall through
19
+ }
20
+ }
21
+ if (!server_url) {
22
+ console.log('');
23
+ console.log(chalk.red('Server URL required.'));
24
+ console.log(chalk.dim(' Pass -s <url>, or run from a workspace whose server.yaml has a `server:` field.'));
25
+ console.log('');
26
+ process.exit(1);
27
+ }
28
+ const server = normalize_server_url(server_url);
7
29
  console.log('');
8
30
  console.log(chalk.bold(`Logging in to ${server}`));
9
31
  console.log('');
10
- // Get email and password
11
32
  let email = options.email;
12
- let password = options.password;
13
33
  if (!email) {
14
34
  email = await prompt('Email: ');
15
35
  }
16
- if (!password) {
17
- password = await prompt_password('Password: ');
18
- }
36
+ const password = await prompt_password('Password: ');
19
37
  const spinner = ora('Authenticating...').start();
20
38
  try {
21
39
  // Authenticate with PocketBase