@brightsideoy/kama 0.1.0-alpha.12 → 0.1.0-alpha.14

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/cli.js +248 -0
  2. package/package.json +7 -2
package/bin/cli.js ADDED
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env node
2
+ import { execSync } from 'node:child_process';
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import * as readline from 'node:readline/promises';
6
+
7
+ const rl = readline.createInterface({
8
+ input: process.stdin,
9
+ output: process.stdout,
10
+ });
11
+
12
+ async function main() {
13
+ console.log('\nšŸ”„ --- KAMA SITE GENERATOR --- šŸ”„\n');
14
+
15
+ console.log('Select mode:');
16
+ console.log(' 1) Kickstart new Kama Monorepo (CMS + Initial Site)');
17
+ console.log(' 2) Add a new Astro Site to current workspace (sites/)');
18
+
19
+ const choice = await rl.question('\nChoice [1/2]: ');
20
+
21
+ if (choice.trim() === '2') {
22
+ await createNewSiteOnly();
23
+ } else {
24
+ await createFullWorkspace();
25
+ }
26
+
27
+ rl.close();
28
+ }
29
+
30
+ /**
31
+ * MODE 1: Kickstart full Monorepo Workspace
32
+ */
33
+ async function createFullWorkspace() {
34
+ const projName = (await rl.question('Project folder name [kama-network]: ')) || 'kama-network';
35
+ const domain = (await rl.question('Base domain [t3cloud.eu]: ')) || 't3cloud.eu';
36
+ const sitePrefix = (await rl.question('First site prefix/subdomain [kamafe]: ')) || 'kamafe';
37
+
38
+ const rootDir = join(process.cwd(), projName);
39
+ const cmsDomain = `kama.${domain}`;
40
+ const siteDomain = `${sitePrefix}.${domain}`;
41
+
42
+ console.log(`\nšŸ“ Creating workspace folder at ./${projName}...`);
43
+ mkdirSync(rootDir, { recursive: true });
44
+
45
+ // 1. Root package.json
46
+ writeFileSync(
47
+ join(rootDir, 'package.json'),
48
+ JSON.stringify(
49
+ {
50
+ name: projName,
51
+ private: true,
52
+ type: 'module',
53
+ workspaces: ['cms-worker', 'sites/*'],
54
+ scripts: {
55
+ 'dev:cms': 'npm run dev -w cms-worker',
56
+ 'deploy:cms': 'npm run deploy -w cms-worker',
57
+ },
58
+ },
59
+ null,
60
+ 2
61
+ )
62
+ );
63
+
64
+ // 2. Setup CMS Worker
65
+ console.log(`\nā˜ļø Configuring CMS Worker (${cmsDomain})...`);
66
+ const cmsDir = join(rootDir, 'cms-worker');
67
+ mkdirSync(cmsDir, { recursive: true });
68
+
69
+ writeFileSync(
70
+ join(cmsDir, 'package.json'),
71
+ JSON.stringify(
72
+ {
73
+ name: 'kama-worker',
74
+ type: 'module',
75
+ version: '1.0.0',
76
+ scripts: {
77
+ dev: 'wrangler dev',
78
+ deploy: 'wrangler deploy',
79
+ },
80
+ dependencies: {
81
+ '@brightsideoy/kama': 'latest',
82
+ },
83
+ devDependencies: {
84
+ wrangler: '^4.127.1',
85
+ tsx: '^4.19.2',
86
+ },
87
+ },
88
+ null,
89
+ 2
90
+ )
91
+ );
92
+
93
+ writeFileSync(
94
+ join(cmsDir, 'wrangler.json'),
95
+ JSON.stringify(
96
+ {
97
+ $schema: 'node_modules/wrangler/config-schema.json',
98
+ name: 'kama-worker',
99
+ main: 'node_modules/@brightsideoy/kama/dist/index.js',
100
+ compatibility_date: '2026-08-01',
101
+ compatibility_flags: ['nodejs_compat'],
102
+ assets: { directory: './dist', binding: 'ASSETS' },
103
+ routes: [{ pattern: cmsDomain, custom_domain: true }],
104
+ vars: { CDN_DOMAIN: cmsDomain },
105
+ d1_databases: [
106
+ {
107
+ binding: 'DB',
108
+ database_name: 'kama_cms_db',
109
+ database_id: 'REPLACE_WITH_YOUR_D1_ID',
110
+ },
111
+ ],
112
+ r2_buckets: [
113
+ {
114
+ binding: 'MEDIA_BUCKET',
115
+ bucket_name: 'kama-media-prod',
116
+ },
117
+ ],
118
+ },
119
+ null,
120
+ 2
121
+ )
122
+ );
123
+
124
+ // 3. Setup First Astro Site
125
+ await generateAstroSite(rootDir, sitePrefix, siteDomain, cmsDomain);
126
+
127
+ console.log(`\n✨ Workspace ready! Next steps:`);
128
+ console.log(` 1. cd ${projName}`);
129
+ console.log(` 2. npm install`);
130
+ console.log(` 3. Update D1 ID in cms-worker/wrangler.json`);
131
+ }
132
+
133
+ /**
134
+ * MODE 2: Add Site to existing workspace
135
+ */
136
+ async function createNewSiteOnly() {
137
+ const rootDir = process.cwd();
138
+
139
+ if (!existsSync(join(rootDir, 'package.json'))) {
140
+ console.error('āŒ Error: Must run this command inside the root of your workspace.');
141
+ return;
142
+ }
143
+
144
+ const siteName = await rl.question('Site folder name (e.g., site-two): ');
145
+ const customDomain = await rl.question('Custom domain (e.g., brand.com or brand.t3cloud.eu): ');
146
+ const cmsDomain = (await rl.question('CMS API URL [https://kama.t3cloud.eu]: ')) || 'https://kama.t3cloud.eu';
147
+
148
+ await generateAstroSite(rootDir, siteName, customDomain, cmsDomain.replace(/^https?:\/\//, ''));
149
+
150
+ console.log(`\n✨ Site created in sites/${siteName}! Run 'npm install' at workspace root.`);
151
+ }
152
+
153
+ /**
154
+ * Helper: Scaffolds the Astro site with middleware, wrangler.json, & slug page
155
+ */
156
+ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsDomain) {
157
+ console.log(`\nšŸš€ Scaffolding Astro site (${siteFolder}) mapped to ${siteDomain}...`);
158
+
159
+ const siteDir = join(rootDir, 'sites', siteFolder);
160
+ mkdirSync(join(siteDir, 'src/pages'), { recursive: true });
161
+ mkdirSync(join(siteDir, 'src/layouts'), { recursive: true });
162
+ mkdirSync(join(siteDir, 'src/components/blocks'), { recursive: true });
163
+ mkdirSync(join(siteDir, 'src/lib'), { recursive: true });
164
+
165
+ // 1. package.json
166
+ writeFileSync(
167
+ join(siteDir, 'package.json'),
168
+ JSON.stringify(
169
+ {
170
+ name: siteFolder,
171
+ type: 'module',
172
+ version: '0.0.1',
173
+ engines: { node: '>=22.12.0' },
174
+ scripts: {
175
+ dev: 'astro dev',
176
+ build: 'astro build',
177
+ preview: 'astro preview',
178
+ deploy: 'astro build && wrangler deploy',
179
+ },
180
+ dependencies: {
181
+ '@astrojs/cloudflare': '^14.2.5',
182
+ '@brightsideoy/kama': 'latest',
183
+ astro: '^7.2.2',
184
+ wrangler: '^4.127.1',
185
+ },
186
+ },
187
+ null,
188
+ 2
189
+ )
190
+ );
191
+
192
+ // 2. wrangler.json
193
+ writeFileSync(
194
+ join(siteDir, 'wrangler.json'),
195
+ JSON.stringify(
196
+ {
197
+ $schema: 'node_modules/wrangler/config-schema.json',
198
+ name: siteFolder,
199
+ compatibility_date: '2026-08-01',
200
+ compatibility_flags: ['nodejs_compat'],
201
+ assets: {
202
+ directory: './dist',
203
+ binding: 'ASSETS',
204
+ html_handling: 'drop-trailing-slash',
205
+ not_found_handling: '404-page',
206
+ },
207
+ services: [{ binding: 'CMS_WORKER', service: 'kama-worker' }],
208
+ routes: [{ pattern: siteDomain, custom_domain: true }],
209
+ vars: {
210
+ PUBLIC_CMS_URL: `https://${cmsDomain}`,
211
+ PUBLIC_API_URL: `https://${cmsDomain}`,
212
+ },
213
+ },
214
+ null,
215
+ 2
216
+ )
217
+ );
218
+
219
+ // 3. astro.config.mjs
220
+ const astroConfig = `import { defineConfig } from 'astro/config';
221
+ import cloudflare from '@astrojs/cloudflare';
222
+
223
+ export default defineConfig({
224
+ output: 'static',
225
+ trailingSlash: 'ignore',
226
+ image: {
227
+ remotePatterns: [
228
+ { protocol: 'http', hostname: 'localhost', port: '3000' },
229
+ { protocol: 'https', hostname: '${cmsDomain}' }
230
+ ]
231
+ },
232
+ build: {
233
+ inlineStylesheets: 'always',
234
+ },
235
+ adapter: cloudflare({
236
+ imageService: 'cloudflare',
237
+ })
238
+ });`;
239
+ writeFileSync(join(siteDir, 'astro.config.mjs'), astroConfig);
240
+
241
+ // 4. .env file
242
+ writeFileSync(
243
+ join(siteDir, '.env'),
244
+ `PUBLIC_CMS_URL="https://${cmsDomain}"\nPUBLIC_API_URL="https://${cmsDomain}"\n`
245
+ );
246
+ }
247
+
248
+ main().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightsideoy/kama",
3
- "version": "0.1.0-alpha.12",
3
+ "version": "0.1.0-alpha.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -10,8 +10,13 @@
10
10
  "import": "./dist/index.js"
11
11
  }
12
12
  },
13
+ "bin": {
14
+ "kama": "./bin/cli.js",
15
+ "create-kama": "./bin/cli.js"
16
+ },
13
17
  "files": [
14
- "dist"
18
+ "dist",
19
+ "bin"
15
20
  ],
16
21
  "scripts": {
17
22
  "dev": "concurrently \"vite\" \"tsx watch server/index.ts\"",