blok0 0.1.3 → 0.1.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.
@@ -8,6 +8,10 @@ export interface BlockMetadata {
8
8
  url: string;
9
9
  };
10
10
  }>;
11
+ externalPackages: Array<{
12
+ id: string;
13
+ package: string;
14
+ }>;
11
15
  _status: 'published' | 'draft';
12
16
  }
13
17
  export interface CodeFile {
@@ -35,6 +35,10 @@ export declare function createBlockEntry(metadata: {
35
35
  name: string;
36
36
  slug: string;
37
37
  sourceUrl: string;
38
+ externalPackages: Array<{
39
+ id: string;
40
+ package: string;
41
+ }>;
38
42
  }, dir: string, configPath: string, componentPath: string, checksums: {
39
43
  [filename: string]: string;
40
44
  }): BlockEntry;
@@ -138,6 +138,7 @@ function createBlockEntry(metadata, dir, configPath, componentPath, checksums) {
138
138
  dir,
139
139
  configPath,
140
140
  componentPath,
141
+ externalPackages: metadata.externalPackages,
141
142
  source: {
142
143
  url: metadata.sourceUrl,
143
144
  id: metadata.id,
@@ -40,6 +40,7 @@ const api_1 = require("../api");
40
40
  const registry_1 = require("../registry");
41
41
  const blocks_1 = require("../blocks");
42
42
  const ast_1 = require("../ast");
43
+ const packageManager_1 = require("../packageManager");
43
44
  const ui_1 = require("../ui");
44
45
  /**
45
46
  * Handle add block command
@@ -87,16 +88,22 @@ async function handleAddBlock(blockUrl, options = {}) {
87
88
  require('fs').rmSync(dir, { recursive: true, force: true });
88
89
  process.exit(1);
89
90
  }
90
- // Step 7: Calculate checksums
91
+ // Step 7: Install external packages if any
92
+ if (metadata.externalPackages && metadata.externalPackages.length > 0) {
93
+ const packageNames = metadata.externalPackages.map(pkg => pkg.package);
94
+ await (0, ui_1.withSpinner)(`Installing ${packageNames.length} external package(s)`, () => (0, packageManager_1.installPackages)(packageNames), { emoji: ui_1.EMOJIS.PACKAGE, successText: `Installed ${packageNames.length} package(s)` });
95
+ }
96
+ // Step 8: Calculate checksums
91
97
  const checksums = (0, registry_1.calculateDirectoryChecksums)(dir);
92
- // Step 8: Create registry entry
98
+ // Step 9: Create registry entry
93
99
  const blockEntry = (0, blocks_1.createBlockEntry)({
94
100
  id: metadata.id,
95
101
  name: metadata.name,
96
102
  slug: metadata.slug,
97
- sourceUrl: blockUrl
103
+ sourceUrl: blockUrl,
104
+ externalPackages: metadata.externalPackages
98
105
  }, dir, configPath, componentPath, checksums);
99
- // Step 9: Update Pages collection (AST manipulation)
106
+ // Step 10: Update Pages collection (AST manipulation)
100
107
  const pagesCollectionPath = (0, ast_1.findPagesCollection)();
101
108
  if (pagesCollectionPath) {
102
109
  await (0, ui_1.withSpinner)('Updating Pages collection', async () => {
@@ -108,7 +115,7 @@ async function handleAddBlock(blockUrl, options = {}) {
108
115
  else {
109
116
  ui_1.log.warning('Could not find Pages collection file. You may need to manually add the block to your collections.');
110
117
  }
111
- // Step 10: Update RenderBlocks component (AST manipulation)
118
+ // Step 11: Update RenderBlocks component (AST manipulation)
112
119
  const renderBlocksPath = (0, ast_1.findRenderBlocksComponent)();
113
120
  if (renderBlocksPath) {
114
121
  await (0, ui_1.withSpinner)('Updating RenderBlocks component', async () => {
@@ -119,7 +126,7 @@ async function handleAddBlock(blockUrl, options = {}) {
119
126
  else {
120
127
  ui_1.log.warning('Could not find RenderBlocks component. You may need to manually add the block component.');
121
128
  }
122
- // Step 11: Register block in registry
129
+ // Step 12: Register block in registry
123
130
  await (0, ui_1.withSpinner)('Registering block', async () => (0, registry_1.addBlockToRegistry)(blockEntry), { emoji: ui_1.EMOJIS.CHECK, successText: 'Block registered successfully' });
124
131
  ui_1.log.success('Block installation complete!');
125
132
  (0, ui_1.showNextSteps)([
package/dist/index.js CHANGED
@@ -143,7 +143,7 @@ async function main() {
143
143
  case 'add':
144
144
  const [addSubcommand, ...addRestArgs] = restArgs;
145
145
  if (addSubcommand === 'block') {
146
- const blockUrl = `https://www.blok0.com/api/cli/sections/${addRestArgs[0]}`;
146
+ const blockUrl = `https://www.blok0.xyz/api/cli/sections/${addRestArgs[0]}`;
147
147
  if (!blockUrl) {
148
148
  console.error('Error: Block Slug is required. Use: blok0 add block <slug>');
149
149
  process.exit(1);
@@ -0,0 +1,9 @@
1
+ export type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
2
+ /**
3
+ * Detect the package manager used in the current project
4
+ */
5
+ export declare function detectPackageManager(): PackageManager;
6
+ /**
7
+ * Install packages using the detected package manager with fallback to npm
8
+ */
9
+ export declare function installPackages(packages: string[]): Promise<void>;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.detectPackageManager = detectPackageManager;
37
+ exports.installPackages = installPackages;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const child_process_1 = require("child_process");
41
+ const util_1 = require("util");
42
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
43
+ /**
44
+ * Detect the package manager used in the current project
45
+ */
46
+ function detectPackageManager() {
47
+ const cwd = process.cwd();
48
+ // Check for lock files in order of preference
49
+ if (fs.existsSync(path.join(cwd, 'bun.lockb'))) {
50
+ return 'bun';
51
+ }
52
+ if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) {
53
+ return 'pnpm';
54
+ }
55
+ if (fs.existsSync(path.join(cwd, 'yarn.lock'))) {
56
+ return 'yarn';
57
+ }
58
+ if (fs.existsSync(path.join(cwd, 'package-lock.json'))) {
59
+ return 'npm';
60
+ }
61
+ // Default to npm if no lock file is found
62
+ return 'npm';
63
+ }
64
+ /**
65
+ * Get the install command for a package manager
66
+ */
67
+ function getInstallCommand(packageManager, packages) {
68
+ const packageList = packages.join(' ');
69
+ switch (packageManager) {
70
+ case 'bun':
71
+ return `bun add ${packageList}`;
72
+ case 'pnpm':
73
+ return `pnpm add ${packageList}`;
74
+ case 'yarn':
75
+ return `yarn add ${packageList}`;
76
+ case 'npm':
77
+ default:
78
+ return `npm install ${packageList}`;
79
+ }
80
+ }
81
+ /**
82
+ * Install packages using the detected package manager with fallback to npm
83
+ */
84
+ async function installPackages(packages) {
85
+ if (packages.length === 0) {
86
+ return;
87
+ }
88
+ const primaryPackageManager = detectPackageManager();
89
+ // Try the detected package manager first
90
+ try {
91
+ const command = getInstallCommand(primaryPackageManager, packages);
92
+ console.log(`Running: ${command}`);
93
+ const { stdout, stderr } = await execAsync(command, {
94
+ cwd: process.cwd(),
95
+ env: { ...process.env }
96
+ });
97
+ if (stderr) {
98
+ console.warn(`Package installation warnings: ${stderr}`);
99
+ }
100
+ console.log(`Successfully installed packages: ${packages.join(', ')}`);
101
+ return;
102
+ }
103
+ catch (error) {
104
+ console.error(`Failed with ${primaryPackageManager}: ${error.message || 'Unknown error'}`);
105
+ if (error.stdout) {
106
+ console.error(`stdout: ${error.stdout}`);
107
+ }
108
+ if (error.stderr) {
109
+ console.error(`stderr: ${error.stderr}`);
110
+ }
111
+ }
112
+ // If primary package manager failed and it's not npm, try npm as fallback
113
+ if (primaryPackageManager !== 'npm') {
114
+ try {
115
+ console.log(`Falling back to npm...`);
116
+ const command = getInstallCommand('npm', packages);
117
+ console.log(`Running: ${command}`);
118
+ const { stdout, stderr } = await execAsync(command, {
119
+ cwd: process.cwd(),
120
+ env: { ...process.env }
121
+ });
122
+ if (stderr) {
123
+ console.warn(`Package installation warnings: ${stderr}`);
124
+ }
125
+ console.log(`Successfully installed packages with npm fallback: ${packages.join(', ')}`);
126
+ return;
127
+ }
128
+ catch (error) {
129
+ console.error(`Failed with npm fallback: ${error.message || 'Unknown error'}`);
130
+ if (error.stdout) {
131
+ console.error(`stdout: ${error.stdout}`);
132
+ }
133
+ if (error.stderr) {
134
+ console.error(`stderr: ${error.stderr}`);
135
+ }
136
+ }
137
+ }
138
+ throw new Error(`Failed to install packages with both ${primaryPackageManager} and npm fallback`);
139
+ }
@@ -9,6 +9,10 @@ export interface BlockEntry {
9
9
  dir: string;
10
10
  configPath: string;
11
11
  componentPath: string;
12
+ externalPackages: Array<{
13
+ id: string;
14
+ package: string;
15
+ }>;
12
16
  source: BlockSource & {
13
17
  fetchedAt: string;
14
18
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blok0",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "CLI tool for Payload CMS scaffolding",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/api/index.ts CHANGED
@@ -11,6 +11,10 @@ export interface BlockMetadata {
11
11
  url: string;
12
12
  };
13
13
  }>;
14
+ externalPackages: Array<{
15
+ id: string;
16
+ package: string;
17
+ }>;
14
18
  _status: 'published' | 'draft';
15
19
  }
16
20
 
@@ -174,4 +178,4 @@ class APIClient {
174
178
 
175
179
  // Export singleton instance
176
180
  export const apiClient = new APIClient();
177
- export { APIClient };
181
+ export { APIClient };
@@ -110,7 +110,7 @@ export function removeBlockDirectory(dirPath: string): void {
110
110
  * Create block entry from metadata and file paths
111
111
  */
112
112
  export function createBlockEntry(
113
- metadata: { id: number; name: string; slug: string; sourceUrl: string },
113
+ metadata: { id: number; name: string; slug: string; sourceUrl: string; externalPackages: Array<{id: string, package: string}> },
114
114
  dir: string,
115
115
  configPath: string,
116
116
  componentPath: string,
@@ -123,6 +123,7 @@ export function createBlockEntry(
123
123
  dir,
124
124
  configPath,
125
125
  componentPath,
126
+ externalPackages: metadata.externalPackages,
126
127
  source: {
127
128
  url: metadata.sourceUrl,
128
129
  id: metadata.id,
@@ -183,4 +184,4 @@ export function ensureBlocksDirectory(): string {
183
184
  }
184
185
 
185
186
  return blocksDir;
186
- }
187
+ }
@@ -10,6 +10,7 @@ import {
10
10
  validateBlockDirectory
11
11
  } from '../blocks';
12
12
  import { updatePageCollectionConfig, updateRenderBlocksComponent, findPagesCollection, findRenderBlocksComponent } from '../ast';
13
+ import { installPackages } from '../packageManager';
13
14
  import { withSpinner, log, showSection, showNextSteps, EMOJIS, ProgressBar } from '../ui';
14
15
 
15
16
  /**
@@ -76,16 +77,27 @@ export async function handleAddBlock(blockUrl: string, options: { force?: boolea
76
77
  process.exit(1);
77
78
  }
78
79
 
79
- // Step 7: Calculate checksums
80
+ // Step 7: Install external packages if any
81
+ if (metadata.externalPackages && metadata.externalPackages.length > 0) {
82
+ const packageNames = metadata.externalPackages.map(pkg => pkg.package);
83
+ await withSpinner(
84
+ `Installing ${packageNames.length} external package(s)`,
85
+ () => installPackages(packageNames),
86
+ { emoji: EMOJIS.PACKAGE, successText: `Installed ${packageNames.length} package(s)` }
87
+ );
88
+ }
89
+
90
+ // Step 8: Calculate checksums
80
91
  const checksums = calculateDirectoryChecksums(dir);
81
92
 
82
- // Step 8: Create registry entry
93
+ // Step 9: Create registry entry
83
94
  const blockEntry = createBlockEntry(
84
95
  {
85
96
  id: metadata.id,
86
97
  name: metadata.name,
87
98
  slug: metadata.slug,
88
- sourceUrl: blockUrl
99
+ sourceUrl: blockUrl,
100
+ externalPackages: metadata.externalPackages
89
101
  },
90
102
  dir,
91
103
  configPath,
@@ -93,7 +105,7 @@ export async function handleAddBlock(blockUrl: string, options: { force?: boolea
93
105
  checksums
94
106
  );
95
107
 
96
- // Step 9: Update Pages collection (AST manipulation)
108
+ // Step 10: Update Pages collection (AST manipulation)
97
109
  const pagesCollectionPath = findPagesCollection();
98
110
  if (pagesCollectionPath) {
99
111
  await withSpinner(
@@ -109,7 +121,7 @@ export async function handleAddBlock(blockUrl: string, options: { force?: boolea
109
121
  log.warning('Could not find Pages collection file. You may need to manually add the block to your collections.');
110
122
  }
111
123
 
112
- // Step 10: Update RenderBlocks component (AST manipulation)
124
+ // Step 11: Update RenderBlocks component (AST manipulation)
113
125
  const renderBlocksPath = findRenderBlocksComponent();
114
126
  if (renderBlocksPath) {
115
127
  await withSpinner(
@@ -124,7 +136,7 @@ export async function handleAddBlock(blockUrl: string, options: { force?: boolea
124
136
  log.warning('Could not find RenderBlocks component. You may need to manually add the block component.');
125
137
  }
126
138
 
127
- // Step 11: Register block in registry
139
+ // Step 12: Register block in registry
128
140
  await withSpinner(
129
141
  'Registering block',
130
142
  async () => addBlockToRegistry(blockEntry),
package/src/index.ts CHANGED
@@ -123,7 +123,7 @@ async function main() {
123
123
  case 'add':
124
124
  const [addSubcommand, ...addRestArgs] = restArgs;
125
125
  if (addSubcommand === 'block') {
126
- const blockUrl = `https://www.blok0.com/api/cli/sections/${addRestArgs[0]}`;
126
+ const blockUrl = `https://www.blok0.xyz/api/cli/sections/${addRestArgs[0]}`;
127
127
  if (!blockUrl) {
128
128
  console.error('Error: Block Slug is required. Use: blok0 add block <slug>');
129
129
  process.exit(1);
@@ -0,0 +1,117 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { exec } from 'child_process';
4
+ import { promisify } from 'util';
5
+
6
+ const execAsync = promisify(exec);
7
+
8
+ export type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
9
+
10
+ /**
11
+ * Detect the package manager used in the current project
12
+ */
13
+ export function detectPackageManager(): PackageManager {
14
+ const cwd = process.cwd();
15
+
16
+ // Check for lock files in order of preference
17
+ if (fs.existsSync(path.join(cwd, 'bun.lockb'))) {
18
+ return 'bun';
19
+ }
20
+ if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) {
21
+ return 'pnpm';
22
+ }
23
+ if (fs.existsSync(path.join(cwd, 'yarn.lock'))) {
24
+ return 'yarn';
25
+ }
26
+ if (fs.existsSync(path.join(cwd, 'package-lock.json'))) {
27
+ return 'npm';
28
+ }
29
+
30
+ // Default to npm if no lock file is found
31
+ return 'npm';
32
+ }
33
+
34
+ /**
35
+ * Get the install command for a package manager
36
+ */
37
+ function getInstallCommand(packageManager: PackageManager, packages: string[]): string {
38
+ const packageList = packages.join(' ');
39
+
40
+ switch (packageManager) {
41
+ case 'bun':
42
+ return `bun add ${packageList}`;
43
+ case 'pnpm':
44
+ return `pnpm add ${packageList}`;
45
+ case 'yarn':
46
+ return `yarn add ${packageList}`;
47
+ case 'npm':
48
+ default:
49
+ return `npm install ${packageList}`;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Install packages using the detected package manager with fallback to npm
55
+ */
56
+ export async function installPackages(packages: string[]): Promise<void> {
57
+ if (packages.length === 0) {
58
+ return;
59
+ }
60
+
61
+ const primaryPackageManager = detectPackageManager();
62
+
63
+ // Try the detected package manager first
64
+ try {
65
+ const command = getInstallCommand(primaryPackageManager, packages);
66
+ console.log(`Running: ${command}`);
67
+ const { stdout, stderr } = await execAsync(command, {
68
+ cwd: process.cwd(),
69
+ env: { ...process.env }
70
+ });
71
+
72
+ if (stderr) {
73
+ console.warn(`Package installation warnings: ${stderr}`);
74
+ }
75
+
76
+ console.log(`Successfully installed packages: ${packages.join(', ')}`);
77
+ return;
78
+ } catch (error: any) {
79
+ console.error(`Failed with ${primaryPackageManager}: ${error.message || 'Unknown error'}`);
80
+ if (error.stdout) {
81
+ console.error(`stdout: ${error.stdout}`);
82
+ }
83
+ if (error.stderr) {
84
+ console.error(`stderr: ${error.stderr}`);
85
+ }
86
+ }
87
+
88
+ // If primary package manager failed and it's not npm, try npm as fallback
89
+ if (primaryPackageManager !== 'npm') {
90
+ try {
91
+ console.log(`Falling back to npm...`);
92
+ const command = getInstallCommand('npm', packages);
93
+ console.log(`Running: ${command}`);
94
+ const { stdout, stderr } = await execAsync(command, {
95
+ cwd: process.cwd(),
96
+ env: { ...process.env }
97
+ });
98
+
99
+ if (stderr) {
100
+ console.warn(`Package installation warnings: ${stderr}`);
101
+ }
102
+
103
+ console.log(`Successfully installed packages with npm fallback: ${packages.join(', ')}`);
104
+ return;
105
+ } catch (error: any) {
106
+ console.error(`Failed with npm fallback: ${error.message || 'Unknown error'}`);
107
+ if (error.stdout) {
108
+ console.error(`stdout: ${error.stdout}`);
109
+ }
110
+ if (error.stderr) {
111
+ console.error(`stderr: ${error.stderr}`);
112
+ }
113
+ }
114
+ }
115
+
116
+ throw new Error(`Failed to install packages with both ${primaryPackageManager} and npm fallback`);
117
+ }
@@ -14,6 +14,10 @@ export interface BlockEntry {
14
14
  dir: string;
15
15
  configPath: string;
16
16
  componentPath: string;
17
+ externalPackages: Array<{
18
+ id: string;
19
+ package: string;
20
+ }>;
17
21
  source: BlockSource & {
18
22
  fetchedAt: string;
19
23
  };
@@ -241,4 +245,4 @@ export function createEmptyRegistry(): void {
241
245
  };
242
246
 
243
247
  saveRegistry(emptyRegistry);
244
- }
248
+ }