BREAKING CHANGE(Smartfile class): switch to a Buffer only approach

This commit is contained in:
Philipp Kunz 2020-08-10 20:58:22 +00:00
parent 7204607c8a
commit e3c46cdd2c
11 changed files with 9575 additions and 567 deletions

View File

@ -19,6 +19,8 @@ mirror:
stage: security
script:
- npmci git mirror
only:
- tags
tags:
- lossless
- docker
@ -33,9 +35,7 @@ audit:
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high
tags:
- lossless
- docker
- notpriv
# ====================
# test stage
@ -50,9 +50,7 @@ testStable:
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- lossless
- docker
- priv
testBuild:
stage: test
@ -63,9 +61,7 @@ testBuild:
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- lossless
- docker
- notpriv
release:
stage: release
@ -85,6 +81,8 @@ release:
codequality:
stage: metadata
allow_failure: true
only:
- tags
script:
- npmci command npm install -g tslint typescript
- npmci npm prepare

View File

@ -15,7 +15,7 @@
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm"]
"enum": ["website", "element", "service", "npm", "wcc"]
}
}
}

9912
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,11 +7,7 @@
"typings": "dist_ts/index.d.ts",
"scripts": {
"test": "(tstest test/)",
"reinstall": "(rm -r node_modules && npm install)",
"release": "(git pull origin master && npm version patch && git push origin master && git checkout release && git merge master && git push origin release && git checkout master)",
"update": "(git checkout master && git pull origin master && npm install)",
"upgrade": "(npm run update) && (ncu upgradeAll && npm install)",
"build": "(tsbuild)"
"build": "(tsbuild --web)"
},
"repository": {
"type": "git",
@ -21,7 +17,7 @@
"filesystem",
"json"
],
"author": "Smart Coordination GmbH <office@push.rocks> (https://push.rocks)",
"author": "Lossless GmbH <hello@lossless.com> (https://lossless.com)",
"license": "MIT",
"bugs": {
"url": "https://gitlab.com/pushrocks/smartfile/issues"
@ -30,22 +26,22 @@
"dependencies": {
"@pushrocks/smarthash": "^2.1.6",
"@pushrocks/smartmime": "^1.0.3",
"@pushrocks/smartpath": "^4.0.1",
"@pushrocks/smartpath": "^4.0.3",
"@pushrocks/smartpromise": "^3.0.6",
"@pushrocks/smartrequest": "^1.1.47",
"@types/fs-extra": "^8.1.0",
"fs-extra": "^8.1.0",
"@types/fs-extra": "^9.0.1",
"fs-extra": "^9.0.1",
"glob": "^7.1.6",
"js-yaml": "^3.13.1"
"js-yaml": "^3.14.0"
},
"devDependencies": {
"@gitzone/tsbuild": "^2.1.22",
"@gitzone/tsrun": "^1.2.8",
"@gitzone/tstest": "^1.0.28",
"@pushrocks/tapbundle": "^3.2.1",
"@types/node": "^13.9.1",
"@gitzone/tsbuild": "^2.1.24",
"@gitzone/tsrun": "^1.2.12",
"@gitzone/tstest": "^1.0.43",
"@pushrocks/tapbundle": "^3.2.9",
"@types/node": "^14.0.27",
"gulp-function": "^2.2.14",
"tslint": "^6.1.0",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0"
},
"files": [
@ -59,5 +55,8 @@
"cli.js",
"npmextra.json",
"readme.md"
],
"browserslist": [
"last 1 chrome versions"
]
}
}

View File

