@epicabdou/create-linkrjs-app 0.0.1

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/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # create-linkrjs-app
2
+
3
+ Scaffold a new **linkr.js** app (Vite + React + React Router + file-based routing).
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npx @epicabdou/create-linkrjs-app my-app
9
+ cd my-app
10
+ pnpm install
11
+ pnpm dev
12
+ ```
13
+
14
+ (Or `npx create-linkrjs-app my-app` if you have the package installed globally.)
15
+
16
+ This creates a folder `my-app` with:
17
+
18
+ - Vite + React + TypeScript
19
+ - React Router v7
20
+ - **@epicabdou/linkr** for file-based routes from `src/pages/`
21
+ - `index.tsx` (home) and `404.tsx` (not found)
22
+
23
+ Dev server runs at http://localhost:8000.
24
+
25
+ ## What gets created
26
+
27
+ - `package.json` — name set to your project name
28
+ - `vite.config.ts` — React plugin, port 8000
29
+ - `src/main.tsx` — router using `createRoutes` + `import.meta.glob("./pages/**/*.tsx")`
30
+ - `src/pages/index.tsx` — home page
31
+ - `src/pages/404.tsx` — 404 page
32
+
33
+ Add more routes by adding files under `src/pages/` (e.g. `about.tsx` → `/about`).
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { cpSync, mkdirSync, existsSync, readFileSync, writeFileSync } from "fs";
4
+ import { dirname, join } from "path";
5
+ import { fileURLToPath } from "url";
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const templateDir = join(__dirname, "..", "template");
9
+
10
+ const projectName = process.argv[2];
11
+ if (!projectName) {
12
+ console.log(`
13
+ Create a new linkr.js app
14
+
15
+ Usage: npx create-linkrjs-app <project-name>
16
+
17
+ Example: npx create-linkrjs-app my-app
18
+ `);
19
+ process.exit(1);
20
+ }
21
+
22
+ const targetDir = join(process.cwd(), projectName);
23
+ if (existsSync(targetDir)) {
24
+ console.error(`Error: "${projectName}" already exists. Choose another name.`);
25
+ process.exit(1);
26
+ }
27
+
28
+ mkdirSync(targetDir, { recursive: true });
29
+ cpSync(templateDir, targetDir, { recursive: true });
30
+
31
+ const pkgPath = join(targetDir, "package.json");
32
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
33
+ pkg.name = projectName.replace(/^[^a-zA-Z]|[^a-zA-Z0-9-_]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g) || "linkrjs-app";
34
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
35
+
36
+ console.log(`
37
+ Done! Your linkr.js app is in ./${projectName}
38
+
39
+ Next steps:
40
+ cd ${projectName}
41
+ pnpm install
42
+ pnpm dev
43
+ `);
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@epicabdou/create-linkrjs-app",
3
+ "version": "0.0.1",
4
+ "description": "Scaffold a new linkr.js app (Vite + React + React Router + file-based routing)",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-linkrjs-app": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "template"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/epicabdou/linkrjs.git"
16
+ },
17
+ "license": "MIT",
18
+ "keywords": [
19
+ "linkr",
20
+ "linkrjs",
21
+ "create-app",
22
+ "scaffold",
23
+ "vite",
24
+ "react",
25
+ "react-router"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "scripts": {}
31
+ }
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>linkr.js App</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.tsx"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "my-linkrjs-app",
3
+ "private": true,
4
+ "version": "0.0.1",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc -b && vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "@epicabdou/linkr": "^1.0.0",
13
+ "react": "^18.2.0",
14
+ "react-dom": "^18.2.0",
15
+ "react-router": "^7.0.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/react": "^18.2.0",
19
+ "@types/react-dom": "^18.2.0",
20
+ "@vitejs/plugin-react": "^4.2.0",
21
+ "typescript": "^5.3.0",
22
+ "vite": "^5.0.0"
23
+ }
24
+ }
@@ -0,0 +1,11 @@
1
+ import type { ProtectConfig } from "@epicabdou/linkr";
2
+
3
+ /**
4
+ * Predefined auth protection: redirect to /login when there is no token.
5
+ * Use in any layout or page: <Protect {...authProtect}><Outlet /></Protect>
6
+ */
7
+ export const authProtect: ProtectConfig = {
8
+ condition: () => !!localStorage.getItem("token"),
9
+ redirectTo: "/login",
10
+ fallback: <div>Checking access…</div>,
11
+ };
@@ -0,0 +1,15 @@
1
+ import { StrictMode } from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import { createBrowserRouter, RouterProvider } from "react-router";
4
+ import { createRoutes } from "@epicabdou/linkr";
5
+
6
+ const pages = import.meta.glob("./pages/**/*.tsx");
7
+ const routes = createRoutes({ pagesGlob: pages, pagesDir: "pages" });
8
+ const router = createBrowserRouter(routes);
9
+
10
+ const root = createRoot(document.getElementById("root")!);
11
+ root.render(
12
+ <StrictMode>
13
+ <RouterProvider router={router} />
14
+ </StrictMode>
15
+ );
@@ -0,0 +1,14 @@
1
+ import { useNavigate } from "react-router";
2
+
3
+ export default function NotFound() {
4
+ const navigate = useNavigate();
5
+ return (
6
+ <div>
7
+ <h1>404</h1>
8
+ <p>Page not found.</p>
9
+ <button type="button" onClick={() => navigate("/")}>
10
+ Go home
11
+ </button>
12
+ </div>
13
+ );
14
+ }
@@ -0,0 +1,8 @@
1
+ export default function Home() {
2
+ return (
3
+ <div>
4
+ <h1>Welcome to linkr.js</h1>
5
+ <p>Edit <code>src/pages/index.tsx</code> to get started.</p>
6
+ </div>
7
+ );
8
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "noEmit": true,
13
+ "jsx": "react-jsx",
14
+ "strict": true,
15
+ "noUnusedLocals": true,
16
+ "noUnusedParameters": true,
17
+ "noFallthroughCasesInSwitch": true
18
+ },
19
+ "include": ["src"]
20
+ }
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: { port: 8000 },
7
+ });