@africode/core 5.0.0 → 5.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@africode/core",
3
- "version": "5.0.0",
3
+ "version": "5.0.2",
4
4
  "description": "Bun-native full-stack framework with generative AI, fintech compliance, and real-time performance - built for Tanzanian digital economy",
5
5
  "module": "src/index.ts",
6
6
  "main": "src/index.ts",
@@ -14,8 +14,8 @@
14
14
  "./components/*": "./components/*"
15
15
  },
16
16
  "bin": {
17
- "africode": "./bin/cli.ts",
18
- "create-africode": "./bin/scaffold.ts"
17
+ "africode": "./bin/africode.js",
18
+ "create-africode": "./bin/create-africode.js"
19
19
  },
20
20
  "scripts": {
21
21
  "dev": "bun run bin/africode.js dev",
@@ -105,6 +105,8 @@
105
105
  "templates",
106
106
  "dist",
107
107
  "AFRICODE_FRAMEWORK_GUIDE.md",
108
- "docs/IDE-Guide.md"
108
+ "docs/IDE-Guide.md",
109
+ "COMPONENT_SCHEMA.json",
110
+ "scripts/generate-component-schema.js"
109
111
  ]
110
112
  }
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Component Schema Generator
5
+ * Generates COMPONENT_SCHEMA.json from component files
6
+ * Run with: bun run scripts/generate-component-schema.js
7
+ */
8
+
9
+ import { readdirSync, readFileSync, writeFileSync } from 'fs';
10
+ import { join, extname } from 'path';
11
+
12
+ const COMPONENTS_DIR = 'components';
13
+ const OUTPUT_FILE = 'COMPONENT_SCHEMA.json';
14
+
15
+ function parseComponentFile(filePath) {
16
+ const content = readFileSync(filePath, 'utf8');
17
+ const fileName = filePath.split(/[/\\]/).pop().replace('.js', '');
18
+
19
+ // Extract class name
20
+ const classMatch = content.match(/export class (\w+)/);
21
+ const className = classMatch ? classMatch[1] : fileName.charAt(0).toUpperCase() + fileName.slice(1) + 'Component';
22
+
23
+ // Extract observed attributes
24
+ const attrMatch = content.match(/observedAttributes\(\) \{\s*return \[([^\]]+)\]/);
25
+ const attributes = attrMatch ? attrMatch[1].split(',').map(attr => attr.trim().replace(/['"]/g, '')) : [];
26
+
27
+ // Generate tag name
28
+ const tagName = `af-${fileName.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
29
+
30
+ // Basic schema structure
31
+ const component = {
32
+ tagName,
33
+ className,
34
+ filePath,
35
+ slots: ["default"], // Default slot
36
+ attributes: {},
37
+ events: [],
38
+ cssCustomProperties: [],
39
+ example: `<${tagName}></${tagName}>`,
40
+ securityNotes: "Sanitizes slot content"
41
+ };
42
+
43
+ // Add attributes
44
+ attributes.forEach(attr => {
45
+ component.attributes[attr] = { type: "string" };
46
+ });
47
+
48
+ // Add common events
49
+ if (attributes.includes('disabled') || attributes.includes('loading')) {
50
+ component.events.push({ name: "click", detail: { type: "object" } });
51
+ }
52
+
53
+ return component;
54
+ }
55
+
56
+ function generateSchema() {
57
+ const componentFiles = readdirSync(COMPONENTS_DIR)
58
+ .filter(file => extname(file) === '.js' && file !== 'index.js' && file !== 'base.js');
59
+
60
+ const components = componentFiles.map(file => {
61
+ const filePath = join(COMPONENTS_DIR, file);
62
+ return parseComponentFile(filePath);
63
+ });
64
+
65
+ const schema = {
66
+ version: "5.0.0",
67
+ timestamp: new Date().toISOString(),
68
+ components,
69
+ forbiddenPatterns: [
70
+ "eval()",
71
+ "innerHTML = userInput",
72
+ "fetch without CORS headers",
73
+ "localStorage for sensitive data"
74
+ ]
75
+ };
76
+
77
+ writeFileSync(OUTPUT_FILE, JSON.stringify(schema, null, 2));
78
+ }
79
+
80
+ generateSchema();