@unciatech/file-manager 0.0.20 → 0.0.25
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 +6 -11
- package/dist/cli.cjs +325 -0
- package/dist/cli.js +140 -22
- package/dist/index.cjs +7837 -0
- package/dist/{index.d.mts → index.d.cts} +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +7712 -23
- package/dist/{file-manager-4KJI2OA3.d.mts → mock-provider-nCBvw7nl.d.cts} +57 -1
- package/dist/{file-manager-4KJI2OA3.d.ts → mock-provider-nCBvw7nl.d.ts} +57 -1
- package/dist/mock.cjs +1395 -0
- package/dist/mock.d.cts +1 -0
- package/dist/mock.d.ts +1 -38
- package/dist/mock.js +1361 -2
- package/package.json +43 -23
- package/dist/chunk-4DQRTTKI.mjs +0 -18
- package/dist/chunk-S4HRPNKF.js +0 -18
- package/dist/cli.mjs +0 -184
- package/dist/index.mjs +0 -100
- package/dist/mock.d.mts +0 -38
- package/dist/mock.mjs +0 -2
- /package/dist/{cli.d.mts → cli.d.cts} +0 -0
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
IFileManagerProvider,
|
|
83
83
|
FolderId,
|
|
84
84
|
FileUploadInput
|
|
85
|
-
} from "@/types/file-manager";
|
|
85
|
+
} from "@/types/file-manager"; // Or "@unciatech/file-manager" for external users
|
|
86
86
|
|
|
87
87
|
export class MyCustomApiProvider implements IFileManagerProvider {
|
|
88
88
|
private baseUrl = "https://api.mybackend.com/v1";
|
|
@@ -126,24 +126,19 @@ export class MyCustomApiProvider implements IFileManagerProvider {
|
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
> **💡 Pro Tip - The Mock Provider:**
|
|
129
|
-
> If you are just prototyping and don't have a backend ready yet, you can skip Step 2 entirely! We included a fully functional `
|
|
129
|
+
> If you are just prototyping and don't have a backend ready yet, you can skip Step 2 entirely! We included a fully functional `MockProvider` that fakes network latency and stores data in memory. Just import it and use it right away to see the UI in action.
|
|
130
130
|
|
|
131
|
-
### Step 3: Wrap Your Page with the Provider
|
|
132
|
-
|
|
133
|
-
Finally, import your provider and wrap the `<FileManager />` component in the Context Provider. Define which file types you want to allow.
|
|
134
|
-
|
|
135
|
-
```tsx
|
|
136
131
|
// app/media/page.tsx
|
|
137
132
|
import { FileManagerProvider } from "@/context/file-manager-context";
|
|
138
133
|
import { FileManager } from "@/components/file-manager";
|
|
134
|
+
import { MockProvider } from "@/providers/mock-provider";
|
|
139
135
|
|
|
140
|
-
//
|
|
136
|
+
// OR import your real provider
|
|
141
137
|
import { MyCustomApiProvider } from "@/lib/my-api-provider";
|
|
142
|
-
// import { MockFileManagerProvider } from "@/providers/mock-provider";
|
|
143
138
|
|
|
144
139
|
export default function MediaLibraryPage() {
|
|
145
|
-
// Instantiate the provider
|
|
146
|
-
const apiProvider = new
|
|
140
|
+
// Instantiate the provider (Real or Mock)
|
|
141
|
+
const apiProvider = new MockProvider();
|
|
147
142
|
|
|
148
143
|
return (
|
|
149
144
|
<div className="h-screen w-full">
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// cli.ts
|
|
27
|
+
var import_fs = __toESM(require("fs"), 1);
|
|
28
|
+
var import_path = __toESM(require("path"), 1);
|
|
29
|
+
var import_child_process = require("child_process");
|
|
30
|
+
var import_readline = __toESM(require("readline"), 1);
|
|
31
|
+
var args = process.argv.slice(2);
|
|
32
|
+
var command = args[0];
|
|
33
|
+
var projectName = args[1];
|
|
34
|
+
var rl = import_readline.default.createInterface({
|
|
35
|
+
input: process.stdin,
|
|
36
|
+
output: process.stdout
|
|
37
|
+
});
|
|
38
|
+
var askQuestion = (query) => {
|
|
39
|
+
return new Promise((resolve) => rl.question(query, resolve));
|
|
40
|
+
};
|
|
41
|
+
var TEMPLATE = `"use client";
|
|
42
|
+
|
|
43
|
+
import React, { Suspense } from "react";
|
|
44
|
+
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
45
|
+
|
|
46
|
+
export default function FileManagerDemo() {
|
|
47
|
+
const mockProvider = new MockProvider();
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div className="h-screen w-full">
|
|
51
|
+
<Suspense fallback={<div className="p-4">Loading Media Library...</div>}>
|
|
52
|
+
<FileManager
|
|
53
|
+
allowedFileTypes={["audios", "videos", "images", "files"]}
|
|
54
|
+
viewMode="grid"
|
|
55
|
+
provider={mockProvider}
|
|
56
|
+
/>
|
|
57
|
+
</Suspense>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
async function main() {
|
|
63
|
+
if (command !== "init") {
|
|
64
|
+
console.log("Usage: npx @unciatech/file-manager init [project-name]");
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
if (!projectName) {
|
|
68
|
+
console.log("\u{1F680} Generating <FileManagerDemo /> component in the current project...");
|
|
69
|
+
let targetDir2 = process.cwd();
|
|
70
|
+
if (import_fs.default.existsSync(import_path.default.join(process.cwd(), "components"))) {
|
|
71
|
+
targetDir2 = import_path.default.join(process.cwd(), "components");
|
|
72
|
+
} else if (import_fs.default.existsSync(import_path.default.join(process.cwd(), "src", "components"))) {
|
|
73
|
+
targetDir2 = import_path.default.join(process.cwd(), "src", "components");
|
|
74
|
+
}
|
|
75
|
+
const targetFile = import_path.default.join(targetDir2, "FileManagerDemo.tsx");
|
|
76
|
+
if (import_fs.default.existsSync(targetFile)) {
|
|
77
|
+
console.error(`\u274C Error: ${targetFile} already exists.`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
import_fs.default.writeFileSync(targetFile, TEMPLATE, "utf-8");
|
|
81
|
+
console.log(`\u2705 Success! Created ${targetFile}`);
|
|
82
|
+
console.log("");
|
|
83
|
+
console.log("You can now import and render <FileManagerDemo /> anywhere in your application.");
|
|
84
|
+
console.log("Don't forget to configure your Tailwind CSS content to scan the library for styles!");
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
console.log(`
|
|
88
|
+
\u{1F680} Initializing a new application: ${projectName}
|
|
89
|
+
`);
|
|
90
|
+
console.log("Which framework would you like to use?");
|
|
91
|
+
console.log(" 1) Next.js (App Router, Tailwind v4)");
|
|
92
|
+
console.log(" 2) Vite (React, Tailwind v4)");
|
|
93
|
+
console.log(" 3) Cancel");
|
|
94
|
+
const choice = await askQuestion("\nSelect an option (1-3): ");
|
|
95
|
+
const targetDir = import_path.default.join(process.cwd(), projectName);
|
|
96
|
+
if (import_fs.default.existsSync(targetDir)) {
|
|
97
|
+
console.error(`
|
|
98
|
+
\u274C Error: Directory "${projectName}" already exists in ${process.cwd()}.`);
|
|
99
|
+
console.error(` Please choose a different project name or delete the existing directory first.`);
|
|
100
|
+
rl.close();
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
if (choice === "1") {
|
|
105
|
+
await scaffoldNextjs(projectName, targetDir);
|
|
106
|
+
} else if (choice === "2") {
|
|
107
|
+
await scaffoldVite(projectName, targetDir);
|
|
108
|
+
} else {
|
|
109
|
+
console.log("Canceled.");
|
|
110
|
+
process.exit(0);
|
|
111
|
+
}
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error("\n\u274C Scaffolding failed:", error);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
process.exit(0);
|
|
117
|
+
}
|
|
118
|
+
async function scaffoldNextjs(projectName2, targetDir) {
|
|
119
|
+
console.log("\n\u{1F4E6} Creating Next.js application (this may take a minute)...");
|
|
120
|
+
(0, import_child_process.execSync)(`npx create-next-app@latest ${projectName2} --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm`, { stdio: "inherit" });
|
|
121
|
+
console.log("\n\u{1F4E6} Installing dependencies (@unciatech/file-manager, tailwindcss-animate)...");
|
|
122
|
+
(0, import_child_process.execSync)("npm install @unciatech/file-manager tailwindcss-animate", { cwd: targetDir, stdio: "inherit" });
|
|
123
|
+
const componentsDir = import_path.default.join(targetDir, "src", "components");
|
|
124
|
+
if (!import_fs.default.existsSync(componentsDir)) import_fs.default.mkdirSync(componentsDir, { recursive: true });
|
|
125
|
+
import_fs.default.writeFileSync(import_path.default.join(componentsDir, "FileManagerDemo.tsx"), TEMPLATE, "utf-8");
|
|
126
|
+
const pagePath = import_path.default.join(targetDir, "src", "app", "page.tsx");
|
|
127
|
+
import_fs.default.writeFileSync(pagePath, `import FileManagerDemo from "@/components/FileManagerDemo";
|
|
128
|
+
|
|
129
|
+
export default function Home() {
|
|
130
|
+
return (
|
|
131
|
+
<main className="min-h-screen bg-neutral-50">
|
|
132
|
+
<FileManagerDemo />
|
|
133
|
+
</main>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
`);
|
|
137
|
+
const mediaRouteDir = import_path.default.join(targetDir, "src", "app", "media", "[[...path]]");
|
|
138
|
+
import_fs.default.mkdirSync(mediaRouteDir, { recursive: true });
|
|
139
|
+
import_fs.default.writeFileSync(
|
|
140
|
+
import_path.default.join(mediaRouteDir, "page.tsx"),
|
|
141
|
+
`import FileManagerDemo from "@/components/FileManagerDemo";
|
|
142
|
+
|
|
143
|
+
export default function MediaPage() {
|
|
144
|
+
return (
|
|
145
|
+
<main className="min-h-screen bg-neutral-50">
|
|
146
|
+
<FileManagerDemo />
|
|
147
|
+
</main>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
`
|
|
151
|
+
);
|
|
152
|
+
const layoutPath = import_path.default.join(targetDir, "src", "app", "layout.tsx");
|
|
153
|
+
if (import_fs.default.existsSync(layoutPath)) {
|
|
154
|
+
let layoutContent = import_fs.default.readFileSync(layoutPath, "utf8");
|
|
155
|
+
if (!layoutContent.includes("@unciatech/file-manager/styles")) {
|
|
156
|
+
layoutContent = layoutContent.replace(
|
|
157
|
+
/^(import type)/m,
|
|
158
|
+
`import '@unciatech/file-manager/styles';
|
|
159
|
+
$1`
|
|
160
|
+
);
|
|
161
|
+
import_fs.default.writeFileSync(layoutPath, layoutContent);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const cssPath = import_path.default.join(targetDir, "src", "app", "globals.css");
|
|
165
|
+
import_fs.default.writeFileSync(cssPath, `@import 'tailwindcss';
|
|
166
|
+
@import 'tw-animate-css';
|
|
167
|
+
@source "../../node_modules/@unciatech/file-manager/dist";
|
|
168
|
+
|
|
169
|
+
/** Dark Mode Variant **/
|
|
170
|
+
@custom-variant dark (&:is(.dark *));
|
|
171
|
+
|
|
172
|
+
@theme {
|
|
173
|
+
--font-sans: 'Geist', 'Geist Fallback', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
174
|
+
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Colors **/
|
|
178
|
+
:root {
|
|
179
|
+
--background: var(--color-white);
|
|
180
|
+
--foreground: var(--color-zinc-950);
|
|
181
|
+
--card: var(--color-white);
|
|
182
|
+
--card-foreground: var(--color-zinc-950);
|
|
183
|
+
--popover: var(--color-white);
|
|
184
|
+
--popover-foreground: var(--color-zinc-950);
|
|
185
|
+
--primary: var(--color-blue-500);
|
|
186
|
+
--primary-foreground: var(--color-white);
|
|
187
|
+
--secondary: var(--color-zinc-100);
|
|
188
|
+
--secondary-foreground: var(--color-zinc-900);
|
|
189
|
+
--muted: var(--color-zinc-100);
|
|
190
|
+
--muted-foreground: var(--color-zinc-500);
|
|
191
|
+
--accent: var(--color-zinc-100);
|
|
192
|
+
--accent-foreground: var(--color-zinc-900);
|
|
193
|
+
--destructive: var(--color-red-600);
|
|
194
|
+
--destructive-foreground: var(--color-white);
|
|
195
|
+
--border: oklch(94% 0.004 286.32);
|
|
196
|
+
--input: var(--color-zinc-200);
|
|
197
|
+
--ring: var(--color-zinc-400);
|
|
198
|
+
--radius: 0.5rem;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.dark {
|
|
202
|
+
--background: var(--color-zinc-950);
|
|
203
|
+
--foreground: var(--color-zinc-50);
|
|
204
|
+
--card: var(--color-zinc-950);
|
|
205
|
+
--card-foreground: var(--color-zinc-50);
|
|
206
|
+
--popover: var(--color-zinc-950);
|
|
207
|
+
--popover-foreground: var(--color-zinc-50);
|
|
208
|
+
--primary: var(--color-blue-600);
|
|
209
|
+
--primary-foreground: var(--color-white);
|
|
210
|
+
--secondary: var(--color-zinc-800);
|
|
211
|
+
--secondary-foreground: var(--color-zinc-50);
|
|
212
|
+
--muted: var(--color-zinc-900);
|
|
213
|
+
--muted-foreground: var(--color-zinc-500);
|
|
214
|
+
--accent: var(--color-zinc-900);
|
|
215
|
+
--accent-foreground: var(--color-zinc-50);
|
|
216
|
+
--destructive: var(--color-red-600);
|
|
217
|
+
--destructive-foreground: var(--color-white);
|
|
218
|
+
--border: var(--color-zinc-800);
|
|
219
|
+
--input: var(--color-zinc-800);
|
|
220
|
+
--ring: var(--color-zinc-600);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** Theme Setup **/
|
|
224
|
+
@theme inline {
|
|
225
|
+
--color-background: var(--background);
|
|
226
|
+
--color-foreground: var(--foreground);
|
|
227
|
+
--color-card: var(--card);
|
|
228
|
+
--color-card-foreground: var(--card-foreground);
|
|
229
|
+
--color-popover: var(--popover);
|
|
230
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
231
|
+
--color-muted: var(--muted);
|
|
232
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
233
|
+
--color-accent: var(--accent);
|
|
234
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
235
|
+
--color-primary: var(--primary);
|
|
236
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
237
|
+
--color-secondary: var(--secondary);
|
|
238
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
239
|
+
--color-destructive: var(--destructive);
|
|
240
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
241
|
+
--color-border: var(--border);
|
|
242
|
+
--color-input: var(--input);
|
|
243
|
+
--color-ring: var(--ring);
|
|
244
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
245
|
+
--radius-lg: var(--radius);
|
|
246
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
247
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Global Styles **/
|
|
251
|
+
@layer base {
|
|
252
|
+
* {
|
|
253
|
+
@apply border-border;
|
|
254
|
+
}
|
|
255
|
+
*:focus-visible {
|
|
256
|
+
@apply outline-ring rounded-xs shadow-none outline-2 outline-offset-3 transition-none!;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/** Custom Scrollbar **/
|
|
261
|
+
@layer base {
|
|
262
|
+
::-webkit-scrollbar { width: 5px; }
|
|
263
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
264
|
+
::-webkit-scrollbar-thumb { background: var(--input); border-radius: 5px; }
|
|
265
|
+
* { scrollbar-width: thin; scrollbar-color: var(--input) transparent; }
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Smooth scroll **/
|
|
269
|
+
html {
|
|
270
|
+
scroll-behavior: smooth;
|
|
271
|
+
}
|
|
272
|
+
`);
|
|
273
|
+
printSuccess(projectName2);
|
|
274
|
+
}
|
|
275
|
+
async function scaffoldVite(projectName2, targetDir) {
|
|
276
|
+
console.log("\n\u{1F4E6} Creating Vite React application...");
|
|
277
|
+
(0, import_child_process.execSync)(`npm create vite@latest ${projectName2} -- --template react-ts`, { stdio: "inherit" });
|
|
278
|
+
console.log("\n\u{1F4E6} Installing dependencies (Tailwind + File Manager)...");
|
|
279
|
+
(0, import_child_process.execSync)("npm install", { cwd: targetDir, stdio: "inherit" });
|
|
280
|
+
(0, import_child_process.execSync)("npm install tailwindcss @tailwindcss/vite @unciatech/file-manager", { cwd: targetDir, stdio: "inherit" });
|
|
281
|
+
const viteConfigPath = import_path.default.join(targetDir, "vite.config.ts");
|
|
282
|
+
const viteConfig = `import { defineConfig } from 'vite'
|
|
283
|
+
import react from '@vitejs/plugin-react'
|
|
284
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
285
|
+
|
|
286
|
+
export default defineConfig({
|
|
287
|
+
plugins: [
|
|
288
|
+
react(),
|
|
289
|
+
tailwindcss(),
|
|
290
|
+
],
|
|
291
|
+
})
|
|
292
|
+
`;
|
|
293
|
+
import_fs.default.writeFileSync(viteConfigPath, viteConfig);
|
|
294
|
+
const cssPath = import_path.default.join(targetDir, "src", "index.css");
|
|
295
|
+
import_fs.default.writeFileSync(cssPath, `@import "tailwindcss";
|
|
296
|
+
@source "../../node_modules/@unciatech/file-manager/dist";
|
|
297
|
+
`);
|
|
298
|
+
const componentsDir = import_path.default.join(targetDir, "src", "components");
|
|
299
|
+
if (!import_fs.default.existsSync(componentsDir)) import_fs.default.mkdirSync(componentsDir, { recursive: true });
|
|
300
|
+
import_fs.default.writeFileSync(import_path.default.join(componentsDir, "FileManagerDemo.tsx"), TEMPLATE, "utf-8");
|
|
301
|
+
const appPath = import_path.default.join(targetDir, "src", "App.tsx");
|
|
302
|
+
import_fs.default.writeFileSync(appPath, `import FileManagerDemo from "./components/FileManagerDemo";
|
|
303
|
+
|
|
304
|
+
function App() {
|
|
305
|
+
return (
|
|
306
|
+
<div className="min-h-screen bg-neutral-50">
|
|
307
|
+
<FileManagerDemo />
|
|
308
|
+
</div>
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export default App;
|
|
313
|
+
`);
|
|
314
|
+
printSuccess(projectName2, "npm run dev");
|
|
315
|
+
}
|
|
316
|
+
function printSuccess(projectName2, devCmd = "npm run dev") {
|
|
317
|
+
console.log("\n=========================================");
|
|
318
|
+
console.log("\u{1F389} Your Media Library application is ready!");
|
|
319
|
+
console.log("=========================================");
|
|
320
|
+
console.log("\nNext steps:");
|
|
321
|
+
console.log(` cd ${projectName2}`);
|
|
322
|
+
console.log(` ${devCmd}`);
|
|
323
|
+
console.log("\nEnjoy building! \u{1F5C2}\uFE0F\n");
|
|
324
|
+
}
|
|
325
|
+
main();
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// cli.ts
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
import readline from "readline";
|
|
8
|
+
var args = process.argv.slice(2);
|
|
9
|
+
var command = args[0];
|
|
10
|
+
var projectName = args[1];
|
|
11
|
+
var rl = readline.createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output: process.stdout
|
|
14
|
+
});
|
|
15
|
+
var askQuestion = (query) => {
|
|
16
|
+
return new Promise((resolve) => rl.question(query, resolve));
|
|
17
|
+
};
|
|
18
|
+
var TEMPLATE = `"use client";
|
|
3
19
|
|
|
4
20
|
import React, { Suspense } from "react";
|
|
5
21
|
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
@@ -19,14 +35,73 @@ export default function FileManagerDemo() {
|
|
|
19
35
|
</div>
|
|
20
36
|
);
|
|
21
37
|
}
|
|
22
|
-
`;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
\u{
|
|
38
|
+
`;
|
|
39
|
+
async function main() {
|
|
40
|
+
if (command !== "init") {
|
|
41
|
+
console.log("Usage: npx @unciatech/file-manager init [project-name]");
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
if (!projectName) {
|
|
45
|
+
console.log("\u{1F680} Generating <FileManagerDemo /> component in the current project...");
|
|
46
|
+
let targetDir2 = process.cwd();
|
|
47
|
+
if (fs.existsSync(path.join(process.cwd(), "components"))) {
|
|
48
|
+
targetDir2 = path.join(process.cwd(), "components");
|
|
49
|
+
} else if (fs.existsSync(path.join(process.cwd(), "src", "components"))) {
|
|
50
|
+
targetDir2 = path.join(process.cwd(), "src", "components");
|
|
51
|
+
}
|
|
52
|
+
const targetFile = path.join(targetDir2, "FileManagerDemo.tsx");
|
|
53
|
+
if (fs.existsSync(targetFile)) {
|
|
54
|
+
console.error(`\u274C Error: ${targetFile} already exists.`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
fs.writeFileSync(targetFile, TEMPLATE, "utf-8");
|
|
58
|
+
console.log(`\u2705 Success! Created ${targetFile}`);
|
|
59
|
+
console.log("");
|
|
60
|
+
console.log("You can now import and render <FileManagerDemo /> anywhere in your application.");
|
|
61
|
+
console.log("Don't forget to configure your Tailwind CSS content to scan the library for styles!");
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
console.log(`
|
|
65
|
+
\u{1F680} Initializing a new application: ${projectName}
|
|
66
|
+
`);
|
|
67
|
+
console.log("Which framework would you like to use?");
|
|
68
|
+
console.log(" 1) Next.js (App Router, Tailwind v4)");
|
|
69
|
+
console.log(" 2) Vite (React, Tailwind v4)");
|
|
70
|
+
console.log(" 3) Cancel");
|
|
71
|
+
const choice = await askQuestion("\nSelect an option (1-3): ");
|
|
72
|
+
const targetDir = path.join(process.cwd(), projectName);
|
|
73
|
+
if (fs.existsSync(targetDir)) {
|
|
74
|
+
console.error(`
|
|
75
|
+
\u274C Error: Directory "${projectName}" already exists in ${process.cwd()}.`);
|
|
76
|
+
console.error(` Please choose a different project name or delete the existing directory first.`);
|
|
77
|
+
rl.close();
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
if (choice === "1") {
|
|
82
|
+
await scaffoldNextjs(projectName, targetDir);
|
|
83
|
+
} else if (choice === "2") {
|
|
84
|
+
await scaffoldVite(projectName, targetDir);
|
|
85
|
+
} else {
|
|
86
|
+
console.log("Canceled.");
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error("\n\u274C Scaffolding failed:", error);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
process.exit(0);
|
|
94
|
+
}
|
|
95
|
+
async function scaffoldNextjs(projectName2, targetDir) {
|
|
96
|
+
console.log("\n\u{1F4E6} Creating Next.js application (this may take a minute)...");
|
|
97
|
+
execSync(`npx create-next-app@latest ${projectName2} --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm`, { stdio: "inherit" });
|
|
98
|
+
console.log("\n\u{1F4E6} Installing dependencies (@unciatech/file-manager, tailwindcss-animate)...");
|
|
99
|
+
execSync("npm install @unciatech/file-manager tailwindcss-animate", { cwd: targetDir, stdio: "inherit" });
|
|
100
|
+
const componentsDir = path.join(targetDir, "src", "components");
|
|
101
|
+
if (!fs.existsSync(componentsDir)) fs.mkdirSync(componentsDir, { recursive: true });
|
|
102
|
+
fs.writeFileSync(path.join(componentsDir, "FileManagerDemo.tsx"), TEMPLATE, "utf-8");
|
|
103
|
+
const pagePath = path.join(targetDir, "src", "app", "page.tsx");
|
|
104
|
+
fs.writeFileSync(pagePath, `import FileManagerDemo from "@/components/FileManagerDemo";
|
|
30
105
|
|
|
31
106
|
export default function Home() {
|
|
32
107
|
return (
|
|
@@ -35,7 +110,12 @@ export default function Home() {
|
|
|
35
110
|
</main>
|
|
36
111
|
);
|
|
37
112
|
}
|
|
38
|
-
`);
|
|
113
|
+
`);
|
|
114
|
+
const mediaRouteDir = path.join(targetDir, "src", "app", "media", "[[...path]]");
|
|
115
|
+
fs.mkdirSync(mediaRouteDir, { recursive: true });
|
|
116
|
+
fs.writeFileSync(
|
|
117
|
+
path.join(mediaRouteDir, "page.tsx"),
|
|
118
|
+
`import FileManagerDemo from "@/components/FileManagerDemo";
|
|
39
119
|
|
|
40
120
|
export default function MediaPage() {
|
|
41
121
|
return (
|
|
@@ -44,8 +124,22 @@ export default function MediaPage() {
|
|
|
44
124
|
</main>
|
|
45
125
|
);
|
|
46
126
|
}
|
|
47
|
-
`
|
|
48
|
-
|
|
127
|
+
`
|
|
128
|
+
);
|
|
129
|
+
const layoutPath = path.join(targetDir, "src", "app", "layout.tsx");
|
|
130
|
+
if (fs.existsSync(layoutPath)) {
|
|
131
|
+
let layoutContent = fs.readFileSync(layoutPath, "utf8");
|
|
132
|
+
if (!layoutContent.includes("@unciatech/file-manager/styles")) {
|
|
133
|
+
layoutContent = layoutContent.replace(
|
|
134
|
+
/^(import type)/m,
|
|
135
|
+
`import '@unciatech/file-manager/styles';
|
|
136
|
+
$1`
|
|
137
|
+
);
|
|
138
|
+
fs.writeFileSync(layoutPath, layoutContent);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const cssPath = path.join(targetDir, "src", "app", "globals.css");
|
|
142
|
+
fs.writeFileSync(cssPath, `@import 'tailwindcss';
|
|
49
143
|
@import 'tw-animate-css';
|
|
50
144
|
@source "../../node_modules/@unciatech/file-manager/dist";
|
|
51
145
|
|
|
@@ -152,9 +246,17 @@ $1`),e__default.default.writeFileSync(a,d));}let u=r__default.default.join(o,"sr
|
|
|
152
246
|
html {
|
|
153
247
|
scroll-behavior: smooth;
|
|
154
248
|
}
|
|
155
|
-
`)
|
|
156
|
-
|
|
157
|
-
|
|
249
|
+
`);
|
|
250
|
+
printSuccess(projectName2);
|
|
251
|
+
}
|
|
252
|
+
async function scaffoldVite(projectName2, targetDir) {
|
|
253
|
+
console.log("\n\u{1F4E6} Creating Vite React application...");
|
|
254
|
+
execSync(`npm create vite@latest ${projectName2} -- --template react-ts`, { stdio: "inherit" });
|
|
255
|
+
console.log("\n\u{1F4E6} Installing dependencies (Tailwind + File Manager)...");
|
|
256
|
+
execSync("npm install", { cwd: targetDir, stdio: "inherit" });
|
|
257
|
+
execSync("npm install tailwindcss @tailwindcss/vite @unciatech/file-manager", { cwd: targetDir, stdio: "inherit" });
|
|
258
|
+
const viteConfigPath = path.join(targetDir, "vite.config.ts");
|
|
259
|
+
const viteConfig = `import { defineConfig } from 'vite'
|
|
158
260
|
import react from '@vitejs/plugin-react'
|
|
159
261
|
import tailwindcss from '@tailwindcss/vite'
|
|
160
262
|
|
|
@@ -164,9 +266,17 @@ export default defineConfig({
|
|
|
164
266
|
tailwindcss(),
|
|
165
267
|
],
|
|
166
268
|
})
|
|
167
|
-
|
|
269
|
+
`;
|
|
270
|
+
fs.writeFileSync(viteConfigPath, viteConfig);
|
|
271
|
+
const cssPath = path.join(targetDir, "src", "index.css");
|
|
272
|
+
fs.writeFileSync(cssPath, `@import "tailwindcss";
|
|
168
273
|
@source "../../node_modules/@unciatech/file-manager/dist";
|
|
169
|
-
`);
|
|
274
|
+
`);
|
|
275
|
+
const componentsDir = path.join(targetDir, "src", "components");
|
|
276
|
+
if (!fs.existsSync(componentsDir)) fs.mkdirSync(componentsDir, { recursive: true });
|
|
277
|
+
fs.writeFileSync(path.join(componentsDir, "FileManagerDemo.tsx"), TEMPLATE, "utf-8");
|
|
278
|
+
const appPath = path.join(targetDir, "src", "App.tsx");
|
|
279
|
+
fs.writeFileSync(appPath, `import FileManagerDemo from "./components/FileManagerDemo";
|
|
170
280
|
|
|
171
281
|
function App() {
|
|
172
282
|
return (
|
|
@@ -177,8 +287,16 @@ function App() {
|
|
|
177
287
|
}
|
|
178
288
|
|
|
179
289
|
export default App;
|
|
180
|
-
`)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
290
|
+
`);
|
|
291
|
+
printSuccess(projectName2, "npm run dev");
|
|
292
|
+
}
|
|
293
|
+
function printSuccess(projectName2, devCmd = "npm run dev") {
|
|
294
|
+
console.log("\n=========================================");
|
|
295
|
+
console.log("\u{1F389} Your Media Library application is ready!");
|
|
296
|
+
console.log("=========================================");
|
|
297
|
+
console.log("\nNext steps:");
|
|
298
|
+
console.log(` cd ${projectName2}`);
|
|
299
|
+
console.log(` ${devCmd}`);
|
|
300
|
+
console.log("\nEnjoy building! \u{1F5C2}\uFE0F\n");
|
|
301
|
+
}
|
|
302
|
+
main();
|