@rebasepro/cli 0.0.1-canary.2 → 0.0.1-canary.4829d6e

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 (83) hide show
  1. package/LICENSE +17 -196
  2. package/README.md +57 -33
  3. package/dist/commands/api-keys.d.ts +1 -0
  4. package/dist/commands/auth.d.ts +1 -0
  5. package/dist/commands/build.d.ts +1 -0
  6. package/dist/commands/cloud/auth.d.ts +3 -0
  7. package/dist/commands/cloud/context.d.ts +61 -0
  8. package/dist/commands/cloud/databases.d.ts +1 -0
  9. package/dist/commands/cloud/deploy.d.ts +2 -0
  10. package/dist/commands/cloud/index.d.ts +1 -0
  11. package/dist/commands/cloud/link.d.ts +5 -0
  12. package/dist/commands/cloud/orgs.d.ts +1 -0
  13. package/dist/commands/cloud/projects.d.ts +13 -0
  14. package/dist/commands/cloud/resources.d.ts +6 -0
  15. package/dist/commands/db.d.ts +1 -0
  16. package/dist/commands/dev.d.ts +1 -0
  17. package/dist/commands/doctor.d.ts +1 -0
  18. package/dist/commands/generate_sdk.d.ts +18 -0
  19. package/dist/commands/init.d.ts +40 -0
  20. package/dist/commands/schema.d.ts +1 -0
  21. package/dist/commands/skills.d.ts +1 -0
  22. package/dist/commands/start.d.ts +1 -0
  23. package/dist/index.d.ts +11 -1
  24. package/dist/index.es.js +3952 -245
  25. package/dist/index.es.js.map +1 -1
  26. package/dist/utils/package-manager.d.ts +33 -0
  27. package/dist/utils/project.d.ts +60 -0
  28. package/package.json +35 -23
  29. package/templates/overlays/baas/README.md +37 -0
  30. package/templates/overlays/baas/backend/package.json +31 -0
  31. package/templates/overlays/baas/backend/src/index.ts +172 -0
  32. package/templates/overlays/baas/backend/tsconfig.json +18 -0
  33. package/templates/overlays/baas/package.json +42 -0
  34. package/templates/overlays/baas/pnpm-workspace.yaml +9 -0
  35. package/templates/template/.cursorrules +2 -0
  36. package/templates/template/.dockerignore +28 -0
  37. package/templates/template/.env.example +120 -0
  38. package/templates/template/.github/copilot-instructions.md +2 -0
  39. package/templates/template/.windsurfrules +2 -0
  40. package/templates/template/AGENTS.md +2 -0
  41. package/templates/template/CLAUDE.md +2 -0
  42. package/templates/template/README.md +88 -21
  43. package/templates/template/ai-instructions.md +17 -0
  44. package/templates/template/backend/Dockerfile +57 -11
  45. package/templates/template/backend/functions/hello.ts +56 -0
  46. package/templates/template/backend/package.json +30 -34
  47. package/templates/template/backend/src/env.ts +23 -0
  48. package/templates/template/backend/src/index.ts +140 -100
  49. package/templates/template/backend/tsconfig.json +1 -1
  50. package/templates/template/config/collections/authors.ts +45 -0
  51. package/templates/template/config/collections/index.ts +26 -0
  52. package/templates/template/{shared → config}/collections/posts.ts +28 -10
  53. package/templates/template/config/collections/presets/blank/index.ts +3 -0
  54. package/templates/template/config/collections/presets/ecommerce/categories.ts +40 -0
  55. package/templates/template/config/collections/presets/ecommerce/index.ts +6 -0
  56. package/templates/template/config/collections/presets/ecommerce/orders.ts +66 -0
  57. package/templates/template/config/collections/presets/ecommerce/products.ts +64 -0
  58. package/templates/template/config/collections/tags.ts +25 -0
  59. package/templates/template/config/collections/users.ts +142 -0
  60. package/templates/template/{shared → config}/index.ts +1 -1
  61. package/templates/template/config/package.json +28 -0
  62. package/templates/template/docker-compose.yml +50 -14
  63. package/templates/template/frontend/Dockerfile +39 -15
  64. package/templates/template/frontend/nginx.conf +40 -0
  65. package/templates/template/frontend/package.json +13 -13
  66. package/templates/template/frontend/src/App.tsx +30 -116
  67. package/templates/template/frontend/src/index.css +15 -1
  68. package/templates/template/frontend/src/main.tsx +6 -2
  69. package/templates/template/frontend/src/virtual.d.ts +6 -0
  70. package/templates/template/frontend/tsconfig.json +3 -2
  71. package/templates/template/frontend/vite.config.ts +48 -5
  72. package/templates/template/package.json +21 -12
  73. package/templates/template/pnpm-workspace.yaml +13 -0
  74. package/templates/template/scripts/example.ts +94 -0
  75. package/dist/auth.d.ts +0 -5
  76. package/dist/index.cjs +0 -293
  77. package/dist/index.cjs.map +0 -1
  78. package/templates/template/.env.template +0 -31
  79. package/templates/template/backend/drizzle.config.ts +0 -22
  80. package/templates/template/backend/scripts/db-generate.ts +0 -60
  81. package/templates/template/shared/collections/index.ts +0 -3
  82. package/templates/template/shared/package.json +0 -28
  83. /package/templates/template/{shared → config}/tsconfig.json +0 -0
