create-feltdb 0.4.13 → 0.4.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.
package/dist/cli.js CHANGED
@@ -73,6 +73,14 @@ async function prompt(message) {
73
73
  const interface_ = readline.createInterface({ input: process.stdin, output: process.stdout });
74
74
  return new Promise(resolve => interface_.question(message, value => { interface_.close(); resolve(value.trim()); }));
75
75
  }
76
+ async function promptForProjectName(defaultName = 'feltdb-app') {
77
+ while (true) {
78
+ const value = (await prompt(`What should we name your FeltDB app? (${defaultName}): `)) || defaultName;
79
+ if (/^[a-z0-9][a-z0-9-]*$/.test(value))
80
+ return value;
81
+ console.log('Use lowercase letters, numbers, and dashes (for example: customer-portal).');
82
+ }
83
+ }
76
84
  async function promptSecret(message) {
77
85
  if (!process.stdin.isTTY || !process.stdout.isTTY)
78
86
  return '';
@@ -207,7 +215,7 @@ Deployment Target (Explicit):
207
215
  Requires production FeltDB instance or self-host
208
216
 
209
217
  --self-host Dedicated FeltDB server with Docker Compose
210
- Best for: Production deployments, multi-user systems
218
+ Best for: Staging first, then explicit production promotion
211
219
  Generates Docker Compose with persistent /data volume
212
220
 
213
221
  --managed Managed FeltDB runtime
@@ -245,10 +253,12 @@ Learn more: https://github.com/rkendel1/feltdb`);
245
253
  }
246
254
  // Find project name (first non-flag argument)
247
255
  let projectName = 'feltdb-app';
256
+ let projectNameProvided = false;
248
257
  for (let i = 0; i < args.length; i++) {
249
258
  const arg = args[i];
250
259
  if (!arg.startsWith('-')) {
251
260
  projectName = arg;
261
+ projectNameProvided = true;
252
262
  break;
253
263
  }
254
264
  // Skip next arg if current arg is a flag that takes a value
@@ -260,10 +270,16 @@ Learn more: https://github.com/rkendel1/feltdb`);
260
270
  const shouldInstall = !args.includes('--no-install');
261
271
  const shouldStart = !args.includes('--no-start');
262
272
  let options = parseArgs(args);
273
+ if (!projectNameProvided && !shouldAutoYes && process.stdin.isTTY && process.stdout.isTTY) {
274
+ projectName = await promptForProjectName(projectName);
275
+ }
276
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(projectName)) {
277
+ throw new Error('Application names must use lowercase letters, numbers, and dashes.');
278
+ }
263
279
  const runtimeDescriptions = {
264
280
  'browser': 'Browser with IndexedDB (local-first, no server)',
265
281
  'node': 'Node.js server (server-side authority)',
266
- 'self-hosted': 'Self-hosted with Docker Compose (production)',
282
+ 'self-hosted': 'Self-hosted with Docker Compose (staging)',
267
283
  'managed': 'Managed FeltDB service (hosted persistence, sync, and workloads)',
268
284
  };
269
285
  if (!runtimeDescriptions[options.runtime]) {
@@ -286,6 +302,7 @@ Learn more: https://github.com/rkendel1/feltdb`);
286
302
  console.log(`Capabilities: ${options.capabilities}`);
287
303
  console.log('\n═══════════════════════════════════════════════\n');
288
304
  const projectDir = path.resolve(process.cwd(), projectName);
305
+ let projectCreated = false;
289
306
  try {
290
307
  await createProject({
291
308
  projectName,
@@ -298,6 +315,7 @@ Learn more: https://github.com/rkendel1/feltdb`);
298
315
  webllm: options.webllm,
299
316
  capabilities: options.capabilities,
300
317
  });
318
+ projectCreated = true;
301
319
  if (options.runtime === 'managed') {
302
320
  console.log('\n☁️ Setting up your managed FeltDB account...\n');
303
321
  const email = process.env.FELTDB_MANAGED_EMAIL || (shouldAutoYes ? '' : await prompt('Email: '));
@@ -341,7 +359,9 @@ Learn more: https://github.com/rkendel1/feltdb`);
341
359
  }
342
360
  }
343
361
  catch (error) {
344
- console.error('❌ Failed to create project:', error);
362
+ console.error(projectCreated
363
+ ? `❌ The project was created at ${projectDir}, but setup or startup failed:`
364
+ : '❌ Failed to create project:', error);
345
365
  process.exit(1);
346
366
  }
347
367
  }
