@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.
- package/LICENSE +17 -196
- package/README.md +57 -33
- package/dist/commands/api-keys.d.ts +1 -0
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/build.d.ts +1 -0
- package/dist/commands/cloud/auth.d.ts +3 -0
- package/dist/commands/cloud/context.d.ts +61 -0
- package/dist/commands/cloud/databases.d.ts +1 -0
- package/dist/commands/cloud/deploy.d.ts +2 -0
- package/dist/commands/cloud/index.d.ts +1 -0
- package/dist/commands/cloud/link.d.ts +5 -0
- package/dist/commands/cloud/orgs.d.ts +1 -0
- package/dist/commands/cloud/projects.d.ts +13 -0
- package/dist/commands/cloud/resources.d.ts +6 -0
- package/dist/commands/db.d.ts +1 -0
- package/dist/commands/dev.d.ts +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/generate_sdk.d.ts +18 -0
- package/dist/commands/init.d.ts +40 -0
- package/dist/commands/schema.d.ts +1 -0
- package/dist/commands/skills.d.ts +1 -0
- package/dist/commands/start.d.ts +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.es.js +3952 -245
- package/dist/index.es.js.map +1 -1
- package/dist/utils/package-manager.d.ts +33 -0
- package/dist/utils/project.d.ts +60 -0
- package/package.json +35 -23
- package/templates/overlays/baas/README.md +37 -0
- package/templates/overlays/baas/backend/package.json +31 -0
- package/templates/overlays/baas/backend/src/index.ts +172 -0
- package/templates/overlays/baas/backend/tsconfig.json +18 -0
- package/templates/overlays/baas/package.json +42 -0
- package/templates/overlays/baas/pnpm-workspace.yaml +9 -0
- package/templates/template/.cursorrules +2 -0
- package/templates/template/.dockerignore +28 -0
- package/templates/template/.env.example +120 -0
- package/templates/template/.github/copilot-instructions.md +2 -0
- package/templates/template/.windsurfrules +2 -0
- package/templates/template/AGENTS.md +2 -0
- package/templates/template/CLAUDE.md +2 -0
- package/templates/template/README.md +88 -21
- package/templates/template/ai-instructions.md +17 -0
- package/templates/template/backend/Dockerfile +57 -11
- package/templates/template/backend/functions/hello.ts +56 -0
- package/templates/template/backend/package.json +30 -34
- package/templates/template/backend/src/env.ts +23 -0
- package/templates/template/backend/src/index.ts +140 -100
- package/templates/template/backend/tsconfig.json +1 -1
- package/templates/template/config/collections/authors.ts +45 -0
- package/templates/template/config/collections/index.ts +26 -0
- package/templates/template/{shared → config}/collections/posts.ts +28 -10
- package/templates/template/config/collections/presets/blank/index.ts +3 -0
- package/templates/template/config/collections/presets/ecommerce/categories.ts +40 -0
- package/templates/template/config/collections/presets/ecommerce/index.ts +6 -0
- package/templates/template/config/collections/presets/ecommerce/orders.ts +66 -0
- package/templates/template/config/collections/presets/ecommerce/products.ts +64 -0
- package/templates/template/config/collections/tags.ts +25 -0
- package/templates/template/config/collections/users.ts +142 -0
- package/templates/template/{shared → config}/index.ts +1 -1
- package/templates/template/config/package.json +28 -0
- package/templates/template/docker-compose.yml +50 -14
- package/templates/template/frontend/Dockerfile +39 -15
- package/templates/template/frontend/nginx.conf +40 -0
- package/templates/template/frontend/package.json +13 -13
- package/templates/template/frontend/src/App.tsx +30 -116
- package/templates/template/frontend/src/index.css +15 -1
- package/templates/template/frontend/src/main.tsx +6 -2
- package/templates/template/frontend/src/virtual.d.ts +6 -0
- package/templates/template/frontend/tsconfig.json +3 -2
- package/templates/template/frontend/vite.config.ts +48 -5
- package/templates/template/package.json +21 -12
- package/templates/template/pnpm-workspace.yaml +13 -0
- package/templates/template/scripts/example.ts +94 -0
- package/dist/auth.d.ts +0 -5
- package/dist/index.cjs +0 -293
- package/dist/index.cjs.map +0 -1
- package/templates/template/.env.template +0 -31
- package/templates/template/backend/drizzle.config.ts +0 -22
- package/templates/template/backend/scripts/db-generate.ts +0 -60
- package/templates/template/shared/collections/index.ts +0 -3
- package/templates/template/shared/package.json +0 -28
- /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/
|
|
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: "./
|
|
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: "../
|
|
67
|
+
rebaseCollectionsPlugin({ collectionsDir: "../config/collections" })
|
|
25
68
|
]
|
|
26
69
|
});
|
|
@@ -7,26 +7,35 @@
|
|
|
7
7
|
"workspaces": [
|
|
8
8
|
"frontend",
|
|
9
9
|
"backend",
|
|
10
|
-
"
|
|
10
|
+
"config"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"dev": "
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
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,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
|
package/dist/index.cjs.map
DELETED
|
@@ -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":";;;;;;;;;;;;;;;;;;;;;;AAWA,QAAM,SAASA,KAAAA,UAAU,GAAG,MAAM;AAClC,QAAM,OAAOA,KAAAA,UAAU,GAAG;AAG1B,QAAMC,eAAaC,IAAAA,qVAA6B;AAChD,QAAMC,cAAY,KAAK,QAAQF,YAAU;AAEzC,WAAS,cAAc,YAAoB,YAAmC;AAC1E,UAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AACpC,WAAO,cAAc,eAAe,MAAM;AACtC,UAAI,KAAK,SAAS,UAAU,MAAM,YAAY;AAC1C,eAAO;AAAA,MACX;AACA,mBAAa,KAAK,QAAQ,UAAU;AAAA,IACxC;AACA,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,cAAcE,aAAW,KAAK;AAS9C,iBAAsB,gBAAgB,SAAmB;AACrD,YAAQ,IAAI;AAAA,EACd,MAAM,KAAK,QAAQ,CAAC;AAAA,CACrB;AAEG,UAAM,UAAU,MAAM,iBAAiB,OAAO;AAC9C,UAAM,cAAc,OAAO;AAAA,EAC/B;AAEA,iBAAe,iBAAiB,SAAyC;AACrE,UAAM,OAAO;AAAA,MACT;AAAA,QACI,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAEV;AAAA,QACI,MAAM,QAAQ,MAAM,CAAC;AAAA;AAAA,QACrB,YAAY;AAAA,MAAA;AAAA,IAChB;AAIJ,UAAM,UAAU,KAAK,EAAE,CAAC;AAExB,UAAM,YAAmB,CAAA;AAEzB,QAAI,CAAC,SAAS;AACV,gBAAU,KAAK;AAAA,QACX,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UAAkB;AACzB,cAAI,CAAC,MAAM,KAAA,EAAQ,QAAO;AAC1B,cAAI,CAAC,yBAAyB,KAAK,KAAK,GAAG;AACvC,mBAAO;AAAA,UACX;AACA,iBAAO;AAAA,QACX;AAAA,MAAA,CACH;AAAA,IACL;AAEA,QAAI,CAAC,KAAK,OAAO,GAAG;AAChB,gBAAU,KAAK;AAAA,QACX,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MAAA,CACZ;AAAA,IACL;AAEA,UAAM,UAAU,MAAM,SAAS,OAAO,SAAS;AAE/C,UAAM,cAAc,WAAW,QAAQ;AACvC,UAAM,kBAAkB,KAAK,QAAQ,QAAQ,IAAA,GAAO,WAAW;AAC/D,UAAM,oBAAoB,KAAK,QAAQ,SAAU,aAAa,UAAU;AAExE,WAAO;AAAA,MACH;AAAA,MACA,KAAK,KAAK,OAAO,KAAK,QAAQ,OAAO;AAAA,MACrC;AAAA,MACA;AAAA,IAAA;AAAA,EAER;AAEA,iBAAe,cAAc,SAAsB;AAE/C,QAAI,GAAG,WAAW,QAAQ,eAAe,GAAG;AACxC,UAAI,GAAG,YAAY,QAAQ,eAAe,EAAE,WAAW,GAAG;AACtD,gBAAQ,MAAM,GAAG,MAAM,IAAI,KAAK,OAAO,CAAC,eAAe,QAAQ,WAAW,mCAAmC;AAC7G,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAAA,IACJ,OAAO;AACH,SAAG,UAAU,QAAQ,iBAAiB,EAAE,WAAW,MAAM;AAAA,IAC7D;AAGA,QAAI;AACA,YAAM,OAAO,QAAQ,mBAAmB,GAAG,UAAU,IAAI;AAAA,IAC7D,QAAQ;AACJ,cAAQ,MAAM,GAAG,MAAM,IAAI,KAAK,OAAO,CAAC,0BAA0B,QAAQ,iBAAiB,EAAE;AAC7F,cAAQ,KAAK,CAAC;AAAA,IAClB;AAGA,YAAQ,IAAI,MAAM,KAAK,4BAA4B,CAAC;AACpD,UAAM,KAAK,QAAQ,mBAAmB,QAAQ,iBAAiB;AAAA,MAC3D,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ,CAAC,WAAmB;AACxB,cAAM,WAAW,KAAK,SAAS,MAAM;AAErC,eAAO,aAAa,kBAAkB,aAAa;AAAA,MACvD;AAAA,IAAA,CACH;AAGD,UAAM,oBAAoB,OAAO;AAGjC,UAAM,kBAAkB,KAAK,KAAK,QAAQ,iBAAiB,eAAe;AAC1E,UAAM,UAAU,KAAK,KAAK,QAAQ,iBAAiB,MAAM;AACzD,QAAI,GAAG,WAAW,eAAe,KAAK,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3D,SAAG,WAAW,iBAAiB,OAAO;AAGtC,YAAM,YAAY,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AACvD,YAAM,aAAa,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAExD,UAAI,aAAa,GAAG,aAAa,SAAS,OAAO;AACjD,mBAAa,WAAW;AAAA,QACpB;AAAA,QACA,uBAAuB,UAAU;AAAA,MAAA;AAErC,mBAAa,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MAAA;AAIJ,oBAAc;AAAA;AAAA,oBAA2D,UAAU;AAAA;AAEnF,SAAG,cAAc,SAAS,YAAY,OAAO;AAAA,IACjD;AAGA,QAAI,QAAQ,KAAK;AACb,cAAQ,IAAI,MAAM,KAAK,kCAAkC,CAAC;AAC1D,UAAI;AACA,cAAM,MAAM,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,QAAQ,iBAAiB;AAAA,MACjE,QAAQ;AACJ,gBAAQ,KAAK,MAAM,OAAO,gDAAgD,CAAC;AAAA,MAC/E;AAAA,IACJ;AAGA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,GAAG,MAAM,MAAM,KAAK,GAAG,CAAC,YAAY,MAAM,KAAK,QAAQ,WAAW,CAAC,wBAAwB;AACvG,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,KAAK,aAAa,CAAC;AACrC,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,QAAQ,WAAW,EAAE;AAC1D,YAAQ,IAAI,KAAK,MAAM,KAAK,cAAc,CAAC,EAAE;AAC7C,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,KAAK,6CAA6C,CAAC;AACrE,YAAQ,IAAI,MAAM,KAAK,eAAe,CAAC;AACvC,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,EAAE;AACzC,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,KAAK,qDAAqD,IACtE,MAAM,KAAK,gDAAgD,CAAC;AAClE,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,MAAM,KAAK,+BAA+B,CAAC;AACvD,YAAQ,IAAI,MAAM,KAAK,4CAA4C,CAAC;AACpE,YAAQ,IAAI,EAAE;AAAA,EAClB;AAEA,iBAAe,oBAAoB,SAAsB;AACrD,UAAM,iBAAiB;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGJ,eAAW,QAAQ,gBAAgB;AAC/B,YAAM,WAAW,KAAK,QAAQ,QAAQ,iBAAiB,IAAI;AAC3D,UAAI,CAAC,GAAG,WAAW,QAAQ,EAAG;AAE9B,UAAI,UAAU,GAAG,aAAa,UAAU,OAAO;AAC/C,gBAAU,QAAQ,QAAQ,yBAAyB,QAAQ,WAAW;AACtE,SAAG,cAAc,UAAU,SAAS,OAAO;AAAA,IAC/C;AAAA,EACJ;AC7MA,QAAMF,eAAaC,IAAAA,qVAA6B;AAChD,QAAMC,cAAY,KAAK,QAAQF,YAAU;AAEzC,WAAS,aAAqB;AAC1B,QAAI;AAEA,YAAM,UAAU,KAAK,QAAQE,aAAW,iBAAiB;AACzD,UAAI,GAAG,WAAW,OAAO,GAAG;AACxB,eAAO,KAAK,MAAM,GAAG,aAAa,SAAS,OAAO,CAAC,EAAE;AAAA,MACzD;AAAA,IACJ,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACX;AAEA,iBAAsB,MAAM,MAAgB;AACxC,UAAM,aAAa;AAAA,MACf;AAAA,QACI,aAAa;AAAA,QACb,UAAU;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,MAEV;AAAA,QACI,MAAM,KAAK,MAAM,CAAC;AAAA,QAClB,YAAY;AAAA,MAAA;AAAA,IAChB;AAGJ,QAAI,WAAW,WAAW,GAAG;AACzB,cAAQ,IAAI,YAAY;AACxB;AAAA,IACJ;AAEA,UAAM,UAAU,WAAW,EAAE,CAAC;AAE9B,QAAI,CAAC,WAAW,WAAW,QAAQ,GAAG;AAClC,gBAAA;AACA;AAAA,IACJ;AAEA,QAAI,YAAY,QAAQ;AACpB,YAAM,gBAAgB,IAAI;AAAA,IAC9B,OAAO;AACH,cAAQ,IAAI,MAAM,IAAI,oBAAoB,OAAO,EAAE,CAAC;AACpD,cAAQ,IAAI,EAAE;AACd,gBAAA;AAAA,IACJ;AAAA,EACJ;AAEA,WAAS,YAAY;AACjB,YAAQ,IAAI;AAAA,EACd,MAAM,KAAK,YAAY,CAAC;AAAA;AAAA,EAExB,MAAM,MAAM,KAAK,OAAO,CAAC;AAAA,WAChB,MAAM,KAAK,WAAW,CAAC;AAAA;AAAA,EAEhC,MAAM,MAAM,KAAK,UAAU,CAAC;AAAA,IAC1B,MAAM,KAAK,KAAK,MAAM,CAAC;AAAA;AAAA,EAEzB,MAAM,MAAM,KAAK,SAAS,CAAC;AAAA,IACzB,MAAM,KAAK,eAAe,CAAC;AAAA,IAC3B,MAAM,KAAK,YAAY,CAAC;AAAA;AAAA,EAE1B,MAAM,KAAK,wCAAwC,CAAC;AAAA,CACrD;AAAA,EACD;AChEA,QAAM,YAAY,KAAK,KAAKC,cAAG,QAAA,GAAW,SAAS;AAEnD,WAAS,UAAU,KAA6B;AAC5C,WAAO,KAAK,KAAK,YAAY,QAAQ,QAAQ,aAAa,MAAM,aAAa;AAAA,EACjF;AAaA,iBAAsB,UAAU,KAAqB,QAA0C;AAC3F,UAAM,KAAK,UAAU,GAAG;AACxB,QAAI,CAAC,GAAG,WAAW,EAAE,EAAG,QAAO;AAC/B,QAAI;AACA,YAAM,OAAO,GAAG,aAAa,IAAI,OAAO;AACxC,aAAO,KAAK,MAAM,IAAI;AAAA,IAC1B,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAEO,WAAS,SAAS,OAAuB;AAC5C,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,cAAc;AAC1C,UAAM,YAAY,MAAM,MAAM,GAAG,EAAE,CAAC;AACpC,UAAM,SAAS,UAAU,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC7D,UAAM,SAAS,OAAO,KAAK,QAAQ,QAAQ;AAC3C,WAAO,KAAK,MAAM,OAAO,SAAA,CAAU;AAAA,EACvC;AAEA,iBAAsB,mBAClB,KACA,aACA,QACsB;AACtB,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,aAAa,IAAI,KAAM,YAAoB,aAAa,CAAC;AAC/D,QAAI,WAAW,QAAA,IAAY,KAAK,OAAO;AACnC,aAAO;AAAA,IACX;AAGA,WAAO;AAAA,EACX;AAEA,iBAAsB,MAAM,KAAqB,QAAiC;AAC9E,YAAQ;AAAA,MACJ,uIAEA,UAAU,GAAG;AAAA,IAAA;AAAA,EAErB;AAEA,iBAAsB,OAAO,KAAqB,QAAiC;AAC/E,UAAM,KAAK,UAAU,GAAG;AACxB,QAAI,GAAG,WAAW,EAAE,GAAG;AACnB,SAAG,WAAW,EAAE;AAChB,cAAQ,IAAI,2BAA2B;AAAA,IAC3C,OAAO;AACH,cAAQ,IAAI,wBAAwB;AAAA,IACxC;AAAA,EACJ;;;;;;;;;;"}
|
|
@@ -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
|
-
});
|