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.
package/dist/index.js CHANGED
@@ -1,10 +1,46 @@
1
- #!/usr/bin/env bun
1
+ #!/usr/bin/env node
2
2
  "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
3
36
  Object.defineProperty(exports, "__esModule", { value: true });
4
37
  const fs_1 = require("fs");
5
38
  const readline_1 = require("readline");
6
39
  const detectors_1 = require("./detectors");
7
40
  const generate_1 = require("./handlers/generate");
41
+ const login_1 = require("./handlers/login");
42
+ const add_block_1 = require("./handlers/add-block");
43
+ const registry_1 = require("./registry");
8
44
  function prompt(question) {
9
45
  return new Promise((resolve) => {
10
46
  const rl = (0, readline_1.createInterface)({
@@ -17,13 +53,119 @@ function prompt(question) {
17
53
  });
18
54
  });
19
55
  }
56
+ async function showHelp() {
57
+ console.log(`
58
+ Blok0 - PayloadCMS Block Management CLI
59
+
60
+ USAGE:
61
+ blok0 <command> [subcommand] [options]
62
+
63
+ COMMANDS:
64
+ login Authenticate via browser or token
65
+ logout Remove stored credentials
66
+ debug Show authentication debug info
67
+ generate starter [folder] Generate PayloadCMS starter project
68
+ add block <url> Add a block from remote API
69
+ update block <id> Update existing block (future)
70
+ remove block <id> Remove block and clean up (future)
71
+ registry validate Validate registry integrity (future)
72
+
73
+ OPTIONS:
74
+ --help, -h Show this help message
75
+ --version, -v Show version information
76
+ --verbose Enable verbose logging
77
+ --dry-run Preview changes without applying them
78
+
79
+ EXAMPLES:
80
+ blok0 login
81
+ blok0 generate starter my-project
82
+ blok0 add block https://www.blok0.com/api/cli/sections/123
83
+
84
+ For more information, visit: https://github.com/blok0-payload/cli
85
+ `);
86
+ }
20
87
  async function main() {
21
88
  const args = process.argv.slice(2);
22
- if (args.length < 2 || args[0] !== 'generate' || args[1] !== 'starter') {
23
- console.error('Error: Invalid command. Supported: generate starter [folder]');
89
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
90
+ showHelp();
91
+ process.exit(0);
92
+ }
93
+ if (args.includes('--version') || args.includes('-v')) {
94
+ const pkg = require('../package.json');
95
+ console.log(`blok0 v${pkg.version}`);
96
+ process.exit(0);
97
+ }
98
+ const [command, ...restArgs] = args;
99
+ try {
100
+ switch (command) {
101
+ case 'generate':
102
+ const [genSubcommand, ...genRestArgs] = restArgs;
103
+ if (genSubcommand === 'starter') {
104
+ await handleGenerateStarter(genRestArgs);
105
+ }
106
+ else {
107
+ console.error('Error: Invalid subcommand. Use: blok0 generate starter [folder]');
108
+ process.exit(1);
109
+ }
110
+ break;
111
+ case 'login':
112
+ // Check for flags
113
+ const tokenIndex = restArgs.indexOf('--token');
114
+ const manualIndex = restArgs.indexOf('--manual');
115
+ if (tokenIndex !== -1 && tokenIndex + 1 < restArgs.length) {
116
+ const token = restArgs[tokenIndex + 1];
117
+ await (0, login_1.handleLogin)(token);
118
+ }
119
+ else if (manualIndex !== -1) {
120
+ await (0, login_1.handleLogin)(undefined, true);
121
+ }
122
+ else {
123
+ await (0, login_1.handleLogin)();
124
+ }
125
+ break;
126
+ case 'logout':
127
+ await (0, login_1.handleLogout)();
128
+ break;
129
+ case 'debug':
130
+ await handleDebug();
131
+ break;
132
+ case 'add':
133
+ const [addSubcommand, ...addRestArgs] = restArgs;
134
+ if (addSubcommand === 'block') {
135
+ const blockUrl = `https://www.blok0.com/api/cli/sections/${addRestArgs[0]}`;
136
+ if (!blockUrl) {
137
+ console.error('Error: Block Slug is required. Use: blok0 add block <slug>');
138
+ process.exit(1);
139
+ }
140
+ const options = {
141
+ force: addRestArgs.includes('--force'),
142
+ dryRun: addRestArgs.includes('--dry-run')
143
+ };
144
+ await (0, add_block_1.handleAddBlock)(blockUrl, options);
145
+ }
146
+ else {
147
+ console.error('Error: Invalid subcommand. Use: blok0 add block <url>');
148
+ process.exit(1);
149
+ }
150
+ break;
151
+ case 'update':
152
+ case 'remove':
153
+ case 'registry':
154
+ console.log(`${command} functionality coming soon...`);
155
+ break;
156
+ default:
157
+ console.error(`Error: Unknown command '${command}'`);
158
+ showHelp();
159
+ process.exit(1);
160
+ }
161
+ }
162
+ catch (error) {
163
+ console.error(`Error: ${error.message}`);
24
164
  process.exit(1);
25
165
  }
26
- let targetFolder = args[2];
166
+ }
167
+ async function handleGenerateStarter(args) {
168
+ let targetFolder = args[0];
27
169
  if (!targetFolder) {
28
170
  targetFolder = await prompt('Enter project folder name: ');
29
171
  }
@@ -34,12 +176,50 @@ async function main() {
34
176
  if (!(0, detectors_1.checkEmptyDirectory)()) {
35
177
  process.exit(1);
36
178
  }
179
+ await (0, generate_1.generateStarter)();
180
+ // Initialize empty registry for the new project
37
181
  try {
38
- await (0, generate_1.generateStarter)();
182
+ (0, registry_1.createEmptyRegistry)();
183
+ console.log('📝 Initialized blok0-registry.json');
39
184
  }
40
185
  catch (error) {
41
- console.error(`Error: ${error.message}`);
42
- process.exit(1);
186
+ console.warn('⚠️ Failed to initialize registry:', error.message);
187
+ }
188
+ }
189
+ async function handleDebug() {
190
+ console.log('🔍 Blok0 CLI Debug Information');
191
+ console.log('==============================');
192
+ console.log('');
193
+ // Check stored token
194
+ const { getAccessToken, isAuthenticated } = await Promise.resolve().then(() => __importStar(require('./auth')));
195
+ const token = await getAccessToken();
196
+ const isAuth = await isAuthenticated();
197
+ console.log('🔐 Authentication Status:');
198
+ console.log(` Authenticated: ${isAuth ? '✅ Yes' : '❌ No'}`);
199
+ console.log(` Token Stored: ${token ? '✅ Yes' : '❌ No'}`);
200
+ if (token) {
201
+ console.log(` Token Preview: ${token.substring(0, 20)}...`);
202
+ console.log(` Authorization Header: Bearer ${token}`);
203
+ }
204
+ console.log('');
205
+ console.log('🌐 API Configuration:');
206
+ console.log(' Base URL: https://www.blok0.xyz');
207
+ console.log(' User Agent: blok0-cli/1.0.0');
208
+ console.log('');
209
+ console.log('🧪 Test API Connection:');
210
+ // Test API connection
211
+ const { apiClient } = await Promise.resolve().then(() => __importStar(require('./api')));
212
+ try {
213
+ const connectionTest = await apiClient.testConnection();
214
+ console.log(` Connection Test: ${connectionTest ? '✅ Passed' : '❌ Failed'}`);
215
+ }
216
+ catch (error) {
217
+ console.log(` Connection Test: ❌ Failed - ${error.message}`);
43
218
  }
219
+ console.log('');
220
+ console.log('💡 Next Steps:');
221
+ console.log(' 1. If no token, run: blok0 login');
222
+ console.log(' 2. Test API with: blok0 add block <url>');
223
+ console.log(' 3. Check server logs for detailed request info');
44
224
  }
45
225
  main();
@@ -0,0 +1,75 @@
1
+ export interface BlockSource {
2
+ url: string;
3
+ id: number;
4
+ }
5
+ export interface BlockEntry {
6
+ id: number;
7
+ name: string;
8
+ slug: string;
9
+ dir: string;
10
+ configPath: string;
11
+ componentPath: string;
12
+ source: BlockSource & {
13
+ fetchedAt: string;
14
+ };
15
+ checksums: {
16
+ [filename: string]: string;
17
+ };
18
+ }
19
+ export interface RegistryData {
20
+ version: string;
21
+ blocks: {
22
+ [slug: string]: BlockEntry;
23
+ };
24
+ }
25
+ /**
26
+ * Load registry from file
27
+ */
28
+ export declare function loadRegistry(): RegistryData;
29
+ /**
30
+ * Save registry to file
31
+ */
32
+ export declare function saveRegistry(registry: RegistryData): void;
33
+ /**
34
+ * Check if block slug already exists in registry
35
+ */
36
+ export declare function isBlockRegistered(slug: string): boolean;
37
+ /**
38
+ * Get block entry by slug
39
+ */
40
+ export declare function getBlockEntry(slug: string): BlockEntry | null;
41
+ /**
42
+ * Add block to registry
43
+ */
44
+ export declare function addBlockToRegistry(entry: BlockEntry): void;
45
+ /**
46
+ * Remove block from registry
47
+ */
48
+ export declare function removeBlockFromRegistry(slug: string): void;
49
+ /**
50
+ * Update block checksums
51
+ */
52
+ export declare function updateBlockChecksums(slug: string, checksums: {
53
+ [filename: string]: string;
54
+ }): void;
55
+ /**
56
+ * Calculate file checksum
57
+ */
58
+ export declare function calculateChecksum(filePath: string): string;
59
+ /**
60
+ * Calculate checksums for all files in a directory
61
+ */
62
+ export declare function calculateDirectoryChecksums(dirPath: string): {
63
+ [filename: string]: string;
64
+ };
65
+ /**
66
+ * Validate registry integrity
67
+ */
68
+ export declare function validateRegistry(): {
69
+ valid: boolean;
70
+ errors: string[];
71
+ };
72
+ /**
73
+ * Create empty registry for new projects
74
+ */
75
+ export declare function createEmptyRegistry(): void;
@@ -0,0 +1,231 @@
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.loadRegistry = loadRegistry;
37
+ exports.saveRegistry = saveRegistry;
38
+ exports.isBlockRegistered = isBlockRegistered;
39
+ exports.getBlockEntry = getBlockEntry;
40
+ exports.addBlockToRegistry = addBlockToRegistry;
41
+ exports.removeBlockFromRegistry = removeBlockFromRegistry;
42
+ exports.updateBlockChecksums = updateBlockChecksums;
43
+ exports.calculateChecksum = calculateChecksum;
44
+ exports.calculateDirectoryChecksums = calculateDirectoryChecksums;
45
+ exports.validateRegistry = validateRegistry;
46
+ exports.createEmptyRegistry = createEmptyRegistry;
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ const crypto = __importStar(require("crypto"));
50
+ const REGISTRY_FILE = 'blok0-registry.json';
51
+ const REGISTRY_VERSION = '1.0';
52
+ /**
53
+ * Get registry file path
54
+ */
55
+ function getRegistryPath() {
56
+ return path.join(process.cwd(), REGISTRY_FILE);
57
+ }
58
+ /**
59
+ * Load registry from file
60
+ */
61
+ function loadRegistry() {
62
+ const registryPath = getRegistryPath();
63
+ if (!fs.existsSync(registryPath)) {
64
+ return {
65
+ version: REGISTRY_VERSION,
66
+ blocks: {}
67
+ };
68
+ }
69
+ try {
70
+ const data = fs.readFileSync(registryPath, 'utf-8');
71
+ const registry = JSON.parse(data);
72
+ // Validate registry structure
73
+ if (!registry.version || !registry.blocks) {
74
+ throw new Error('Invalid registry structure');
75
+ }
76
+ return registry;
77
+ }
78
+ catch (error) {
79
+ throw new Error(`Failed to load registry: ${error.message}`);
80
+ }
81
+ }
82
+ /**
83
+ * Save registry to file
84
+ */
85
+ function saveRegistry(registry) {
86
+ const registryPath = getRegistryPath();
87
+ try {
88
+ fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2));
89
+ }
90
+ catch (error) {
91
+ throw new Error(`Failed to save registry: ${error.message}`);
92
+ }
93
+ }
94
+ /**
95
+ * Check if block slug already exists in registry
96
+ */
97
+ function isBlockRegistered(slug) {
98
+ const registry = loadRegistry();
99
+ return slug in registry.blocks;
100
+ }
101
+ /**
102
+ * Get block entry by slug
103
+ */
104
+ function getBlockEntry(slug) {
105
+ const registry = loadRegistry();
106
+ return registry.blocks[slug] || null;
107
+ }
108
+ /**
109
+ * Add block to registry
110
+ */
111
+ function addBlockToRegistry(entry) {
112
+ const registry = loadRegistry();
113
+ if (entry.slug in registry.blocks) {
114
+ throw new Error(`Block with slug '${entry.slug}' is already registered`);
115
+ }
116
+ registry.blocks[entry.slug] = entry;
117
+ saveRegistry(registry);
118
+ }
119
+ /**
120
+ * Remove block from registry
121
+ */
122
+ function removeBlockFromRegistry(slug) {
123
+ const registry = loadRegistry();
124
+ if (!(slug in registry.blocks)) {
125
+ throw new Error(`Block with slug '${slug}' is not registered`);
126
+ }
127
+ delete registry.blocks[slug];
128
+ saveRegistry(registry);
129
+ }
130
+ /**
131
+ * Update block checksums
132
+ */
133
+ function updateBlockChecksums(slug, checksums) {
134
+ const registry = loadRegistry();
135
+ if (!(slug in registry.blocks)) {
136
+ throw new Error(`Block with slug '${slug}' is not registered`);
137
+ }
138
+ registry.blocks[slug].checksums = checksums;
139
+ saveRegistry(registry);
140
+ }
141
+ /**
142
+ * Calculate file checksum
143
+ */
144
+ function calculateChecksum(filePath) {
145
+ const fileBuffer = fs.readFileSync(filePath);
146
+ const hashSum = crypto.createHash('sha256');
147
+ hashSum.update(fileBuffer);
148
+ return hashSum.digest('hex');
149
+ }
150
+ /**
151
+ * Calculate checksums for all files in a directory
152
+ */
153
+ function calculateDirectoryChecksums(dirPath) {
154
+ const checksums = {};
155
+ function walkDirectory(dir) {
156
+ const files = fs.readdirSync(dir);
157
+ for (const file of files) {
158
+ const filePath = path.join(dir, file);
159
+ const stat = fs.statSync(filePath);
160
+ if (stat.isDirectory()) {
161
+ walkDirectory(filePath);
162
+ }
163
+ else {
164
+ const relativePath = path.relative(dirPath, filePath);
165
+ checksums[relativePath] = calculateChecksum(filePath);
166
+ }
167
+ }
168
+ }
169
+ walkDirectory(dirPath);
170
+ return checksums;
171
+ }
172
+ /**
173
+ * Validate registry integrity
174
+ */
175
+ function validateRegistry() {
176
+ const errors = [];
177
+ try {
178
+ const registry = loadRegistry();
179
+ for (const [slug, entry] of Object.entries(registry.blocks)) {
180
+ // Check if block directory exists
181
+ if (!fs.existsSync(entry.dir)) {
182
+ errors.push(`Block '${slug}': directory '${entry.dir}' does not exist`);
183
+ continue;
184
+ }
185
+ // Check if config file exists
186
+ if (!fs.existsSync(entry.configPath)) {
187
+ errors.push(`Block '${slug}': config file '${entry.configPath}' does not exist`);
188
+ }
189
+ // Check if component file exists
190
+ if (!fs.existsSync(entry.componentPath)) {
191
+ errors.push(`Block '${slug}': component file '${entry.componentPath}' does not exist`);
192
+ }
193
+ // Validate checksums if they exist
194
+ if (entry.checksums) {
195
+ for (const [file, expectedChecksum] of Object.entries(entry.checksums)) {
196
+ const filePath = path.join(entry.dir, file);
197
+ if (fs.existsSync(filePath)) {
198
+ const actualChecksum = calculateChecksum(filePath);
199
+ if (actualChecksum !== expectedChecksum) {
200
+ errors.push(`Block '${slug}': checksum mismatch for '${file}'`);
201
+ }
202
+ }
203
+ else {
204
+ errors.push(`Block '${slug}': file '${file}' referenced in checksums does not exist`);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ }
210
+ catch (error) {
211
+ errors.push(`Registry validation failed: ${error.message}`);
212
+ }
213
+ return {
214
+ valid: errors.length === 0,
215
+ errors
216
+ };
217
+ }
218
+ /**
219
+ * Create empty registry for new projects
220
+ */
221
+ function createEmptyRegistry() {
222
+ const registryPath = getRegistryPath();
223
+ if (fs.existsSync(registryPath)) {
224
+ throw new Error('Registry already exists');
225
+ }
226
+ const emptyRegistry = {
227
+ version: REGISTRY_VERSION,
228
+ blocks: {}
229
+ };
230
+ saveRegistry(emptyRegistry);
231
+ }
package/package.json CHANGED
@@ -1,25 +1,33 @@
1
- {
2
- "name": "blok0",
3
- "version": "0.1.0",
4
- "description": "CLI tool for Payload CMS scaffolding",
5
- "main": "dist/index.js",
6
- "bin": {
7
- "blok0": "./dist/index.js"
8
- },
9
- "scripts": {
10
- "build": "bun run tsc",
11
- "dev": "bun run tsx src/index.ts"
12
- },
13
- "keywords": ["cli", "payload", "cms"],
14
- "author": "Your Name",
15
- "license": "MIT",
16
- "dependencies": {
17
- "payload": "^2.0.0"
18
- },
19
- "devDependencies": {
20
- "@types/node": "^20.0.0",
21
- "bun-types": "^1.0.0",
22
- "tsx": "^4.0.0",
23
- "typescript": "^5.0.0"
24
- }
25
- }
1
+ {
2
+ "name": "blok0",
3
+ "version": "0.1.2",
4
+ "description": "CLI tool for Payload CMS scaffolding",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "blok0": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "bun run tsc",
11
+ "dev": "bun run tsx src/index.ts"
12
+ },
13
+ "keywords": [
14
+ "cli",
15
+ "payload",
16
+ "cms"
17
+ ],
18
+ "author": "Your Name",
19
+ "license": "MIT",
20
+ "dependencies": {
21
+ "axios": "^1.13.2",
22
+ "keytar": "^7.9.0",
23
+ "open": "^11.0.0",
24
+ "payload": "^2.0.0",
25
+ "ts-morph": "^27.0.2"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^20.19.27",
29
+ "bun-types": "^1.0.0",
30
+ "tsx": "^4.0.0",
31
+ "typescript": "^5.0.0"
32
+ }
33
+ }