package/dist/create.js CHANGED
@@ -3,7 +3,6 @@
3
3
  */
4
4
  import fs from 'fs';
5
5
  import path from 'path';
6
- import { fileURLToPath } from 'url';
7
6
  import { randomBytes } from 'crypto';
8
7
  import { feltdbPackageRange } from './package-versions.js';
9
8
  import { generateDockerCompose, generateDockerfile, generateDockerIgnore, generateDotEnvLocal, generateFeltDBDockerfile, generateStudioDockerfile, } from './docker-compose-generator.js';
@@ -1218,7 +1217,8 @@ VITE_FELTDB_MANAGED_NAMESPACE=
1218
1217
  VITE_FELTDB_MANAGED_ENVIRONMENT=production
1219
1218
 
1220
1219
  # Override the default self-hosted container image
1221
- # Example: ghcr.io/rkendel1/feltdb:latest
1220
+ # By default the server image is built locally from the bundled source.
1221
+ # Example override: your-registry.example/feltdb:staging
1222
1222
  FELTDB_IMAGE=
1223
1223
 
1224
1224
  # Node environment
@@ -1239,11 +1239,8 @@ NODE_ENV=development
1239
1239
  fs.writeFileSync(path.join(projectDir, 'Dockerfile'), generateDockerfile(dockerConfig, framework));
1240
1240
  fs.writeFileSync(path.join(projectDir, 'Dockerfile.feltdb'), generateFeltDBDockerfile(dockerConfig));
1241
1241
  fs.writeFileSync(path.join(projectDir, 'Dockerfile.studio'), generateStudioDockerfile(dockerConfig));
1242
- const serverSource = fileURLToPath(new URL('./server-source', import.meta.url));
1243
- fs.cpSync(serverSource, path.join(projectDir, '.feltdb', 'server-source'), { recursive: true });
1244
1242
  fs.writeFileSync(path.join(projectDir, '.dockerignore'), generateDockerIgnore());
1245
1243
  const dockerEnvironment = generateDotEnvLocal(dockerConfig, randomBytes(32).toString('hex'));
1246
- fs.writeFileSync(path.join(projectDir, '.env.docker'), dockerEnvironment);
1247
1244
  // Docker Compose loads .env automatically; it is already excluded from git.
1248
1245
  fs.writeFileSync(path.join(projectDir, '.env'), dockerEnvironment);
1249
1246
  }
@@ -1497,7 +1494,8 @@ Verify vector database connection and that embeddings are enabled in capabilitie
1497
1494
  - Check out example projects in the templates
1498
1495
  - Join the community Discord for support
1499
1496
  `;
1500
- fs.writeFileSync(path.join(projectDir, 'RUNTIME_GUIDE.md'), runtimeGuide);
1497
+ // Keep generated projects focused; the runtime guide lives in FeltDB's docs.
1498
+ void runtimeGuide;
1501
1499
  // Create .gitignore
1502
1500
  const gitignore = `node_modules/
1503
1501
  dist/