@ -8,13 +8,20 @@ smart ways to work with files in nodejs
* [docs (typedoc)](https://pushrocks.gitlab.io/smartfile/)
## Status for master
[![pipeline status](https://gitlab.com/pushrocks/smartfile/badges/master/pipeline.svg)](https://gitlab.com/pushrocks/smartfile/commits/master)
[![coverage report](https://gitlab.com/pushrocks/smartfile/badges/master/coverage.svg)](https://gitlab.com/pushrocks/smartfile/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/@pushrocks/smartfile.svg)](https://www.npmjs.com/package/@pushrocks/smartfile)
[![Known Vulnerabilities](https://snyk.io/test/npm/@pushrocks/smartfile/badge.svg)](https://snyk.io/test/npm/@pushrocks/smartfile)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
Status Category | Status Badge
-- | --
GitLab Pipelines | [![pipeline status](https://gitlab.com/pushrocks/smartfile/badges/master/pipeline.svg)](https://lossless.cloud)
GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/pushrocks/smartfile/badges/master/coverage.svg)](https://lossless.cloud)
npm | [![npm downloads per month](https://badgen.net/npm/dy/@pushrocks/smartfile)](https://lossless.cloud)
Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/pushrocks/smartfile)](https://lossless.cloud)
TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@pushrocks/smartfile)](https://lossless.cloud)
PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@pushrocks/smartfile)](https://lossless.cloud)
BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@pushrocks/smartfile)](https://lossless.cloud)
Platform support | [![Supports Windows 10](https://badgen.net/badge/supports%20Windows%2010/yes/green?icon=windows)](https://lossless.cloud) [![Supports Mac OS X](https://badgen.net/badge/supports%20Mac%20OS%20X/yes/green?icon=apple)](https://lossless.cloud)
## Usage

View File

@ -15,7 +15,7 @@ tap.test('.fs.fileExistsSync -> should return an accurate boolean', async () =>
tap.test('.fs.fileExists -> should resolve or reject a promise', async () => {
expect(smartfile.fs.fileExists('./test/testassets/mytest.json')).to.be.instanceof(Promise);
await smartfile.fs.fileExists('./test/testassets/mytest.json');
await smartfile.fs.fileExists('./test/testassets/notthere.json').catch(err => {
await smartfile.fs.fileExists('./test/testassets/notthere.json').catch((err) => {
return expect(err.message).to.equal(
"ENOENT: no such file or directory, access './test/testassets/notthere.json'"
);
@ -28,7 +28,7 @@ tap.test('.fs.listFoldersSync() -> should get the file type from a string', asyn
});
tap.test('.fs.listFolders() -> should get the file type from a string', async () => {
let folderArrayArg = await smartfile.fs.listFolders('./test/testassets/');
const folderArrayArg = await smartfile.fs.listFolders('./test/testassets/');
expect(folderArrayArg).to.include('testfolder');
expect(folderArrayArg).to.not.include('notExistentFolder');
});
@ -45,13 +45,13 @@ tap.test('.fs.listFilesSync() -> should get the file type from a string', async
});
tap.test('.fs.listFiles() -> should get the file type from a string', async () => {
let folderArrayArg = await smartfile.fs.listFiles('./test/testassets/');
const folderArrayArg = await smartfile.fs.listFiles('./test/testassets/');
expect(folderArrayArg).to.include('mytest.json');
expect(folderArrayArg).to.not.include('notExistentFile');
});
tap.test('.fs.listFileTree() -> should get a file tree', async () => {
let folderArrayArg = await smartfile.fs.listFileTree(
const folderArrayArg = await smartfile.fs.listFileTree(
path.resolve('./test/testassets/'),
'**/*.txt'
);
@ -60,7 +60,7 @@ tap.test('.fs.listFileTree() -> should get a file tree', async () => {
});
tap.test('.fs.fileTreeToObject -> should read a file tree into an Object', async () => {
let fileArrayArg = await smartfile.fs.fileTreeToObject(
const fileArrayArg = await smartfile.fs.fileTreeToObject(
path.resolve('./test/testassets/'),
'**/*.txt'
);
@ -106,26 +106,26 @@ tap.test('.fs.removeMany -> should remove and array of files', async () => {
tap.test('.fs.removeManySync -> should remove and array of single files synchronouly', async () => {
smartfile.fs.removeManySync([
'./test/testassets/temp/testfile1.txt',
'./test/testassets/temp/testfile2.txt'
'./test/testassets/temp/testfile2.txt',
]);
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).to.be.false;
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile2.txt')).to.be.false;
});
tap.test('.fs.toObjectSync() -> should read an ' + '.yaml' + ' file to an object', async () => {
let testData = smartfile.fs.toObjectSync('./test/testassets/mytest.yaml');
const testData = smartfile.fs.toObjectSync('./test/testassets/mytest.yaml');
expect(testData).to.include({ key1: 'this works' });
expect(testData).to.include({ key2: 'this works too' });
});
tap.test(
'.fs.toObjectSync() -> should state unknown file type for unknown file types',
async () => {
let testData = smartfile.fs.toObjectSync('./test/testassets/mytest.txt');
const testData = smartfile.fs.toObjectSync('./test/testassets/mytest.txt');
}
);
tap.test('.fs.toObjectSync() -> should read an ' + '.json' + ' file to an object', async () => {
let testData = smartfile.fs.toObjectSync('./test/testassets/mytest.json');
const testData = smartfile.fs.toObjectSync('./test/testassets/mytest.json');
expect(testData).to.include({ key1: 'this works' });
expect(testData).to.include({ key2: 'this works too' });
});
@ -149,7 +149,7 @@ tap.test('.interpreter.filetype() -> should get the file type from a string', as
// ---------------------------
tap.test('.memory.toFs() -> should write a file to disk and return a promise', async () => {
let localString = 'myString';
const localString = 'myString';
await smartfile.memory.toFs(
localString,
path.join(process.cwd(), './test/testassets/temp/testMemToFs.txt')
@ -159,7 +159,7 @@ tap.test('.memory.toFs() -> should write a file to disk and return a promise', a
tap.test(
'.memory.toFsSync() -> should write a file to disk and return true if successfull',
async () => {
let localString = 'myString';
const localString = 'myString';
smartfile.memory.toFsSync(
localString,
path.join(process.cwd(), './test/testassets/temp/testMemToFsSync.txt')
@ -174,8 +174,8 @@ tap.test('.remote.toString() -> should load a remote file to a variable', async
expect(responseString).to.equal('Some TestString &&%$');
});
tap.test('.remote.toString() -> should reject a Promise when the link is false', async tools => {
await smartfile.remote.toString('https://push.rocks/doesnotexist.txt').catch(err => {
tap.test('.remote.toString() -> should reject a Promise when the link is false', async (tools) => {
await smartfile.remote.toString('https://push.rocks/doesnotexist.txt').catch((err) => {
return expect(err.message).to.equal(
'could not get remote file from https://push.rocks/doesnotexist.txt'
);
@ -187,11 +187,11 @@ tap.test('.remote.toString() -> should reject a Promise when the link is false',
// ---------------------------
tap.test('.Smartfile -> should produce vinyl compatible files', async () => {
let smartfileArray = await smartfile.fs.fileTreeToObject(
const smartfileArray = await smartfile.fs.fileTreeToObject(
process.cwd(),
'./test/testassets/testfolder/**/*'
);
let localSmartfile = smartfileArray[0];
const localSmartfile = smartfileArray[0];
expect(localSmartfile).to.be.instanceof(smartfile.Smartfile);
expect(localSmartfile.contents).to.be.instanceof(Buffer);
// tslint:disable-next-line:no-unused-expression
@ -203,12 +203,12 @@ tap.test('.Smartfile -> should produce vinyl compatible files', async () => {
});
tap.test('should output a smartfile array to disk', async () => {
let smartfileArray = await smartfile.fs.fileTreeToObject('./test/testassets/testfolder/', '*');
for (let smartfile of smartfileArray) {
console.log(smartfile.relative);
console.log(smartfile.path);
console.log(smartfile.base);
console.log(smartfile.parsedPath);
const smartfileArray = await smartfile.fs.fileTreeToObject('./test/testassets/testfolder/', '*');
for (const smartfileInstance of smartfileArray) {
console.log(smartfileInstance.relative);
console.log(smartfileInstance.path);
console.log(smartfileInstance.base);
console.log(smartfileInstance.parsedPath);
}
await smartfile.memory.smartfileArrayToFs(
smartfileArray,
@ -216,4 +216,14 @@ tap.test('should output a smartfile array to disk', async () => {
);
});
tap.test('should create, store and retrieve valid smartfiles', async () => {
const fileString = 'hi there';
const filePath = './test/testassets/utf8.txt';
const smartfileInstance = await smartfile.Smartfile.fromString(filePath, fileString, 'utf8');
smartfileInstance.write();
const smartfileInstance2 = await smartfile.Smartfile.fromFilePath(filePath);
const retrievedString = smartfileInstance.contents.toString();
expect(retrievedString).to.equal(fileString);
});
tap.start();

1
test/testassets/utf8.txt Normal file
View File

@ -0,0 +1 @@
hi there

View File

@ -4,7 +4,6 @@ import * as memory from './smartfile.memory';
export interface ISmartfileConstructorOptions {
path?: string;
contentString?: string;
contentBuffer?: Buffer;
base?: string;
}
@ -24,42 +23,64 @@ export class Smartfile {
*/
public static async fromFilePath(filePath: string) {
filePath = plugins.path.resolve(filePath);
const fileString = fs.toStringSync(filePath);
const fileBuffer = fs.toBufferSync(filePath);
const smartfile = new Smartfile({
path: filePath,
contentString: fileString
contentBuffer: fileBuffer,
});
return smartfile;
}
public static async fromBuffer(filePath: string, contentBufferArg: Buffer) {
const smartfile = new Smartfile({
contentBuffer: contentBufferArg,
path: filePath,
});
return smartfile;
}
public static async fromString(
filePath: string,
contentStringArg: string,
encodingArg: 'utf8' | 'binary'
) {
const smartfile = new Smartfile({
contentBuffer: Buffer.from(contentStringArg, encodingArg),
path: filePath,
});
return smartfile;
}
// ========
// INSTANCE
// ========
/**
* the full path of the file on disk
*/
path: string;
public path: string;
/**
*
*/
parsedPath: plugins.path.ParsedPath;
public parsedPath: plugins.path.ParsedPath;
/**
* the content of the file as Buffer
*/
contentBuffer: Buffer;
public contentBuffer: Buffer;
/**
* The current working directory of the file
* Note:this is similar to gulp and different from native node path base
*/
base: string;
public base: string;
/**
* sync the file with disk
*/
sync: boolean;
public sync: boolean;
/**
* the constructor of Smartfile
@ -69,8 +90,6 @@ export class Smartfile {
constructor(optionsArg: ISmartfileConstructorOptions) {
if (optionsArg.contentBuffer) {
this.contentBuffer = optionsArg.contentBuffer;
} else if (optionsArg.contentString) {
this.setContentsFromString(optionsArg.contentString);
} else {
console.log('created empty Smartfile?');
}
@ -83,8 +102,8 @@ export class Smartfile {
* set contents from string
* @param contentString
*/
setContentsFromString(contentString: string) {
this.contents = new Buffer(contentString);
public setContentsFromString(contentString: string, encodingArg: 'utf8' | 'binary' = 'utf8') {
this.contents = new Buffer(contentString, encodingArg);
}
/**
@ -92,7 +111,7 @@ export class Smartfile {
* Behaviours:
* - no argument write to exactly where the file was picked up
*/
async write(pathArg?: string) {
public async write(pathArg?: string) {
const stringToWrite = this.contentBuffer.toString();
await memory.toFs(stringToWrite, this.path);
}
@ -100,7 +119,7 @@ export class Smartfile {
/**
* read file from disk
*/
async read() {}
public async read() {}
// -----------------------------------------------
// vinyl compatibility
@ -118,21 +137,21 @@ export class Smartfile {
/**
* vinyl-compatibility
*/
get cwd() {
public get cwd() {
return process.cwd();
}
/**
* return relative path of file
*/
get relative(): string {
public get relative(): string {
return plugins.path.relative(this.base, this.path);
}
/**
* return truw when the file has content
*/
isNull(): boolean {
public isNull(): boolean {
if (!this.contentBuffer) {
return true;
}
@ -142,28 +161,28 @@ export class Smartfile {
/**
* return true if contents are Buffer
*/
isBuffer(): boolean {
public isBuffer(): boolean {
if (this.contents instanceof Buffer) {
return true;
}
return false;
}
isDirectory() {
public isDirectory() {
return false;
}
isStream() {
public isStream() {
return false;
}
isSymbolic() {
public isSymbolic() {
return false;
}
// update things
updateFileName(fileNameArg: string) {
let oldFileName = this.parsedPath.base;
public updateFileName(fileNameArg: string) {
const oldFileName = this.parsedPath.base;
this.path = this.path.replace(new RegExp(oldFileName + '$'), fileNameArg);
}
}

View File

@ -31,7 +31,7 @@ export const fileExistsSync = (filePath): boolean => {
*/
export const fileExists = async (filePath): Promise<boolean> => {
const done = plugins.smartpromise.defer<boolean>();
plugins.fs.access(filePath, 4, err => {
plugins.fs.access(filePath, 4, (err) => {
err ? done.resolve(false) : done.resolve(true);
});
return done.promise;
@ -64,7 +64,7 @@ export const isFile = (pathArg): boolean => {
*/
export const copy = async (fromArg: string, toArg: string): Promise<boolean> => {
const done = plugins.smartpromise.defer<boolean>();
plugins.fsExtra.copy(fromArg, toArg, {}, err => {
plugins.fsExtra.copy(fromArg, toArg, {}, (err) => {
if (err) {
throw new Error(`Could not copy from ${fromArg} to ${toArg}: ${err}`);
}
@ -244,7 +244,7 @@ export const fileTreeToObject = async (dirPathArg: string, miniMatchFilter: stri
new Smartfile({
contentBuffer: Buffer.from(fileContentString),
base: dirPath,
path: filePath
path: filePath,
})
);
}
@ -264,11 +264,11 @@ export const listFolders = async (pathArg: string, regexFilter?: RegExp): Promis
* @returns an array with the folder names as strings
*/
export const listFoldersSync = (pathArg: string, regexFilter?: RegExp): string[] => {
let folderArray = plugins.fsExtra.readdirSync(pathArg).filter(file => {
let folderArray = plugins.fsExtra.readdirSync(pathArg).filter((file) => {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isDirectory();
});
if (regexFilter) {
folderArray = folderArray.filter(fileItem => {
folderArray = folderArray.filter((fileItem) => {
return regexFilter.test(fileItem);
});
}
@ -288,11 +288,11 @@ export const listFiles = async (pathArg: string, regexFilter?: RegExp): Promise<
* @returns an array with the folder names as strings
*/
export const listFilesSync = (pathArg: string, regexFilter?: RegExp): string[] => {
let fileArray = plugins.fsExtra.readdirSync(pathArg).filter(file => {
let fileArray = plugins.fsExtra.readdirSync(pathArg).filter((file) => {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
fileArray = fileArray.filter(fileItem => {
fileArray = fileArray.filter((fileItem) => {
return regexFilter.test(fileItem);
});
}
@ -313,11 +313,11 @@ export const listAllItems = async (pathArg: string, regexFilter?: RegExp): Promi
* @executes SYNC
*/
export const listAllItemsSync = (pathArg: string, regexFilter?: RegExp): string[] => {
let allItmesArray = plugins.fsExtra.readdirSync(pathArg).filter(file => {
let allItmesArray = plugins.fsExtra.readdirSync(pathArg).filter((file) => {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
allItmesArray = allItmesArray.filter(fileItem => {
allItmesArray = allItmesArray.filter((fileItem) => {
return regexFilter.test(fileItem);
});
}
@ -347,7 +347,7 @@ export const listFileTree = async (
const options = {
cwd: dirPath,
nodir: true,
dot: true
dot: true,
};
plugins.glob(miniMatchFilter, options, (err, files: string[]) => {
if (err) {
@ -359,7 +359,7 @@ export const listFileTree = async (
let fileList = await done.promise;
if (absolutePathsBool) {
fileList = fileList.map(filePath => {
fileList = fileList.map((filePath) => {
return plugins.path.resolve(plugins.path.join(dirPath, filePath));
});
}

View File

@ -10,7 +10,7 @@ import SmartfileInterpreter = require('./smartfile.interpreter');
* @param fileTypeArg
* @returns {any|any}
*/
export let toObject = function(fileStringArg: string, fileTypeArg: string) {
export let toObject = function (fileStringArg: string, fileTypeArg: string) {
return SmartfileInterpreter.objectFile(fileStringArg, fileTypeArg);
};
@ -37,27 +37,27 @@ export let toFs = async (
}
// prepare actual write action
let fileString: string;
let fileEncoding: string = 'utf8';
let fileContent: string | Buffer;
let fileEncoding: 'utf8' | 'binary' = 'utf8';
let filePath: string = filePathArg;
// handle Smartfile
if (fileContentArg instanceof Smartfile) {
fileString = fileContentArg.contentBuffer.toString();
fileContent = fileContentArg.contentBuffer;
// handle options
if (optionsArg.respectRelative) {
filePath = plugins.path.join(filePath, fileContentArg.path);
}
} else if (Buffer.isBuffer(fileContentArg)) {
fileString = fileContentArg.toString('binary');
fileContent = fileContentArg;
fileEncoding = 'binary';
} else if (typeof fileContentArg === 'string') {
fileString = fileContentArg;
fileContent = fileContentArg;
} else {
throw new Error('fileContent is neither string nor Smartfile');
}
await smartfileFs.ensureDir(plugins.path.parse(filePath).dir);
plugins.fsExtra.writeFile(filePath, fileString, { encoding: fileEncoding }, done.resolve);
plugins.fsExtra.writeFile(filePath, fileContent, { encoding: fileEncoding }, done.resolve);
return await done.promise;
};
@ -66,7 +66,7 @@ export let toFs = async (
* @param fileArg
* @param filePathArg
*/
export let toFsSync = function(fileArg: string, filePathArg: string) {
export const toFsSync = (fileArg: string, filePathArg: string) => {
// function checks to abort if needed
if (!fileArg || !filePathArg) {
throw new Error('expected a valid arguments');
@ -74,7 +74,7 @@ export let toFsSync = function(fileArg: string, filePathArg: string) {
// prepare actual write action
let fileString: string;
let filePath: string = filePathArg;
const filePath: string = filePathArg;
if (typeof fileArg !== 'string') {
throw new Error('fileArg is not of type String.');
@ -86,9 +86,9 @@ export let toFsSync = function(fileArg: string, filePathArg: string) {
export let smartfileArrayToFs = async (smartfileArrayArg: Smartfile[], dirArg: string) => {
await smartfileFs.ensureDir(dirArg);
for (let smartfile of smartfileArrayArg) {
for (const smartfile of smartfileArrayArg) {
await toFs(smartfile, dirArg, {
respectRelative: true
respectRelative: true,
});
}
};

View File

@ -19,7 +19,7 @@ export let toObject = (fromArg: string) => {
const done = plugins.smartpromise.defer();
plugins.smartrequest
.request(fromArg, {
method: 'get'
method: 'get',
})
.then((res: any) => {
if (res.statusCode === 200) {