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
|
@@ -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,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,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
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
export {};
|