@@ -14,16 +14,33 @@ export function generateDockerCompose(config) {
14
14
  build:
15
15
  context: .
16
16
  dockerfile: Dockerfile.feltdb
17
+ args:
18
+ FELTDB_VERSION: ${config.version}
17
19
  container_name: \${COMPOSE_PROJECT_NAME}-feltdb
18
20
  environment:
19
21
  FELTDB_APP_NAME: \${FELTDB_APP_NAME:-${config.appName}}
20
22
  FELTDB_APP_ID: \${FELTDB_APP_ID:-${config.appId}}
21
23
  FELTDB_VERSION: \${FELTDB_VERSION:-${config.version}}
24
+ FELTDB_ENVIRONMENT: \${FELTDB_ENVIRONMENT:-staging}
22
25
  FELTDB_PEERS: \${FELTDB_PEERS:-}
23
26
  FELTDB_MASTER_KEY: \${FELTDB_MASTER_KEY}
24
27
  NODE_ENV: \${NODE_ENV:-production}
25
28
  ports:
26
29
  - "\${FELTDB_API_PORT:-${config.port}}:7700"
30
+ command:
31
+ - feltdb-server
32
+ - --host
33
+ - 0.0.0.0
34
+ - --port
35
+ - "7700"
36
+ - --namespace
37
+ - \${FELTDB_APP_ID:-${config.appId}}
38
+ - --data
39
+ - /data/feltdb.log
40
+ - --allow-origin
41
+ - http://127.0.0.1:\${APP_PORT:-5173}
42
+ - --allow-origin
43
+ - http://127.0.0.1:\${STUDIO_PORT:-${config.studioPort}}
27
44
  volumes:
28
45
  - feltdb_data:/data
29
46
  - ./feltdb.flow:/app/feltdb.flow:ro
@@ -106,11 +123,13 @@ volumes:
106
123
  `;
107
124
  }
108
125
  export function generateFeltDBDockerfile(config) {
109
- return `# FeltDB server source is bundled with create-feltdb for a reproducible build.
126
+ return `# Build the matching FeltDB server without adding engine source to the application.
110
127
  FROM rust:1.96-alpine AS builder
111
- RUN apk add --no-cache pkgconf openssl-dev musl-dev
128
+ RUN apk add --no-cache nodejs npm pkgconf openssl-dev musl-dev
112
129
  WORKDIR /source
113
- COPY .feltdb/server-source/ ./
130
+ ARG FELTDB_VERSION=${config.version}
131
+ RUN npm install --global "create-feltdb@\${FELTDB_VERSION}" \
132
+ && cp -R "\$(npm root --global)/create-feltdb/dist/server-source/." /source/
114
133
  RUN cargo build -p feltdb-server --release --locked
115
134
 
116
135
  FROM alpine:3.22
@@ -191,6 +210,7 @@ COMPOSE_PROJECT_NAME=${config.appName.toLowerCase().replace(/[^a-z0-9]/g, '-')}
191
210
  FELTDB_APP_NAME=${config.appName}
192
211
  FELTDB_APP_ID=${config.appId}
193
212
  FELTDB_VERSION=${config.version}
213
+ FELTDB_ENVIRONMENT=staging
194
214
  FELTDB_API_PORT=${config.port}
195
215
  FELTDB_REPLICATION_PORT=${config.replicationPort}
196
216
  FELTDB_PEERS=
@@ -203,8 +223,6 @@ FELTDB_API_URL=http://feltdb:7700
203
223
  # Studio Configuration
204
224
  STUDIO_PORT=${config.studioPort}
205
225
 
206
- # Runtime
207
- NODE_ENV=production
208
226
  `;
209
227
  }
210
228
  export function generateHealthCheckScript() {
@@ -1,4 +1,4 @@
1
1
  // One release train keeps generated applications installable. The repository
2
2
  // validation script checks these values against every workspace manifest.
3
- export const FELTDB_PACKAGE_VERSION = '0.4.13';
3
+ export const FELTDB_PACKAGE_VERSION = '0.4.14';
4
4
  export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "create-feltdb",
3
3
  "private": false,
4
4
  "description": "Create a new FeltDB application with one command",
5
- "version": "0.4.13",
5
+ "version": "0.4.14",
6
6
  "license": "MIT",
7
7
  "bin": {
8
8
  "create-feltdb": "bin/create-feltdb.js"