@fydemy/cms 1.0.2 → 1.0.4
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/admin.template.tsx +661 -0
- package/dist/bin.js +124 -16
- package/dist/bin.js.map +1 -1
- package/dist/bin.mjs +124 -16
- package/dist/bin.mjs.map +1 -1
- package/dist/components/ui/badge.tsx +36 -0
- package/dist/components/ui/button.tsx +56 -0
- package/dist/components/ui/card.tsx +86 -0
- package/dist/components/ui/input.tsx +25 -0
- package/dist/components/ui/label.tsx +24 -0
- package/dist/components/ui/textarea.tsx +24 -0
- package/dist/components.json +16 -0
- package/dist/index.js +124 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +124 -16
- package/dist/index.mjs.map +1 -1
- package/dist/lib/utils.ts +6 -0
- package/dist/login.template.tsx +126 -0
- package/package.json +4 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
const Card = React.forwardRef<
|
|
6
|
+
HTMLDivElement,
|
|
7
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
8
|
+
>(({ className, ...props }, ref) => (
|
|
9
|
+
<div
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={cn(
|
|
12
|
+
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
));
|
|
18
|
+
Card.displayName = "Card";
|
|
19
|
+
|
|
20
|
+
const CardHeader = React.forwardRef<
|
|
21
|
+
HTMLDivElement,
|
|
22
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
23
|
+
>(({ className, ...props }, ref) => (
|
|
24
|
+
<div
|
|
25
|
+
ref={ref}
|
|
26
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
));
|
|
30
|
+
CardHeader.displayName = "CardHeader";
|
|
31
|
+
|
|
32
|
+
const CardTitle = React.forwardRef<
|
|
33
|
+
HTMLParagraphElement,
|
|
34
|
+
React.HTMLAttributes<HTMLHeadingElement>
|
|
35
|
+
>(({ className, ...props }, ref) => (
|
|
36
|
+
<h3
|
|
37
|
+
ref={ref}
|
|
38
|
+
className={cn(
|
|
39
|
+
"text-2xl font-semibold leading-none tracking-tight",
|
|
40
|
+
className
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
));
|
|
45
|
+
CardTitle.displayName = "CardTitle";
|
|
46
|
+
|
|
47
|
+
const CardDescription = React.forwardRef<
|
|
48
|
+
HTMLParagraphElement,
|
|
49
|
+
React.HTMLAttributes<HTMLParagraphElement>
|
|
50
|
+
>(({ className, ...props }, ref) => (
|
|
51
|
+
<p
|
|
52
|
+
ref={ref}
|
|
53
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
));
|
|
57
|
+
CardDescription.displayName = "CardDescription";
|
|
58
|
+
|
|
59
|
+
const CardContent = React.forwardRef<
|
|
60
|
+
HTMLDivElement,
|
|
61
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
62
|
+
>(({ className, ...props }, ref) => (
|
|
63
|
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
64
|
+
));
|
|
65
|
+
CardContent.displayName = "CardContent";
|
|
66
|
+
|
|
67
|
+
const CardFooter = React.forwardRef<
|
|
68
|
+
HTMLDivElement,
|
|
69
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
70
|
+
>(({ className, ...props }, ref) => (
|
|
71
|
+
<div
|
|
72
|
+
ref={ref}
|
|
73
|
+
className={cn("flex items-center p-6 pt-0", className)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
));
|
|
77
|
+
CardFooter.displayName = "CardFooter";
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
Card,
|
|
81
|
+
CardHeader,
|
|
82
|
+
CardFooter,
|
|
83
|
+
CardTitle,
|
|
84
|
+
CardDescription,
|
|
85
|
+
CardContent,
|
|
86
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
export interface InputProps
|
|
6
|
+
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
|
7
|
+
|
|
8
|
+
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
9
|
+
({ className, type, ...props }, ref) => {
|
|
10
|
+
return (
|
|
11
|
+
<input
|
|
12
|
+
type={type}
|
|
13
|
+
className={cn(
|
|
14
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
15
|
+
className
|
|
16
|
+
)}
|
|
17
|
+
ref={ref}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
Input.displayName = "Input";
|
|
24
|
+
|
|
25
|
+
export { Input };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
const labelVariants = cva(
|
|
8
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const Label = React.forwardRef<
|
|
12
|
+
React.ElementRef<typeof LabelPrimitive.Root>,
|
|
13
|
+
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
|
|
14
|
+
VariantProps<typeof labelVariants>
|
|
15
|
+
>(({ className, ...props }, ref) => (
|
|
16
|
+
<LabelPrimitive.Root
|
|
17
|
+
ref={ref}
|
|
18
|
+
className={cn(labelVariants(), className)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
));
|
|
22
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
23
|
+
|
|
24
|
+
export { Label };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
export interface TextareaProps
|
|
6
|
+
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
|
7
|
+
|
|
8
|
+
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
9
|
+
({ className, ...props }, ref) => {
|
|
10
|
+
return (
|
|
11
|
+
<textarea
|
|
12
|
+
className={cn(
|
|
13
|
+
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
14
|
+
className
|
|
15
|
+
)}
|
|
16
|
+
ref={ref}
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
Textarea.displayName = "Textarea";
|
|
23
|
+
|
|
24
|
+
export { Textarea };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "default",
|
|
4
|
+
"rsc": true,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "tailwind.config.ts",
|
|
8
|
+
"css": "app/globals.css",
|
|
9
|
+
"baseColor": "slate",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"aliases": {
|
|
13
|
+
"components": "@/components",
|
|
14
|
+
"utils": "@/lib/utils"
|
|
15
|
+
}
|
|
16
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1902,6 +1902,9 @@ function createAuthMiddleware(options = {}) {
|
|
|
1902
1902
|
// src/init/setup.ts
|
|
1903
1903
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
1904
1904
|
var import_path3 = __toESM(require("path"));
|
|
1905
|
+
var import_child_process = require("child_process");
|
|
1906
|
+
var import_util = require("util");
|
|
1907
|
+
var execAsync = (0, import_util.promisify)(import_child_process.exec);
|
|
1905
1908
|
async function initCMS(config = {}) {
|
|
1906
1909
|
const contentDir = config.contentDir || "public/content";
|
|
1907
1910
|
const fullPath = import_path3.default.join(process.cwd(), contentDir);
|
|
@@ -1915,6 +1918,48 @@ async function initCMS(config = {}) {
|
|
|
1915
1918
|
return;
|
|
1916
1919
|
}
|
|
1917
1920
|
console.log("\u{1F680} Initializing @fydemy/cms...");
|
|
1921
|
+
console.log("\u{1F4E6} Checking dependencies...");
|
|
1922
|
+
try {
|
|
1923
|
+
const packageJsonPath = import_path3.default.join(process.cwd(), "package.json");
|
|
1924
|
+
const packageJson = JSON.parse(await import_promises2.default.readFile(packageJsonPath, "utf-8"));
|
|
1925
|
+
const dependencies = {
|
|
1926
|
+
...packageJson.dependencies,
|
|
1927
|
+
...packageJson.devDependencies
|
|
1928
|
+
};
|
|
1929
|
+
const missingDeps = [];
|
|
1930
|
+
if (!dependencies["@fydemy/cms"]) missingDeps.push("@fydemy/cms");
|
|
1931
|
+
if (!dependencies["tailwindcss"]) missingDeps.push("tailwindcss");
|
|
1932
|
+
if (!dependencies["class-variance-authority"])
|
|
1933
|
+
missingDeps.push("class-variance-authority");
|
|
1934
|
+
if (!dependencies["clsx"]) missingDeps.push("clsx");
|
|
1935
|
+
if (!dependencies["tailwind-merge"]) missingDeps.push("tailwind-merge");
|
|
1936
|
+
if (!dependencies["@radix-ui/react-slot"])
|
|
1937
|
+
missingDeps.push("@radix-ui/react-slot");
|
|
1938
|
+
if (!dependencies["@radix-ui/react-label"])
|
|
1939
|
+
missingDeps.push("@radix-ui/react-label");
|
|
1940
|
+
if (missingDeps.length > 0) {
|
|
1941
|
+
console.log(
|
|
1942
|
+
`\u{1F527} Installing missing dependencies: ${missingDeps.join(", ")}...`
|
|
1943
|
+
);
|
|
1944
|
+
let installCmd = "npm install";
|
|
1945
|
+
try {
|
|
1946
|
+
await import_promises2.default.access("pnpm-lock.yaml");
|
|
1947
|
+
installCmd = "pnpm add";
|
|
1948
|
+
} catch {
|
|
1949
|
+
try {
|
|
1950
|
+
await import_promises2.default.access("yarn.lock");
|
|
1951
|
+
installCmd = "yarn add";
|
|
1952
|
+
} catch {
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
await execAsync(`${installCmd} ${missingDeps.join(" ")}`);
|
|
1956
|
+
console.log("\u2705 Dependencies installed");
|
|
1957
|
+
}
|
|
1958
|
+
} catch (error) {
|
|
1959
|
+
console.warn(
|
|
1960
|
+
"\u26A0\uFE0F Could not check/install dependencies automatically. Please ensure all dependencies are installed."
|
|
1961
|
+
);
|
|
1962
|
+
}
|
|
1918
1963
|
await import_promises2.default.mkdir(fullPath, { recursive: true });
|
|
1919
1964
|
const exampleContent = `---
|
|
1920
1965
|
title: Example Post
|
|
@@ -1940,23 +1985,55 @@ This is an example markdown file. You can edit or delete it from the admin dashb
|
|
|
1940
1985
|
const adminDir = import_path3.default.join(appDir, "admin");
|
|
1941
1986
|
const loginDir = import_path3.default.join(adminDir, "login");
|
|
1942
1987
|
await import_promises2.default.mkdir(loginDir, { recursive: true });
|
|
1943
|
-
await import_promises2.default.
|
|
1944
|
-
import_path3.default.join(
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1988
|
+
const loginTemplate = await import_promises2.default.readFile(
|
|
1989
|
+
import_path3.default.join(__dirname, "login.template.tsx"),
|
|
1990
|
+
"utf-8"
|
|
1991
|
+
);
|
|
1992
|
+
const adminTemplate = await import_promises2.default.readFile(
|
|
1993
|
+
import_path3.default.join(__dirname, "admin.template.tsx"),
|
|
1994
|
+
"utf-8"
|
|
1995
|
+
);
|
|
1996
|
+
await import_promises2.default.writeFile(import_path3.default.join(adminDir, "page.tsx"), adminTemplate, "utf-8");
|
|
1997
|
+
await import_promises2.default.writeFile(import_path3.default.join(loginDir, "page.tsx"), loginTemplate, "utf-8");
|
|
1998
|
+
console.log("\u2705 Scaffolded Admin UI (shadcn/ui components)");
|
|
1999
|
+
const componentsDir = import_path3.default.join(process.cwd(), "components", "ui");
|
|
2000
|
+
const libDir = import_path3.default.join(process.cwd(), "lib");
|
|
2001
|
+
await import_promises2.default.mkdir(componentsDir, { recursive: true });
|
|
2002
|
+
await import_promises2.default.mkdir(libDir, { recursive: true });
|
|
2003
|
+
const utilsTemplate = await import_promises2.default.readFile(
|
|
2004
|
+
import_path3.default.join(__dirname, "lib", "utils.ts"),
|
|
2005
|
+
"utf-8"
|
|
2006
|
+
);
|
|
2007
|
+
await import_promises2.default.writeFile(import_path3.default.join(libDir, "utils.ts"), utilsTemplate, "utf-8");
|
|
2008
|
+
const componentFiles = [
|
|
2009
|
+
"button.tsx",
|
|
2010
|
+
"input.tsx",
|
|
2011
|
+
"card.tsx",
|
|
2012
|
+
"label.tsx",
|
|
2013
|
+
"textarea.tsx",
|
|
2014
|
+
"badge.tsx"
|
|
2015
|
+
];
|
|
2016
|
+
for (const componentFile of componentFiles) {
|
|
2017
|
+
const componentTemplate = await import_promises2.default.readFile(
|
|
2018
|
+
import_path3.default.join(__dirname, "components", "ui", componentFile),
|
|
2019
|
+
"utf-8"
|
|
2020
|
+
);
|
|
2021
|
+
await import_promises2.default.writeFile(
|
|
2022
|
+
import_path3.default.join(componentsDir, componentFile),
|
|
2023
|
+
componentTemplate,
|
|
2024
|
+
"utf-8"
|
|
2025
|
+
);
|
|
2026
|
+
}
|
|
2027
|
+
const componentsJsonTemplate = await import_promises2.default.readFile(
|
|
2028
|
+
import_path3.default.join(__dirname, "components.json"),
|
|
1949
2029
|
"utf-8"
|
|
1950
2030
|
);
|
|
1951
2031
|
await import_promises2.default.writeFile(
|
|
1952
|
-
import_path3.default.join(
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
export default Login;
|
|
1956
|
-
`,
|
|
2032
|
+
import_path3.default.join(process.cwd(), "components.json"),
|
|
2033
|
+
componentsJsonTemplate,
|
|
1957
2034
|
"utf-8"
|
|
1958
2035
|
);
|
|
1959
|
-
console.log("\u2705
|
|
2036
|
+
console.log("\u2705 Scaffolded shadcn/ui components");
|
|
1960
2037
|
const apiCmsDir = import_path3.default.join(appDir, "api", "cms");
|
|
1961
2038
|
await import_promises2.default.mkdir(import_path3.default.join(apiCmsDir, "login"), { recursive: true });
|
|
1962
2039
|
await import_promises2.default.writeFile(
|
|
@@ -1988,9 +2065,17 @@ export { handleUpload as POST };
|
|
|
1988
2065
|
await import_promises2.default.writeFile(
|
|
1989
2066
|
import_path3.default.join(apiCmsDir, "list", "[[...path]]", "route.ts"),
|
|
1990
2067
|
`import { createListApiHandlers } from '@fydemy/cms';
|
|
2068
|
+
import { NextRequest } from 'next/server';
|
|
1991
2069
|
|
|
1992
2070
|
const handlers = createListApiHandlers();
|
|
1993
|
-
|
|
2071
|
+
|
|
2072
|
+
export async function GET(
|
|
2073
|
+
request: NextRequest,
|
|
2074
|
+
context: { params: Promise<{ path?: string[] }> }
|
|
2075
|
+
) {
|
|
2076
|
+
const params = await context.params;
|
|
2077
|
+
return handlers.GET(request, { params });
|
|
2078
|
+
}
|
|
1994
2079
|
`,
|
|
1995
2080
|
"utf-8"
|
|
1996
2081
|
);
|
|
@@ -2000,11 +2085,33 @@ export const GET = handlers.GET;
|
|
|
2000
2085
|
await import_promises2.default.writeFile(
|
|
2001
2086
|
import_path3.default.join(apiCmsDir, "content", "[...path]", "route.ts"),
|
|
2002
2087
|
`import { createContentApiHandlers } from '@fydemy/cms';
|
|
2088
|
+
import { NextRequest } from 'next/server';
|
|
2003
2089
|
|
|
2004
2090
|
const handlers = createContentApiHandlers();
|
|
2005
|
-
|
|
2006
|
-
export
|
|
2007
|
-
|
|
2091
|
+
|
|
2092
|
+
export async function GET(
|
|
2093
|
+
request: NextRequest,
|
|
2094
|
+
context: { params: Promise<{ path: string[] }> }
|
|
2095
|
+
) {
|
|
2096
|
+
const params = await context.params;
|
|
2097
|
+
return handlers.GET(request, { params });
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
export async function POST(
|
|
2101
|
+
request: NextRequest,
|
|
2102
|
+
context: { params: Promise<{ path: string[] }> }
|
|
2103
|
+
) {
|
|
2104
|
+
const params = await context.params;
|
|
2105
|
+
return handlers.POST(request, { params });
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
export async function DELETE(
|
|
2109
|
+
request: NextRequest,
|
|
2110
|
+
context: { params: Promise<{ path: string[] }> }
|
|
2111
|
+
) {
|
|
2112
|
+
const params = await context.params;
|
|
2113
|
+
return handlers.DELETE(request, { params });
|
|
2114
|
+
}
|
|
2008
2115
|
`,
|
|
2009
2116
|
"utf-8"
|
|
2010
2117
|
);
|
|
@@ -2039,6 +2146,7 @@ export function middleware(request: NextRequest) {
|
|
|
2039
2146
|
|
|
2040
2147
|
export const config = {
|
|
2041
2148
|
matcher: ['/admin/:path*'],
|
|
2149
|
+
runtime: 'nodejs',
|
|
2042
2150
|
};
|
|
2043
2151
|
`,
|
|
2044
2152
|
"utf-8"
|