We're continuing in our list directory route.
We now listed the node files and directories, but we need to make each child as proper node.
Let's get the same Node
type that we did in our React Project and import it.
// src/utils/node.ts
// 👇🏻 import the Node type from the client directory xD
import { Node } from "./../../../client/src/apps/front-office/file-manager/Kernel/Kernel.types";
export type { Node };
/**
* Generate a node object to the given path,
* the given path should be relative to the data directory
*/
export default function makeNode(path: string, children: string[]): Node {
}
Now we imported the same node type from our client directory, we can use it in our server.
Then we created a makeNode
function to generate a new node object, lets do it.
// src/utils/node.ts
// 👇🏻 import the Node type from the client directory xD
import { Node } from "./../../../client/src/apps/front-office/file-manager/Kernel/Kernel.types";
import { isDirectory, size } from "@mongez/fs";
import { dataPath } from "./paths";
export type { Node };
/**
* Generate a node object to the given path,
* the given path should be relative to the data directory
*/
export default function makeNode(path: string, children?: string[]): Node {
// get the full path of the node
const fullPath = dataPath(path);
const node: Node = {
path,
name: path.split("/")?.pop() || "/",
isDirectory: isDirectory(fullPath),
size: size(fullPath),
};
if (node.isDirectory && children?.length) {
node.children = children.map((child) =>
makeNode((path === "/" ? path : path + "/") + child)
);
}
return node;
So the path will be the relative path to data
directory, so if its the root then the path
will be /.
The name will be the last segment of the path so we split the path by /
and get the last segment.
The given children are the children list of the node, so we map over them and generate a new node for each child.
If there are children then we'll loop over them and generate a new node for each child.
Don't forget the given children is list of names for the given node path, so we need to add the child name to the path.
The isDirectory
will be the result of isDirectory
function that we imported from @mongez/fs
package, we need to pass the full path of the node path so we used fullPath
to get the full path using dataPath
.
The size
will be the result of size
function that we imported from @mongez/fs
package, we need to pass the full path of the node path so we used fullPath
to get the full path using dataPath
.
Calling the function
Now let's head to our listDirectory
route and call the makeNode
function.
import fs from "@mongez/fs";
import makeNode from "app/utils/node";
import { dataPath } from "app/utils/paths";
import { Request, Response } from "express";
/**
*List directories
*/
export default async function listDirectory(
request: Request,
response: Response
) {
// get the directory path from the request query string
// let's set `/` as the default path
const path = (request.query.path as string) || "/";
const directoryPath = dataPath(path); // the full path to the directory
if (!fs.isDirectory(directoryPath)) {
return response.status(404).json({
message: "Directory not found",
});
}
// get the directory content
const children = fs.list(directoryPath);
return response.json({
node: makeNode(path, children),
});
}
Now let's run the server and see it again.
Walaa, It works!.
Actually we can always return children with empty array if the node is an array, because we may later add another feature to set the depth of the children, so we can return the children of the children.
// src/utils/node.ts
/**
* Generate a node object to the given path,
* the given path should be relative to the data directory
*/
export default function makeNode(path: string, children?: string[]): Node {
// get the full path of the node
const fullPath = dataPath(path);
const node: Node = {
path,
name: path.split("/")?.pop() || "/",
isDirectory: isDirectory(fullPath),
size: size(fullPath),
};
// 👇🏻 we can always return children with empty array if the node is a directory
if (node.isDirectory) {
node.children = (children || []).map((child) =>
// 👇🏻 we need to check if the path is the root then we will just append it to the child
// if its not the root then we need to append `/` to the path and then append the child
makeNode((path === "/" ? path : path + "/") + child)
);
}
return node;
}
Now we can try any route to check if it works properly.
-
http://localhost:3000/file-manager?path=/
will return the root directory. -
http://localhost:3000/file-manager?path=/Application
will return theApplication
directory.
Next Chapter
In the next chapter we'll implement this api in our React project to make it more real.
Article Repository
You can see chapter files in Github Repository
Don't forget the
main
branch has the latest updated code.
Tell me where you are now
If you're following up with me this series, tell me where are you now and what you're struggling with, i'll try to help you as much as i can.
Salam.
Top comments (0)