@electric-sql/start 1.0.1 → 1.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/dist/bin.js CHANGED
@@ -1,7 +1,8 @@
1
+ #!/usr/bin/env node
1
2
  import {
2
3
  provisionElectricResources,
3
4
  setupTemplate
4
- } from "./chunk-DWNDVGD3.js";
5
+ } from "./chunk-J5QG5B4S.js";
5
6
 
6
7
  // src/cli.ts
7
8
  import { execSync } from "child_process";
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execSync } from 'child_process'\nimport { provisionElectricResources } from './electric-api.js'\nimport { setupTemplate } from './template-setup.js'\nimport { join } from 'path'\n\nfunction printNextSteps(appName: string, fullSetup: boolean = false) {\n console.log(`Next steps:`)\n if (appName !== `.`) {\n console.log(` cd ${appName}`)\n }\n\n if (fullSetup) {\n console.log(` pnpm install`)\n console.log(` pnpm migrate`)\n }\n\n console.log(` pnpm dev`)\n console.log(``)\n console.log(`Commands:`)\n console.log(` pnpm psql # Connect to database`)\n console.log(` pnpm claim # Claim cloud resources`)\n console.log(` pnpm deploy:netlify # Deploy to Netlify`)\n console.log(``)\n console.log(`Tutorial: https://electric-sql.com/docs`)\n}\n\nasync function main() {\n const args = process.argv.slice(2)\n\n if (args.length === 0) {\n console.error(`Usage: npx @electric-sql/start <app-name>`)\n console.error(\n ` npx @electric-sql/start . (configure current directory)`\n )\n\n process.exit(1)\n }\n\n const appName = args[0]\n\n // Validate app name (skip validation for \".\" which means current directory)\n if (appName !== `.` && !/^[a-zA-Z0-9-_]+$/.test(appName)) {\n console.error(\n `App name must contain only letters, numbers, hyphens, and underscores`\n )\n\n process.exit(1)\n }\n\n if (appName === `.`) {\n console.log(`Configuring current directory...`)\n } else {\n console.log(`Creating app: ${appName}`)\n }\n\n try {\n const credentials = await provisionElectricResources()\n\n // Step 2: Setup TanStack Start template\n console.log(`Setting up template...`)\n await setupTemplate(appName, credentials)\n\n console.log(`Installing dependencies...`)\n try {\n execSync(`pnpm install`, {\n stdio: `inherit`,\n cwd: appName === `.` ? process.cwd() : join(process.cwd(), appName),\n })\n } catch (_error) {\n console.log(`Failed to install dependencies`)\n printNextSteps(appName, true)\n process.exit(1)\n }\n\n console.log(`Running migrations...`)\n try {\n execSync(`pnpm migrate`, {\n stdio: `inherit`,\n cwd: appName === `.` ? process.cwd() : join(process.cwd(), appName),\n })\n } catch (_error) {\n console.log(`Failed to apply migrations`)\n printNextSteps(appName, true)\n process.exit(1)\n }\n\n // Step 3: Display completion message\n console.log(`Setup complete`)\n printNextSteps(appName)\n } catch (error) {\n console.error(\n `Setup failed:`,\n error instanceof Error ? error.message : error\n )\n process.exit(1)\n }\n}\n\nexport { main }\n","import { main } from './cli.js'\n\nmain().catch((error) => {\n console.error(`Unexpected error:`, error)\n process.exit(1)\n})\n"],"mappings":";;;;;;AAEA,SAAS,gBAAgB;AAGzB,SAAS,YAAY;AAErB,SAAS,eAAe,SAAiB,YAAqB,OAAO;AACnE,UAAQ,IAAI,aAAa;AACzB,MAAI,YAAY,KAAK;AACnB,YAAQ,IAAI,QAAQ,OAAO,EAAE;AAAA,EAC/B;AAEA,MAAI,WAAW;AACb,YAAQ,IAAI,gBAAgB;AAC5B,YAAQ,IAAI,gBAAgB;AAAA,EAC9B;AAEA,UAAQ,IAAI,YAAY;AACxB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW;AACvB,UAAQ,IAAI,+CAA+C;AAC3D,UAAQ,IAAI,iDAAiD;AAC7D,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,yCAAyC;AACvD;AAEA,eAAe,OAAO;AACpB,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AAEjC,MAAI,KAAK,WAAW,GAAG;AACrB,YAAQ,MAAM,2CAA2C;AACzD,YAAQ;AAAA,MACN;AAAA,IACF;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,KAAK,CAAC;AAGtB,MAAI,YAAY,OAAO,CAAC,mBAAmB,KAAK,OAAO,GAAG;AACxD,YAAQ;AAAA,MACN;AAAA,IACF;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,YAAY,KAAK;AACnB,YAAQ,IAAI,kCAAkC;AAAA,EAChD,OAAO;AACL,YAAQ,IAAI,iBAAiB,OAAO,EAAE;AAAA,EACxC;AAEA,MAAI;AACF,UAAM,cAAc,MAAM,2BAA2B;AAGrD,YAAQ,IAAI,wBAAwB;AACpC,UAAM,cAAc,SAAS,WAAW;AAExC,YAAQ,IAAI,4BAA4B;AACxC,QAAI;AACF,eAAS,gBAAgB;AAAA,QACvB,OAAO;AAAA,QACP,KAAK,YAAY,MAAM,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,OAAO;AAAA,MACpE,CAAC;AAAA,IACH,SAAS,QAAQ;AACf,cAAQ,IAAI,gCAAgC;AAC5C,qBAAe,SAAS,IAAI;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI,uBAAuB;AACnC,QAAI;AACF,eAAS,gBAAgB;AAAA,QACvB,OAAO;AAAA,QACP,KAAK,YAAY,MAAM,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,OAAO;AAAA,MACpE,CAAC;AAAA,IACH,SAAS,QAAQ;AACf,cAAQ,IAAI,4BAA4B;AACxC,qBAAe,SAAS,IAAI;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,YAAQ,IAAI,gBAAgB;AAC5B,mBAAe,OAAO;AAAA,EACxB,SAAS,OAAO;AACd,YAAQ;AAAA,MACN;AAAA,MACA,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAC3C;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AChGA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,qBAAqB,KAAK;AACxC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execSync } from 'child_process'\nimport { provisionElectricResources } from './electric-api.js'\nimport { setupTemplate } from './template-setup.js'\nimport { join } from 'path'\n\nfunction printNextSteps(appName: string, fullSetup: boolean = false) {\n console.log(`Next steps:`)\n if (appName !== `.`) {\n console.log(` cd ${appName}`)\n }\n\n if (fullSetup) {\n console.log(` pnpm install`)\n console.log(` pnpm migrate`)\n }\n\n console.log(` pnpm dev`)\n console.log(``)\n console.log(`Commands:`)\n console.log(` pnpm psql # Connect to database`)\n console.log(` pnpm claim # Claim cloud resources`)\n console.log(` pnpm deploy:netlify # Deploy to Netlify`)\n console.log(``)\n console.log(`Tutorial: https://electric-sql.com/docs`)\n}\n\nasync function main() {\n const args = process.argv.slice(2)\n\n if (args.length === 0) {\n console.error(`Usage: npx @electric-sql/start <app-name>`)\n console.error(\n ` npx @electric-sql/start . (configure current directory)`\n )\n\n process.exit(1)\n }\n\n const appName = args[0]\n\n // Validate app name (skip validation for \".\" which means current directory)\n if (appName !== `.` && !/^[a-zA-Z0-9-_]+$/.test(appName)) {\n console.error(\n `App name must contain only letters, numbers, hyphens, and underscores`\n )\n\n process.exit(1)\n }\n\n if (appName === `.`) {\n console.log(`Configuring current directory...`)\n } else {\n console.log(`Creating app: ${appName}`)\n }\n\n try {\n const credentials = await provisionElectricResources()\n\n // Step 2: Setup TanStack Start template\n console.log(`Setting up template...`)\n await setupTemplate(appName, credentials)\n\n console.log(`Installing dependencies...`)\n try {\n execSync(`pnpm install`, {\n stdio: `inherit`,\n cwd: appName === `.` ? process.cwd() : join(process.cwd(), appName),\n })\n } catch (_error) {\n console.log(`Failed to install dependencies`)\n printNextSteps(appName, true)\n process.exit(1)\n }\n\n console.log(`Running migrations...`)\n try {\n execSync(`pnpm migrate`, {\n stdio: `inherit`,\n cwd: appName === `.` ? process.cwd() : join(process.cwd(), appName),\n })\n } catch (_error) {\n console.log(`Failed to apply migrations`)\n printNextSteps(appName, true)\n process.exit(1)\n }\n\n // Step 3: Display completion message\n console.log(`Setup complete`)\n printNextSteps(appName)\n } catch (error) {\n console.error(\n `Setup failed:`,\n error instanceof Error ? error.message : error\n )\n process.exit(1)\n }\n}\n\nexport { main }\n","import { main } from './cli.js'\n\nmain().catch((error) => {\n console.error(`Unexpected error:`, error)\n process.exit(1)\n})\n"],"mappings":";;;;;;;AAEA,SAAS,gBAAgB;AAGzB,SAAS,YAAY;AAErB,SAAS,eAAe,SAAiB,YAAqB,OAAO;AACnE,UAAQ,IAAI,aAAa;AACzB,MAAI,YAAY,KAAK;AACnB,YAAQ,IAAI,QAAQ,OAAO,EAAE;AAAA,EAC/B;AAEA,MAAI,WAAW;AACb,YAAQ,IAAI,gBAAgB;AAC5B,YAAQ,IAAI,gBAAgB;AAAA,EAC9B;AAEA,UAAQ,IAAI,YAAY;AACxB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW;AACvB,UAAQ,IAAI,+CAA+C;AAC3D,UAAQ,IAAI,iDAAiD;AAC7D,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,yCAAyC;AACvD;AAEA,eAAe,OAAO;AACpB,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AAEjC,MAAI,KAAK,WAAW,GAAG;AACrB,YAAQ,MAAM,2CAA2C;AACzD,YAAQ;AAAA,MACN;AAAA,IACF;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,KAAK,CAAC;AAGtB,MAAI,YAAY,OAAO,CAAC,mBAAmB,KAAK,OAAO,GAAG;AACxD,YAAQ;AAAA,MACN;AAAA,IACF;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,YAAY,KAAK;AACnB,YAAQ,IAAI,kCAAkC;AAAA,EAChD,OAAO;AACL,YAAQ,IAAI,iBAAiB,OAAO,EAAE;AAAA,EACxC;AAEA,MAAI;AACF,UAAM,cAAc,MAAM,2BAA2B;AAGrD,YAAQ,IAAI,wBAAwB;AACpC,UAAM,cAAc,SAAS,WAAW;AAExC,YAAQ,IAAI,4BAA4B;AACxC,QAAI;AACF,eAAS,gBAAgB;AAAA,QACvB,OAAO;AAAA,QACP,KAAK,YAAY,MAAM,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,OAAO;AAAA,MACpE,CAAC;AAAA,IACH,SAAS,QAAQ;AACf,cAAQ,IAAI,gCAAgC;AAC5C,qBAAe,SAAS,IAAI;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI,uBAAuB;AACnC,QAAI;AACF,eAAS,gBAAgB;AAAA,QACvB,OAAO;AAAA,QACP,KAAK,YAAY,MAAM,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,GAAG,OAAO;AAAA,MACpE,CAAC;AAAA,IACH,SAAS,QAAQ;AACf,cAAQ,IAAI,4BAA4B;AACxC,qBAAe,SAAS,IAAI;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,YAAQ,IAAI,gBAAgB;AAC5B,mBAAe,OAAO;AAAA,EACxB,SAAS,OAAO;AACd,YAAQ;AAAA,MACN;AAAA,MACA,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAC3C;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AChGA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,qBAAqB,KAAK;AACxC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env node
2
+
1
3
  // src/electric-api.ts
2
4
  var DEFAULT_ELECTRIC_API_BASE = `https://dashboard.electric-sql.cloud/api`;
3
5
  var DEFAULT_ELECTRIC_URL = `https://api.electric-sql.cloud`;
@@ -205,4 +207,4 @@ export {
205
207
  claimResources,
206
208
  setupTemplate
207
209
  };
208
- //# sourceMappingURL=chunk-DWNDVGD3.js.map
210
+ //# sourceMappingURL=chunk-J5QG5B4S.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/electric-api.ts","../src/template-setup.ts"],"sourcesContent":["// Using native fetch (Node.js 18+)\n\nexport interface ElectricCredentials {\n source_id: string\n secret: string\n DATABASE_URL: string\n}\n\nexport interface ClaimableSourceResponse {\n claimId: string\n}\n\ninterface ClaimableSourceStatus {\n state: `pending` | `ready` | `failed`\n source: {\n source_id: string\n secret: string\n }\n connection_uri: string\n claim_link?: string\n project_id?: string\n error: string | null\n}\n\nexport const DEFAULT_ELECTRIC_API_BASE = `https://dashboard.electric-sql.cloud/api`\nexport const DEFAULT_ELECTRIC_URL = `https://api.electric-sql.cloud`\nexport const DEFAULT_ELECTRIC_DASHBOARD_URL = `https://dashboard.electric-sql.cloud`\n\nexport function getElectricApiBase(): string {\n return process.env.ELECTRIC_API_BASE_URL ?? DEFAULT_ELECTRIC_API_BASE\n}\n\nexport function getElectricUrl(): string {\n return process.env.ELECTRIC_URL ?? DEFAULT_ELECTRIC_URL\n}\n\nexport function getElectricDashboardUrl(): string {\n return process.env.ELECTRIC_DASHBOARD_URL ?? DEFAULT_ELECTRIC_DASHBOARD_URL\n}\n\nconst POLL_INTERVAL_MS = 1000 // Poll every 1 second\nconst MAX_POLL_ATTEMPTS = 60 // Max 60 seconds\n\nasync function pollClaimableSource(\n claimId: string,\n maxAttempts: number = MAX_POLL_ATTEMPTS\n): Promise<ClaimableSourceStatus> {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const response = await fetch(\n `${getElectricApiBase()}/public/v1/claimable-sources/${claimId}`,\n {\n method: `GET`,\n headers: {\n 'User-Agent': `@electric-sql/start`,\n },\n }\n )\n\n // Handle 404 as \"still being provisioned\" - continue polling\n if (response.status === 404) {\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))\n continue\n }\n\n // For other non-OK responses, throw an error\n if (!response.ok) {\n throw new Error(\n `Electric API error: ${response.status} ${response.statusText}`\n )\n }\n\n const status = (await response.json()) as ClaimableSourceStatus\n\n if (status.state === `ready`) {\n return status\n }\n\n if (status.state === `failed` || status.error) {\n throw new Error(\n `Resource provisioning failed${status.error ? `: ${status.error}` : ``}`\n )\n }\n\n // Wait before polling again\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))\n }\n\n throw new Error(\n `Timeout waiting for resources to be provisioned after ${maxAttempts} attempts`\n )\n}\n\nexport async function provisionElectricResources(): Promise<\n ElectricCredentials & ClaimableSourceResponse\n> {\n console.log(`Provisioning resources...`)\n try {\n // Step 1: POST to create claimable source and get claimId\n const response = await fetch(\n `${getElectricApiBase()}/public/v1/claimable-sources`,\n {\n method: `POST`,\n headers: {\n 'Content-Type': `application/json`,\n 'User-Agent': `@electric-sql/start`,\n },\n body: JSON.stringify({}),\n }\n )\n\n if (!response.ok) {\n throw new Error(\n `Electric API error: ${response.status} ${response.statusText}`\n )\n }\n\n const { claimId } = (await response.json()) as ClaimableSourceResponse\n\n if (!claimId) {\n throw new Error(`Invalid response from Electric API - missing claimId`)\n }\n\n // Step 2: Poll until state === 'ready'\n const status = await pollClaimableSource(claimId)\n\n // Step 3: Extract and validate credentials\n if (\n !status.source?.source_id ||\n !status.source?.secret ||\n !status.connection_uri\n ) {\n throw new Error(\n `Invalid response from Electric API - missing required credentials`\n )\n }\n\n return {\n source_id: status.source.source_id,\n secret: status.source.secret,\n DATABASE_URL: status.connection_uri,\n claimId,\n }\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(\n `Failed to provision Electric resources: ${error.message}`\n )\n }\n throw new Error(`Failed to provision Electric resources: Unknown error`)\n }\n}\n\nexport async function claimResources(\n sourceId: string,\n secret: string\n): Promise<{ claimUrl: string }> {\n try {\n const response = await fetch(`${getElectricApiBase()}/v1/claim`, {\n method: `POST`,\n headers: {\n 'Content-Type': `application/json`,\n Authorization: `Bearer ${secret}`,\n 'User-Agent': `@electric-sql/start`,\n },\n body: JSON.stringify({\n source_id: sourceId,\n }),\n })\n\n if (!response.ok) {\n throw new Error(\n `Electric API error: ${response.status} ${response.statusText}`\n )\n }\n\n const result = (await response.json()) as { claimUrl: string }\n\n if (!result.claimUrl) {\n throw new Error(`Invalid response from Electric API - missing claim URL`)\n }\n\n return result\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to initiate resource claim: ${error.message}`)\n }\n throw new Error(`Failed to initiate resource claim: Unknown error`)\n }\n}\n","import { execSync } from 'child_process'\nimport { randomBytes } from 'crypto'\nimport { writeFileSync, readFileSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport {\n ElectricCredentials,\n ClaimableSourceResponse,\n getElectricUrl,\n getElectricDashboardUrl,\n} from './electric-api'\n\n/**\n * Generates a cryptographically secure random string for use as a secret\n * @param length - The length of the secret in bytes (will be hex encoded, so output is 2x length)\n * @returns A random hex string\n */\nfunction generateSecret(length: number = 32): string {\n return randomBytes(length).toString(`hex`)\n}\n\nexport async function setupTemplate(\n appName: string,\n credentials: ElectricCredentials & ClaimableSourceResponse\n): Promise<void> {\n const appPath = appName === `.` ? process.cwd() : join(process.cwd(), appName)\n\n try {\n // Step 1: Pull TanStack Start template using gitpick (skip for current directory)\n if (appName !== `.`) {\n console.log(`Pulling template...`)\n execSync(\n `npx gitpick electric-sql/electric/tree/main/examples/tanstack-db-web-starter ${appName}`,\n { stdio: `inherit` }\n )\n }\n\n // Step 2: Generate .env file with credentials\n console.log(`Configuring environment...`)\n const betterAuthSecret = generateSecret(32)\n const electricUrl = getElectricUrl()\n const envContent = `# Electric SQL Configuration\n# Generated by @electric-sql/start\n# DO NOT COMMIT THIS FILE\n\n# Database\nDATABASE_URL=${credentials.DATABASE_URL}\n\n# Electric Cloud\nELECTRIC_URL=${electricUrl}\nELECTRIC_SOURCE_ID=${credentials.source_id}\nELECTRIC_SECRET=${credentials.secret}\n\n# Authentication\nBETTER_AUTH_SECRET=${betterAuthSecret}\n`\n\n writeFileSync(join(appPath, `.env`), envContent)\n\n // Step 3: Ensure .gitignore includes .env\n console.log(`Updating .gitignore...`)\n const gitignorePath = join(appPath, `.gitignore`)\n let gitignoreContent = ``\n\n if (existsSync(gitignorePath)) {\n gitignoreContent = readFileSync(gitignorePath, `utf8`)\n }\n\n if (!gitignoreContent.includes(`.env`)) {\n gitignoreContent += `\\n# Environment variables\\n.env\\n.env.local\\n.env.*.local\\n`\n writeFileSync(gitignorePath, gitignoreContent)\n }\n\n console.log(`Adding Electric commands...`)\n const packageJsonPath = join(appPath, `package.json`)\n\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, `utf8`))\n\n // Add/update scripts for cloud mode and Electric commands\n packageJson.scripts = {\n ...packageJson.scripts,\n claim: `npx open-cli \"${getElectricDashboardUrl()}/claim?uuid=${credentials.claimId}\"`,\n 'deploy:netlify': `NODE_ENV=production NITRO_PRESET=netlify pnpm build && NODE_ENV=production npx netlify deploy --no-build --prod --dir=dist --functions=.netlify/functions-internal && npx netlify env:import .env`,\n }\n\n writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))\n }\n\n console.log(`Template setup complete`)\n } catch (error) {\n throw new Error(\n `Template setup failed: ${error instanceof Error ? error.message : error}`\n )\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/electric-api.ts","../src/template-setup.ts"],"sourcesContent":["// Using native fetch (Node.js 18+)\n\nexport interface ElectricCredentials {\n source_id: string\n secret: string\n DATABASE_URL: string\n}\n\nexport interface ClaimableSourceResponse {\n claimId: string\n}\n\ninterface ClaimableSourceStatus {\n state: `pending` | `ready` | `failed`\n source: {\n source_id: string\n secret: string\n }\n connection_uri: string\n claim_link?: string\n project_id?: string\n error: string | null\n}\n\nexport const DEFAULT_ELECTRIC_API_BASE = `https://dashboard.electric-sql.cloud/api`\nexport const DEFAULT_ELECTRIC_URL = `https://api.electric-sql.cloud`\nexport const DEFAULT_ELECTRIC_DASHBOARD_URL = `https://dashboard.electric-sql.cloud`\n\nexport function getElectricApiBase(): string {\n return process.env.ELECTRIC_API_BASE_URL ?? DEFAULT_ELECTRIC_API_BASE\n}\n\nexport function getElectricUrl(): string {\n return process.env.ELECTRIC_URL ?? DEFAULT_ELECTRIC_URL\n}\n\nexport function getElectricDashboardUrl(): string {\n return process.env.ELECTRIC_DASHBOARD_URL ?? DEFAULT_ELECTRIC_DASHBOARD_URL\n}\n\nconst POLL_INTERVAL_MS = 1000 // Poll every 1 second\nconst MAX_POLL_ATTEMPTS = 60 // Max 60 seconds\n\nasync function pollClaimableSource(\n claimId: string,\n maxAttempts: number = MAX_POLL_ATTEMPTS\n): Promise<ClaimableSourceStatus> {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const response = await fetch(\n `${getElectricApiBase()}/public/v1/claimable-sources/${claimId}`,\n {\n method: `GET`,\n headers: {\n 'User-Agent': `@electric-sql/start`,\n },\n }\n )\n\n // Handle 404 as \"still being provisioned\" - continue polling\n if (response.status === 404) {\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))\n continue\n }\n\n // For other non-OK responses, throw an error\n if (!response.ok) {\n throw new Error(\n `Electric API error: ${response.status} ${response.statusText}`\n )\n }\n\n const status = (await response.json()) as ClaimableSourceStatus\n\n if (status.state === `ready`) {\n return status\n }\n\n if (status.state === `failed` || status.error) {\n throw new Error(\n `Resource provisioning failed${status.error ? `: ${status.error}` : ``}`\n )\n }\n\n // Wait before polling again\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))\n }\n\n throw new Error(\n `Timeout waiting for resources to be provisioned after ${maxAttempts} attempts`\n )\n}\n\nexport async function provisionElectricResources(): Promise<\n ElectricCredentials & ClaimableSourceResponse\n> {\n console.log(`Provisioning resources...`)\n try {\n // Step 1: POST to create claimable source and get claimId\n const response = await fetch(\n `${getElectricApiBase()}/public/v1/claimable-sources`,\n {\n method: `POST`,\n headers: {\n 'Content-Type': `application/json`,\n 'User-Agent': `@electric-sql/start`,\n },\n body: JSON.stringify({}),\n }\n )\n\n if (!response.ok) {\n throw new Error(\n `Electric API error: ${response.status} ${response.statusText}`\n )\n }\n\n const { claimId } = (await response.json()) as ClaimableSourceResponse\n\n if (!claimId) {\n throw new Error(`Invalid response from Electric API - missing claimId`)\n }\n\n // Step 2: Poll until state === 'ready'\n const status = await pollClaimableSource(claimId)\n\n // Step 3: Extract and validate credentials\n if (\n !status.source?.source_id ||\n !status.source?.secret ||\n !status.connection_uri\n ) {\n throw new Error(\n `Invalid response from Electric API - missing required credentials`\n )\n }\n\n return {\n source_id: status.source.source_id,\n secret: status.source.secret,\n DATABASE_URL: status.connection_uri,\n claimId,\n }\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(\n `Failed to provision Electric resources: ${error.message}`\n )\n }\n throw new Error(`Failed to provision Electric resources: Unknown error`)\n }\n}\n\nexport async function claimResources(\n sourceId: string,\n secret: string\n): Promise<{ claimUrl: string }> {\n try {\n const response = await fetch(`${getElectricApiBase()}/v1/claim`, {\n method: `POST`,\n headers: {\n 'Content-Type': `application/json`,\n Authorization: `Bearer ${secret}`,\n 'User-Agent': `@electric-sql/start`,\n },\n body: JSON.stringify({\n source_id: sourceId,\n }),\n })\n\n if (!response.ok) {\n throw new Error(\n `Electric API error: ${response.status} ${response.statusText}`\n )\n }\n\n const result = (await response.json()) as { claimUrl: string }\n\n if (!result.claimUrl) {\n throw new Error(`Invalid response from Electric API - missing claim URL`)\n }\n\n return result\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to initiate resource claim: ${error.message}`)\n }\n throw new Error(`Failed to initiate resource claim: Unknown error`)\n }\n}\n","import { execSync } from 'child_process'\nimport { randomBytes } from 'crypto'\nimport { writeFileSync, readFileSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport {\n ElectricCredentials,\n ClaimableSourceResponse,\n getElectricUrl,\n getElectricDashboardUrl,\n} from './electric-api'\n\n/**\n * Generates a cryptographically secure random string for use as a secret\n * @param length - The length of the secret in bytes (will be hex encoded, so output is 2x length)\n * @returns A random hex string\n */\nfunction generateSecret(length: number = 32): string {\n return randomBytes(length).toString(`hex`)\n}\n\nexport async function setupTemplate(\n appName: string,\n credentials: ElectricCredentials & ClaimableSourceResponse\n): Promise<void> {\n const appPath = appName === `.` ? process.cwd() : join(process.cwd(), appName)\n\n try {\n // Step 1: Pull TanStack Start template using gitpick (skip for current directory)\n if (appName !== `.`) {\n console.log(`Pulling template...`)\n execSync(\n `npx gitpick electric-sql/electric/tree/main/examples/tanstack-db-web-starter ${appName}`,\n { stdio: `inherit` }\n )\n }\n\n // Step 2: Generate .env file with credentials\n console.log(`Configuring environment...`)\n const betterAuthSecret = generateSecret(32)\n const electricUrl = getElectricUrl()\n const envContent = `# Electric SQL Configuration\n# Generated by @electric-sql/start\n# DO NOT COMMIT THIS FILE\n\n# Database\nDATABASE_URL=${credentials.DATABASE_URL}\n\n# Electric Cloud\nELECTRIC_URL=${electricUrl}\nELECTRIC_SOURCE_ID=${credentials.source_id}\nELECTRIC_SECRET=${credentials.secret}\n\n# Authentication\nBETTER_AUTH_SECRET=${betterAuthSecret}\n`\n\n writeFileSync(join(appPath, `.env`), envContent)\n\n // Step 3: Ensure .gitignore includes .env\n console.log(`Updating .gitignore...`)\n const gitignorePath = join(appPath, `.gitignore`)\n let gitignoreContent = ``\n\n if (existsSync(gitignorePath)) {\n gitignoreContent = readFileSync(gitignorePath, `utf8`)\n }\n\n if (!gitignoreContent.includes(`.env`)) {\n gitignoreContent += `\\n# Environment variables\\n.env\\n.env.local\\n.env.*.local\\n`\n writeFileSync(gitignorePath, gitignoreContent)\n }\n\n console.log(`Adding Electric commands...`)\n const packageJsonPath = join(appPath, `package.json`)\n\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, `utf8`))\n\n // Add/update scripts for cloud mode and Electric commands\n packageJson.scripts = {\n ...packageJson.scripts,\n claim: `npx open-cli \"${getElectricDashboardUrl()}/claim?uuid=${credentials.claimId}\"`,\n 'deploy:netlify': `NODE_ENV=production NITRO_PRESET=netlify pnpm build && NODE_ENV=production npx netlify deploy --no-build --prod --dir=dist --functions=.netlify/functions-internal && npx netlify env:import .env`,\n }\n\n writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))\n }\n\n console.log(`Template setup complete`)\n } catch (error) {\n throw new Error(\n `Template setup failed: ${error instanceof Error ? error.message : error}`\n )\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  import {
2
3
  DEFAULT_ELECTRIC_API_BASE,
3
4
  DEFAULT_ELECTRIC_DASHBOARD_URL,
@@ -8,7 +9,7 @@ import {
8
9
  getElectricUrl,
9
10
  provisionElectricResources,
10
11
  setupTemplate
11
- } from "./chunk-DWNDVGD3.js";
12
+ } from "./chunk-J5QG5B4S.js";
12
13
  export {
13
14
  DEFAULT_ELECTRIC_API_BASE,
14
15
  DEFAULT_ELECTRIC_DASHBOARD_URL,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electric-sql/start",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "CLI package for the ElectricSQL Quickstart.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",