Skip to content

Commit

Permalink
feat: add some webdav functions (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
clement-berard authored Dec 8, 2024
1 parent f1f4faa commit a234b83
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 28 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ All actions use the same node, you just need to change the action in the node co

Many feature are missing, but the package is growing. Here is the list of the current features:

### `createDirectory`
### `deleteFile`

### `exists`
### `getDirectoryContents`
### `getFileContents`

## Roadmap

Expand Down
1 change: 0 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
}
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": { "noForEach": "off" },
Expand Down
3 changes: 3 additions & 0 deletions src/common/constants-client-side.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const webdavMethods: WebdavMethods[] = [
},
{
methodName: 'createDirectory',
enabled: true,
},
{
methodName: 'createReadStream',
Expand All @@ -33,13 +34,15 @@ export const webdavMethods: WebdavMethods[] = [
},
{
methodName: 'exists',
enabled: true,
},
{
methodName: 'getDirectoryContents',
enabled: true,
},
{
methodName: 'getFileContents',
enabled: true,
},
{
methodName: 'getFileDownloadLink',
Expand Down
18 changes: 17 additions & 1 deletion src/common/validator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as sstruct from 'superstruct';
import type { Infer } from 'superstruct';
import { methodsEnum } from './constants-client-side';

export const methodsSchema = sstruct.enums(methodsEnum);
Expand All @@ -12,11 +11,28 @@ export const actionValidators = {
directory: sstruct.string(),
}),
},
getFileContents: {
schema: sstruct.object({
file: sstruct.string(),
format: sstruct.enums(['text', 'binary']),
}),
},
createDirectory: {
schema: sstruct.object({
directory: sstruct.string(),
recursive: sstruct.optional(sstruct.boolean()),
}),
},
deleteFile: {
schema: sstruct.object({
directory: sstruct.string(),
}),
},
exists: {
schema: sstruct.object({
directory: sstruct.string(),
}),
},
};

export function validateAction(actionName: string, toValidate: Record<string, any>) {
Expand Down
10 changes: 0 additions & 10 deletions src/common/webdavClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@ type GetWebDavClientParams = {
};

export function getWebDavClient(params: GetWebDavClientParams) {
// let basePath = params.basePath || '';
//
// if (basePath === '/') {
// basePath = '';
// }
//
// if (basePath !== '' && basePath.endsWith('/')) {
// basePath = basePath.slice(0, -1);
// }

return createClient(`${params.host}`, {
username: params?.user,
password: params?.password,
Expand Down
31 changes: 29 additions & 2 deletions src/nodes/list/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function (this: NodeControllerInst<NodeListProps>, config: NodeCo
const action = config.action;

const actions = {
getDirectoryContents: (innerPayload: Record<any, any>) => {
getDirectoryContents: (innerPayload: Record<string, unknown>) => {
const [err, resp] = resolveActionData(config, 'getDirectoryContents', innerPayload);
if (err) {
return [err] as const;
Expand All @@ -28,7 +28,34 @@ export default function (this: NodeControllerInst<NodeListProps>, config: NodeCo
const { directory, ...options } = resp || {};
return tryit(webDavClient.getDirectoryContents)(directory || '/', options || {});
},
deleteFile: (innerPayload: Record<any, any>) => {
getFileContents: (innerPayload: Record<string, unknown>) => {
const [err, resp] = resolveActionData(config, 'getFileContents', innerPayload);
if (err) {
return [err] as const;
}

const { file, ...options } = resp || {};
return tryit(webDavClient.getFileContents)(file, options || {});
},
createDirectory: (innerPayload: Record<string, unknown>) => {
const [err, resp] = resolveActionData(config, 'createDirectory', innerPayload);
if (err) {
return [err] as const;
}

const { directory, ...options } = resp || {};
return tryit(webDavClient.createDirectory)(directory, options || {});
},
exists: (innerPayload: Record<string, unknown>) => {
const [err, resp] = resolveActionData(config, 'exists', innerPayload);
if (err) {
return [err] as const;
}

const { directory } = resp || {};
return tryit(webDavClient.exists)(directory);
},
deleteFile: (innerPayload: Record<string, unknown>) => {
const [err, resp] = resolveActionData(config, 'deleteFile', innerPayload);
if (err) {
return [err] as const;
Expand Down
15 changes: 3 additions & 12 deletions src/nodes/list/docs.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
In the node you can list or delete directories/files.
A collection of nodes to manage WebDAV with Node-RED.

### Inputs

: payload (string) : the folder to list or delete.

### Outputs

1. Standard output
: payload (string) : void if delete, list of files and directories if list.

2. Standard error
: payload (string) : the standard error of the command.
_If payload is passed, it will set values passed in the payload.
All other values configured in the node will be ignored._
30 changes: 29 additions & 1 deletion src/nodes/list/editor/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,35 @@
<div class="extra-params deleteFile">
<dxp-form-row label="Directory" type="text" row-id="deleteFile-directory" icon="folder-o">
<div class="hint">
Folder/File. If folder, it must end with a slash.
Folder/File. If folder, it must end with a slash.
</div>
</dxp-form-row>
</div>

<div class="extra-params getFileContents">
<dxp-form-row label="File" type="text" row-id="getFileContents-file" icon="folder"></dxp-form-row>
<div class="dxp-form-row">
<div class="main">
<div>
<label for="node-input-getFileContents-format">Format</label>
</div>
<select id="node-input-getFileContents-format">
<option value="text" selected>text</option>
<option value="binary">binary</option>
</select>
</div>
</div>
</div>

<div class="extra-params createDirectory">
<dxp-form-row label="Directory" type="text" row-id="createDirectory-directory" icon="folder-o"></dxp-form-row>
<dxp-form-row label="Recursive" type="checkbox" row-id="createDirectory-recursive"></dxp-form-row>
</div>

<div class="extra-params exists">
<dxp-form-row label="Directory" type="text" row-id="exists-directory" icon="folder-o">
<div class="hint">
Folder/File. If folder, it must end with a slash.
</div>
</dxp-form-row>
</div>
3 changes: 3 additions & 0 deletions src/nodes/list/editor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ const List = createEditorNode<NodeEditorProps<NodeListProps>>({
action: { value: '' },
getDirectoryContents: { value: {} },
deleteFile: { value: {} },
getFileContents: { value: {} },
createDirectory: { value: {} },
exists: { value: {} },
},
inputs: 1,
outputs: 1,
Expand Down
3 changes: 3 additions & 0 deletions src/nodes/list/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ export interface NodeListProps {
entryType: string;
getDirectoryContents: OrEmpty<Infer<(typeof actionValidators)['getDirectoryContents']['schema']>>;
deleteFile: OrEmpty<Infer<(typeof actionValidators)['deleteFile']['schema']>>;
getFileContents: OrEmpty<Infer<(typeof actionValidators)['getFileContents']['schema']>>;
createDirectory: OrEmpty<Infer<(typeof actionValidators)['createDirectory']['schema']>>;
exists: OrEmpty<Infer<(typeof actionValidators)['exists']['schema']>>;
}

0 comments on commit a234b83

Please sign in to comment.