cbs-block 1.0.4 → 1.0.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.
Files changed (2) hide show
  1. package/bin/cbs-block.js +119 -33
  2. package/package.json +1 -1
package/bin/cbs-block.js CHANGED
@@ -20,34 +20,103 @@ async function main() {
20
20
  const colors = { 'Math': '#4A90E2', 'Logic': '#F5A623', 'Control': '#FFCC00', 'Custom': '#4CAF50' };
21
21
  return colors[a.category] || '#4CAF50';
22
22
  }},
23
- { type: 'confirm', name: 'hasFlow', message: 'Include flow ports?', default: true },
23
+ { type: 'confirm', name: 'useDir', message: 'Create as directory (Recommended for external packages)?', default: true },
24
24
  { type: 'list', name: 'lang', message: 'Primary Language:', choices: ['JavaScript', 'TypeScript'] }
25
25
  ]);
26
26
 
27
- const ext = answers.lang === 'TypeScript' ? 'ts' : 'js';
28
- const template = {
29
- name: answers.name,
30
- category: answers.category,
31
- color: answers.color,
32
- ports: [
33
- ...(answers.hasFlow ? [{ name: "flowIn", type: "FlowIn" }, { name: "flowOut", type: "FlowOut" }] : []),
34
- { name: "input1", type: "Input", dataType: "string" },
35
- { name: "output1", type: "Output", dataType: "string" }
36
- ],
37
- codeTemplates: {
38
- python: "print({input1})",
39
- web: "console.log({input1})",
40
- javascript: "console.log({input1})",
41
- typescript: `console.log({input1} as string)`
42
- },
43
- logic: answers.lang === 'TypeScript'
44
- ? `function run(inputs: { input1: string }): string { return inputs.input1; }`
45
- : `function run(inputs) { return inputs.input1; }`
46
- };
27
+ if (answers.useDir) {
28
+ const dirName = answers.name.toLowerCase().replace(/\s+/g, '_');
29
+ fs.mkdirSync(dirName, { recursive: true });
30
+
31
+ const metadata = {
32
+ name: answers.name,
33
+ category: answers.category,
34
+ color: answers.color,
35
+ ports: [
36
+ { name: "flowIn", type: "FlowIn" },
37
+ { name: "flowOut", type: "FlowOut" },
38
+ { name: "input1", type: "Input", dataType: "string" },
39
+ { name: "output1", type: "Output", dataType: "string" }
40
+ ],
41
+ codeTemplates: {
42
+ python: "print({input1})",
43
+ web: "console.log({input1})",
44
+ javascript: "console.log({input1})",
45
+ typescript: `console.log({input1} as string)`
46
+ }
47
+ };
48
+
49
+ const logicStr = answers.lang === 'TypeScript'
50
+ ? `export function run(inputs: { input1: string }): string {\n // TIP: You can now npm install packages here!\n return inputs.input1;\n}`
51
+ : `export function run(inputs) {\n // TIP: You can now npm install packages here!\n return inputs.input1;\n}`;
52
+
53
+ fs.writeFileSync(path.join(dirName, 'metadata.json'), JSON.stringify(metadata, null, 2));
54
+ fs.writeFileSync(path.join(dirName, answers.lang === 'TypeScript' ? 'index.ts' : 'index.js'), logicStr);
55
+ fs.writeFileSync(path.join(dirName, 'package.json'), JSON.stringify({
56
+ name: dirName,
57
+ version: "1.0.0",
58
+ main: "index.js",
59
+ dependencies: {}
60
+ }, null, 2));
61
+
62
+ console.log(chalk.green(`\n✔ Created code-first block directory: ${chalk.bold(dirName)}`));
63
+ console.log(chalk.cyan(` → cd ${dirName}`));
64
+ console.log(chalk.cyan(` → npm install <your-package>`));
65
+ console.log(chalk.cyan(` → cbs-block build`));
66
+
67
+ } else {
68
+ const template = {
69
+ name: answers.name,
70
+ category: answers.category,
71
+ color: answers.color,
72
+ ports: [
73
+ { name: "flowIn", type: "FlowIn" }, { name: "flowOut", type: "FlowOut" },
74
+ { name: "input1", type: "Input", dataType: "string" },
75
+ { name: "output1", type: "Output", dataType: "string" }
76
+ ],
77
+ codeTemplates: {
78
+ python: "print({input1})",
79
+ web: "console.log({input1})",
80
+ javascript: "console.log({input1})",
81
+ typescript: `console.log({input1} as string)`
82
+ },
83
+ logic: answers.lang === 'TypeScript'
84
+ ? `function run(inputs: { input1: string }): string { return inputs.input1; }`
85
+ : `function run(inputs) { return inputs.input1; }`
86
+ };
87
+
88
+ const fileName = `${answers.name.toLowerCase().replace(/\s+/g, '_')}.cbsblock`;
89
+ fs.writeFileSync(fileName, JSON.stringify(template, null, 2));
90
+ console.log(chalk.green(`\n✔ Successfully created block file: ${chalk.bold(fileName)}`));
91
+ }
92
+
93
+ } else if (command === 'build') {
94
+ const targetDir = target || '.';
95
+ const metaPath = path.join(targetDir, 'metadata.json');
96
+ const indexPath = fs.existsSync(path.join(targetDir, 'index.ts')) ? path.join(targetDir, 'index.ts') : path.join(targetDir, 'index.js');
47
97
 
48
- const fileName = `${answers.name.toLowerCase().replace(/\s+/g, '_')}.cbsblock`;
49
- fs.writeFileSync(fileName, JSON.stringify(template, null, 2));
50
- console.log(chalk.green(`\n✔ Successfully created block: ${chalk.bold(fileName)}`));
98
+ if (!fs.existsSync(metaPath)) return console.error(chalk.red(`Error: metadata.json not found in ${targetDir}`));
99
+ if (!fs.existsSync(indexPath)) return console.error(chalk.red(`Error: index.js/ts not found in ${targetDir}`));
100
+
101
+ console.log(chalk.yellow(`Building code-first block from ${targetDir}...`));
102
+
103
+ const metadata = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
104
+ let logic = fs.readFileSync(indexPath, 'utf8');
105
+
106
+ // Simple bundle logic: find imports and Warn for now (Premium feature for Phase 15.1)
107
+ // For now, we wrap it into a compatible run function for the engine
108
+ if (logic.includes('export function run')) {
109
+ logic = logic.replace(/export\s+function\s+run/g, 'function run');
110
+ } else if (logic.includes('export const run')) {
111
+ logic = logic.replace(/export\s+const\s+run\s*=\s*/g, 'function run');
112
+ }
113
+
114
+ metadata.logic = logic;
115
+ const outName = `${metadata.name.toLowerCase().replace(/\s+/g, '_')}.cbsblock`;
116
+ fs.writeFileSync(outName, JSON.stringify(metadata, null, 2));
117
+
118
+ console.log(chalk.green(`\n✔ Built ${chalk.bold(outName)} successfully!`));
119
+ console.log(chalk.dim(`(Note: Dynamic bundling for node_modules coming in next update)`));
51
120
 
52
121
  } else if (command === 'init') {
53
122
  const answers = await inquirer.prompt([
@@ -66,16 +135,32 @@ async function main() {
66
135
  fs.mkdirSync(path.join(answers.projName, 'blocks'), { recursive: true });
67
136
  console.log(chalk.green(`\n✔ Project ${chalk.bold(answers.projName)} initialized!`));
68
137
 
69
- } else if (command === 'pack' || command === 'build') {
138
+ } else if (command === 'pack') {
70
139
  const files = fs.readdirSync('.').filter(f => f.endsWith('.cbsblock'));
140
+ const dirs = fs.readdirSync('.').filter(d => fs.statSync(d).isDirectory() && fs.existsSync(path.join(d, 'metadata.json')));
141
+
142
+ console.log(chalk.yellow(`Packing ${files.length} files and ${dirs.length} directories into a .cbspak...`));
143
+
144
+ const packedBlocks = [
145
+ ...files.map(f => JSON.parse(fs.readFileSync(f, 'utf8'))),
146
+ ...dirs.map(d => {
147
+ const meta = JSON.parse(fs.readFileSync(path.join(d, 'metadata.json'), 'utf8'));
148
+ const indexPath = fs.existsSync(path.join(d, 'index.ts')) ? path.join(d, 'index.ts') : path.join(d, 'index.js');
149
+ let logic = fs.readFileSync(indexPath, 'utf8');
150
+ if (logic.includes('export function run')) logic = logic.replace('export function run', 'function run');
151
+ meta.logic = logic;
152
+ return meta;
153
+ })
154
+ ];
155
+
71
156
  const pack = {
72
157
  package: path.basename(process.cwd()),
73
158
  version: "1.0.0",
74
- blocks: files.map(f => JSON.parse(fs.readFileSync(f, 'utf8')))
159
+ blocks: packedBlocks
75
160
  };
76
161
  const packName = `${pack.package}.cbspak`;
77
162
  fs.writeFileSync(packName, JSON.stringify(pack, null, 2));
78
- console.log(chalk.green(`\n✔ Packed ${files.length} blocks into ${chalk.bold(packName)}`));
163
+ console.log(chalk.green(`\n✔ Packed ${packedBlocks.length} blocks into ${chalk.bold(packName)}`));
79
164
 
80
165
  } else if (command === 'doc' && target) {
81
166
  if (!fs.existsSync(target)) return console.error(chalk.red(`Error: File ${target} not found.`));
@@ -123,7 +208,7 @@ async function main() {
123
208
  const block = JSON.parse(fs.readFileSync(target, 'utf8'));
124
209
  console.log(chalk.yellow(`Testing logic for: ${block.name}...`));
125
210
  try {
126
- const run = new Function('inputs', `return (${block.logic.replace('function run(inputs)', '').replace(/ as string/g, '')})(inputs)`);
211
+ const run = new Function('inputs', block.logic + '\nreturn run(inputs);');
127
212
  const testResult = run({ input1: "Test Input" });
128
213
  console.log(chalk.green(`\n✔ Test Passed! Output: ${testResult}`));
129
214
  } catch (e) {
@@ -149,7 +234,7 @@ async function main() {
149
234
  console.log(chalk.cyan(`\n[CHANGE] Re-testing ${target}...`));
150
235
  try {
151
236
  const block = JSON.parse(fs.readFileSync(target, 'utf8'));
152
- const run = new Function('inputs', `return (${block.logic.replace('function run(inputs)', '').replace(/ as string/g, '')})(inputs)`);
237
+ const run = new Function('inputs', block.logic + '\nreturn run(inputs);');
153
238
  const result = run({ input1: "Watch Input" });
154
239
  console.log(chalk.green(`✔ Test Passed: ${result}`));
155
240
  } catch (e) {
@@ -177,7 +262,7 @@ async function main() {
177
262
  const block = JSON.parse(fs.readFileSync(target, 'utf8'));
178
263
  console.log(chalk.yellow(`Benchmarking: ${block.name} (100,000 iterations)...`));
179
264
  try {
180
- const run = new Function('inputs', `return (${block.logic.replace('function run(inputs)', '').replace(/ as string/g, '')})(inputs)`);
265
+ const run = new Function('inputs', block.logic + '\nreturn run(inputs);');
181
266
  const start = performance.now();
182
267
  for(let i=0; i<100000; i++) run({ input1: "bench" });
183
268
  const end = performance.now();
@@ -206,9 +291,10 @@ async function main() {
206
291
 
207
292
  } else {
208
293
  console.log(chalk.white(`Available commands:`));
209
- console.log(` ${chalk.bold('create [name]')} - Create a new block interactively`);
210
- console.log(` ${chalk.bold('init [name]')} - Initialize a new project`);
211
- console.log(` ${chalk.bold('pack')} - Build a .cbspak package`);
294
+ console.log(` ${chalk.bold('create [name]')} - Create a new block (file or directory)`);
295
+ console.log(` ${chalk.bold('build [dir]')} - Build a directory block into a .cbsblock`);
296
+ console.log(` ${chalk.bold('pack')} - Bundle all blocks in folder into .cbspak`);
297
+ console.log(` ${chalk.bold('init [name]')} - Initialize a new block project`);
212
298
  console.log(` ${chalk.bold('test <file>')} - Run unit tests on a block`);
213
299
  console.log(` ${chalk.bold('dev <file>')} - Watch for changes and re-test`);
214
300
  console.log(` ${chalk.bold('search <query>')} - Search Marketplace from CLI`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cbs-block",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "SDK for creating CodeBlock Studio blocks",
5
5
  "main": "index.js",
6
6
  "bin": {