@@ -1,26 +1,69 @@
1
- // @ts-ignore
2
1
  import path from "path";
3
2
  import { defineConfig } from "vite";
4
3
  import react from "@vitejs/plugin-react";
5
4
  import svgr from "vite-plugin-svgr";
6
5
  import tailwindcss from "@tailwindcss/vite";
7
- import { rebaseCollectionsPlugin } from "@rebasepro/core/vitePlugin";
6
+ import { rebaseCollectionsPlugin } from "@rebasepro/app/vitePlugin";
8
7
 
9
8
  export default defineConfig({
9
+ envDir: path.resolve(__dirname, ".."),
10
+ // Force a single copy of React and React Router across the app and all
11
+ // @rebasepro/* packages. Without this, a locally `link:`ed Rebase checkout
12
+ // resolves its own copies of react-router, producing "multiple copies of
13
+ // React" and "useBlocker must be used within a data router" errors in the
14
+ // admin. Safe to keep for npm-installed setups too.
15
+ resolve: {
16
+ dedupe: [
17
+ "react",
18
+ "react-dom",
19
+ "react-router",
20
+ "react-router-dom",
21
+ "@remix-run/router"
22
+ ]
23
+ },
10
24
  esbuild: {
11
25
  logOverride: { "this-is-undefined-in-esm": "silent" }
12
26
  },
13
27
  build: {
14
28
  minify: true,
15
- outDir: "./build",
29
+ outDir: "./dist",
16
30
  target: "ESNEXT",
17
- sourcemap: true
31
+ sourcemap: true,
32
+ rollupOptions: {
33
+ output: {
34
+ manualChunks(id) {
35
+ // Heavy vendor libraries — split into individually cached chunks
36
+ if (id.includes("exceljs")) return "vendor-exceljs";
37
+ if (id.includes("prosemirror")) return "vendor-prosemirror";
38
+ if (id.includes("monaco-editor") || id.includes("@monaco-editor")) return "vendor-monaco";
39
+ if (id.includes("@xyflow") || id.includes("dagre")) return "vendor-xyflow";
40
+ if (id.includes("@dnd-kit")) return "vendor-dnd";
41
+ if (id.includes("prism-react-renderer")) return "vendor-prism";
42
+ if (id.includes("markdown-it")) return "vendor-markdown";
43
+ if (id.includes("react-dropzone")) return "vendor-dropzone";
44
+ if (id.includes("date-fns")) return "vendor-datefns";
45
+ if (id.includes("fuse.js")) return "vendor-fuse";
46
+ if (id.includes("node_modules/react-dom/")) return "vendor-react-dom";
47
+ if (id.includes("node_modules/react-router") || id.includes("node_modules/@remix-run")) return "vendor-react-router";
48
+ if (id.includes("node_modules/@radix-ui/")) return "vendor-radix";
49
+ if (id.includes("node_modules/framer-motion/")) return "vendor-framer-motion";
50
+ if (id.includes("node_modules/zod/")) return "vendor-zod";
51
+ if (id.includes("node_modules/i18next") || id.includes("node_modules/react-i18next")) return "vendor-i18next";
52
+ if (id.includes("node_modules/@floating-ui/")) return "vendor-floating-ui";
53
+ if (id.includes("node_modules/tailwind-merge/")) return "vendor-tailwind-merge";
54
+ if (id.includes("node_modules/notistack/")) return "vendor-notistack";
55
+ if (id.includes("node_modules/lucide-react/")) return "vendor-lucide-react";
56
+
57
+ return undefined;
58
+ }
59
+ }
60
+ }
18
61
  },
19
62
  optimizeDeps: { include: ["react/jsx-runtime"] },
20
63
  plugins: [
21
64
  svgr(),
22
65
  react({}),
23
66
  tailwindcss(),
24
- rebaseCollectionsPlugin({ collectionsDir: "../shared/collections" })
67
+ rebaseCollectionsPlugin({ collectionsDir: "../config/collections" })
25
68
  ]
26
69
  });
@@ -7,26 +7,35 @@
7
7
  "workspaces": [
8
8
  "frontend",
9
9
  "backend",
10
- "shared"
10
+ "config"
11
11
  ],
12
12
  "scripts": {
13
- "dev": "concurrently \"pnpm run dev:backend\" \"pnpm run dev:frontend\"",
14
- "dev:frontend": "cd frontend && pnpm run dev",
15
- "dev:backend": "cd backend && pnpm run dev",
16
- "build": "pnpm run build:shared && pnpm run build:frontend && pnpm run build:backend",
17
- "build:shared": "cd shared && pnpm run build",
18
- "build:frontend": "cd frontend && pnpm run build",
19
- "build:backend": "cd backend && pnpm run build",
20
- "start": "cd backend && pnpm start",
21
- "db:generate": "cd backend && pnpm run db:generate",
22
- "db:migrate": "cd backend && pnpm run db:migrate",
23
- "db:studio": "cd backend && pnpm run db:studio"
13
+ "dev": "rebase dev",
14
+ "build": "rebase build",
15
+ "start": "rebase start",
16
+ "db:generate": "rebase db generate --collections ../config/collections",
17
+ "db:migrate": "rebase db migrate",
18
+ "schema:introspect": "rebase schema introspect",
19
+ "db:push": "rebase db push --collections ../config/collections",
20
+ "schema:generate": "rebase schema generate --collections ../config/collections",
21
+ "generate:sdk": "rebase generate-sdk",
22
+ "skills:install": "rebase skills install",
23
+ "deploy": "rebase build && rebase start"
24
24
  },
