Comparing version 2.0.2 to 2.1.0
187
CHANGELOG.md
@@ -0,24 +1,67 @@ | ||
## 2.1.0 / 2024-07-23 | ||
- Re-init `package-lock.json`. | ||
- Added _coverage_ for testing. | ||
- Added _watcher_ for coding. | ||
- Updated _eslint_ to flat `eslint.config.js`. | ||
- Improved `OSftp.list` to return always a sortened list by name. | ||
- Improved _github cicd_ adding sftp-server for testing. | ||
- Improved _github cicd_ replacing `actions/--@v3` by `actions/--@v4`, and replacing `npm install` to `npm ci`. | ||
- Improved `export` declarations in index files. | ||
- Enhanced _linter_ adding some extensions. | ||
- Enhanced _prettier_ adding import-sorter. | ||
- Updated _prettier_ `printWidth: 120` | ||
- Simplified `tsup.config.ts`. | ||
- Moved _tests_ inside `src` and simplified `*.test.ts`. | ||
- Enhanced testing to achieve over `987%` of coverage (yay!). | ||
- Updated libs: | ||
- `fs-extra` from `v11.1.1` to `v11.2.0`. | ||
- `oro-functions` from `v2.0.2` to `v2.3.1`. | ||
- `ssh2-sftp-client` from `v9.1.0` to `v10.0.3`. | ||
- Added _dev_ libs: | ||
- `@eslint/js` | ||
- `@trivago/prettier-plugin-sort-imports` | ||
- `eslint-config-prettier` | ||
- `eslint-plugin-jest` | ||
- `globals` | ||
- `nodemon` | ||
- `typescript-eslint` | ||
- Updated _dev_ libs: | ||
- `@babel/core` from `v7.23.3` to `v7.24.9`. | ||
- `@babel/preset-env` from `v7.23.` to `v7.24.8`. | ||
- `@babel/preset-typescript` from `v7.23.3` to `v7.24.7`. | ||
- `@types/jest` from `v29.5.10` to `v29.5.12`. | ||
- `eslint` from `v8.54.0` to `v^^8.57.0`. | ||
- `eslint-plugin-unicorn` from `v49.0.0` to `v54.0.0`. | ||
- `husky` from `v8.0.3` to `v9.1.1`. | ||
- `prettier` from `v3.1.0` to `v3.3.3`. | ||
- `tsup` from `v8.0.1` to `v8.2.2`. | ||
- `typescript` from `v5.2.2` to `v5.5.4`. | ||
- Removed _dev_ libs: | ||
- `@typescript-eslint/eslint-plugin` removed. | ||
- `@typescript-eslint/parser` removed. | ||
- `eslint-config-alloy` removed. | ||
## 2.0.2 / 2023-11-02 | ||
* Fixed _github action_ `npm_publish_on_pr_merge_to_master`. | ||
* Updated libs: | ||
* `fs-extra` to `v11.1.1`. | ||
* `oro-functions` from `v2.0.0` to `v2.0.2`. | ||
* Updated _dev_ libs: | ||
* `@babel/core` from `v7.23.2` to `v7.23.3`. | ||
* `@babel/preset-env` from `v7.23.2` to `v7.23.3`. | ||
* `@babel/preset-typescript` from `v7.23.2` to `v7.23.3`. | ||
* `@types/fs-extra` from `v11.0.3` to `v11.0.4`. | ||
* `@types/jest` from `v29.5.7` to `v29.5.10`. | ||
* `@types/ssh2-sftp-client` from `v9.0.2` to `v9.0.3`. | ||
* `@typescript-eslint/eslint-plugin` from `v6.9.1` to `v6.12.0`. | ||
* `@typescript-eslint/parser` from `v6.9.1` to `v6.12.0`. | ||
* `eslint` from `v8.52.0` to `v8.54.0`. | ||
* `prettier` from `v3.0.3` to `v3.1.0`. | ||
* `tsup` from `v7.2.0` to `v8.0.1`. | ||
* Removed non-used _dev_ libs: | ||
* `@nearst/ftp`. | ||
- Fixed _github action_ `npm_publish_on_pr_merge_to_master`. | ||
- Updated libs: | ||
- `fs-extra` to `v11.1.1`. | ||
- `oro-functions` from `v2.0.0` to `v2.0.2`. | ||
- Updated _dev_ libs: | ||
- `@babel/core` from `v7.23.2` to `v7.23.3`. | ||
- `@babel/preset-env` from `v7.23.2` to `v7.23.3`. | ||
- `@babel/preset-typescript` from `v7.23.2` to `v7.23.3`. | ||
- `@types/fs-extra` from `v11.0.3` to `v11.0.4`. | ||
- `@types/jest` from `v29.5.7` to `v29.5.10`. | ||
- `@types/ssh2-sftp-client` from `v9.0.2` to `v9.0.3`. | ||
- `@typescript-eslint/eslint-plugin` from `v6.9.1` to `v6.12.0`. | ||
- `@typescript-eslint/parser` from `v6.9.1` to `v6.12.0`. | ||
- `eslint` from `v8.52.0` to `v8.54.0`. | ||
- `prettier` from `v3.0.3` to `v3.1.0`. | ||
- `tsup` from `v7.2.0` to `v8.0.1`. | ||
- Removed non-used _dev_ libs: | ||
- `@nearst/ftp`. | ||
## 2.0.1 / 2023-11-02 | ||
* Updated _dev_ libs: | ||
* `@types/ssh2-sftp-client` to `v9.0.2`. | ||
- Updated _dev_ libs: | ||
- `@types/ssh2-sftp-client` to `v9.0.2`. | ||
@@ -30,71 +73,71 @@ ## 2.0.0 / 2023-11-02 | ||
* Refactored `./index.js` to `./src/index.ts`. | ||
* Updated _package_ as `type: "module"`. | ||
* Added `tsup` and now _package_ is compiled to `cjs` _(common)_ and `mjs` _(module)_. | ||
* Added _github actions_: | ||
* `validate_pr_to_master` | ||
* `npm_publish_on_pr_merge_to_master`. | ||
* Added `husky` (to ensure only valid commits). | ||
* Added `eslint` (and applied it). | ||
* Added `prettier` (and applied it). | ||
* Updated _package description_ | ||
* Updated libs: | ||
* `oro-functions` to `v2.0.0`. | ||
* Updated _dev_ libs: | ||
* `@babel/core` to `v7.23.2`. | ||
* `@babel/preset-env` to `v7.23.2`. | ||
* `@babel/preset-typescript` to `v7.23.2`. | ||
* `@types/jest` to `v29.5.7`. | ||
* `@types/fs-extra` to `v11.0.3`. | ||
* `@types/promise-ftp` to `v1.3.7`. | ||
* `babel-jest` to `v29.7.0`. | ||
* `jest` to `v29.7.0`. | ||
- Refactored `./index.js` to `./src/index.ts`. | ||
- Updated _package_ as `type: "module"`. | ||
- Added `tsup` and now _package_ is compiled to `cjs` _(common)_ and `mjs` _(module)_. | ||
- Added _github actions_: | ||
- `validate_pr_to_master` | ||
- `npm_publish_on_pr_merge_to_master`. | ||
- Added `husky` (to ensure only valid commits). | ||
- Added `eslint` (and applied it). | ||
- Added `prettier` (and applied it). | ||
- Updated _package description_ | ||
- Updated libs: | ||
- `oro-functions` to `v2.0.0`. | ||
- Updated _dev_ libs: | ||
- `@babel/core` to `v7.23.2`. | ||
- `@babel/preset-env` to `v7.23.2`. | ||
- `@babel/preset-typescript` to `v7.23.2`. | ||
- `@types/jest` to `v29.5.7`. | ||
- `@types/fs-extra` to `v11.0.3`. | ||
- `@types/promise-ftp` to `v1.3.7`. | ||
- `babel-jest` to `v29.7.0`. | ||
- `jest` to `v29.7.0`. | ||
## 1.1.0 / 2023-07-04 | ||
* Added `TS` support. | ||
* Added _ts tests_. | ||
* Added `package-lock.json`. | ||
* Improved _tests_. | ||
* Improved _readme_. | ||
* Improved _error messages_ and added param `code` in _responseKO error_. | ||
* Fixed reducing duration of _connection timeout_ when fails. | ||
* Fixed method `delete` allowing to remove folder (as `rmdir`) when it's empty. | ||
* Updated lib `oro-functions` to `v1.3.2`. | ||
* Updated lib `ssh2-sftp-client` to `v9.1.0`. | ||
* Updated lib-dev `jest` to `v29.5.0`. | ||
- Added `TS` support. | ||
- Added _ts tests_. | ||
- Added `package-lock.json`. | ||
- Improved _tests_. | ||
- Improved _readme_. | ||
- Improved _error messages_ and added param `code` in _responseKO error_. | ||
- Fixed reducing duration of _connection timeout_ when fails. | ||
- Fixed method `delete` allowing to remove folder (as `rmdir`) when it's empty. | ||
- Updated lib `oro-functions` to `v1.3.2`. | ||
- Updated lib `ssh2-sftp-client` to `v9.1.0`. | ||
- Updated lib-dev `jest` to `v29.5.0`. | ||
## 1.0.3 / 2022-06-21 | ||
* Updated lib `oro-functions` to `v1.1.7`. | ||
* Updated lib-dev `jest` to `v28.1.1`. | ||
- Updated lib `oro-functions` to `v1.1.7`. | ||
- Updated lib-dev `jest` to `v28.1.1`. | ||
## 1.0.0 / 2022-05-26 | ||
* Added `MIT License`. | ||
* Added _unit testing_ `Jest`. | ||
* Added _package_ in `github.com` & `npmjs.com`. | ||
* Updated lib `oro-functions` to `^v1.1.4`. | ||
* Updated lib `ssh2-sftp-client` to `^v8.1.0`. | ||
- Added `MIT License`. | ||
- Added _unit testing_ `Jest`. | ||
- Added _package_ in `github.com` & `npmjs.com`. | ||
- Updated lib `oro-functions` to `^v1.1.4`. | ||
- Updated lib `ssh2-sftp-client` to `^v8.1.0`. | ||
## 0.1.3 / 2021-12-13 | ||
* Updated lib `oro-functions` to `v1.0.2`. | ||
* Updated lib `ssh2-sftp-client` to `v7.1.0`. | ||
- Updated lib `oro-functions` to `v1.0.2`. | ||
- Updated lib `ssh2-sftp-client` to `v7.1.0`. | ||
## 0.1.2 / 2021-11-30 | ||
* Updated lib `ssh2-sftp-client` to `v7.1.0`. | ||
- Updated lib `ssh2-sftp-client` to `v7.1.0`. | ||
## 0.1.1 / 2021-11-16 | ||
* Update `oro-functions` to _v1.0.1_. | ||
- Update `oro-functions` to _v1.0.1_. | ||
## 0.1.0 / 2021-06-18 | ||
* Added methods `list`, `move`, `delete`, `exists`, `mkdir`, `rmdir`. | ||
* Fixed `readme.md information` and _error object_ of `upload`, `download`, `disconnect`. | ||
* Updated lib `oro-functions`. | ||
- Added methods `list`, `move`, `delete`, `exists`, `mkdir`, `rmdir`. | ||
- Fixed `readme.md information` and _error object_ of `upload`, `download`, `disconnect`. | ||
- Updated lib `oro-functions`. | ||
## 0.0.3 / 2021-05-07 | ||
* Fixed _constructor_ `param:config`. | ||
* Fixed _constructor_ `param:config.user` is changed by `param:config.username`. | ||
* Fixed avoid `tryAgain` when _connect_ failed by _wrong username_. | ||
- Fixed _constructor_ `param:config`. | ||
- Fixed _constructor_ `param:config.user` is changed by `param:config.username`. | ||
- Fixed avoid `tryAgain` when _connect_ failed by _wrong username_. | ||
## 0.0.2 / 2021-05-07 | ||
* Added changelog. | ||
* Fixed _constructor_ `param:config`. | ||
* Updated npm `oro-functions` to `v0.9.1`. | ||
- Added changelog. | ||
- Fixed _constructor_ `param:config`. | ||
- Updated npm `oro-functions` to `v0.9.1`. |
@@ -12,3 +12,3 @@ import SftpClient, { ListFilterFunction } from 'ssh2-sftp-client'; | ||
}; | ||
type OSFtpErrorCode = 'UNCONNECTED' | 'ECONNREFUSED' | 'ENOTFOUND' | 'ENTIMEOUT' | 'ENOENT' | 'EEXIST' | 'ENOTEMPTY'; | ||
type OSFtpErrorCode = 'UNCONNECTED' | 'ECONNREFUSED' | 'ENOTFOUND' | 'ENTIMEOUT' | 'ENOENT' | 'EEXIST' | 'ENOTEMPTY' | 'EISDIR'; | ||
interface OSFtpConnectError { | ||
@@ -91,2 +91,3 @@ msg: string; | ||
type OSFtpUploadOneResponse = SResponseOKObject<OSFtpFileObject> | SResponseKOObject<OSFtpFileError | OSFtpConnectError>; | ||
declare class OSFtp { | ||
@@ -109,2 +110,2 @@ #private; | ||
export { OSFtp, type OSFtpConfig, type OSFtpConnectError, type OSFtpConnectResponse, type OSFtpDisconnectResponse, type OSFtpExistError, type OSFtpExistObject, type OSFtpExistResponse, type OSFtpFileError, type OSFtpFileObject, type OSFtpFileResponse, type OSFtpFolderError, type OSFtpFolderObject, type OSFtpFolderResponse, type OSFtpListError, type OSFtpListFile, type OSFtpListFileType, type OSFtpListFilters, type OSFtpListObject, type OSFtpListResponse, type OSFtpUploadOneResponse, OSFtp as default }; | ||
export { OSFtp, type OSFtpConfig, type OSFtpConnectError, type OSFtpConnectResponse, type OSFtpDisconnectResponse, type OSFtpErrorCode, type OSFtpExistError, type OSFtpExistObject, type OSFtpExistResponse, type OSFtpFileError, type OSFtpFileObject, type OSFtpFileResponse, type OSFtpFolderError, type OSFtpFolderObject, type OSFtpFolderResponse, type OSFtpListError, type OSFtpListFile, type OSFtpListFileType, type OSFtpListFilters, type OSFtpListObject, type OSFtpListResponse, type OSFtpUploadOneResponse }; |
@@ -5,2 +5,5 @@ var __defProp = Object.defineProperty; | ||
var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __typeError = (msg) => { | ||
throw TypeError(msg); | ||
}; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
@@ -18,24 +21,7 @@ var __spreadValues = (a, b) => { | ||
}; | ||
var __accessCheck = (obj, member, msg) => { | ||
if (!member.has(obj)) | ||
throw TypeError("Cannot " + msg); | ||
}; | ||
var __privateGet = (obj, member, getter) => { | ||
__accessCheck(obj, member, "read from private field"); | ||
return getter ? getter.call(obj) : member.get(obj); | ||
}; | ||
var __privateAdd = (obj, member, value) => { | ||
if (member.has(obj)) | ||
throw TypeError("Cannot add the same private member more than once"); | ||
member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
}; | ||
var __privateSet = (obj, member, value, setter) => { | ||
__accessCheck(obj, member, "write to private field"); | ||
setter ? setter.call(obj, value) : member.set(obj, value); | ||
return value; | ||
}; | ||
var __privateMethod = (obj, member, method) => { | ||
__accessCheck(obj, member, "access private method"); | ||
return method; | ||
}; | ||
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); | ||
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); | ||
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); | ||
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); | ||
var __async = (__this, __arguments, generator) => { | ||
@@ -62,16 +48,29 @@ return new Promise((resolve, reject) => { | ||
// src/index.ts | ||
// src/OSftp.ts | ||
import fsExtra from "fs-extra"; | ||
import path from "path"; | ||
import fsExtra from "fs-extra"; | ||
import Ofn from "oro-functions"; | ||
import SftpClient from "ssh2-sftp-client"; | ||
var _ftpClient, _config, _setFtpConfig, setFtpConfig_fn; | ||
function pathExists(path2) { | ||
return __async(this, null, function* () { | ||
return path2 ? yield fsExtra.stat(path2).then(() => true).catch(() => false) : false; | ||
}); | ||
} | ||
function getMsgAndCodeByError(error) { | ||
let msg = error.toString().split("\r\n")[0].replace("Error: ", ""); | ||
let code = error.code === 2 ? "ENOTFOUND" : error.code === 4 ? "ENOTEMPTY" : String(error.code) === "ERR_BAD_PATH" ? "ENOTFOUND" : String(error.code); | ||
if (msg.includes("No SFTP connection available")) { | ||
msg = `FtpConnectionError: connection status is not yet connected`; | ||
code = "UNCONNECTED"; | ||
} | ||
return { msg, code }; | ||
} | ||
var _ftpClient, _config, _OSFtp_instances, checkFtpConfig_fn, setFtpConfig_fn; | ||
var OSFtp = class { | ||
constructor(config = {}) { | ||
__privateAdd(this, _setFtpConfig); | ||
__privateAdd(this, _ftpClient, void 0); | ||
// @ts-ignore | ||
__privateAdd(this, _config, void 0); | ||
__privateAdd(this, _OSFtp_instances); | ||
__privateAdd(this, _ftpClient); | ||
__privateAdd(this, _config); | ||
if (Ofn.objIsNotEmpty(config)) { | ||
__privateMethod(this, _setFtpConfig, setFtpConfig_fn).call(this, config); | ||
__privateMethod(this, _OSFtp_instances, setFtpConfig_fn).call(this, config); | ||
} | ||
@@ -86,15 +85,13 @@ __privateSet(this, _ftpClient, new SftpClient()); | ||
if (Ofn.objIsNotEmpty(config)) { | ||
__privateMethod(this, _setFtpConfig, setFtpConfig_fn).call(this, config); | ||
__privateMethod(this, _OSFtp_instances, setFtpConfig_fn).call(this, config); | ||
} | ||
if (Ofn.objIsEmpty(__privateGet(this, _config))) { | ||
const config2 = Ofn.cloneObject(__privateGet(this, _config)); | ||
if (config2.password) { | ||
config2.password = Array.from({ length: config2.password.length }).fill("*").join(""); | ||
} | ||
const exposedConfig = Ofn.cloneObject(__privateGet(this, _config)); | ||
if (exposedConfig.password) { | ||
exposedConfig.password = Array.from({ length: exposedConfig.password.length }).fill("*").join("").substring(0, 5); | ||
} | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Connect"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO( | ||
`SFTP Connect failed: config is empty.`, | ||
{ | ||
code: "UNCONNECTED", | ||
config: config2 | ||
}, | ||
checkResponse.error.msg, | ||
{ code: checkResponse.error.code, config: exposedConfig }, | ||
false | ||
@@ -104,12 +101,9 @@ ); | ||
return __privateGet(this, _ftpClient).connect(__privateGet(this, _config)).then((_data) => Ofn.setResponseOK()).catch((error) => { | ||
const config2 = Ofn.cloneObject(__privateGet(this, _config)); | ||
if (config2.password) { | ||
config2.password = Array.from({ length: config2.password.length }).fill("*").join(""); | ||
} | ||
const { msg } = getMsgAndCodeByError(error); | ||
const code = msg.includes("Timed out while waiting for handshake") ? "ENTIMEOUT" : String(error.code); | ||
const { msg, code } = getMsgAndCodeByError(error); | ||
const message = msg.replace("connect: ", ""); | ||
const sanitizeCode = msg.includes("Timed out while waiting for handshake") ? "ENTIMEOUT" : String(code); | ||
const tryAgain = msg !== "Invalid username"; | ||
return Ofn.setResponseKO( | ||
`SFTP Connect failed: ${msg.replace("connect: ", "")}.`, | ||
{ config: config2, code }, | ||
`SFTP Connect failed: ${message}.`, | ||
{ code: sanitizeCode, config: exposedConfig }, | ||
tryAgain | ||
@@ -124,3 +118,11 @@ ); | ||
const filepathOrigin = path.isAbsolute(filepathFrom) ? filepathFrom : path.resolve(filepathFrom); | ||
if (!(yield fsExtra.exists(filepathOrigin))) { | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Upload"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
filepathFrom: filepathOrigin, | ||
filepathTo: filepathDestiny, | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
if (!(yield pathExists(filepathOrigin))) { | ||
__privateGet(this, _config).disconnectWhenError && (yield this.disconnect()); | ||
@@ -141,6 +143,8 @@ return Ofn.setResponseKO(`SFTP Upload failed: File (From) to upload not exist.`, { | ||
const { msg, code } = getMsgAndCodeByError(error); | ||
return Ofn.setResponseKO( | ||
`SFTP Upload failed: ${msg.replace("_put: ", "").replace("Write stream error: ", "")}.`, | ||
{ filepathFrom: filepathOrigin, filepathTo: filepathDestiny, code } | ||
); | ||
const message = msg.replace("_put: ", "").replace("Write stream error: ", ""); | ||
return Ofn.setResponseKO(`SFTP Upload failed: ${message}.`, { | ||
filepathFrom: filepathOrigin, | ||
filepathTo: filepathDestiny, | ||
code | ||
}); | ||
}); | ||
@@ -155,3 +159,11 @@ }); | ||
} | ||
if (!(yield fsExtra.exists(Ofn.getFolderByPath(filepathDestiny)))) { | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Download"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
filepathFrom, | ||
filepathTo: filepathDestiny, | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
if (!(yield pathExists(Ofn.getFolderByPath(filepathDestiny)))) { | ||
__privateGet(this, _config).disconnectWhenError && (yield this.disconnect()); | ||
@@ -172,3 +184,4 @@ return Ofn.setResponseKO(`SFTP Download failed: Folder (From) to download not exist.`, { | ||
const { msg, code } = getMsgAndCodeByError(error); | ||
return Ofn.setResponseKO(`SFTP Download failed: ${msg.replace("get: ", "")}.`, { | ||
const message = msg.replace("get: ", ""); | ||
return Ofn.setResponseKO(`SFTP Download failed: ${message}.`, { | ||
filepathFrom, | ||
@@ -192,5 +205,14 @@ filepathTo: filepathDestiny, | ||
const folderPath = listFolder.indexOf("./") === 0 ? listFolder.slice(2) : listFolder; | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "List"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
folder: listFolder, | ||
filters: listFilter, | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
return yield __privateGet(this, _ftpClient).list(listFolder, listFilter.pattern).then((data) => { | ||
const files = []; | ||
for (const element of data) { | ||
const listMap = /* @__PURE__ */ new Map(); | ||
for (let index = 0, length = data.length; index < length; index++) { | ||
const element = data[index]; | ||
switch (true) { | ||
@@ -215,5 +237,7 @@ case (listFilter.onlyFiles && element.type !== "-"): | ||
}; | ||
files.push(file); | ||
const fileKey = `${file.name}-${element.type === "-" ? "x" : element.type}-${Ofn.strPad(index, 8, "0")}`; | ||
listMap.set(fileKey, file); | ||
} | ||
return Ofn.setResponseOK({ count: files.length, list: files }); | ||
const list = [...listMap.entries()].sort(([a], [b]) => String(a).localeCompare(b)).map(([_, file]) => file); | ||
return Ofn.setResponseOK({ count: list.length, list }); | ||
}).catch((error) => { | ||
@@ -232,2 +256,10 @@ __privateGet(this, _config).disconnectWhenError && this.disconnect(); | ||
return __async(this, null, function* () { | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Move"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
filepathFrom, | ||
filepathTo, | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
return yield __privateGet(this, _ftpClient).rename(filepathFrom, filepathTo).then(() => { | ||
@@ -251,2 +283,9 @@ return Ofn.setResponseOK({ | ||
return __async(this, null, function* () { | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Delete"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
filepathFrom, | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
return yield __privateGet(this, _ftpClient).delete(filepathFrom).then(() => { | ||
@@ -282,3 +321,4 @@ return Ofn.setResponseOK("deleted successfully", { | ||
} | ||
return Ofn.setResponseKO(`SFTP Delete failed: ${msg.replace("delete: ", "")}.`, { | ||
const message = msg.replace("delete: ", ""); | ||
return Ofn.setResponseKO(`SFTP Delete failed: ${message}.`, { | ||
filepathFrom, | ||
@@ -292,2 +332,10 @@ code | ||
return __async(this, null, function* () { | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Exists"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
filepath: filepathFrom, | ||
filename: Ofn.getFilenameByPath(filepathFrom), | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
return yield __privateGet(this, _ftpClient).exists(filepathFrom).then((data) => { | ||
@@ -316,2 +364,9 @@ return data ? Ofn.setResponseOK({ | ||
return __async(this, null, function* () { | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Mkdir"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
folder, | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
if (!folder) { | ||
@@ -339,5 +394,5 @@ __privateGet(this, _config).disconnectWhenError && (yield this.disconnect()); | ||
__privateGet(this, _config).disconnectWhenError && this.disconnect(); | ||
let { msg, code } = getMsgAndCodeByError(error); | ||
msg = msg.replace("mkdir: ", "").replace("_doMkdir: ", ""); | ||
return Ofn.setResponseKO(`SFTP Mkdir failed: ${msg}.`, { folder: dirFolder, code }); | ||
const { msg, code } = getMsgAndCodeByError(error); | ||
const message = msg.replace("mkdir: ", "").replace("_doMkdir: ", ""); | ||
return Ofn.setResponseKO(`SFTP Mkdir failed: ${message}.`, { folder: dirFolder, code }); | ||
}); | ||
@@ -348,2 +403,9 @@ }); | ||
return __async(this, null, function* () { | ||
const checkResponse = __privateMethod(this, _OSFtp_instances, checkFtpConfig_fn).call(this, "Rmdir"); | ||
if (!checkResponse.status) { | ||
return Ofn.setResponseKO(checkResponse.error.msg, { | ||
folder, | ||
code: checkResponse.error.code | ||
}); | ||
} | ||
if (!folder) { | ||
@@ -361,3 +423,3 @@ __privateGet(this, _config).disconnectWhenError && (yield this.disconnect()); | ||
).catch((error) => { | ||
let { msg, code } = getMsgAndCodeByError(error); | ||
const { msg, code } = getMsgAndCodeByError(error); | ||
if (!strict && /(Bad Path:)/.test(msg)) { | ||
@@ -370,3 +432,4 @@ return Ofn.setResponseOK(`Folder not found.`, { | ||
__privateGet(this, _config).disconnectWhenError && this.disconnect(); | ||
return Ofn.setResponseKO(`SFTP Rmdir failed: ${msg.replace("rmdir: ", "")}.`, { | ||
const message = msg.replace("rmdir: ", ""); | ||
return Ofn.setResponseKO(`SFTP Rmdir failed: ${message}.`, { | ||
folder: dirFolder, | ||
@@ -406,3 +469,6 @@ code | ||
_config = new WeakMap(); | ||
_setFtpConfig = new WeakSet(); | ||
_OSFtp_instances = new WeakSet(); | ||
checkFtpConfig_fn = function(action) { | ||
return !__privateGet(this, _config) || Ofn.objIsEmpty(__privateGet(this, _config)) ? Ofn.setResponseKO(`SFTP ${action} failed: config is empty.`, { code: "UNCONNECTED" }) : Ofn.setResponseOK(); | ||
}; | ||
setFtpConfig_fn = function(config) { | ||
@@ -418,15 +484,4 @@ __privateSet(this, _config, Ofn.cloneObject(config)); | ||
}; | ||
function getMsgAndCodeByError(error) { | ||
let msg = error.toString().split("\r\n")[0].replace("Error: ", ""); | ||
let code = error.code === 2 ? "ENOTFOUND" : error.code === 4 ? "ENOTEMPTY" : String(error.code) === "ERR_BAD_PATH" ? "ENOTFOUND" : String(error.code); | ||
if (msg.includes("No SFTP connection available")) { | ||
msg = `FtpConnectionError: connection status is not yet connected`; | ||
code = "UNCONNECTED"; | ||
} | ||
return { msg, code }; | ||
} | ||
var src_default = OSFtp; | ||
export { | ||
OSFtp, | ||
src_default as default | ||
OSFtp | ||
}; |
{ | ||
"name": "oro-sftp", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "OroSftp Class is a wrapper of ssh2-sftp-client to work as promises async/await and typescript.", | ||
@@ -18,6 +18,11 @@ "type": "module", | ||
"test": "jest", | ||
"coverage": "jest --coverage", | ||
"coverage:open": "node coverage.open.js", | ||
"coverage-open": "jest --coverage && node coverage.open.js", | ||
"lint": "eslint .", | ||
"prettier": "prettier --write .", | ||
"clean": "rm -R ./dist", | ||
"clean:all": "rm -R ./dist ./node_modules", | ||
"build": "tsup ./src/index.ts --format cjs,esm --dts --clean" | ||
"clean:all": "rm -R ./dist ./node_modules ./coverage", | ||
"build": "tsup ./src/index.ts", | ||
"watch": "nodemon" | ||
}, | ||
@@ -42,25 +47,29 @@ "keywords": [ | ||
"dependencies": { | ||
"fs-extra": "^11.1.1", | ||
"oro-functions": "^2.0.2", | ||
"ssh2-sftp-client": "^9.1.0" | ||
"fs-extra": "^11.2.0", | ||
"oro-functions": "^2.3.1", | ||
"ssh2-sftp-client": "^10.0.3" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.23.3", | ||
"@babel/preset-env": "^7.23.3", | ||
"@babel/preset-typescript": "^7.23.3", | ||
"@babel/core": "^7.24.9", | ||
"@babel/preset-env": "^7.24.8", | ||
"@babel/preset-typescript": "^7.24.7", | ||
"@eslint/js": "^9.7.0", | ||
"@trivago/prettier-plugin-sort-imports": "^4.3.0", | ||
"@types/fs-extra": "^11.0.4", | ||
"@types/jest": "^29.5.10", | ||
"@types/jest": "^29.5.12", | ||
"@types/ssh2-sftp-client": "^9.0.3", | ||
"@typescript-eslint/eslint-plugin": "^6.12.0", | ||
"@typescript-eslint/parser": "^6.12.0", | ||
"babel-jest": "^29.7.0", | ||
"eslint": "^8.54.0", | ||
"eslint-config-alloy": "^5.1.2", | ||
"eslint-plugin-unicorn": "^49.0.0", | ||
"husky": "^8.0.3", | ||
"eslint": "^8.57.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-jest": "^28.6.0", | ||
"eslint-plugin-unicorn": "^54.0.0", | ||
"globals": "^15.8.0", | ||
"husky": "^9.1.1", | ||
"jest": "^29.7.0", | ||
"prettier": "^3.1.0", | ||
"tsup": "^8.0.1", | ||
"typescript": "^5.2.2" | ||
"nodemon": "^3.1.4", | ||
"prettier": "^3.3.3", | ||
"tsup": "^8.2.2", | ||
"typescript": "^5.5.4", | ||
"typescript-eslint": "^7.17.0" | ||
} | ||
} |
@@ -774,35 +774,23 @@ # Oro Sftp | ||
If you want to run `npm run test`, it's required to declare your own `./test/config.json` | ||
(you can _copypaste_ it from `./test/config-default.json`) | ||
If you want to run `npm run test` in local, first you need to run a sftp server (i.e. via docker): | ||
```bash | ||
# 'atmoz/sftp:alpine' is smaller and faster | ||
> docker run --name oro-sftp-server -p 2222:22 -d atmoz/sftp:alpine -e osftp_user:osftp_pass:::osftp_folder | ||
# change the login-folder to have full privileges in main folder | ||
> docker exec oro-sftp-server sh -c "sed -i -e 's#ForceCommand internal-sftp#ForceCommand internal-sftp -d /osftp_folder#' /etc/ssh/sshd_config" | ||
# restart container | ||
> docker restart oro-sftp-server | ||
``` | ||
Then, you have to declare your own `./test/config.json`, <br> | ||
<small>You can _copypaste_ it from `./test/config-default.json`</small> | ||
```json | ||
{ | ||
"host": "IPADDRESS", | ||
"port": 22, | ||
"user": "user", | ||
"password": "password" | ||
"host": "localhost", | ||
"port": 2222, | ||
"user": "osftp_user", | ||
"password": "osftp_pass" | ||
} | ||
``` | ||
__NOTICE:__ When tests are running, in the _server ftp_ it's created (and removed when it has finished) the next folders: | ||
* `test-exists`, | ||
* `test-mkdir`, | ||
* `test-rmdir`, | ||
* `test-list`, | ||
* `test-delete`, | ||
* `test-move`, | ||
* `test-upload`, | ||
* `test-download`; | ||
* `test-exists-ts`, | ||
* `test-mkdir-ts`, | ||
* `test-rmdir-ts`, | ||
* `test-list-ts`, | ||
* `test-delete-ts`, | ||
* `test-move-ts`, | ||
* `test-upload-ts`, | ||
* `test-download-ts`; | ||
and the files `./zpython.pdf`, `./zpython2.pdf`. | ||
So, | ||
* `rw` permissions should be allowed, | ||
* and if in your _sftp server_ already exist them and there are required for you, avoid to `run test`. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
77053
1070
0
21
796
+ Addedssh2-sftp-client@10.0.3(transitive)
- Removedssh2-sftp-client@9.1.0(transitive)
Updatedfs-extra@^11.2.0
Updatedoro-functions@^2.3.1
Updatedssh2-sftp-client@^10.0.3