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/api/index.d.ts +46 -0
- package/dist/api/index.js +147 -0
- package/dist/ast/index.d.ts +31 -0
- package/dist/ast/index.js +324 -0
- package/dist/auth/constants.d.ts +11 -0
- package/dist/auth/constants.js +155 -0
- package/dist/auth/index.d.ts +61 -0
- package/dist/auth/index.js +168 -0
- package/dist/auth/server.d.ts +55 -0
- package/dist/auth/server.js +236 -0
- package/dist/blocks/index.d.ts +56 -0
- package/dist/blocks/index.js +189 -0
- package/dist/handlers/add-block.d.ts +7 -0
- package/dist/handlers/add-block.js +142 -0
- package/dist/handlers/login.d.ts +8 -0
- package/dist/handlers/login.js +124 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +187 -7
- package/dist/registry/index.d.ts +75 -0
- package/dist/registry/index.js +231 -0
- package/package.json +33 -25
- package/src/api/index.ts +177 -0
- package/src/ast/index.ts +368 -0
- package/src/auth/constants.ts +155 -0
- package/src/auth/index.ts +154 -0
- package/src/auth/server.ts +240 -0
- package/src/blocks/index.ts +186 -0
- package/src/handlers/add-block.ts +132 -0
- package/src/handlers/login.ts +130 -0
- package/src/index.ts +212 -51
- package/src/registry/index.ts +244 -0
- package/test-ast.js +150 -0
package/dist/index.js
CHANGED
|
@@ -1,10 +1,46 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
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
|
|
23
|
-
|
|
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
|
-
|
|
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
|
-
|
|
182
|
+
(0, registry_1.createEmptyRegistry)();
|
|
183
|
+
console.log('📝 Initialized blok0-registry.json');
|
|
39
184
|
}
|
|
40
185
|
catch (error) {
|
|
41
|
-
console.
|
|
42
|
-
|
|
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.
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
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
|
+
}
|