blok0 0.1.5 → 0.1.6
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 +7 -4
- package/dist/api/index.js +7 -0
- package/dist/ast/index.d.ts +8 -0
- package/dist/ast/index.js +151 -2
- package/dist/blocks/index.d.ts +0 -4
- package/dist/blocks/index.js +0 -1
- package/dist/handlers/add-block.js +50 -42
- package/dist/handlers/generate.js +35 -18
- package/dist/handlers/login.js +29 -20
- package/dist/handlers/remove-block.d.ts +6 -0
- package/dist/handlers/remove-block.js +115 -0
- package/dist/index.js +38 -27
- package/dist/registry/index.d.ts +0 -4
- package/package.json +35 -37
- package/src/api/index.ts +9 -5
- package/src/ast/index.ts +162 -5
- package/src/blocks/index.ts +2 -3
- package/src/detectors.ts +22 -22
- package/src/handlers/add-block.ts +52 -69
- package/src/handlers/generate.ts +62 -59
- package/src/handlers/login.ts +29 -40
- package/src/handlers/remove-block.ts +94 -0
- package/src/index.ts +38 -36
- package/src/registry/index.ts +1 -5
- package/tsconfig.json +16 -16
- package/dist/packageManager.d.ts +0 -9
- package/dist/packageManager.js +0 -139
- package/dist/ui.d.ts +0 -77
- package/dist/ui.js +0 -222
- package/src/packageManager.ts +0 -117
- package/src/ui.ts +0 -234
package/dist/api/index.d.ts
CHANGED
|
@@ -8,10 +8,6 @@ export interface BlockMetadata {
|
|
|
8
8
|
url: string;
|
|
9
9
|
};
|
|
10
10
|
}>;
|
|
11
|
-
externalPackages: Array<{
|
|
12
|
-
id: string;
|
|
13
|
-
package: string;
|
|
14
|
-
}>;
|
|
15
11
|
_status: 'published' | 'draft';
|
|
16
12
|
}
|
|
17
13
|
export interface CodeFile {
|
|
@@ -41,6 +37,13 @@ declare class APIClient {
|
|
|
41
37
|
metadata: BlockMetadata;
|
|
42
38
|
files: CodeFile[];
|
|
43
39
|
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Fetch block data by slug
|
|
42
|
+
*/
|
|
43
|
+
fetchBlockBySlug(slug: string): Promise<{
|
|
44
|
+
metadata: BlockMetadata;
|
|
45
|
+
files: CodeFile[];
|
|
46
|
+
}>;
|
|
44
47
|
/**
|
|
45
48
|
* Test API connectivity and authentication
|
|
46
49
|
*/
|
package/dist/api/index.js
CHANGED
|
@@ -128,6 +128,13 @@ class APIClient {
|
|
|
128
128
|
}
|
|
129
129
|
return { metadata, files };
|
|
130
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Fetch block data by slug
|
|
133
|
+
*/
|
|
134
|
+
async fetchBlockBySlug(slug) {
|
|
135
|
+
const url = `/api/cli/sections/${slug}`;
|
|
136
|
+
return this.fetchBlockData(url);
|
|
137
|
+
}
|
|
131
138
|
/**
|
|
132
139
|
* Test API connectivity and authentication
|
|
133
140
|
*/
|
package/dist/ast/index.d.ts
CHANGED
|
@@ -29,3 +29,11 @@ export declare function findPagesCollection(): string | null;
|
|
|
29
29
|
* Extract the component name from a Component.tsx file
|
|
30
30
|
*/
|
|
31
31
|
export declare function extractComponentName(componentPath: string): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* Remove block from Pages collection config
|
|
34
|
+
*/
|
|
35
|
+
export declare function removePageCollectionConfig(pagesCollectionPath: string, blockName: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Remove block component from RenderBlocks.tsx
|
|
38
|
+
*/
|
|
39
|
+
export declare function removeRenderBlocksComponent(componentPath: string, blockSlug: string): void;
|
package/dist/ast/index.js
CHANGED
|
@@ -7,6 +7,8 @@ exports.findPayloadConfig = findPayloadConfig;
|
|
|
7
7
|
exports.findRenderBlocksComponent = findRenderBlocksComponent;
|
|
8
8
|
exports.findPagesCollection = findPagesCollection;
|
|
9
9
|
exports.extractComponentName = extractComponentName;
|
|
10
|
+
exports.removePageCollectionConfig = removePageCollectionConfig;
|
|
11
|
+
exports.removeRenderBlocksComponent = removeRenderBlocksComponent;
|
|
10
12
|
const ts_morph_1 = require("ts-morph");
|
|
11
13
|
/**
|
|
12
14
|
* Update Payload page collection config to include new block
|
|
@@ -144,8 +146,8 @@ function updateRenderBlocksComponent(componentPath, blockSlug, blockComponentPat
|
|
|
144
146
|
if (!componentName) {
|
|
145
147
|
throw new Error(`Could not extract component name from ${fullComponentPath}`);
|
|
146
148
|
}
|
|
147
|
-
//
|
|
148
|
-
const blockTypeKey = blockSlug
|
|
149
|
+
// Use slug directly as blockType key (quoted)
|
|
150
|
+
const blockTypeKey = blockSlug;
|
|
149
151
|
const project = new ts_morph_1.Project();
|
|
150
152
|
const sourceFile = project.addSourceFileAtPath(componentPath);
|
|
151
153
|
// Find the blockComponents object
|
|
@@ -322,3 +324,150 @@ function extractComponentName(componentPath) {
|
|
|
322
324
|
return null;
|
|
323
325
|
}
|
|
324
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Remove block from Pages collection config
|
|
329
|
+
*/
|
|
330
|
+
function removePageCollectionConfig(pagesCollectionPath, blockName) {
|
|
331
|
+
const project = new ts_morph_1.Project();
|
|
332
|
+
const sourceFile = project.addSourceFileAtPath(pagesCollectionPath);
|
|
333
|
+
// 1. Remove from blocks array
|
|
334
|
+
const pagesExport = sourceFile.getVariableDeclaration('Pages');
|
|
335
|
+
if (pagesExport) {
|
|
336
|
+
const pagesObject = pagesExport.getInitializer();
|
|
337
|
+
if (pagesObject && ts_morph_1.Node.isObjectLiteralExpression(pagesObject)) {
|
|
338
|
+
const fieldsProperty = pagesObject.getProperty('fields');
|
|
339
|
+
if (fieldsProperty && ts_morph_1.Node.isPropertyAssignment(fieldsProperty)) {
|
|
340
|
+
const fieldsArray = fieldsProperty.getInitializer();
|
|
341
|
+
if (fieldsArray && ts_morph_1.Node.isArrayLiteralExpression(fieldsArray)) {
|
|
342
|
+
// Find tabs
|
|
343
|
+
const tabsField = fieldsArray.getElements().find(element => {
|
|
344
|
+
if (ts_morph_1.Node.isObjectLiteralExpression(element)) {
|
|
345
|
+
const typeProperty = element.getProperty('type');
|
|
346
|
+
if (ts_morph_1.Node.isPropertyAssignment(typeProperty)) {
|
|
347
|
+
const initializer = typeProperty.getInitializer();
|
|
348
|
+
return ts_morph_1.Node.isStringLiteral(initializer) && initializer.getLiteralValue() === 'tabs';
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
});
|
|
353
|
+
if (tabsField && ts_morph_1.Node.isObjectLiteralExpression(tabsField)) {
|
|
354
|
+
const tabsProperty = tabsField.getProperty('tabs');
|
|
355
|
+
if (tabsProperty && ts_morph_1.Node.isPropertyAssignment(tabsProperty)) {
|
|
356
|
+
const tabsArray = tabsProperty.getInitializer();
|
|
357
|
+
if (tabsArray && ts_morph_1.Node.isArrayLiteralExpression(tabsArray)) {
|
|
358
|
+
// Find content tab
|
|
359
|
+
const contentTab = tabsArray.getElements().find(element => {
|
|
360
|
+
if (ts_morph_1.Node.isObjectLiteralExpression(element)) {
|
|
361
|
+
const labelProperty = element.getProperty('label');
|
|
362
|
+
if (ts_morph_1.Node.isPropertyAssignment(labelProperty)) {
|
|
363
|
+
const initializer = labelProperty.getInitializer();
|
|
364
|
+
return ts_morph_1.Node.isStringLiteral(initializer) && initializer.getLiteralValue() === 'Content';
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return false;
|
|
368
|
+
});
|
|
369
|
+
if (contentTab && ts_morph_1.Node.isObjectLiteralExpression(contentTab)) {
|
|
370
|
+
const contentFields = contentTab.getProperty('fields');
|
|
371
|
+
if (contentFields && ts_morph_1.Node.isPropertyAssignment(contentFields)) {
|
|
372
|
+
const contentFieldsArray = contentFields.getInitializer();
|
|
373
|
+
if (contentFieldsArray && ts_morph_1.Node.isArrayLiteralExpression(contentFieldsArray)) {
|
|
374
|
+
// Find layout field
|
|
375
|
+
const layoutField = contentFieldsArray.getElements().find(element => {
|
|
376
|
+
if (ts_morph_1.Node.isObjectLiteralExpression(element)) {
|
|
377
|
+
const nameProperty = element.getProperty('name');
|
|
378
|
+
if (ts_morph_1.Node.isPropertyAssignment(nameProperty)) {
|
|
379
|
+
const initializer = nameProperty.getInitializer();
|
|
380
|
+
return ts_morph_1.Node.isStringLiteral(initializer) && initializer.getLiteralValue() === 'layout';
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return false;
|
|
384
|
+
});
|
|
385
|
+
if (layoutField && ts_morph_1.Node.isObjectLiteralExpression(layoutField)) {
|
|
386
|
+
const blocksProperty = layoutField.getProperty('blocks');
|
|
387
|
+
if (blocksProperty && ts_morph_1.Node.isPropertyAssignment(blocksProperty)) {
|
|
388
|
+
const blocksArray = blocksProperty.getInitializer();
|
|
389
|
+
if (blocksArray && ts_morph_1.Node.isArrayLiteralExpression(blocksArray)) {
|
|
390
|
+
// Find and remove the block
|
|
391
|
+
const elements = blocksArray.getElements();
|
|
392
|
+
for (let i = 0; i < elements.length; i++) {
|
|
393
|
+
if (elements[i].getText() === blockName) {
|
|
394
|
+
blocksArray.removeElement(i);
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// 2. Remove import
|
|
412
|
+
const importDeclarations = sourceFile.getImportDeclarations();
|
|
413
|
+
for (const imp of importDeclarations) {
|
|
414
|
+
const namedImports = imp.getNamedImports();
|
|
415
|
+
for (const namedImport of namedImports) {
|
|
416
|
+
if (namedImport.getName() === blockName) {
|
|
417
|
+
if (namedImports.length === 1) {
|
|
418
|
+
imp.remove();
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
namedImport.remove();
|
|
422
|
+
}
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
sourceFile.saveSync();
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Remove block component from RenderBlocks.tsx
|
|
431
|
+
*/
|
|
432
|
+
function removeRenderBlocksComponent(componentPath, blockSlug) {
|
|
433
|
+
const blockTypeKey = blockSlug;
|
|
434
|
+
const project = new ts_morph_1.Project();
|
|
435
|
+
const sourceFile = project.addSourceFileAtPath(componentPath);
|
|
436
|
+
// 1. Remove from blockComponents object
|
|
437
|
+
const blockComponents = sourceFile.getVariableDeclaration('blockComponents')?.getInitializer();
|
|
438
|
+
if (blockComponents && ts_morph_1.Node.isObjectLiteralExpression(blockComponents)) {
|
|
439
|
+
const property = blockComponents.getProperty(`'${blockTypeKey}'`) || blockComponents.getProperty(`"${blockTypeKey}"`);
|
|
440
|
+
if (property) {
|
|
441
|
+
// Get component name before removing property
|
|
442
|
+
const assignment = property;
|
|
443
|
+
const componentName = assignment.getInitializer()?.getText();
|
|
444
|
+
property.remove();
|
|
445
|
+
// 2. Remove import if we found the component name
|
|
446
|
+
if (componentName) {
|
|
447
|
+
const importDeclarations = sourceFile.getImportDeclarations();
|
|
448
|
+
for (const imp of importDeclarations) {
|
|
449
|
+
// Check default import
|
|
450
|
+
const defaultImport = imp.getDefaultImport();
|
|
451
|
+
if (defaultImport && defaultImport.getText() === componentName) {
|
|
452
|
+
imp.remove();
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
// Check named imports
|
|
456
|
+
const namedImports = imp.getNamedImports();
|
|
457
|
+
for (const namedImport of namedImports) {
|
|
458
|
+
if (namedImport.getName() === componentName) {
|
|
459
|
+
if (namedImports.length === 1) {
|
|
460
|
+
imp.remove();
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
namedImport.remove();
|
|
464
|
+
}
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
sourceFile.saveSync();
|
|
473
|
+
}
|
package/dist/blocks/index.d.ts
CHANGED
|
@@ -35,10 +35,6 @@ 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
|
-
}>;
|
|
42
38
|
}, dir: string, configPath: string, componentPath: string, checksums: {
|
|
43
39
|
[filename: string]: string;
|
|
44
40
|
}): BlockEntry;
|
package/dist/blocks/index.js
CHANGED
|
@@ -40,33 +40,43 @@ 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");
|
|
44
|
-
const ui_1 = require("../ui");
|
|
45
43
|
/**
|
|
46
44
|
* Handle add block command
|
|
47
45
|
*/
|
|
48
46
|
async function handleAddBlock(blockUrl, options = {}) {
|
|
49
|
-
|
|
47
|
+
console.log('📦 Adding Blok0 Block');
|
|
48
|
+
console.log('====================');
|
|
49
|
+
console.log('');
|
|
50
50
|
try {
|
|
51
51
|
// Step 1: Authentication check
|
|
52
|
-
|
|
52
|
+
console.log('🔐 Checking authentication...');
|
|
53
|
+
const authenticated = await (0, auth_1.isAuthenticated)();
|
|
53
54
|
if (!authenticated) {
|
|
54
|
-
|
|
55
|
+
console.error('❌ You are not logged in. Please run `blok0 login` first.');
|
|
55
56
|
process.exit(1);
|
|
56
57
|
}
|
|
57
58
|
// Step 2: Fetch block data from API
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
let blockData;
|
|
60
|
+
if (blockUrl.startsWith('http://') || blockUrl.startsWith('https://')) {
|
|
61
|
+
console.log(`📡 Fetching block from URL: ${blockUrl}`);
|
|
62
|
+
blockData = await api_1.apiClient.fetchBlockData(blockUrl);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.log(`📡 Fetching block by slug: ${blockUrl}`);
|
|
66
|
+
blockData = await api_1.apiClient.fetchBlockBySlug(blockUrl);
|
|
67
|
+
}
|
|
68
|
+
const { metadata, files } = blockData;
|
|
69
|
+
console.log(`✅ Found block: "${metadata.name}" (${metadata.slug})`);
|
|
60
70
|
// Step 3: Check if block is already registered
|
|
61
71
|
if ((0, registry_1.isBlockRegistered)(metadata.slug)) {
|
|
62
72
|
if (!options.force) {
|
|
63
|
-
|
|
73
|
+
console.error(`❌ Block "${metadata.slug}" is already installed. Use --force to reinstall.`);
|
|
64
74
|
process.exit(1);
|
|
65
75
|
}
|
|
66
|
-
|
|
76
|
+
console.log('⚠️ Block already exists, reinstalling...');
|
|
67
77
|
}
|
|
68
78
|
if (options.dryRun) {
|
|
69
|
-
|
|
79
|
+
console.log('🔍 Dry run mode - would perform the following actions:');
|
|
70
80
|
console.log(` - Create directory: src/blocks/${metadata.slug}`);
|
|
71
81
|
console.log(` - Download ${files.length} files`);
|
|
72
82
|
console.log(' - Update Payload config');
|
|
@@ -77,63 +87,61 @@ async function handleAddBlock(blockUrl, options = {}) {
|
|
|
77
87
|
// Step 4: Ensure blocks directory exists
|
|
78
88
|
const blocksDir = (0, blocks_1.ensureBlocksDirectory)();
|
|
79
89
|
// Step 5: Create block directory and files
|
|
90
|
+
console.log('📁 Creating block directory and files...');
|
|
80
91
|
const { dir, configPath, componentPath } = (0, blocks_1.createBlockDirectory)(blocksDir, metadata.slug, files);
|
|
81
|
-
|
|
92
|
+
console.log(`✅ Created block directory: ${path.relative(process.cwd(), dir)}`);
|
|
82
93
|
// Step 6: Validate created block
|
|
83
94
|
const validation = (0, blocks_1.validateBlockDirectory)(dir);
|
|
84
95
|
if (!validation.valid) {
|
|
85
|
-
|
|
96
|
+
console.error('❌ Block validation failed:');
|
|
86
97
|
validation.errors.forEach(error => console.error(` - ${error}`));
|
|
87
98
|
// Cleanup on failure
|
|
88
99
|
require('fs').rmSync(dir, { recursive: true, force: true });
|
|
89
100
|
process.exit(1);
|
|
90
101
|
}
|
|
91
|
-
// Step 7:
|
|
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
|
|
102
|
+
// Step 7: Calculate checksums
|
|
97
103
|
const checksums = (0, registry_1.calculateDirectoryChecksums)(dir);
|
|
98
|
-
// Step
|
|
104
|
+
// Step 8: Create registry entry
|
|
99
105
|
const blockEntry = (0, blocks_1.createBlockEntry)({
|
|
100
106
|
id: metadata.id,
|
|
101
107
|
name: metadata.name,
|
|
102
108
|
slug: metadata.slug,
|
|
103
|
-
sourceUrl: blockUrl
|
|
104
|
-
externalPackages: metadata.externalPackages
|
|
109
|
+
sourceUrl: blockUrl
|
|
105
110
|
}, dir, configPath, componentPath, checksums);
|
|
106
|
-
// Step
|
|
111
|
+
// Step 9: Update Pages collection (AST manipulation)
|
|
107
112
|
const pagesCollectionPath = (0, ast_1.findPagesCollection)();
|
|
108
113
|
if (pagesCollectionPath) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
console.log('🔧 Updating Pages collection...');
|
|
115
|
+
const blockIdentifier = (0, blocks_1.slugToIdentifier)(metadata.slug);
|
|
116
|
+
const relativeConfigPath = `@/blocks/${metadata.slug}/config`;
|
|
117
|
+
(0, ast_1.updatePageCollectionConfig)(pagesCollectionPath, relativeConfigPath, blockIdentifier);
|
|
118
|
+
console.log(`✅ Added ${blockIdentifier} to Pages collection`);
|
|
114
119
|
}
|
|
115
120
|
else {
|
|
116
|
-
|
|
121
|
+
console.warn('⚠️ Could not find Pages collection file. You may need to manually add the block to your collections.');
|
|
117
122
|
}
|
|
118
|
-
// Step
|
|
123
|
+
// Step 10: Update RenderBlocks component (AST manipulation)
|
|
119
124
|
const renderBlocksPath = (0, ast_1.findRenderBlocksComponent)();
|
|
120
125
|
if (renderBlocksPath) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
console.log('🔧 Updating RenderBlocks component...');
|
|
127
|
+
const relativeComponentPath = `./${metadata.slug}/Component`;
|
|
128
|
+
(0, ast_1.updateRenderBlocksComponent)(renderBlocksPath, metadata.slug, relativeComponentPath);
|
|
129
|
+
console.log(`✅ Added ${metadata.slug} component to RenderBlocks`);
|
|
125
130
|
}
|
|
126
131
|
else {
|
|
127
|
-
|
|
132
|
+
console.warn('⚠️ Could not find RenderBlocks component. You may need to manually add the block component.');
|
|
128
133
|
}
|
|
129
|
-
// Step
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
// Step 11: Register block in registry
|
|
135
|
+
console.log('📝 Registering block...');
|
|
136
|
+
(0, registry_1.addBlockToRegistry)(blockEntry);
|
|
137
|
+
console.log('✅ Block registered successfully');
|
|
138
|
+
console.log('');
|
|
139
|
+
console.log('🎉 Block installation complete!');
|
|
140
|
+
console.log('');
|
|
141
|
+
console.log('Next steps:');
|
|
142
|
+
console.log('1. Review the installed files in src/blocks/' + metadata.slug);
|
|
143
|
+
console.log('2. Test your application to ensure the block works correctly');
|
|
144
|
+
console.log('3. Commit the changes to your repository');
|
|
137
145
|
}
|
|
138
146
|
catch (error) {
|
|
139
147
|
console.error('❌ Failed to add block:', error.message);
|
|
@@ -4,7 +4,6 @@ exports.generateStarter = generateStarter;
|
|
|
4
4
|
const readline_1 = require("readline");
|
|
5
5
|
const child_process_1 = require("child_process");
|
|
6
6
|
const util_1 = require("util");
|
|
7
|
-
const ui_1 = require("../ui");
|
|
8
7
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
9
8
|
const repoUrl = 'https://github.com/blok0-payload/starter.git';
|
|
10
9
|
function prompt(question) {
|
|
@@ -20,27 +19,45 @@ function prompt(question) {
|
|
|
20
19
|
});
|
|
21
20
|
}
|
|
22
21
|
async function generateStarter() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
await (0, ui_1.withSpinner)('Cloning starter repository', async () => {
|
|
22
|
+
console.log('Cloning starter repository...');
|
|
23
|
+
try {
|
|
26
24
|
await execAsync(`git clone --depth 1 ${repoUrl} .`);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
console.log('Repository cloned successfully.');
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw new Error(`Failed to clone repository: ${error}`);
|
|
29
|
+
}
|
|
30
|
+
// Prompt for bun install
|
|
31
|
+
const installDeps = await prompt('Run \'bun install\' to install dependencies? (y/n): ');
|
|
32
|
+
if (installDeps) {
|
|
33
|
+
console.log('Installing dependencies...');
|
|
34
|
+
try {
|
|
35
|
+
await new Promise((resolve, reject) => {
|
|
36
|
+
const child = (0, child_process_1.spawn)('bun', ['install'], { stdio: 'inherit' });
|
|
37
|
+
child.on('close', (code) => {
|
|
38
|
+
if (code === 0)
|
|
39
|
+
resolve();
|
|
40
|
+
else
|
|
41
|
+
reject(new Error('Failed to install dependencies'));
|
|
42
|
+
});
|
|
43
|
+
child.on('error', reject);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error('Failed to install dependencies:', error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
31
50
|
// Prompt for git init
|
|
32
51
|
const initGit = await prompt('Initialize git repository? (y/n): ');
|
|
33
52
|
if (initGit) {
|
|
34
|
-
|
|
53
|
+
console.log('Initializing git repository...');
|
|
54
|
+
try {
|
|
35
55
|
await execAsync('git init');
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
console.log('Git repository initialized.');
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error('Failed to initialize git:', error);
|
|
60
|
+
}
|
|
40
61
|
}
|
|
41
|
-
|
|
42
|
-
(0, ui_1.showNextSteps)([
|
|
43
|
-
'Run \'npm install\' or \'bun install\' to install dependencies',
|
|
44
|
-
'Start developing your Blok0 x PayloadCMS project'
|
|
45
|
-
]);
|
|
62
|
+
console.log('Blok0 starter project created successfully!');
|
|
46
63
|
}
|
package/dist/handlers/login.js
CHANGED
|
@@ -8,7 +8,6 @@ exports.handleLogout = handleLogout;
|
|
|
8
8
|
const auth_1 = require("../auth");
|
|
9
9
|
const server_1 = require("../auth/server");
|
|
10
10
|
const open_1 = __importDefault(require("open"));
|
|
11
|
-
const ui_1 = require("../ui");
|
|
12
11
|
// Add SIGINT handler for graceful cleanup
|
|
13
12
|
process.on('SIGINT', () => {
|
|
14
13
|
console.log('\n\n⚠️ Authentication cancelled by user.');
|
|
@@ -21,12 +20,14 @@ async function handleLogin(token, manual) {
|
|
|
21
20
|
// Direct token authentication (CI/CD)
|
|
22
21
|
if (token) {
|
|
23
22
|
try {
|
|
24
|
-
|
|
23
|
+
console.log('🔐 Saving authentication token...');
|
|
24
|
+
await (0, auth_1.storeAccessToken)(token);
|
|
25
|
+
console.log('✅ Successfully authenticated!');
|
|
25
26
|
console.log('');
|
|
26
|
-
|
|
27
|
+
console.log('You can now use blok0 commands that require authentication.');
|
|
27
28
|
}
|
|
28
29
|
catch (error) {
|
|
29
|
-
|
|
30
|
+
console.error('❌ Failed to save authentication token:', error.message);
|
|
30
31
|
process.exit(1);
|
|
31
32
|
}
|
|
32
33
|
return;
|
|
@@ -52,24 +53,29 @@ async function handleLogin(token, manual) {
|
|
|
52
53
|
* Handle browser-based authentication flow
|
|
53
54
|
*/
|
|
54
55
|
async function handleBrowserLogin() {
|
|
55
|
-
|
|
56
|
+
console.log('🔐 Blok0 Authentication');
|
|
57
|
+
console.log('======================');
|
|
58
|
+
console.log('');
|
|
56
59
|
// Create authentication server
|
|
57
60
|
const authServer = new server_1.AuthServer();
|
|
58
61
|
try {
|
|
59
62
|
// Initialize server (find available port)
|
|
60
|
-
|
|
63
|
+
console.log('🚀 Starting authentication server...');
|
|
64
|
+
await authServer.initialize();
|
|
61
65
|
// Get the authorization URL (now port is available)
|
|
62
66
|
const authUrl = authServer.getAuthorizationUrl();
|
|
63
|
-
|
|
67
|
+
console.log('🌐 Opening browser for authentication...');
|
|
64
68
|
await (0, open_1.default)(authUrl);
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
console.log('📱 Please complete authentication in your browser.');
|
|
70
|
+
console.log('⏳ Waiting for authentication to complete...');
|
|
67
71
|
// Start server and wait for callback
|
|
68
72
|
const authCallback = await authServer.start();
|
|
69
73
|
// Store the token
|
|
70
|
-
|
|
74
|
+
console.log('🔐 Saving authentication token...');
|
|
75
|
+
await (0, auth_1.storeAccessToken)(authCallback.token);
|
|
76
|
+
console.log('✅ Successfully authenticated!');
|
|
71
77
|
console.log('');
|
|
72
|
-
|
|
78
|
+
console.log('You can now use blok0 commands that require authentication.');
|
|
73
79
|
}
|
|
74
80
|
catch (error) {
|
|
75
81
|
authServer.stop();
|
|
@@ -80,36 +86,39 @@ async function handleBrowserLogin() {
|
|
|
80
86
|
* Show manual authentication instructions
|
|
81
87
|
*/
|
|
82
88
|
function showManualInstructions() {
|
|
83
|
-
|
|
89
|
+
console.log('🔐 Blok0 Manual Authentication');
|
|
90
|
+
console.log('==============================');
|
|
91
|
+
console.log('');
|
|
84
92
|
console.log('To authenticate with the Blok0 API, make a POST request to:');
|
|
85
93
|
console.log('https://www.blok0.xyz/api/customers/login');
|
|
86
94
|
console.log('');
|
|
87
|
-
|
|
95
|
+
console.log('Example using curl:');
|
|
88
96
|
console.log('curl -X POST https://www.blok0.xyz/api/customers/login \\');
|
|
89
97
|
console.log(' -H "Content-Type: application/json" \\');
|
|
90
98
|
console.log(' -d \'{"email": "your-email@example.com", "password": "your-password"}\'');
|
|
91
99
|
console.log('');
|
|
92
|
-
|
|
100
|
+
console.log('Then copy the access token and run:');
|
|
93
101
|
console.log('blok0 login --token <your-token>');
|
|
94
102
|
console.log('');
|
|
95
|
-
|
|
103
|
+
console.log('For CI/CD environments, set the BLOK0_TOKEN environment variable.');
|
|
96
104
|
console.log('');
|
|
97
|
-
|
|
105
|
+
console.log('💡 For browser-based login, run: blok0 login');
|
|
98
106
|
}
|
|
99
107
|
/**
|
|
100
108
|
* Handle logout command
|
|
101
109
|
*/
|
|
102
110
|
async function handleLogout() {
|
|
103
111
|
try {
|
|
104
|
-
const wasAuthenticated = await (0,
|
|
112
|
+
const wasAuthenticated = await (0, auth_1.isAuthenticated)();
|
|
105
113
|
if (!wasAuthenticated) {
|
|
106
|
-
|
|
114
|
+
console.log('You are not currently logged in.');
|
|
107
115
|
return;
|
|
108
116
|
}
|
|
109
|
-
await (0,
|
|
117
|
+
await (0, auth_1.clearCredentials)();
|
|
118
|
+
console.log('✅ Successfully logged out and cleared stored credentials.');
|
|
110
119
|
}
|
|
111
120
|
catch (error) {
|
|
112
|
-
|
|
121
|
+
console.error('❌ Failed to logout:', error.message);
|
|
113
122
|
process.exit(1);
|
|
114
123
|
}
|
|
115
124
|
}
|