@wikex/admin-kit 0.2.2 → 0.4.0

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.
@@ -0,0 +1,23 @@
1
+ type WikexDiscoveredRoute = {
2
+ dynamic: boolean;
3
+ file: string;
4
+ route: string;
5
+ title: string;
6
+ };
7
+ type WikexDiscoveredComponent = {
8
+ editable: boolean;
9
+ file: string;
10
+ name: string;
11
+ };
12
+ type WikexProjectInventory = {
13
+ components: WikexDiscoveredComponent[];
14
+ routes: WikexDiscoveredRoute[];
15
+ };
16
+ type ScanWikexProjectOptions = {
17
+ appDirectory?: string;
18
+ componentsDirectory?: string;
19
+ cwd?: string;
20
+ };
21
+ declare const scanWikexProject: ({ appDirectory, componentsDirectory, cwd, }?: ScanWikexProjectOptions) => Promise<WikexProjectInventory>;
22
+
23
+ export { type ScanWikexProjectOptions, type WikexDiscoveredComponent, type WikexDiscoveredRoute, type WikexProjectInventory, scanWikexProject };
@@ -0,0 +1,72 @@
1
+ // src/scanner.ts
2
+ import { readdir, readFile } from "fs/promises";
3
+ import path from "path";
4
+ var walk = async (directory) => {
5
+ try {
6
+ const entries = await readdir(directory, { withFileTypes: true });
7
+ const files = await Promise.all(
8
+ entries.map((entry) => {
9
+ const target = path.join(directory, entry.name);
10
+ return entry.isDirectory() ? walk(target) : Promise.resolve([target]);
11
+ })
12
+ );
13
+ return files.flat();
14
+ } catch (error) {
15
+ if (error.code === "ENOENT") return [];
16
+ throw error;
17
+ }
18
+ };
19
+ var routeTitle = (route) => {
20
+ if (route === "/") return "Trang ch\u1EE7";
21
+ return route.split("/").filter(Boolean).at(-1).replace(/\[(?:\.\.\.)?([^\]]+)\]/g, "$1").replace(/[-_]/g, " ").replace(/\b\p{L}/gu, (letter) => letter.toUpperCase());
22
+ };
23
+ var exportedComponentNames = (source, fallback) => {
24
+ const names = /* @__PURE__ */ new Set();
25
+ for (const match of source.matchAll(/export\s+(?:default\s+)?(?:async\s+)?function\s+([A-Z]\w*)/g)) {
26
+ names.add(match[1]);
27
+ }
28
+ for (const match of source.matchAll(/export\s+const\s+([A-Z]\w*)\s*=/g)) {
29
+ names.add(match[1]);
30
+ }
31
+ const defaultMatch = source.match(/export\s+default\s+([A-Z]\w*)/);
32
+ if (defaultMatch) names.add(defaultMatch[1] || fallback);
33
+ return [...names];
34
+ };
35
+ var scanWikexProject = async ({
36
+ appDirectory = "src/app",
37
+ componentsDirectory = "src/components",
38
+ cwd = process.cwd()
39
+ } = {}) => {
40
+ const appRoot = path.resolve(cwd, appDirectory);
41
+ const componentRoot = path.resolve(cwd, componentsDirectory);
42
+ const [appFiles, componentFiles] = await Promise.all([walk(appRoot), walk(componentRoot)]);
43
+ const routes = appFiles.filter((file) => /[/\\]page\.(?:tsx?|jsx?)$/.test(file)).map((file) => {
44
+ const relative = path.relative(appRoot, file).replace(/\\/g, "/");
45
+ const directory = relative.replace(/(?:^|\/)page\.(?:tsx?|jsx?)$/, "");
46
+ const segments = directory.split("/").filter((segment) => segment && !/^\(.+\)$/.test(segment) && !segment.startsWith("@"));
47
+ const route = `/${segments.join("/")}`.replace(/\/$/, "") || "/";
48
+ return {
49
+ dynamic: route.includes("["),
50
+ file: relative,
51
+ route,
52
+ title: routeTitle(route)
53
+ };
54
+ }).filter(({ route }) => !route.startsWith("/admin")).sort((left, right) => left.route.localeCompare(right.route));
55
+ const components = (await Promise.all(
56
+ componentFiles.filter((file) => /\.(?:tsx|jsx)$/.test(file)).map(async (file) => {
57
+ const relative = path.relative(componentRoot, file).replace(/\\/g, "/");
58
+ const source = await readFile(file, "utf8");
59
+ const fallback = path.basename(file).replace(/\.wikex\.(?:tsx|jsx)$|\.(?:tsx|jsx)$/g, "");
60
+ const editable = /\.wikex\.(?:tsx|jsx)$/.test(file) || /\bdefineWikexBlock\s*\(/.test(source);
61
+ return exportedComponentNames(source, fallback).map((name) => ({
62
+ editable,
63
+ file: relative,
64
+ name
65
+ }));
66
+ })
67
+ )).flat().sort((left, right) => left.name.localeCompare(right.name) || left.file.localeCompare(right.file));
68
+ return { components, routes };
69
+ };
70
+ export {
71
+ scanWikexProject
72
+ };
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  "use client";
3
- import "./chunk-SM6CCKQQ.js";
3
+ import "./chunk-AY7N3B45.js";
4
4
  import {
5
5
  configureAdminBrand
6
6
  } from "./chunk-X7VETFVD.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wikex/admin-kit",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "Reusable Payload CMS admin shell, visual editor and typography tools for Wikex projects",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -36,6 +36,7 @@
36
36
  "./project": "./dist/project.js",
37
37
  "./rich-text": "./dist/rich-text.js",
38
38
  "./rich-text/client": "./dist/rich-text-client.js",
39
+ "./scanner": "./dist/scanner.js",
39
40
  "./starter": "./dist/starter.js",
40
41
  "./starter/client": "./dist/starter-client.js",
41
42
  "./styles": "./src/styles/admin.scss",