@rebasepro/cli 0.0.1-canary.4d4fb3e → 0.0.1-canary.5584634
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/commands/cli.test.d.ts +1 -0
- package/dist/commands/dev.test.d.ts +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/generate_sdk.d.ts +1 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.test.d.ts +1 -0
- package/dist/index.cjs +295 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +295 -73
- package/dist/index.es.js.map +1 -1
- package/dist/utils/project.test.d.ts +1 -0
- package/package.json +67 -66
- package/templates/template/.env.template +22 -1
- package/templates/template/README.md +2 -2
- package/templates/template/backend/Dockerfile +6 -6
- package/templates/template/backend/drizzle.config.ts +15 -3
- package/templates/template/backend/functions/hello.ts +24 -6
- package/templates/template/backend/package.json +2 -2
- package/templates/template/backend/src/env.ts +52 -0
- package/templates/template/backend/src/index.ts +86 -34
- package/templates/template/backend/tsconfig.json +1 -1
- package/templates/template/config/collections/authors.ts +45 -0
- package/templates/template/config/collections/index.ts +5 -0
- package/templates/template/{shared → config}/collections/posts.ts +39 -1
- package/templates/template/config/collections/tags.ts +27 -0
- package/templates/template/{shared → config}/package.json +1 -1
- package/templates/template/docker-compose.yml +12 -0
- package/templates/template/frontend/Dockerfile +3 -3
- package/templates/template/frontend/package.json +2 -2
- package/templates/template/frontend/src/App.tsx +21 -101
- package/templates/template/frontend/src/main.tsx +2 -2
- package/templates/template/frontend/vite.config.ts +32 -3
- package/templates/template/package.json +5 -4
- package/templates/template/pnpm-workspace.yaml +1 -1
- package/templates/template/scripts/example.ts +91 -0
- package/templates/template/shared/collections/index.ts +0 -3
- /package/templates/template/{shared → config}/index.ts +0 -0
- /package/templates/template/{shared → config}/tsconfig.json +0 -0
|
@@ -1,48 +1,23 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react";
|
|
2
2
|
|
|
3
3
|
import "@fontsource/jetbrains-mono";
|
|
4
4
|
import "typeface-rubik";
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from "@rebasepro/auth";
|
|
11
|
-
import {
|
|
12
|
-
AppBar,
|
|
13
|
-
Drawer,
|
|
14
|
-
Rebase,
|
|
15
|
-
ModeControllerProvider,
|
|
16
|
-
NotFoundPage,
|
|
17
|
-
Scaffold,
|
|
18
|
-
SideDialogs,
|
|
19
|
-
RebaseRoutes,
|
|
20
|
-
SnackbarProvider,
|
|
21
|
-
ContentHomePage,
|
|
22
|
-
useBuildUrlController,
|
|
23
|
-
useBuildCollectionRegistryController,
|
|
24
|
-
useBuildLocalConfigurationPersistence,
|
|
25
|
-
useBuildModeController,
|
|
26
|
-
useBuildNavigationStateController
|
|
27
|
-
} from "@rebasepro/core";
|
|
28
|
-
import { RebaseRoute } from "@rebasepro/cms";
|
|
29
|
-
import { CircularProgressCenter } from "@rebasepro/ui";
|
|
30
|
-
import { collections } from "virtual:rebase-collections";
|
|
31
|
-
import { Route, Outlet } from "react-router-dom";
|
|
6
|
+
import { useRebaseAuthController, useBackendUserManagement, RebaseAuth } from "@rebasepro/auth";
|
|
7
|
+
import { Rebase } from "@rebasepro/core";
|
|
8
|
+
import { RebaseCMS, RebaseShell } from "@rebasepro/admin";
|
|
9
|
+
import { RebaseStudio } from "@rebasepro/studio";
|
|
32
10
|
import { createRebaseClient } from "@rebasepro/client";
|
|
11
|
+
import { collections } from "virtual:rebase-collections";
|
|
33
12
|
|
|
34
13
|
// Configuration from environment
|
|
35
|
-
const API_URL = import.meta.env.VITE_API_URL || "http://localhost:3001";
|
|
14
|
+
const API_URL = import.meta.env.VITE_API_URL || (import.meta.env.DEV ? "http://localhost:3001" : undefined);
|
|
36
15
|
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
|
|
37
16
|
|
|
38
17
|
export function App() {
|
|
39
|
-
const modeController = useBuildModeController();
|
|
40
|
-
const userConfigPersistence = useBuildLocalConfigurationPersistence();
|
|
41
|
-
|
|
42
18
|
const rebaseClient = React.useMemo(() => createRebaseClient({
|
|
43
|
-
baseUrl: API_URL
|
|
44
|
-
|
|
45
|
-
}), [API_URL]);
|
|
19
|
+
baseUrl: API_URL
|
|
20
|
+
}), []);
|
|
46
21
|
|
|
47
22
|
const authController = useRebaseAuthController({
|
|
48
23
|
client: rebaseClient,
|
|
@@ -54,73 +29,18 @@ export function App() {
|
|
|
54
29
|
currentUser: authController.user
|
|
55
30
|
});
|
|
56
31
|
|
|
57
|
-
const collectionsBuilder = useCallback(() => {
|
|
58
|
-
return [...collections];
|
|
59
|
-
}, []);
|
|
60
|
-
|
|
61
|
-
const collectionRegistryController = useBuildCollectionRegistryController({ userConfigPersistence });
|
|
62
|
-
const urlController = useBuildUrlController({
|
|
63
|
-
basePath: "/",
|
|
64
|
-
baseCollectionPath: "/c",
|
|
65
|
-
collectionRegistryController
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const navigationStateController = useBuildNavigationStateController({
|
|
69
|
-
collections: collectionsBuilder,
|
|
70
|
-
authController,
|
|
71
|
-
data: rebaseClient.data,
|
|
72
|
-
collectionRegistryController,
|
|
73
|
-
urlController,
|
|
74
|
-
userManagement
|
|
75
|
-
});
|
|
76
|
-
|
|
77
32
|
return (
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
{({ loading }) => {
|
|
91
|
-
if (loading || authController.initialLoading) {
|
|
92
|
-
return <CircularProgressCenter />;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (!authController.user) {
|
|
96
|
-
return (
|
|
97
|
-
<RebaseLoginView
|
|
98
|
-
authController={authController}
|
|
99
|
-
googleEnabled={!!GOOGLE_CLIENT_ID}
|
|
100
|
-
googleClientId={GOOGLE_CLIENT_ID}
|
|
101
|
-
/>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return (
|
|
106
|
-
<RebaseRoutes>
|
|
107
|
-
<Route element={
|
|
108
|
-
<Scaffold autoOpenDrawer={false}>
|
|
109
|
-
<AppBar />
|
|
110
|
-
<Drawer />
|
|
111
|
-
<Outlet />
|
|
112
|
-
<SideDialogs />
|
|
113
|
-
</Scaffold>
|
|
114
|
-
}>
|
|
115
|
-
<Route path={"/"} element={<ContentHomePage />} />
|
|
116
|
-
<Route path={"/c/*"} element={<RebaseRoute />} />
|
|
117
|
-
<Route path={"*"} element={<NotFoundPage />} />
|
|
118
|
-
</Route>
|
|
119
|
-
</RebaseRoutes>
|
|
120
|
-
);
|
|
121
|
-
}}
|
|
122
|
-
</Rebase>
|
|
123
|
-
</ModeControllerProvider>
|
|
124
|
-
</SnackbarProvider>
|
|
33
|
+
<Rebase
|
|
34
|
+
client={rebaseClient}
|
|
35
|
+
authController={authController}
|
|
36
|
+
userManagement={userManagement}
|
|
37
|
+
>
|
|
38
|
+
<RebaseAuth />
|
|
39
|
+
<RebaseCMS
|
|
40
|
+
collections={collections}
|
|
41
|
+
/>
|
|
42
|
+
<RebaseStudio/>
|
|
43
|
+
<RebaseShell title="Rebase"/>
|
|
44
|
+
</Rebase>
|
|
125
45
|
);
|
|
126
46
|
}
|
|
@@ -7,12 +7,12 @@ import "./index.css";
|
|
|
7
7
|
const router = createBrowserRouter([
|
|
8
8
|
{
|
|
9
9
|
path: "/*",
|
|
10
|
-
element: <App
|
|
10
|
+
element: <App/>
|
|
11
11
|
}
|
|
12
12
|
]);
|
|
13
13
|
|
|
14
14
|
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
|
15
15
|
<React.StrictMode>
|
|
16
|
-
<RouterProvider router={router}
|
|
16
|
+
<RouterProvider router={router}/>
|
|
17
17
|
</React.StrictMode>
|
|
18
18
|
);
|
|
@@ -12,15 +12,44 @@ export default defineConfig({
|
|
|
12
12
|
},
|
|
13
13
|
build: {
|
|
14
14
|
minify: true,
|
|
15
|
-
outDir: "./
|
|
15
|
+
outDir: "./dist",
|
|
16
16
|
target: "ESNEXT",
|
|
17
|
-
sourcemap: true
|
|
17
|
+
sourcemap: true,
|
|
18
|
+
rollupOptions: {
|
|
19
|
+
output: {
|
|
20
|
+
manualChunks(id) {
|
|
21
|
+
// Heavy vendor libraries — split into individually cached chunks
|
|
22
|
+
if (id.includes("xlsx")) return "vendor-xlsx";
|
|
23
|
+
if (id.includes("prosemirror")) return "vendor-prosemirror";
|
|
24
|
+
if (id.includes("monaco-editor") || id.includes("@monaco-editor")) return "vendor-monaco";
|
|
25
|
+
if (id.includes("@xyflow") || id.includes("dagre")) return "vendor-xyflow";
|
|
26
|
+
if (id.includes("@dnd-kit")) return "vendor-dnd";
|
|
27
|
+
if (id.includes("prism-react-renderer")) return "vendor-prism";
|
|
28
|
+
if (id.includes("markdown-it")) return "vendor-markdown";
|
|
29
|
+
if (id.includes("react-dropzone")) return "vendor-dropzone";
|
|
30
|
+
if (id.includes("date-fns")) return "vendor-datefns";
|
|
31
|
+
if (id.includes("fuse.js")) return "vendor-fuse";
|
|
32
|
+
if (id.includes("node_modules/react-dom/")) return "vendor-react-dom";
|
|
33
|
+
if (id.includes("node_modules/react-router") || id.includes("node_modules/@remix-run")) return "vendor-react-router";
|
|
34
|
+
if (id.includes("node_modules/@radix-ui/")) return "vendor-radix";
|
|
35
|
+
if (id.includes("node_modules/framer-motion/")) return "vendor-framer-motion";
|
|
36
|
+
if (id.includes("node_modules/zod/")) return "vendor-zod";
|
|
37
|
+
if (id.includes("node_modules/i18next") || id.includes("node_modules/react-i18next")) return "vendor-i18next";
|
|
38
|
+
if (id.includes("node_modules/@floating-ui/")) return "vendor-floating-ui";
|
|
39
|
+
if (id.includes("node_modules/tailwind-merge/")) return "vendor-tailwind-merge";
|
|
40
|
+
if (id.includes("node_modules/notistack/")) return "vendor-notistack";
|
|
41
|
+
if (id.includes("node_modules/lucide-react/")) return "vendor-lucide-react";
|
|
42
|
+
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
18
47
|
},
|
|
19
48
|
optimizeDeps: { include: ["react/jsx-runtime"] },
|
|
20
49
|
plugins: [
|
|
21
50
|
svgr(),
|
|
22
51
|
react({}),
|
|
23
52
|
tailwindcss(),
|
|
24
|
-
rebaseCollectionsPlugin({ collectionsDir: "../
|
|
53
|
+
rebaseCollectionsPlugin({ collectionsDir: "../config/collections" })
|
|
25
54
|
]
|
|
26
55
|
});
|
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
"dev": "rebase dev",
|
|
9
9
|
"build": "pnpm -r run build",
|
|
10
10
|
"start": "pnpm --filter \"*-backend\" start",
|
|
11
|
-
"db:generate": "rebase db generate",
|
|
11
|
+
"db:generate": "rebase db generate --collections ../config/collections",
|
|
12
12
|
"db:migrate": "rebase db migrate",
|
|
13
13
|
"db:pull": "rebase db pull",
|
|
14
|
-
"db:push": "rebase db push",
|
|
14
|
+
"db:push": "rebase db push --collections ../config/collections",
|
|
15
15
|
"db:studio": "rebase db studio",
|
|
16
|
-
"schema:generate": "rebase schema generate",
|
|
17
|
-
"generate:sdk": "rebase generate-sdk"
|
|
16
|
+
"schema:generate": "rebase schema generate --collections ../config/collections",
|
|
17
|
+
"generate:sdk": "rebase generate-sdk",
|
|
18
|
+
"deploy": "pnpm run build && pnpm run start"
|
|
18
19
|
},
|
|
19
20
|
"devDependencies": {
|
|
20
21
|
"@rebasepro/cli": "workspace:*",
|
|
@@ -0,0 +1,91 @@
|
|
|
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 Firebase 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 health = await fetch(`${baseUrl}/api/health`).then(res => res.json());
|
|
79
|
+
console.log("✅ Backend health:", health);
|
|
80
|
+
|
|
81
|
+
// Example: Fetch some data (requires auth if backend is secure-by-default)
|
|
82
|
+
// const items = await rebase.data.collection("users").find({ limit: 5 });
|
|
83
|
+
// console.log("Items:", items);
|
|
84
|
+
|
|
85
|
+
console.log("✨ Script finished successfully.");
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error("❌ Script failed:", error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
run();
|
|
File without changes
|
|
File without changes
|