blok0 0.1.0 → 0.1.2

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.
@@ -0,0 +1,56 @@
1
+ import { BlockEntry } from '../registry';
2
+ import { CodeFile } from '../api';
3
+ /**
4
+ * Convert slug to PascalCase identifier
5
+ */
6
+ export declare function slugToIdentifier(slug: string): string;
7
+ /**
8
+ * Convert slug to folder name (direct mapping)
9
+ */
10
+ export declare function slugToFolderName(slug: string): string;
11
+ /**
12
+ * Validate that a directory contains a valid block
13
+ */
14
+ export declare function validateBlockDirectory(dirPath: string): {
15
+ valid: boolean;
16
+ errors: string[];
17
+ };
18
+ /**
19
+ * Create block directory structure and write files
20
+ */
21
+ export declare function createBlockDirectory(baseDir: string, slug: string, files: CodeFile[]): {
22
+ dir: string;
23
+ configPath: string;
24
+ componentPath: string;
25
+ };
26
+ /**
27
+ * Remove block directory
28
+ */
29
+ export declare function removeBlockDirectory(dirPath: string): void;
30
+ /**
31
+ * Create block entry from metadata and file paths
32
+ */
33
+ export declare function createBlockEntry(metadata: {
34
+ id: number;
35
+ name: string;
36
+ slug: string;
37
+ sourceUrl: string;
38
+ }, dir: string, configPath: string, componentPath: string, checksums: {
39
+ [filename: string]: string;
40
+ }): BlockEntry;
41
+ /**
42
+ * Get all block directories in src/blocks
43
+ */
44
+ export declare function getBlockDirectories(blocksDir?: string): string[];
45
+ /**
46
+ * Find blocks by scanning filesystem (fallback when registry is unavailable)
47
+ */
48
+ export declare function discoverBlocksFromFilesystem(): Array<{
49
+ slug: string;
50
+ dir: string;
51
+ hasConfig: boolean;
52
+ }>;
53
+ /**
54
+ * Ensure src/blocks directory exists
55
+ */
56
+ export declare function ensureBlocksDirectory(): string;
@@ -0,0 +1,189 @@
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.slugToIdentifier = slugToIdentifier;
37
+ exports.slugToFolderName = slugToFolderName;
38
+ exports.validateBlockDirectory = validateBlockDirectory;
39
+ exports.createBlockDirectory = createBlockDirectory;
40
+ exports.removeBlockDirectory = removeBlockDirectory;
41
+ exports.createBlockEntry = createBlockEntry;
42
+ exports.getBlockDirectories = getBlockDirectories;
43
+ exports.discoverBlocksFromFilesystem = discoverBlocksFromFilesystem;
44
+ exports.ensureBlocksDirectory = ensureBlocksDirectory;
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ /**
48
+ * Convert slug to PascalCase identifier
49
+ */
50
+ function slugToIdentifier(slug) {
51
+ return slug
52
+ .split('-')
53
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
54
+ .join('');
55
+ }
56
+ /**
57
+ * Convert slug to folder name (direct mapping)
58
+ */
59
+ function slugToFolderName(slug) {
60
+ return slug;
61
+ }
62
+ /**
63
+ * Validate that a directory contains a valid block
64
+ */
65
+ function validateBlockDirectory(dirPath) {
66
+ const errors = [];
67
+ if (!fs.existsSync(dirPath)) {
68
+ errors.push('Block directory does not exist');
69
+ return { valid: false, errors };
70
+ }
71
+ const configPath = path.join(dirPath, 'config.ts');
72
+ if (!fs.existsSync(configPath)) {
73
+ errors.push('config.ts file is missing');
74
+ }
75
+ // Check if config.ts exports a valid block configuration
76
+ if (fs.existsSync(configPath)) {
77
+ try {
78
+ const configContent = fs.readFileSync(configPath, 'utf-8');
79
+ // Basic validation - check for required exports
80
+ if (!configContent.includes('export') || !configContent.includes('Block')) {
81
+ errors.push('config.ts does not appear to export a valid block configuration');
82
+ }
83
+ }
84
+ catch (error) {
85
+ errors.push(`Failed to read config.ts: ${error.message}`);
86
+ }
87
+ }
88
+ return { valid: errors.length === 0, errors };
89
+ }
90
+ /**
91
+ * Create block directory structure and write files
92
+ */
93
+ function createBlockDirectory(baseDir, slug, files) {
94
+ const blockDir = path.join(baseDir, slugToFolderName(slug));
95
+ // Check if directory already exists
96
+ if (fs.existsSync(blockDir)) {
97
+ throw new Error(`Block directory already exists: ${blockDir}`);
98
+ }
99
+ // Create directory
100
+ fs.mkdirSync(blockDir, { recursive: true });
101
+ let configPath = '';
102
+ let componentPath = '';
103
+ // Write files
104
+ for (const file of files) {
105
+ const filePath = path.join(blockDir, file.name);
106
+ fs.writeFileSync(filePath, file.content);
107
+ if (file.name === 'config.ts') {
108
+ configPath = filePath;
109
+ }
110
+ else if (file.name === 'Component.tsx') {
111
+ componentPath = filePath;
112
+ }
113
+ }
114
+ if (!configPath) {
115
+ throw new Error('config.ts file was not found in downloaded files');
116
+ }
117
+ if (!componentPath) {
118
+ throw new Error('Component.tsx file was not found in downloaded files');
119
+ }
120
+ return { dir: blockDir, configPath, componentPath };
121
+ }
122
+ /**
123
+ * Remove block directory
124
+ */
125
+ function removeBlockDirectory(dirPath) {
126
+ if (fs.existsSync(dirPath)) {
127
+ fs.rmSync(dirPath, { recursive: true, force: true });
128
+ }
129
+ }
130
+ /**
131
+ * Create block entry from metadata and file paths
132
+ */
133
+ function createBlockEntry(metadata, dir, configPath, componentPath, checksums) {
134
+ return {
135
+ id: metadata.id,
136
+ name: metadata.name,
137
+ slug: metadata.slug,
138
+ dir,
139
+ configPath,
140
+ componentPath,
141
+ source: {
142
+ url: metadata.sourceUrl,
143
+ id: metadata.id,
144
+ fetchedAt: new Date().toISOString()
145
+ },
146
+ checksums
147
+ };
148
+ }
149
+ /**
150
+ * Get all block directories in src/blocks
151
+ */
152
+ function getBlockDirectories(blocksDir = 'src/blocks') {
153
+ const fullBlocksDir = path.join(process.cwd(), blocksDir);
154
+ if (!fs.existsSync(fullBlocksDir)) {
155
+ return [];
156
+ }
157
+ const entries = fs.readdirSync(fullBlocksDir, { withFileTypes: true });
158
+ return entries
159
+ .filter(entry => entry.isDirectory())
160
+ .map(entry => path.join(fullBlocksDir, entry.name));
161
+ }
162
+ /**
163
+ * Find blocks by scanning filesystem (fallback when registry is unavailable)
164
+ */
165
+ function discoverBlocksFromFilesystem() {
166
+ const blocksDir = path.join(process.cwd(), 'src/blocks');
167
+ if (!fs.existsSync(blocksDir)) {
168
+ return [];
169
+ }
170
+ const blockDirs = getBlockDirectories();
171
+ const blocks = [];
172
+ for (const dir of blockDirs) {
173
+ const slug = path.basename(dir);
174
+ const configPath = path.join(dir, 'config.ts');
175
+ const hasConfig = fs.existsSync(configPath);
176
+ blocks.push({ slug, dir, hasConfig });
177
+ }
178
+ return blocks;
179
+ }
180
+ /**
181
+ * Ensure src/blocks directory exists
182
+ */
183
+ function ensureBlocksDirectory() {
184
+ const blocksDir = path.join(process.cwd(), 'src/blocks');
185
+ if (!fs.existsSync(blocksDir)) {
186
+ fs.mkdirSync(blocksDir, { recursive: true });
187
+ }
188
+ return blocksDir;
189
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Handle add block command
3
+ */
4
+ export declare function handleAddBlock(blockUrl: string, options?: {
5
+ force?: boolean;
6
+ dryRun?: boolean;
7
+ }): Promise<void>;
@@ -0,0 +1,142 @@
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.handleAddBlock = handleAddBlock;
37
+ const path = __importStar(require("path"));
38
+ const auth_1 = require("../auth");
39
+ const api_1 = require("../api");
40
+ const registry_1 = require("../registry");
41
+ const blocks_1 = require("../blocks");
42
+ const ast_1 = require("../ast");
43
+ /**
44
+ * Handle add block command
45
+ */
46
+ async function handleAddBlock(blockUrl, options = {}) {
47
+ console.log('📦 Adding Blok0 Block');
48
+ console.log('====================');
49
+ console.log('');
50
+ try {
51
+ // Step 1: Authentication check
52
+ console.log('🔐 Checking authentication...');
53
+ const authenticated = await (0, auth_1.isAuthenticated)();
54
+ if (!authenticated) {
55
+ console.error('❌ You are not logged in. Please run `blok0 login` first.');
56
+ process.exit(1);
57
+ }
58
+ // Step 2: Fetch block data from API
59
+ console.log(`📡 Fetching block from: ${blockUrl}`);
60
+ const { metadata, files } = await api_1.apiClient.fetchBlockData(blockUrl);
61
+ console.log(`✅ Found block: "${metadata.name}" (${metadata.slug})`);
62
+ // Step 3: Check if block is already registered
63
+ if ((0, registry_1.isBlockRegistered)(metadata.slug)) {
64
+ if (!options.force) {
65
+ console.error(`❌ Block "${metadata.slug}" is already installed. Use --force to reinstall.`);
66
+ process.exit(1);
67
+ }
68
+ console.log('⚠️ Block already exists, reinstalling...');
69
+ }
70
+ if (options.dryRun) {
71
+ console.log('🔍 Dry run mode - would perform the following actions:');
72
+ console.log(` - Create directory: src/blocks/${metadata.slug}`);
73
+ console.log(` - Download ${files.length} files`);
74
+ console.log(' - Update Payload config');
75
+ console.log(' - Update RenderBlocks component');
76
+ console.log(' - Register block in blok0-registry.json');
77
+ return;
78
+ }
79
+ // Step 4: Ensure blocks directory exists
80
+ const blocksDir = (0, blocks_1.ensureBlocksDirectory)();
81
+ // Step 5: Create block directory and files
82
+ console.log('📁 Creating block directory and files...');
83
+ const { dir, configPath, componentPath } = (0, blocks_1.createBlockDirectory)(blocksDir, metadata.slug, files);
84
+ console.log(`✅ Created block directory: ${path.relative(process.cwd(), dir)}`);
85
+ // Step 6: Validate created block
86
+ const validation = (0, blocks_1.validateBlockDirectory)(dir);
87
+ if (!validation.valid) {
88
+ console.error('❌ Block validation failed:');
89
+ validation.errors.forEach(error => console.error(` - ${error}`));
90
+ // Cleanup on failure
91
+ require('fs').rmSync(dir, { recursive: true, force: true });
92
+ process.exit(1);
93
+ }
94
+ // Step 7: Calculate checksums
95
+ const checksums = (0, registry_1.calculateDirectoryChecksums)(dir);
96
+ // Step 8: Create registry entry
97
+ const blockEntry = (0, blocks_1.createBlockEntry)({
98
+ id: metadata.id,
99
+ name: metadata.name,
100
+ slug: metadata.slug,
101
+ sourceUrl: blockUrl
102
+ }, dir, configPath, componentPath, checksums);
103
+ // Step 9: Update Pages collection (AST manipulation)
104
+ const pagesCollectionPath = (0, ast_1.findPagesCollection)();
105
+ if (pagesCollectionPath) {
106
+ console.log('🔧 Updating Pages collection...');
107
+ const blockIdentifier = (0, blocks_1.slugToIdentifier)(metadata.slug);
108
+ const relativeConfigPath = `@/blocks/${metadata.slug}/config`;
109
+ (0, ast_1.updatePageCollectionConfig)(pagesCollectionPath, relativeConfigPath, blockIdentifier);
110
+ console.log(`✅ Added ${blockIdentifier} to Pages collection`);
111
+ }
112
+ else {
113
+ console.warn('⚠️ Could not find Pages collection file. You may need to manually add the block to your collections.');
114
+ }
115
+ // Step 10: Update RenderBlocks component (AST manipulation)
116
+ const renderBlocksPath = (0, ast_1.findRenderBlocksComponent)();
117
+ if (renderBlocksPath) {
118
+ console.log('🔧 Updating RenderBlocks component...');
119
+ const relativeComponentPath = `./${metadata.slug}/Component`;
120
+ (0, ast_1.updateRenderBlocksComponent)(renderBlocksPath, metadata.slug, relativeComponentPath);
121
+ console.log(`✅ Added ${metadata.slug} component to RenderBlocks`);
122
+ }
123
+ else {
124
+ console.warn('⚠️ Could not find RenderBlocks component. You may need to manually add the block component.');
125
+ }
126
+ // Step 11: Register block in registry
127
+ console.log('📝 Registering block...');
128
+ (0, registry_1.addBlockToRegistry)(blockEntry);
129
+ console.log('✅ Block registered successfully');
130
+ console.log('');
131
+ console.log('🎉 Block installation complete!');
132
+ console.log('');
133
+ console.log('Next steps:');
134
+ console.log('1. Review the installed files in src/blocks/' + metadata.slug);
135
+ console.log('2. Test your application to ensure the block works correctly');
136
+ console.log('3. Commit the changes to your repository');
137
+ }
138
+ catch (error) {
139
+ console.error('❌ Failed to add block:', error.message);
140
+ process.exit(1);
141
+ }
142
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Handle login command
3
+ */
4
+ export declare function handleLogin(token?: string, manual?: boolean): Promise<void>;
5
+ /**
6
+ * Handle logout command
7
+ */
8
+ export declare function handleLogout(): Promise<void>;
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleLogin = handleLogin;
7
+ exports.handleLogout = handleLogout;
8
+ const auth_1 = require("../auth");
9
+ const server_1 = require("../auth/server");
10
+ const open_1 = __importDefault(require("open"));
11
+ // Add SIGINT handler for graceful cleanup
12
+ process.on('SIGINT', () => {
13
+ console.log('\n\n⚠️ Authentication cancelled by user.');
14
+ process.exit(0);
15
+ });
16
+ /**
17
+ * Handle login command
18
+ */
19
+ async function handleLogin(token, manual) {
20
+ // Direct token authentication (CI/CD)
21
+ if (token) {
22
+ try {
23
+ console.log('🔐 Saving authentication token...');
24
+ await (0, auth_1.storeAccessToken)(token);
25
+ console.log('✅ Successfully authenticated!');
26
+ console.log('');
27
+ console.log('You can now use blok0 commands that require authentication.');
28
+ }
29
+ catch (error) {
30
+ console.error('❌ Failed to save authentication token:', error.message);
31
+ process.exit(1);
32
+ }
33
+ return;
34
+ }
35
+ // Manual authentication instructions
36
+ if (manual) {
37
+ showManualInstructions();
38
+ return;
39
+ }
40
+ // Default: Browser-based authentication
41
+ try {
42
+ await handleBrowserLogin();
43
+ }
44
+ catch (error) {
45
+ console.error('❌ Browser authentication failed:', error.message);
46
+ console.log('');
47
+ console.log('💡 Try manual authentication:');
48
+ console.log(' blok0 login --manual');
49
+ process.exit(1);
50
+ }
51
+ }
52
+ /**
53
+ * Handle browser-based authentication flow
54
+ */
55
+ async function handleBrowserLogin() {
56
+ console.log('🔐 Blok0 Authentication');
57
+ console.log('======================');
58
+ console.log('');
59
+ // Create authentication server
60
+ const authServer = new server_1.AuthServer();
61
+ try {
62
+ // Initialize server (find available port)
63
+ console.log('🚀 Starting authentication server...');
64
+ await authServer.initialize();
65
+ // Get the authorization URL (now port is available)
66
+ const authUrl = authServer.getAuthorizationUrl();
67
+ console.log('🌐 Opening browser for authentication...');
68
+ await (0, open_1.default)(authUrl);
69
+ console.log('📱 Please complete authentication in your browser.');
70
+ console.log('⏳ Waiting for authentication to complete...');
71
+ // Start server and wait for callback
72
+ const authCallback = await authServer.start();
73
+ // Store the token
74
+ console.log('🔐 Saving authentication token...');
75
+ await (0, auth_1.storeAccessToken)(authCallback.token);
76
+ console.log('✅ Successfully authenticated!');
77
+ console.log('');
78
+ console.log('You can now use blok0 commands that require authentication.');
79
+ }
80
+ catch (error) {
81
+ authServer.stop();
82
+ throw error;
83
+ }
84
+ }
85
+ /**
86
+ * Show manual authentication instructions
87
+ */
88
+ function showManualInstructions() {
89
+ console.log('🔐 Blok0 Manual Authentication');
90
+ console.log('==============================');
91
+ console.log('');
92
+ console.log('To authenticate with the Blok0 API, make a POST request to:');
93
+ console.log('https://www.blok0.xyz/api/customers/login');
94
+ console.log('');
95
+ console.log('Example using curl:');
96
+ console.log('curl -X POST https://www.blok0.xyz/api/customers/login \\');
97
+ console.log(' -H "Content-Type: application/json" \\');
98
+ console.log(' -d \'{"email": "your-email@example.com", "password": "your-password"}\'');
99
+ console.log('');
100
+ console.log('Then copy the access token and run:');
101
+ console.log('blok0 login --token <your-token>');
102
+ console.log('');
103
+ console.log('For CI/CD environments, set the BLOK0_TOKEN environment variable.');
104
+ console.log('');
105
+ console.log('💡 For browser-based login, run: blok0 login');
106
+ }
107
+ /**
108
+ * Handle logout command
109
+ */
110
+ async function handleLogout() {
111
+ try {
112
+ const wasAuthenticated = await (0, auth_1.isAuthenticated)();
113
+ if (!wasAuthenticated) {
114
+ console.log('You are not currently logged in.');
115
+ return;
116
+ }
117
+ await (0, auth_1.clearCredentials)();
118
+ console.log('✅ Successfully logged out and cleared stored credentials.');
119
+ }
120
+ catch (error) {
121
+ console.error('❌ Failed to logout:', error.message);
122
+ process.exit(1);
123
+ }
124
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- #!/usr/bin/env bun
1
+ #!/usr/bin/env node
2
2
  export {};