25
25
  "devDependencies": {
26
+ "@rebasepro/cli": "workspace:*",
27
+ "@rebasepro/types": "workspace:*",
26
28
  "concurrently": "^8.2.2",
27
29
  "typescript": "^5.9.2"
28
30
  },
29
31
  "engines": {
30
32
  "node": ">=18.0.0"
33
+ },
34
+ "pnpm": {
35
+ "onlyBuiltDependencies": [
36
+ "esbuild",
37
+ "sharp",
38
+ "@ariga/atlas"
39
+ ]
31
40
  }
32
41
  }
@@ -0,0 +1,13 @@
1
+ packages:
2
+ - "frontend"
3
+ - "backend"
4
+ - "config"
5
+ linkWorkspacePackages: true
6
+ blockExoticSubdeps: false
7
+ minimumReleaseAge: 0
8
+ allowBuilds:
9
+ esbuild: true
10
+ sharp: true
11
+ "@ariga/atlas": true
12
+ "{{PROJECT_NAME}}-config": true
13
+
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Example Rebase Script
3
+ *
4
+ * Scripts run OUTSIDE the server and need explicit authentication.
5
+ * Use a Service Key (set in .env as REBASE_SERVICE_KEY) to get admin
6
+ * access — similar to a Service Account credential.
7
+ *
8
+ * Usage:
9
+ * # With local dev server running (`pnpm dev` in another terminal):
10
+ * npx tsx scripts/example.ts
11
+ *
12
+ * # With remote backend:
13
+ * REBASE_URL=https://api.yourdomain.com npx tsx scripts/example.ts
14
+ *
15
+ * # Service key can also be passed as env var:
16
+ * REBASE_SERVICE_KEY=<key> REBASE_URL=https://api.yourdomain.com npx tsx scripts/example.ts
17
+ *
18
+ * Generate a service key:
19
+ * node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"
20
+ */
21
+
22
+ import fs from "node:fs";
23
+ import path from "node:path";
24
+ import * as dotenv from "dotenv";
25
+ import { createRebaseClient } from "@rebasepro/client";
26
+ // import type { Database } from "../config/database.types"; // Optional: For fully typed collections
27
+
28
+ // Load .env from project root (same file the backend uses)
29
+ dotenv.config({ path: path.resolve(process.cwd(), ".env") });
30
+
31
+ // ─── Resolve Backend URL ─────────────────────────────────────────────
32
+ let baseUrl = process.env.REBASE_URL;
33
+
34
+ if (!baseUrl) {
35
+ try {
36
+ // Try to read the URL from the local dev server
37
+ const urlFile = path.join(process.cwd(), ".rebase-dev-url");
38
+ if (fs.existsSync(urlFile)) {
39
+ baseUrl = fs.readFileSync(urlFile, "utf-8").trim();
40
+ console.log(`Found local dev server running at: ${baseUrl}`);
41
+ }
42
+ } catch (e) {
43
+ // Ignore errors reading the file
44
+ }
45
+ }
46
+
47
+ if (!baseUrl) {
48
+ console.error("❌ No backend URL found!");
49
+ console.error("");
50
+ console.error("Please make sure you have either:");
51
+ console.error("1. Started the local dev server in another terminal (`pnpm dev`)");
52
+ console.error("2. Set the REBASE_URL environment variable (e.g. `REBASE_URL=https://api.yourdomain.com npx tsx scripts/example.ts`)");
53
+ process.exit(1);
54
+ }
55
+
56
+ // ─── Resolve Service Key ─────────────────────────────────────────────
57
+ const serviceKey = process.env.REBASE_SERVICE_KEY;
58
+
59
+ if (!serviceKey) {
60
+ console.warn("⚠️ No REBASE_SERVICE_KEY found — requests will be unauthenticated.");
61
+ console.warn(" Set REBASE_SERVICE_KEY in your .env to get admin access.");
62
+ console.warn(" Generate one with: node -e \"console.log(require('crypto').randomBytes(48).toString('base64'))\"");
63
+ console.warn("");
64
+ }
65
+
66
+ // ─── Initialize the SDK client ───────────────────────────────────────
67
+ const rebase = createRebaseClient({
68
+ baseUrl,
69
+ // The service key is sent as a Bearer token for admin access
70
+ token: serviceKey
71
+ });
72
+
73
+ async function run() {
74
+ console.log("🚀 Starting script...");
75
+
76
+ try {
77
+ // Example: Check backend health
78
+ const res = await fetch(`${baseUrl}/health`);
79
+ const health = res.headers.get("content-type")?.includes("application/json")
80
+ ? await res.json()
81
+ : { status: res.status, text: await res.text() };
82
+ console.log("✅ Backend health:", health);
83
+
84
+ // Example: Fetch some data (requires auth if backend is secure-by-default)
85
+ // const items = await rebase.data.collection("users").find({ limit: 5 });
86
+ // console.log("Items:", items);
87
+
88
+ console.log("✨ Script finished successfully.");
89
+ } catch (error) {
90
+ console.error("❌ Script failed:", error);
91
+ }
92
+ }
93
+
94
+ run();
package/dist/auth.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export declare function getTokens(env: "prod" | "dev", _debug?: boolean): Promise<object | null>;
2
- export declare function parseJwt(token: string): object;
3
- export declare function refreshCredentials(env: "dev" | "prod", credentials?: object | null, _onErr?: (e: unknown) => void): Promise<object | null>;
4
- export declare function login(env: "prod" | "dev", _debug?: boolean): Promise<void>;
5
- export declare function logout(env: "prod" | "dev", _debug?: boolean): Promise<void>;
package/dist/index.cjs DELETED
@@ -1,293 +0,0 @@
1
- (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("chalk"), require("arg"), require("inquirer"), require("path"), require("fs"), require("util"), require("execa"), require("ncp"), require("url"), require("crypto"), require("os")) : typeof define === "function" && define.amd ? define(["exports", "chalk", "arg", "inquirer", "path", "fs", "util", "execa", "ncp", "url", "crypto", "os"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["Rebase CLI"] = {}, global.chalk, global.arg, global.inquirer, global.path, global.fs, global.util, global.execa, global.ncp, global.url, global.crypto, global.os));
3
- })(this, (function(exports2, chalk, arg, inquirer, path, fs, util, execa, ncp, url, crypto, os) {
4
- "use strict";
5
- var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
6
- function _interopNamespaceDefault(e) {
7
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
8
- if (e) {
9
- for (const k in e) {
10
- if (k !== "default") {
11
- const d = Object.getOwnPropertyDescriptor(e, k);
12
- Object.defineProperty(n, k, d.get ? d : {
13
- enumerable: true,
14
- get: () => e[k]
15
- });
16
- }
17
- }
18
- }
19
- n.default = e;
20
- return Object.freeze(n);
21
- }
22
- const os__namespace = /* @__PURE__ */ _interopNamespaceDefault(os);
23
- const access = util.promisify(fs.access);
24
- const copy = util.promisify(ncp);
25
- const __filename$2 = url.fileURLToPath(typeof document === "undefined" && typeof location === "undefined" ? require("url").pathToFileURL(__filename).href : typeof document === "undefined" ? location.href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href);
26
- const __dirname$2 = path.dirname(__filename$2);
27
- function findParentDir(currentDir, targetName) {
28
- const root = path.parse(currentDir).root;
29
- while (currentDir && currentDir !== root) {
30
- if (path.basename(currentDir) === targetName) {
31
- return currentDir;
32
- }
33
- currentDir = path.dirname(currentDir);
34
- }
35
- return null;
36
- }
37
- const cliRoot = findParentDir(__dirname$2, "cli");
38
- async function createRebaseApp(rawArgs) {
39
- console.log(`
40
- ${chalk.bold("Rebase")} — Create a new project 🚀
41
- `);
42
- const options = await promptForOptions(rawArgs);
43
- await createProject(options);
44
- }
45
- async function promptForOptions(rawArgs) {
46
- const args = arg(
47
- {
48
- "--git": Boolean,
49
- "-g": "--git"
50
- },
51
- {
52
- argv: rawArgs.slice(3),
53
- // skip "node", "rebase", "init"
54
- permissive: true
55
- }
56
- );
57
- const nameArg = args._[0];
58
- const questions = [];
59
- if (!nameArg) {
60
- questions.push({
61
- type: "input",
62
- name: "projectName",
63
- message: "Project name:",
64
- default: "my-rebase-app",
65
- validate: (input) => {
66
- if (!input.trim()) return "Project name is required";
67
- if (!/^[a-z0-9][a-z0-9._-]*$/.test(input)) {
68
- return "Project name must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, dots, or underscores";
69
- }
70
- return true;
71
- }
72
- });
73
- }
74
- if (!args["--git"]) {
75
- questions.push({
76
- type: "confirm",
77
- name: "git",
78
- message: "Initialize a git repository?",
79
- default: true
80
- });
81
- }
82
- const answers = await inquirer.prompt(questions);
83
- const projectName = nameArg || answers.projectName;
84
- const targetDirectory = path.resolve(process.cwd(), projectName);
85
- const templateDirectory = path.resolve(cliRoot, "templates", "template");
86
- return {
87
- projectName,
88
- git: args["--git"] || answers.git || false,
89
- targetDirectory,
90
- templateDirectory
91
- };
92
- }
93
- async function createProject(options) {
94
- if (fs.existsSync(options.targetDirectory)) {
95
- if (fs.readdirSync(options.targetDirectory).length !== 0) {
96
- console.error(`${chalk.red.bold("ERROR")} Directory "${options.projectName}" already exists and is not empty`);
97
- process.exit(1);
98
- }
99
- } else {
100
- fs.mkdirSync(options.targetDirectory, { recursive: true });
101
- }
102
- try {
103
- await access(options.templateDirectory, fs.constants.R_OK);
104
- } catch {
105
- console.error(`${chalk.red.bold("ERROR")} Template not found at ${options.templateDirectory}`);
106
- process.exit(1);
107
- }
108
- console.log(chalk.gray(" Copying project files..."));
109
- await copy(options.templateDirectory, options.targetDirectory, {
110
- clobber: false,
111
- dot: true,
112
- filter: (source) => {
113
- const basename = path.basename(source);
114
- return basename !== "node_modules" && basename !== ".DS_Store";
115
- }
116
- });
117
- await replacePlaceholders(options);
118
- const envTemplatePath = path.join(options.targetDirectory, ".env.template");
119
- const envPath = path.join(options.targetDirectory, ".env");
120
- if (fs.existsSync(envTemplatePath) && !fs.existsSync(envPath)) {
121
- fs.renameSync(envTemplatePath, envPath);
122
- const jwtSecret = crypto.randomBytes(32).toString("hex");
123
- const dbPassword = crypto.randomBytes(16).toString("hex");
124
- let envContent = fs.readFileSync(envPath, "utf-8");
125
- envContent = envContent.replace(
126
- "postgresql://rebase:password@localhost:5432/rebase",
127
- `postgresql://rebase:${dbPassword}@localhost:5432/rebase`
128
- );
129
- envContent = envContent.replace(
130
- "change-this-to-a-secure-random-string",
131
- jwtSecret
132
- );
133
- envContent += `
134
- # Docker Compose Database Password
135
- POSTGRES_PASSWORD=${dbPassword}
136
- `;
137
- fs.writeFileSync(envPath, envContent, "utf-8");
138
- }
139
- if (options.git) {
140
- console.log(chalk.gray(" Initializing git repository..."));
141
- try {
142
- await execa("git", ["init"], { cwd: options.targetDirectory });
143
- } catch {
144
- console.warn(chalk.yellow(" Warning: Failed to initialize git repository"));
145
- }
146
- }
147
- console.log("");
148
- console.log(`${chalk.green.bold("✓")} Project ${chalk.bold(options.projectName)} created successfully!`);
149
- console.log("");
150
- console.log(chalk.bold("Next steps:"));
151
- console.log("");
152
- console.log(` ${chalk.cyan("cd")} ${options.projectName}`);
153
- console.log(` ${chalk.cyan("pnpm install")}`);
154
- console.log("");
155
- console.log(chalk.gray(" # Set up your database connection in .env"));
156
- console.log(chalk.gray(" # Then run:"));
157
- console.log("");
158
- console.log(` ${chalk.cyan("pnpm dev")}`);
159
- console.log("");
160
- console.log(chalk.gray("This starts both the backend (Express + PostgreSQL)") + chalk.gray(" and the frontend (Vite + React) concurrently."));
161
- console.log("");
162
- console.log(chalk.gray("Docs: https://rebase.pro/docs"));
163
- console.log(chalk.gray("GitHub: https://github.com/rebaseco/rebase"));
164
- console.log("");
165
- }
166
- async function replacePlaceholders(options) {
167
- const filesToProcess = [
168
- "package.json",
169
- "frontend/package.json",
170
- "backend/package.json",
171
- "shared/package.json",
172
- "frontend/index.html"
173
- ];
174
- for (const file of filesToProcess) {
175
- const fullPath = path.resolve(options.targetDirectory, file);
176
- if (!fs.existsSync(fullPath)) continue;
177
- let content = fs.readFileSync(fullPath, "utf-8");
178
- content = content.replace(/\{\{PROJECT_NAME\}\}/g, options.projectName);
179
- fs.writeFileSync(fullPath, content, "utf-8");
180
- }
181
- }
182
- const __filename$1 = url.fileURLToPath(typeof document === "undefined" && typeof location === "undefined" ? require("url").pathToFileURL(__filename).href : typeof document === "undefined" ? location.href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href);
183
- const __dirname$1 = path.dirname(__filename$1);
184
- function getVersion() {
185
- try {
186
- const pkgPath = path.resolve(__dirname$1, "../package.json");
187
- if (fs.existsSync(pkgPath)) {
188
- return JSON.parse(fs.readFileSync(pkgPath, "utf-8")).version;
189
- }
190
- } catch {
191
- }
192
- return "unknown";
193
- }
194
- async function entry(args) {
195
- const parsedArgs = arg(
196
- {
197
- "--version": Boolean,
198
- "--help": Boolean,
199
- "-v": "--version",
200
- "-h": "--help"
201
- },
202
- {
203
- argv: args.slice(2),
204
- permissive: true
205
- }
206
- );
207
- if (parsedArgs["--version"]) {
208
- console.log(getVersion());
209
- return;
210
- }
211
- const command = parsedArgs._[0];
212
- if (!command || parsedArgs["--help"]) {
213
- printHelp();
214
- return;
215
- }
216
- if (command === "init") {
217
- await createRebaseApp(args);
218
- } else {
219
- console.log(chalk.red(`Unknown command: ${command}`));
220
- console.log("");
221
- printHelp();
222
- }
223
- }
224
- function printHelp() {
225
- console.log(`
226
- ${chalk.bold("Rebase CLI")} — Developer tools for Rebase projects
227
-
228
- ${chalk.green.bold("Usage")}
229
- rebase ${chalk.blue("<command>")} [options]
230
-
231
- ${chalk.green.bold("Commands")}
232
- ${chalk.blue.bold("init")} Create a new Rebase project
233
-
234
- ${chalk.green.bold("Options")}
235
- ${chalk.blue("--version, -v")} Show version number
236
- ${chalk.blue("--help, -h")} Show this help message
237
-
238
- ${chalk.gray("Documentation: https://rebase.pro/docs")}
239
- `);
240
- }
241
- const TOKEN_DIR = path.join(os__namespace.homedir(), ".rebase");
242
- function tokenPath(env) {
243
- return path.join(TOKEN_DIR, (env === "dev" ? "staging." : "") + "tokens.json");
244
- }
245
- async function getTokens(env, _debug) {
246
- const fp = tokenPath(env);
247
- if (!fs.existsSync(fp)) return null;
248
- try {
249
- const data = fs.readFileSync(fp, "utf-8");
250
- return JSON.parse(data);
251
- } catch {
252
- return null;
253
- }
254
- }
255
- function parseJwt(token) {
256
- if (!token) throw new Error("No JWT token");
257
- const base64Url = token.split(".")[1];
258
- const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
259
- const buffer = Buffer.from(base64, "base64");
260
- return JSON.parse(buffer.toString());
261
- }
262
- async function refreshCredentials(env, credentials, _onErr) {
263
- if (!credentials) return null;
264
- const expiryDate = new Date(credentials["expiry_date"]);
265
- if (expiryDate.getTime() > Date.now()) {
266
- return credentials;
267
- }
268
- return null;
269
- }
270
- async function login(env, _debug) {
271
- console.log(
272
- "Interactive login is not yet implemented in @rebasepro/cli.\nPlease authenticate via the Rebase dashboard and copy your tokens to " + tokenPath(env)
273
- );
274
- }
275
- async function logout(env, _debug) {
276
- const fp = tokenPath(env);
277
- if (fs.existsSync(fp)) {
278
- fs.unlinkSync(fp);
279
- console.log("You have been logged out.");
280
- } else {
281
- console.log("You are not logged in.");
282
- }
283
- }
284
- exports2.createRebaseApp = createRebaseApp;
285
- exports2.entry = entry;
286
- exports2.getTokens = getTokens;
287
- exports2.login = login;
288
- exports2.logout = logout;
289
- exports2.parseJwt = parseJwt;
290
- exports2.refreshCredentials = refreshCredentials;
291
- Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
292
- }));
293
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/commands/init.ts","../src/cli.ts","../src/auth.ts"],"sourcesContent":["import arg from \"arg\";\nimport inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { promisify } from \"util\";\nimport execa from \"execa\";\nimport ncp from \"ncp\";\nimport { fileURLToPath } from \"url\";\nimport crypto from \"crypto\";\n\nconst access = promisify(fs.access);\nconst copy = promisify(ncp);\n\n// Resolve template path relative to this file\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nfunction findParentDir(currentDir: string, targetName: string): string | null {\n const root = path.parse(currentDir).root;\n while (currentDir && currentDir !== root) {\n if (path.basename(currentDir) === targetName) {\n return currentDir;\n }\n currentDir = path.dirname(currentDir);\n }\n return null;\n}\n\nconst cliRoot = findParentDir(__dirname, \"cli\");\n\nexport interface InitOptions {\n projectName: string;\n git: boolean;\n targetDirectory: string;\n templateDirectory: string;\n}\n\nexport async function createRebaseApp(rawArgs: string[]) {\n console.log(`\n${chalk.bold(\"Rebase\")} — Create a new project 🚀\n`);\n\n const options = await promptForOptions(rawArgs);\n await createProject(options);\n}\n\nasync function promptForOptions(rawArgs: string[]): Promise<InitOptions> {\n const args = arg(\n {\n \"--git\": Boolean,\n \"-g\": \"--git\"\n },\n {\n argv: rawArgs.slice(3), // skip \"node\", \"rebase\", \"init\"\n permissive: true\n }\n );\n\n // The first positional arg after \"init\" is the project name\n const nameArg = args._[0];\n\n const questions: any[] = [];\n\n if (!nameArg) {\n questions.push({\n type: \"input\",\n name: \"projectName\",\n message: \"Project name:\",\n default: \"my-rebase-app\",\n validate: (input: string) => {\n if (!input.trim()) return \"Project name is required\";\n if (!/^[a-z0-9][a-z0-9._-]*$/.test(input)) {\n return \"Project name must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, dots, or underscores\";\n }\n return true;\n }\n });\n }\n\n if (!args[\"--git\"]) {\n questions.push({\n type: \"confirm\",\n name: \"git\",\n message: \"Initialize a git repository?\",\n default: true\n });\n }\n\n const answers = await inquirer.prompt(questions);\n\n const projectName = nameArg || answers.projectName;\n const targetDirectory = path.resolve(process.cwd(), projectName);\n const templateDirectory = path.resolve(cliRoot!, \"templates\", \"template\");\n\n return {\n projectName,\n git: args[\"--git\"] || answers.git || false,\n targetDirectory,\n templateDirectory\n };\n}\n\nasync function createProject(options: InitOptions) {\n // Check if directory already exists and is not empty\n if (fs.existsSync(options.targetDirectory)) {\n if (fs.readdirSync(options.targetDirectory).length !== 0) {\n console.error(`${chalk.red.bold(\"ERROR\")} Directory \"${options.projectName}\" already exists and is not empty`);\n process.exit(1);\n }\n } else {\n fs.mkdirSync(options.targetDirectory, { recursive: true });\n }\n\n // Verify template exists\n try {\n await access(options.templateDirectory, fs.constants.R_OK);\n } catch {\n console.error(`${chalk.red.bold(\"ERROR\")} Template not found at ${options.templateDirectory}`);\n process.exit(1);\n }\n\n // Copy template files\n console.log(chalk.gray(\" Copying project files...\"));\n await copy(options.templateDirectory, options.targetDirectory, {\n clobber: false,\n dot: true,\n filter: (source: string) => {\n const basename = path.basename(source);\n // Skip node_modules and .DS_Store\n return basename !== \"node_modules\" && basename !== \".DS_Store\";\n }\n });\n\n // Replace placeholder project name in package.json files\n await replacePlaceholders(options);\n\n // Rename .env.template to .env if it exists and randomize secrets\n const envTemplatePath = path.join(options.targetDirectory, \".env.template\");\n const envPath = path.join(options.targetDirectory, \".env\");\n if (fs.existsSync(envTemplatePath) && !fs.existsSync(envPath)) {\n fs.renameSync(envTemplatePath, envPath);\n \n // Generate secure random strings\n const jwtSecret = crypto.randomBytes(32).toString(\"hex\");\n const dbPassword = crypto.randomBytes(16).toString(\"hex\");\n \n let envContent = fs.readFileSync(envPath, \"utf-8\");\n envContent = envContent.replace(\n \"postgresql://rebase:password@localhost:5432/rebase\",\n `postgresql://rebase:${dbPassword}@localhost:5432/rebase`\n );\n envContent = envContent.replace(\n \"change-this-to-a-secure-random-string\",\n jwtSecret\n );\n \n // Append POSTGRES_PASSWORD for docker-compose interpolation\n envContent += `\\n# Docker Compose Database Password\\nPOSTGRES_PASSWORD=${dbPassword}\\n`;\n \n fs.writeFileSync(envPath, envContent, \"utf-8\");\n }\n\n // Initialize git\n if (options.git) {\n console.log(chalk.gray(\" Initializing git repository...\"));\n try {\n await execa(\"git\", [\"init\"], { cwd: options.targetDirectory });\n } catch {\n console.warn(chalk.yellow(\" Warning: Failed to initialize git repository\"));\n }\n }\n\n // Success message\n console.log(\"\");\n console.log(`${chalk.green.bold(\"✓\")} Project ${chalk.bold(options.projectName)} created successfully!`);\n console.log(\"\");\n console.log(chalk.bold(\"Next steps:\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(\"cd\")} ${options.projectName}`);\n console.log(` ${chalk.cyan(\"pnpm install\")}`);\n console.log(\"\");\n console.log(chalk.gray(\" # Set up your database connection in .env\"));\n console.log(chalk.gray(\" # Then run:\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(\"pnpm dev\")}`);\n console.log(\"\");\n console.log(chalk.gray(\"This starts both the backend (Express + PostgreSQL)\")\n + chalk.gray(\" and the frontend (Vite + React) concurrently.\"));\n console.log(\"\");\n console.log(chalk.gray(\"Docs: https://rebase.pro/docs\"));\n console.log(chalk.gray(\"GitHub: https://github.com/rebaseco/rebase\"));\n console.log(\"\");\n}\n\nasync function replacePlaceholders(options: InitOptions) {\n const filesToProcess = [\n \"package.json\",\n \"frontend/package.json\",\n \"backend/package.json\",\n \"shared/package.json\",\n \"frontend/index.html\"\n ];\n\n for (const file of filesToProcess) {\n const fullPath = path.resolve(options.targetDirectory, file);\n if (!fs.existsSync(fullPath)) continue;\n\n let content = fs.readFileSync(fullPath, \"utf-8\");\n content = content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, options.projectName);\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n}\n","import chalk from \"chalk\";\nimport arg from \"arg\";\nimport { createRebaseApp } from \"./commands/init\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nfunction getVersion(): string {\n try {\n // Try to read version from package.json\n const pkgPath = path.resolve(__dirname, \"../package.json\");\n if (fs.existsSync(pkgPath)) {\n return JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")).version;\n }\n } catch {\n // ignore\n }\n return \"unknown\";\n}\n\nexport async function entry(args: string[]) {\n const parsedArgs = arg(\n {\n \"--version\": Boolean,\n \"--help\": Boolean,\n \"-v\": \"--version\",\n \"-h\": \"--help\"\n },\n {\n argv: args.slice(2),\n permissive: true\n }\n );\n\n if (parsedArgs[\"--version\"]) {\n console.log(getVersion());\n return;\n }\n\n const command = parsedArgs._[0];\n\n if (!command || parsedArgs[\"--help\"]) {\n printHelp();\n return;\n }\n\n if (command === \"init\") {\n await createRebaseApp(args);\n } else {\n console.log(chalk.red(`Unknown command: ${command}`));\n console.log(\"\");\n printHelp();\n }\n}\n\nfunction printHelp() {\n console.log(`\n${chalk.bold(\"Rebase CLI\")} — Developer tools for Rebase projects\n\n${chalk.green.bold(\"Usage\")}\n rebase ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"init\")} Create a new Rebase project\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue(\"--version, -v\")} Show version number\n ${chalk.blue(\"--help, -h\")} Show this help message\n\n${chalk.gray(\"Documentation: https://rebase.pro/docs\")}\n`);\n}\n","/**\n * Authentication helpers for the Rebase CLI.\n *\n * Token storage lives at ~/.rebase/tokens.json (prod) or\n * ~/.rebase/staging.tokens.json (dev).\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport * as os from \"os\";\n\nconst TOKEN_DIR = path.join(os.homedir(), \".rebase\");\n\nfunction tokenPath(env: \"prod\" | \"dev\"): string {\n return path.join(TOKEN_DIR, (env === \"dev\" ? \"staging.\" : \"\") + \"tokens.json\");\n}\n\n// ─── Token persistence ────────────────────────────────────\n\nfunction saveTokens(tokens: object, env: \"prod\" | \"dev\") {\n if (!fs.existsSync(TOKEN_DIR)) {\n fs.mkdirSync(TOKEN_DIR, { recursive: true });\n }\n fs.writeFileSync(tokenPath(env), JSON.stringify(tokens));\n}\n\n// ─── Public API ───────────────────────────────────────────\n\nexport async function getTokens(env: \"prod\" | \"dev\", _debug?: boolean): Promise<object | null> {\n const fp = tokenPath(env);\n if (!fs.existsSync(fp)) return null;\n try {\n const data = fs.readFileSync(fp, \"utf-8\");\n return JSON.parse(data);\n } catch {\n return null;\n }\n}\n\nexport function parseJwt(token: string): object {\n if (!token) throw new Error(\"No JWT token\");\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const buffer = Buffer.from(base64, \"base64\");\n return JSON.parse(buffer.toString());\n}\n\nexport async function refreshCredentials(\n env: \"dev\" | \"prod\",\n credentials?: object | null,\n _onErr?: (e: unknown) => void,\n): Promise<object | null> {\n if (!credentials) return null;\n // If the token hasn't expired, just return it.\n const expiryDate = new Date((credentials as any)[\"expiry_date\"]);\n if (expiryDate.getTime() > Date.now()) {\n return credentials;\n }\n // Without a server endpoint we can't actually refresh –\n // the caller should handle the null return by re-authenticating.\n return null;\n}\n\nexport async function login(env: \"prod\" | \"dev\", _debug?: boolean): Promise<void> {\n console.log(\n \"Interactive login is not yet implemented in @rebasepro/cli.\\n\" +\n \"Please authenticate via the Rebase dashboard and copy your tokens to \" +\n tokenPath(env),\n );\n}\n\nexport async function logout(env: \"prod\" | \"dev\", _debug?: boolean): Promise<void> {\n const fp = tokenPath(env);\n if (fs.existsSync(fp)) {\n fs.unlinkSync(fp);\n console.log(\"You have been logged out.\");\n } else {\n console.log(\"You are not logged in.\");\n }\n}\n"],"names":["promisify","__filename","fileURLToPath","__dirname","os"],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- # Database Configuration
2
- DATABASE_URL=postgresql://rebase:password@localhost:5432/rebase
3
-
4
- # Server Configuration
5
- PORT=3001
6
- NODE_ENV=development
7
-
8
- # JWT Authentication
9
- JWT_SECRET=change-this-to-a-secure-random-string
10
- JWT_ACCESS_EXPIRES_IN=1h
11
- JWT_REFRESH_EXPIRES_IN=30d
12
-
13
- # Allow new user registration
14
- ALLOW_REGISTRATION=true
15
-
16
- # Frontend API URL
17
- VITE_API_URL=http://localhost:3001
18
-
19
- # Google OAuth (optional — uncomment to enable)
20
- # GOOGLE_CLIENT_ID=your-google-client-id
21
- # VITE_GOOGLE_CLIENT_ID=your-google-client-id
22
-
23
- # Email (optional — uncomment to enable password reset emails)
24
- # SMTP_HOST=smtp.example.com
25
- # SMTP_PORT=587
26
- # SMTP_SECURE=false
27
- # SMTP_USER=your-smtp-username
28
- # SMTP_PASS=your-smtp-password
29
- # SMTP_FROM=noreply@yourapp.com
30
- # APP_NAME=My Rebase App
31
- # FRONTEND_URL=http://localhost:5173
@@ -1,22 +0,0 @@
1
- import "dotenv/config";
2
- import { defineConfig } from "drizzle-kit";
3
- import { tables } from "./src/schema.generated";
4
- import { getTableName, Table } from "drizzle-orm";
5
-
6
- if (!process.env.DATABASE_URL) {
7
- throw new Error("DATABASE_URL is not set. Make sure .env file exists in the project root and contains DATABASE_URL");
8
- }
9
-
10
- // Extract table names from the generated schema
11
- // This ensures drizzle-kit ONLY manages tables defined in the schema
12
- const tableNames = Object.values(tables).map(table => getTableName(table as Table));
13
-
14
- export default defineConfig({
15
- schema: "./src/schema.generated.ts",
16
- out: "./drizzle",
17
- dialect: "postgresql",
18
- dbCredentials: {
19
- url: process.env.DATABASE_URL
20
- },
21
- tablesFilter: tableNames
22
- });