Compare commits

...

52 Commits

Author SHA1 Message Date
0ca38c109e 10.0.6 2023-01-09 15:32:37 +01:00
4e2321e1ee fix(core): update 2023-01-09 15:32:37 +01:00
a640ab3d7b 10.0.5 2022-09-05 00:21:43 +02:00
37d6d56287 fix(core): update 2022-09-05 00:21:42 +02:00
443a026502 10.0.4 2022-07-24 23:11:41 +02:00
9644c5b7e3 fix(core): update 2022-07-24 23:11:41 +02:00
25faa8c697 10.0.3 2022-07-24 23:04:52 +02:00
982387aaa3 fix(core): update 2022-07-24 23:04:51 +02:00
4a11f50efe 10.0.2 2022-06-09 19:27:00 +02:00
0ddec29392 fix(core): update 2022-06-09 19:26:59 +02:00
df484d54e8 10.0.1 2022-06-07 15:50:48 +02:00
f637c20241 fix(core): update 2022-06-07 15:50:47 +02:00
ed0c1a9181 10.0.0 2022-06-07 15:43:28 +02:00
0e22999f69 BREAKING CHANGE(core): switch to esm 2022-06-07 15:43:28 +02:00
38f001ab23 9.0.7 2022-06-07 15:11:22 +02:00
d1429c5a41 fix(core): update 2022-06-07 15:11:21 +02:00
403a0f4fae 9.0.6 2022-03-11 09:46:54 +01:00
91ade8a4d4 fix(updated repo structure): update 2022-03-11 09:46:54 +01:00
1a571bba90 9.0.5 2021-12-22 19:08:54 +01:00
bcb66b2ccf fix(core): update 2021-12-22 19:08:53 +01:00
0000984e4b 9.0.4 2021-12-20 15:11:22 +01:00
b391e54083 fix(core): update 2021-12-20 15:11:21 +01:00
b32c06aef2 9.0.3 2021-12-03 00:24:10 +01:00
27f60f6719 fix(core): update 2021-12-03 00:24:10 +01:00
b2482ab8a5 9.0.2 2021-12-01 10:47:29 +01:00
9c614bd2f3 fix(core): update 2021-12-01 10:47:29 +01:00
b12de7aed4 9.0.1 2021-12-01 01:19:50 +01:00
d6eb54d21c fix(absolute pathing): add functions for easily getting absolute paths 2021-12-01 01:19:49 +01:00
6646f173c6 9.0.0 2021-12-01 01:14:07 +01:00
f20657ff71 BREAKING CHANGE(relative pathing): improved relative pathing 2021-12-01 01:14:07 +01:00
7f3f2da702 8.0.11 2021-11-30 16:34:36 +01:00
1e60ab375b fix(core): update 2021-11-30 16:34:35 +01:00
98fa607c43 8.0.10 2021-04-26 08:24:36 +00:00
12b1672e58 fix(core): update 2021-04-26 08:24:36 +00:00
9fca2c3aa4 8.0.9 2021-04-07 09:48:54 +00:00
5b7d822cfc fix(core): update 2021-04-07 09:48:54 +00:00
ce57478e39 8.0.8 2020-10-11 15:34:24 +00:00
292c2699ea fix(core): update 2020-10-11 15:34:24 +00:00
afb7fa8e89 8.0.7 2020-10-09 15:15:48 +00:00
e2c3005a08 fix(core): update 2020-10-09 15:15:47 +00:00
53e595a023 8.0.6 2020-10-06 00:57:48 +00:00
93702dca78 fix(core): update 2020-10-06 00:57:47 +00:00
0a95ae6284 8.0.5 2020-10-05 16:20:58 +00:00
de09f85c34 fix(core): update 2020-10-05 16:20:57 +00:00
b9fefc7c95 8.0.4 2020-10-02 14:34:10 +00:00
76eae15f7d fix(core): update 2020-10-02 14:34:09 +00:00
2e457f6011 8.0.3 2020-10-02 14:13:34 +00:00
e83c63fd2a fix(core): update 2020-10-02 14:13:34 +00:00
c01006e365 8.0.2 2020-10-02 13:29:40 +00:00
a7adec8275 fix(core): update 2020-10-02 13:29:40 +00:00
2eddbf5751 8.0.1 2020-10-02 13:26:54 +00:00
eca3e141d2 fix(core): update 2020-10-02 13:26:53 +00:00
26 changed files with 4792 additions and 11091 deletions

View File

@ -12,31 +12,38 @@ stages:
- release - release
- metadata - metadata
before_script:
- pnpm install -g pnpm
- pnpm install -g @shipzone/pnpm
- npmci npm prepare
# ==================== # ====================
# security stage # security stage
# ==================== # ====================
mirror: # ====================
stage: security # security stage
script: # ====================
- npmci git mirror auditProductionDependencies:
only:
- tags
tags:
- lossless
- docker
- notpriv
audit:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security stage: security
script: script:
- npmci npm prepare - npmci command npm config set registry https://registry.npmjs.org
- npmci command npm install --ignore-scripts - npmci command pnpm audit --audit-level=high --prod
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high
tags: tags:
- lossless
- docker - docker
auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci command npm config set registry https://registry.npmjs.org
- npmci command pnpm audit --audit-level=high --dev
tags:
- lossless
- docker
allow_failure: true
# ==================== # ====================
# test stage # test stage
# ==================== # ====================
@ -44,7 +51,6 @@ audit:
testStable: testStable:
stage: test stage: test
script: script:
- npmci npm prepare
- npmci node install stable - npmci node install stable
- npmci npm install - npmci npm install
- npmci npm test - npmci npm test
@ -55,7 +61,6 @@ testStable:
testBuild: testBuild:
stage: test stage: test
script: script:
- npmci npm prepare
- npmci node install stable - npmci node install stable
- npmci npm install - npmci npm install
- npmci command npm run build - npmci command npm run build
@ -84,10 +89,9 @@ codequality:
only: only:
- tags - tags
script: script:
- npmci command npm install -g tslint typescript - npmci command npm install -g typescript
- npmci npm prepare - npmci npm prepare
- npmci npm install - npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags: tags:
- lossless - lossless
- docker - docker
@ -107,11 +111,9 @@ trigger:
pages: pages:
stage: metadata stage: metadata
script: script:
- npmci node install lts - npmci node install stable
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install - npmci npm install
- npmci command tsdoc - npmci command npm run buildDocs
tags: tags:
- lossless - lossless
- docker - docker

4
.snyk
View File

@ -1,4 +0,0 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.13.1
ignore: {}
patch: {}

24
.vscode/launch.json vendored
View File

@ -2,28 +2,10 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "current file", "command": "npm test",
"type": "node", "name": "Run npm test",
"request": "launch", "request": "launch",
"args": [ "type": "node-terminal"
"${relativeFile}"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "test.ts",
"type": "node",
"request": "launch",
"args": [
"test/test.ts"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
} }
] ]
} }

View File

View File

@ -1,8 +1,4 @@
{ {
"npmts": {
"mode": "default",
"coverageTreshold": 70
},
"npmdocker": {}, "npmdocker": {},
"npmci": { "npmci": {
"npmGlobalTools": [], "npmGlobalTools": [],
@ -14,7 +10,7 @@
"githost": "gitlab.com", "githost": "gitlab.com",
"gitscope": "pushrocks", "gitscope": "pushrocks",
"gitrepo": "smartfile", "gitrepo": "smartfile",
"shortDescription": "smart ways to work with files in nodejs", "description": "smart ways to work with files in nodejs",
"npmPackagename": "@pushrocks/smartfile", "npmPackagename": "@pushrocks/smartfile",
"license": "MIT" "license": "MIT"
} }

10839
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,15 @@
{ {
"name": "@pushrocks/smartfile", "name": "@pushrocks/smartfile",
"private": false, "private": false,
"version": "8.0.0", "version": "10.0.6",
"description": "offers smart ways to work with files in nodejs", "description": "offers smart ways to work with files in nodejs",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts", "typings": "dist_ts/index.d.ts",
"type": "module",
"scripts": { "scripts": {
"test": "(tstest test/)", "test": "(tstest test/)",
"build": "(tsbuild --web)" "build": "(tsbuild --web --allowimplicitany)",
"buildDocs": "tsdoc"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -24,25 +26,30 @@
}, },
"homepage": "https://gitlab.com/pushrocks/smartfile", "homepage": "https://gitlab.com/pushrocks/smartfile",
"dependencies": { "dependencies": {
"@pushrocks/smarthash": "^2.1.6", "@pushrocks/lik": "^6.0.0",
"@pushrocks/smartmime": "^1.0.3", "@pushrocks/smartdelay": "^2.0.13",
"@pushrocks/smartpath": "^4.0.3", "@pushrocks/smartfile-interfaces": "^1.0.7",
"@pushrocks/smartpromise": "^3.0.6", "@pushrocks/smarthash": "^3.0.1",
"@pushrocks/smartrequest": "^1.1.47", "@pushrocks/smartjson": "^5.0.5",
"@types/fs-extra": "^9.0.1", "@pushrocks/smartmime": "^1.0.5",
"fs-extra": "^9.0.1", "@pushrocks/smartpath": "^5.0.5",
"glob": "^7.1.6", "@pushrocks/smartpromise": "^3.1.6",
"js-yaml": "^3.14.0" "@pushrocks/smartrequest": "^2.0.11",
"@pushrocks/smartstream": "^2.0.3",
"@pushrocks/streamfunction": "^4.0.4",
"@types/fs-extra": "^11.0.0",
"@types/glob": "^8.0.0",
"@types/js-yaml": "^4.0.5",
"fs-extra": "^11.1.0",
"glob": "^8.0.3",
"js-yaml": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.24", "@gitzone/tsbuild": "^2.1.65",
"@gitzone/tsrun": "^1.2.12", "@gitzone/tsrun": "^1.2.39",
"@gitzone/tstest": "^1.0.43", "@gitzone/tstest": "^1.0.74",
"@pushrocks/tapbundle": "^3.2.9", "@pushrocks/tapbundle": "^5.0.4",
"@types/node": "^14.0.27", "@types/node": "^18.11.18"
"gulp-function": "^2.2.14",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

4396
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import * as smartfile from '../ts/index'; import * as smartfile from '../ts/index.js';
import path = require('path'); import * as path from 'path';
import { expect, tap } from '@pushrocks/tapbundle'; import { expect, tap } from '@pushrocks/tapbundle';
@ -8,46 +8,46 @@ import { expect, tap } from '@pushrocks/tapbundle';
// --------------------------- // ---------------------------
tap.test('.fs.fileExistsSync -> should return an accurate boolean', async () => { tap.test('.fs.fileExistsSync -> should return an accurate boolean', async () => {
expect(smartfile.fs.fileExistsSync('./test/testassets/mytest.json')).to.be.true; // tslint:disable-next-line: no-unused-expression
expect(smartfile.fs.fileExistsSync('./test/testassets/notthere.json')).be.false; expect(smartfile.fs.fileExistsSync('./test/testassets/mytest.json')).toBeTrue();
// tslint:disable-next-line: no-unused-expression
expect(smartfile.fs.fileExistsSync('./test/testassets/notthere.json')).toBeFalse();
}); });
tap.test('.fs.fileExists -> should resolve or reject a promise', async () => { tap.test('.fs.fileExists -> should resolve or reject a promise', async () => {
expect(smartfile.fs.fileExists('./test/testassets/mytest.json')).to.be.instanceof(Promise); expect(smartfile.fs.fileExists('./test/testassets/mytest.json')).toBeInstanceOf(Promise);
await smartfile.fs.fileExists('./test/testassets/mytest.json'); 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( return expect(err.message).toEqual(
"ENOENT: no such file or directory, access './test/testassets/notthere.json'" "ENOENT: no such file or directory, access './test/testassets/notthere.json'"
); );
}); });
}); });
tap.test('.fs.listFoldersSync() -> should get the file type from a string', async () => { tap.test('.fs.listFoldersSync() -> should get the file type from a string', async () => {
expect(smartfile.fs.listFoldersSync('./test/testassets/')).to.include('testfolder'); expect(smartfile.fs.listFoldersSync('./test/testassets/')).toContain('testfolder');
expect(smartfile.fs.listFoldersSync('./test/testassets/')).to.not.include('notExistentFolder'); expect(smartfile.fs.listFoldersSync('./test/testassets/')).not.toContain('notExistentFolder');
}); });
tap.test('.fs.listFolders() -> should get the file type from a string', async () => { tap.test('.fs.listFolders() -> should get the file type from a string', async () => {
const folderArrayArg = await smartfile.fs.listFolders('./test/testassets/'); const folderArrayArg = await smartfile.fs.listFolders('./test/testassets/');
expect(folderArrayArg).to.include('testfolder'); expect(folderArrayArg).toContain('testfolder');
expect(folderArrayArg).to.not.include('notExistentFolder'); expect(folderArrayArg).not.toContain('notExistentFolder');
}); });
tap.test('.fs.listFilesSync() -> should get the file type from a string', async () => { tap.test('.fs.listFilesSync() -> should get the file type from a string', async () => {
expect(smartfile.fs.listFilesSync('./test/testassets/')).to.include('mytest.json'); expect(smartfile.fs.listFilesSync('./test/testassets/')).toContain('mytest.json');
expect(smartfile.fs.listFilesSync('./test/testassets/')).to.not.include('notExistentFile'); expect(smartfile.fs.listFilesSync('./test/testassets/')).not.toContain('notExistentFile');
expect(smartfile.fs.listFilesSync('./test/testassets/', /mytest\.json/)).to.include( expect(smartfile.fs.listFilesSync('./test/testassets/', /mytest\.json/)).toContain('mytest.json');
'mytest.json' expect(smartfile.fs.listFilesSync('./test/testassets/', /mytests.json/)).not.toContain(
);
expect(smartfile.fs.listFilesSync('./test/testassets/', /mytests.json/)).to.not.include(
'mytest.json' 'mytest.json'
); );
}); });
tap.test('.fs.listFiles() -> should get the file type from a string', async () => { tap.test('.fs.listFiles() -> should get the file type from a string', async () => {
const folderArrayArg = await smartfile.fs.listFiles('./test/testassets/'); const folderArrayArg = await smartfile.fs.listFiles('./test/testassets/');
expect(folderArrayArg).to.include('mytest.json'); expect(folderArrayArg).toContain('mytest.json');
expect(folderArrayArg).to.not.include('notExistentFile'); expect(folderArrayArg).not.toContain('notExistentFile');
}); });
tap.test('.fs.listFileTree() -> should get a file tree', async () => { tap.test('.fs.listFileTree() -> should get a file tree', async () => {
@ -55,8 +55,8 @@ tap.test('.fs.listFileTree() -> should get a file tree', async () => {
path.resolve('./test/testassets/'), path.resolve('./test/testassets/'),
'**/*.txt' '**/*.txt'
); );
expect(folderArrayArg).to.include('testfolder/testfile1.txt'); expect(folderArrayArg).toContain('testfolder/testfile1.txt');
expect(folderArrayArg).to.not.include('mytest.json'); expect(folderArrayArg).not.toContain('mytest.json');
}); });
tap.test('.fs.fileTreeToObject -> should read a file tree into an Object', async () => { tap.test('.fs.fileTreeToObject -> should read a file tree into an Object', async () => {
@ -64,8 +64,8 @@ tap.test('.fs.fileTreeToObject -> should read a file tree into an Object', async
path.resolve('./test/testassets/'), path.resolve('./test/testassets/'),
'**/*.txt' '**/*.txt'
); );
expect(fileArrayArg[0]).to.be.instanceof(smartfile.Smartfile); expect(fileArrayArg[0]).toBeInstanceOf(smartfile.Smartfile);
expect(fileArrayArg[0].contents.toString()).to.equal(fileArrayArg[0].contentBuffer.toString()); expect(fileArrayArg[0].contents.toString()).toEqual(fileArrayArg[0].contentBuffer.toString());
}); });
tap.test('.fs.copy() -> should copy a directory', async () => { tap.test('.fs.copy() -> should copy a directory', async () => {
@ -91,15 +91,15 @@ tap.test('.fs.remove -> should remove single files', async () => {
tap.test('.fs.removeSync -> should remove single files synchronouly', async () => { tap.test('.fs.removeSync -> should remove single files synchronouly', async () => {
smartfile.fs.removeSync('./test/testassets/temp/testfile1.txt'); smartfile.fs.removeSync('./test/testassets/temp/testfile1.txt');
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).to.be.false; expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).toBeFalse();
}); });
tap.test('.fs.removeMany -> should remove and array of files', async () => { tap.test('.fs.removeMany -> should remove and array of files', async () => {
smartfile.fs smartfile.fs
.removeMany(['./test/testassets/temp/testfile1.txt', './test/testassets/temp/testfile2.txt']) .removeMany(['./test/testassets/temp/testfile1.txt', './test/testassets/temp/testfile2.txt'])
.then(() => { .then(() => {
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).to.be.false; expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).toBeFalse();
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile2.txt')).to.be.false; expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile2.txt')).toBeFalse();
}); });
}); });
@ -108,14 +108,14 @@ tap.test('.fs.removeManySync -> should remove and array of single files synchron
'./test/testassets/temp/testfile1.txt', './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/testfile1.txt')).toBeFalse();
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile2.txt')).to.be.false; expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile2.txt')).toBeFalse();
}); });
tap.test('.fs.toObjectSync() -> should read an ' + '.yaml' + ' file to an object', async () => { tap.test('.fs.toObjectSync() -> should read an .yaml file to an object', async () => {
const 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.key1).toEqual('this works');
expect(testData).to.include({ key2: 'this works too' }); expect(testData.key2).toEqual('this works too');
}); });
tap.test( tap.test(
'.fs.toObjectSync() -> should state unknown file type for unknown file types', '.fs.toObjectSync() -> should state unknown file type for unknown file types',
@ -124,16 +124,14 @@ tap.test(
} }
); );
tap.test('.fs.toObjectSync() -> should read an ' + '.json' + ' file to an object', async () => { tap.test('.fs.toObjectSync() -> should read an .json file to an object', async () => {
const 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.key1).toEqual('this works');
expect(testData).to.include({ key2: 'this works too' }); expect(testData.key2).toEqual('this works too');
}); });
tap.test('.fs.toStringSync() -> should read a file to a string', async () => { tap.test('.fs.toStringSync() -> should read a file to a string', async () => {
expect(smartfile.fs.toStringSync('./test/testassets/mytest.txt')).to.equal( expect(smartfile.fs.toStringSync('./test/testassets/mytest.txt')).toEqual('Some TestString &&%$');
'Some TestString &&%$'
);
}); });
// --------------------------- // ---------------------------
@ -141,7 +139,7 @@ tap.test('.fs.toStringSync() -> should read a file to a string', async () => {
// --------------------------- // ---------------------------
tap.test('.interpreter.filetype() -> should get the file type from a string', async () => { tap.test('.interpreter.filetype() -> should get the file type from a string', async () => {
expect(smartfile.interpreter.filetype('./somefolder/data.json')).equal('json'); expect(smartfile.interpreter.filetype('./somefolder/data.json')).toEqual('json');
}); });
// --------------------------- // ---------------------------
@ -167,21 +165,6 @@ tap.test(
} }
); );
tap.test('.remote.toString() -> should load a remote file to a variable', async () => {
const responseString = await smartfile.remote.toString(
'https://raw.githubusercontent.com/pushrocks/smartfile/master/test/testassets/mytest.txt'
);
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) => {
return expect(err.message).to.equal(
'could not get remote file from https://push.rocks/doesnotexist.txt'
);
});
});
// --------------------------- // ---------------------------
// smartfile.Smartfile // smartfile.Smartfile
// --------------------------- // ---------------------------
@ -192,14 +175,14 @@ tap.test('.Smartfile -> should produce vinyl compatible files', async () => {
'./test/testassets/testfolder/**/*' './test/testassets/testfolder/**/*'
); );
const localSmartfile = smartfileArray[0]; const localSmartfile = smartfileArray[0];
expect(localSmartfile).to.be.instanceof(smartfile.Smartfile); expect(localSmartfile).toBeInstanceOf(smartfile.Smartfile);
expect(localSmartfile.contents).to.be.instanceof(Buffer); expect(localSmartfile.contents).toBeInstanceOf(Buffer);
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(localSmartfile.isBuffer()).to.be.true; expect(localSmartfile.isBuffer()).toBeTrue();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(localSmartfile.isDirectory()).to.be.false; expect(localSmartfile.isDirectory()).toBeFalse();
// tslint:disable-next-line:no-unused-expression // tslint:disable-next-line:no-unused-expression
expect(localSmartfile.isNull()).to.be.false; expect(localSmartfile.isNull()).toBeFalse();
}); });
tap.test('should output a smartfile array to disk', async () => { tap.test('should output a smartfile array to disk', async () => {
@ -223,7 +206,19 @@ tap.test('should create, store and retrieve valid smartfiles', async () => {
smartfileInstance.write(); smartfileInstance.write();
const smartfileInstance2 = await smartfile.Smartfile.fromFilePath(filePath); const smartfileInstance2 = await smartfile.Smartfile.fromFilePath(filePath);
const retrievedString = smartfileInstance.contents.toString(); const retrievedString = smartfileInstance.contents.toString();
expect(retrievedString).to.equal(fileString); expect(retrievedString).toEqual(fileString);
});
tap.test('should get a hash', async () => {
const fileString = 'hi there';
const filePath = './test/testassets/utf8.txt';
const smartfileInstance = await smartfile.Smartfile.fromString(filePath, fileString, 'utf8');
const hash = await smartfileInstance.getHash();
console.log(hash);
});
tap.test('should wait for file to be ready', async () => {
await smartfile.fs.waitForFileToBeReady('./test/testassets/mytest.json');
}); });
tap.start(); tap.start();

View File

@ -0,0 +1,15 @@
import { tap, expect } from '@pushrocks/tapbundle';
import * as smartfile from '../ts/index.js';
tap.test('should create a virtualdirectory', async () => {
const virtualDir = await smartfile.VirtualDirectory.fromFsDirPath('./test/testassets/testfolder');
expect(virtualDir.smartfileArray.length).toEqual(4);
});
tap.test('should write to a directory', async () => {
const virtualDir = await smartfile.VirtualDirectory.fromFsDirPath('./test/testassets/testfolder');
virtualDir.saveToDisk('./test/testassets/test');
});
tap.start();

View File

@ -0,0 +1 @@
okidoks

View File

@ -0,0 +1 @@
hi

View File

View File

8
ts/00_commitinfo_data.ts Normal file
View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@pushrocks/smartfile',
version: '10.0.6',
description: 'offers smart ways to work with files in nodejs'
}

View File

@ -1,12 +1,13 @@
import * as plugins from './smartfile.plugins'; import * as plugins from './smartfile.plugins.js';
import * as SmartfileFs from './smartfile.fs'; import * as fsMod from './smartfile.fs.js';
import * as SmartfileInterpreter from './smartfile.interpreter'; import * as fsStreamMod from './smartfile.fsstream.js';
import * as SmartfileMemory from './smartfile.memory'; import * as interpreterMod from './smartfile.interpreter.js';
import * as SmartfileRemote from './smartfile.remote'; import * as memoryMod from './smartfile.memory.js';
export { Smartfile } from './smartfile.classes.smartfile'; export * from './smartfile.classes.smartfile.js';
export * from './smartfile.classes.virtualdirectory.js';
export let fs = SmartfileFs; export const fs = fsMod;
export let interpreter = SmartfileInterpreter; export const fsStream = fsStreamMod;
export let memory = SmartfileMemory; export const interpreter = interpreterMod;
export let remote = SmartfileRemote; export const memory = memoryMod;

View File

@ -1,18 +1,18 @@
import * as plugins from './smartfile.plugins'; import * as plugins from './smartfile.plugins.js';
import * as fs from './smartfile.fs'; import * as fs from './smartfile.fs.js';
import * as memory from './smartfile.memory'; import * as memory from './smartfile.memory.js';
export interface ISmartfileConstructorOptions { export interface ISmartfileConstructorOptions {
path?: string; path: string;
contentBuffer?: Buffer; contentBuffer: Buffer;
base?: string; base: string;
} }
/** /**
* class Smartfile * class Smartfile
* -> is vinyl file compatible * -> is vinyl file compatible
*/ */
export class Smartfile { export class Smartfile extends plugins.smartjson.Smartjson {
// ====== // ======
// STATIC // STATIC
// ====== // ======
@ -21,20 +21,26 @@ export class Smartfile {
* creates a Smartfile from a filePath * creates a Smartfile from a filePath
* @param filePath * @param filePath
*/ */
public static async fromFilePath(filePath: string) { public static async fromFilePath(filePath: string, baseArg: string = process.cwd()) {
filePath = plugins.path.resolve(filePath); filePath = plugins.path.resolve(filePath);
const fileBuffer = fs.toBufferSync(filePath); const fileBuffer = fs.toBufferSync(filePath);
const smartfile = new Smartfile({ const smartfile = new Smartfile({
path: filePath,
contentBuffer: fileBuffer, contentBuffer: fileBuffer,
base: baseArg,
path: plugins.path.relative(baseArg, filePath),
}); });
return smartfile; return smartfile;
} }
public static async fromBuffer(filePath: string, contentBufferArg: Buffer) { public static async fromBuffer(
filePath: string,
contentBufferArg: Buffer,
baseArg: string = process.cwd()
) {
const smartfile = new Smartfile({ const smartfile = new Smartfile({
contentBuffer: contentBufferArg, contentBuffer: contentBufferArg,
path: filePath, base: baseArg,
path: plugins.path.relative(baseArg, filePath),
}); });
return smartfile; return smartfile;
@ -43,43 +49,62 @@ export class Smartfile {
public static async fromString( public static async fromString(
filePath: string, filePath: string,
contentStringArg: string, contentStringArg: string,
encodingArg: 'utf8' | 'binary' encodingArg: 'utf8' | 'binary',
baseArg = process.cwd()
) { ) {
const smartfile = new Smartfile({ const smartfile = new Smartfile({
contentBuffer: Buffer.from(contentStringArg, encodingArg), contentBuffer: Buffer.from(contentStringArg, encodingArg),
path: filePath, base: baseArg,
path: plugins.path.relative(baseArg, filePath),
}); });
return smartfile; return smartfile;
} }
public static async fromFoldedJson(foldedJsonArg: string) {
return new Smartfile(plugins.smartjson.parse(foldedJsonArg));
}
// ======== // ========
// INSTANCE // INSTANCE
// ======== // ========
/** /**
* the full path of the file on disk * the relative path of the file
*/ */
@plugins.smartjson.foldDec()
public path: string; public path: string;
/** /**
* * a parsed path
*/ */
public parsedPath: plugins.path.ParsedPath; public get parsedPath(): plugins.path.ParsedPath {
return plugins.path.parse(this.path);
}
public get absolutePath() {
return plugins.path.join(this.base, this.path);
}
public get absoluteParsedPath() {
return plugins.path.parse(this.absolutePath);
}
/** /**
* the content of the file as Buffer * the content of the file as Buffer
*/ */
@plugins.smartjson.foldDec()
public contentBuffer: Buffer; public contentBuffer: Buffer;
/** /**
* The current working directory of the file * The current working directory of the file
* Note:this is similar to gulp and different from native node path base * Note:this is similar to gulp and different from native node path base
*/ */
@plugins.smartjson.foldDec()
public base: string; public base: string;
/** /**
* sync the file with disk * sync the file with disk
*/ */
@plugins.smartjson.foldDec()
public sync: boolean; public sync: boolean;
/** /**
@ -88,13 +113,13 @@ export class Smartfile {
*/ */
constructor(optionsArg: ISmartfileConstructorOptions) { constructor(optionsArg: ISmartfileConstructorOptions) {
super();
if (optionsArg.contentBuffer) { if (optionsArg.contentBuffer) {
this.contentBuffer = optionsArg.contentBuffer; this.contentBuffer = optionsArg.contentBuffer;
} else { } else {
console.log('created empty Smartfile?'); console.log('created empty Smartfile?');
} }
this.path = optionsArg.path; this.path = optionsArg.path;
this.parsedPath = plugins.path.parse(this.path);
this.base = optionsArg.base; this.base = optionsArg.base;
} }
@ -107,19 +132,51 @@ export class Smartfile {
} }
/** /**
* write file to disk * write file to disk at its original location
* Behaviours: * Behaviours:
* - no argument write to exactly where the file was picked up * - no argument write to exactly where the file was picked up
*/ */
public async write(pathArg?: string) { public async write() {
const stringToWrite = this.contentBuffer.toString(); await memory.toFs(this.contentBuffer, plugins.path.join(this.base, this.path));
await memory.toFs(stringToWrite, this.path); }
/**
* writes the file to path given as argument
* note: if the path is not absolute, takes process.cwd() as base
* @param filePathArg
*/
public async writeToDiskAtPath(filePathArg: string) {
if (!plugins.path.isAbsolute(filePathArg)) {
filePathArg = plugins.path.join(process.cwd(), filePathArg);
}
await memory.toFs(this.contentBuffer, filePathArg);
}
/**
* writes the file to a directory combined with the relative path portion
* @param dirPathArg
* @returns
*/
public async writeToDir(dirPathArg: string) {
dirPathArg = plugins.smartpath.transform.toAbsolute(dirPathArg) as string;
const filePath = plugins.path.join(dirPathArg, this.path);
await memory.toFs(this.contentBuffer, filePath);
return filePath;
} }
/** /**
* read file from disk * read file from disk
*/ */
public async read() {} public async read() {
this.contentBuffer = await fs.toBuffer(plugins.path.join(this.base, this.path));
}
/**
* deletes the file from disk at its original location
*/
public async delete() {
await fs.remove(plugins.path.join(this.base, this.path));
}
// ----------------------------------------------- // -----------------------------------------------
// vinyl compatibility // vinyl compatibility
@ -145,7 +202,7 @@ export class Smartfile {
* return relative path of file * return relative path of file
*/ */
public get relative(): string { public get relative(): string {
return plugins.path.relative(this.base, this.path); return this.path;
} }
/** /**
@ -180,9 +237,29 @@ export class Smartfile {
return false; return false;
} }
public async getHash(typeArg: 'path' | 'content' | 'all' = 'all') {
const pathHash = await plugins.smarthash.sha256FromString(this.path);
const contentHash = await plugins.smarthash.sha256FromBuffer(this.contentBuffer);
const combinedHash = await plugins.smarthash.sha256FromString(pathHash + contentHash);
switch(typeArg) {
case 'path':
return pathHash;
case 'content':
return contentHash;
case 'all':
default:
return combinedHash;
}
}
// update things // update things
public updateFileName(fileNameArg: string) { public updateFileName(fileNameArg: string) {
const oldFileName = this.parsedPath.base; const oldFileName = this.parsedPath.base;
this.path = this.path.replace(new RegExp(oldFileName + '$'), fileNameArg); this.path = this.path.replace(new RegExp(oldFileName + '$'), fileNameArg);
} }
public async editContentAsString(editFuncArg: (fileStringArg: string) => Promise<string>) {
const newFileString = await editFuncArg(this.contentBuffer.toString());
this.contentBuffer = Buffer.from(newFileString);
}
} }

View File

@ -0,0 +1,61 @@
import { Smartfile } from './smartfile.classes.smartfile.js';
import * as plugins from './smartfile.plugins.js';
import * as fs from './smartfile.fs.js';
/**
* a virtual directory exposes a fs api
*/
export class VirtualDirectory {
// STATIC
public static async fromFsDirPath(pathArg: string): Promise<VirtualDirectory> {
const newVirtualDir = new VirtualDirectory();
newVirtualDir.addSmartfiles(await fs.fileTreeToObject(pathArg, '**/*'));
return newVirtualDir;
}
public static async fromVirtualDirTransferableObject(
virtualDirTransferableObjectArg: plugins.smartfileInterfaces.VirtualDirTransferableObject
): Promise<VirtualDirectory> {
const newVirtualDir = new VirtualDirectory();
for (const fileArg of virtualDirTransferableObjectArg.files) {
newVirtualDir.addSmartfiles([Smartfile.enfoldFromJson(fileArg) as Smartfile]);
}
return newVirtualDir;
}
// INSTANCE
public smartfileArray: Smartfile[] = [];
constructor() {}
public addSmartfiles(smartfileArrayArg: Smartfile[]) {
this.smartfileArray = this.smartfileArray.concat(smartfileArrayArg);
}
public async getFileByPath(pathArg: string) {
for (const smartfile of this.smartfileArray) {
if (smartfile.path === pathArg) {
return smartfile;
}
}
}
public async toVirtualDirTransferableObject(): Promise<plugins.smartfileInterfaces.VirtualDirTransferableObject> {
return {
files: this.smartfileArray.map((smartfileArg) => smartfileArg.foldToJson()),
};
}
public async saveToDisk(dirArg: string) {
console.log(`writing VirtualDirectory with ${this.smartfileArray.length} to directory:
--> ${dirArg}`);
for (const smartfileArg of this.smartfileArray) {
const filePath = await smartfileArg.writeToDir(dirArg);
console.log(`wrote ${smartfileArg.relative} to
--> ${filePath}`);
}
}
// TODO implement root shifting to get subdirectories as new virtual directories
// TODO implement root shifting to combine VirtualDirecotries in a parent virtual directory
}

View File

@ -1,9 +1,9 @@
import plugins = require('./smartfile.plugins'); import * as plugins from './smartfile.plugins.js';
import SmartfileInterpreter = require('./smartfile.interpreter'); import * as interpreter from './smartfile.interpreter.js';
import { Smartfile } from './smartfile.classes.smartfile'; import { Smartfile } from './smartfile.classes.smartfile.js';
import * as memory from './smartfile.memory'; import * as memory from './smartfile.memory.js';
/*=============================================================== /*===============================================================
============================ Checks ============================= ============================ Checks =============================
===============================================================*/ ===============================================================*/
@ -186,8 +186,8 @@ export const removeManySync = (filePathArrayArg: string[]): void => {
export const toObjectSync = (filePathArg, fileTypeArg?) => { export const toObjectSync = (filePathArg, fileTypeArg?) => {
const fileString = plugins.fsExtra.readFileSync(filePathArg, 'utf8'); const fileString = plugins.fsExtra.readFileSync(filePathArg, 'utf8');
let fileType; let fileType;
fileTypeArg ? (fileType = fileTypeArg) : (fileType = SmartfileInterpreter.filetype(filePathArg)); fileTypeArg ? (fileType = fileTypeArg) : (fileType = interpreter.filetype(filePathArg));
return SmartfileInterpreter.objectFile(fileString, fileType); return interpreter.objectFile(fileString, fileType);
}; };
/** /**
@ -195,10 +195,17 @@ export const toObjectSync = (filePathArg, fileTypeArg?) => {
*/ */
export const toStringSync = (filePath: string): string => { export const toStringSync = (filePath: string): string => {
const encoding = plugins.smartmime.getEncoding(filePath); const encoding = plugins.smartmime.getEncoding(filePath);
const fileString: string = plugins.fsExtra.readFileSync(filePath, encoding); let fileString: string | Buffer = plugins.fsExtra.readFileSync(filePath, encoding);
if (Buffer.isBuffer(fileString)) {
fileString = fileString.toString('binary');
}
return fileString; return fileString;
}; };
export const toBuffer = async (filePath: string): Promise<Buffer> => {
return plugins.fsExtra.readFile(filePath);
};
export const toBufferSync = (filePath: string): Buffer => { export const toBufferSync = (filePath: string): Buffer => {
return plugins.fsExtra.readFileSync(filePath); return plugins.fsExtra.readFileSync(filePath);
}; };
@ -207,7 +214,7 @@ export const fileTreeToHash = async (dirPathArg: string, miniMatchFilter: string
const fileTreeObject = await fileTreeToObject(dirPathArg, miniMatchFilter); const fileTreeObject = await fileTreeToObject(dirPathArg, miniMatchFilter);
let combinedString = ''; let combinedString = '';
for (const smartfile of fileTreeObject) { for (const smartfile of fileTreeObject) {
combinedString += smartfile.contentBuffer.toString(); combinedString += await smartfile.getHash();
} }
const hash = await plugins.smarthash.sha256FromString(combinedString); const hash = await plugins.smarthash.sha256FromString(combinedString);
return hash; return hash;
@ -224,7 +231,7 @@ export const fileTreeToObject = async (dirPathArg: string, miniMatchFilter: stri
if (plugins.path.isAbsolute(miniMatchFilter)) { if (plugins.path.isAbsolute(miniMatchFilter)) {
dirPath = '/'; dirPath = '/';
} else { } else {
dirPath = dirPathArg; dirPath = plugins.smartpath.transform.toAbsolute(dirPathArg) as string;
} }
const fileTree = await listFileTree(dirPath, miniMatchFilter); const fileTree = await listFileTree(dirPath, miniMatchFilter);
@ -366,3 +373,29 @@ export const listFileTree = async (
return fileList; return fileList;
}; };
/**
* checks wether a file is ready for processing
*/
export const waitForFileToBeReady = async (filePathArg: string): Promise<void> => {
if (!plugins.path.isAbsolute(filePathArg)) {
filePathArg = plugins.path.resolve(filePathArg);
}
const limitedArray = new plugins.lik.LimitedArray<number>(3);
let fileReady = false;
while (!fileReady) {
const stats = await plugins.fsExtra.stat(filePathArg);
limitedArray.addOne(stats.size);
if (
limitedArray.array.length < 3 ||
!(
limitedArray.array[0] === limitedArray.array[1] &&
limitedArray.array[1] === limitedArray.array[2]
)
) {
await plugins.smartdelay.delayFor(5000);
} else {
fileReady = true;
}
}
};

14
ts/smartfile.fsstream.ts Normal file
View File

@ -0,0 +1,14 @@
/*
This file contains logic for streaming things from and to the filesystem
*/
import * as plugins from './smartfile.plugins.js';
export const createReadStream = (pathArg: string) => {
return plugins.fs.createReadStream(pathArg);
};
export const createWriteStream = (pathArg: string) => {
return plugins.fs.createWriteStream(pathArg);
};
export const streamDirectory = async (dirPathArg: string) => {};

View File

@ -1,4 +1,4 @@
import plugins = require('./smartfile.plugins'); import * as plugins from './smartfile.plugins.js';
export let filetype = (pathArg: string): string => { export let filetype = (pathArg: string): string => {
const extName = plugins.path.extname(pathArg); const extName = plugins.path.extname(pathArg);
@ -10,7 +10,7 @@ export let objectFile = (fileStringArg: string, fileTypeArg) => {
switch (fileTypeArg) { switch (fileTypeArg) {
case 'yml': case 'yml':
case 'yaml': case 'yaml':
return plugins.yaml.safeLoad(fileStringArg); return plugins.yaml.load(fileStringArg);
case 'json': case 'json':
return JSON.parse(fileStringArg); return JSON.parse(fileStringArg);
default: default:

View File

@ -1,8 +1,7 @@
import plugins = require('./smartfile.plugins'); import * as plugins from './smartfile.plugins.js';
import { Smartfile } from './smartfile.classes.smartfile'; import { Smartfile } from './smartfile.classes.smartfile.js';
import * as smartfileFs from './smartfile.fs'; import * as smartfileFs from './smartfile.fs.js';
import * as interpreter from './smartfile.interpreter.js';
import SmartfileInterpreter = require('./smartfile.interpreter');
/** /**
* converts file to Object * converts file to Object
@ -10,8 +9,8 @@ import SmartfileInterpreter = require('./smartfile.interpreter');
* @param fileTypeArg * @param fileTypeArg
* @returns {any|any} * @returns {any|any}
*/ */
export let toObject = function (fileStringArg: string, fileTypeArg: string) { export let toObject = (fileStringArg: string, fileTypeArg: string) => {
return SmartfileInterpreter.objectFile(fileStringArg, fileTypeArg); return interpreter.objectFile(fileStringArg, fileTypeArg);
}; };
export interface IToFsOptions { export interface IToFsOptions {

View File

@ -5,16 +5,32 @@ import * as path from 'path';
export { fs, path }; export { fs, path };
// @pushrocks scope // @pushrocks scope
import * as lik from '@pushrocks/lik';
import * as smartfileInterfaces from '@pushrocks/smartfile-interfaces';
import * as smartdelay from '@pushrocks/smartdelay';
import * as smarthash from '@pushrocks/smarthash'; import * as smarthash from '@pushrocks/smarthash';
import * as smartjson from '@pushrocks/smartjson';
import * as smartmime from '@pushrocks/smartmime'; import * as smartmime from '@pushrocks/smartmime';
import * as smartpath from '@pushrocks/smartpath'; import * as smartpath from '@pushrocks/smartpath';
import * as smartpromise from '@pushrocks/smartpromise'; import * as smartpromise from '@pushrocks/smartpromise';
import * as smartrequest from '@pushrocks/smartrequest'; import * as smartrequest from '@pushrocks/smartrequest';
import * as smartstream from '@pushrocks/smartstream';
export { smarthash, smartmime, smartpath, smartpromise, smartrequest }; export {
lik,
smartfileInterfaces,
smartdelay,
smarthash,
smartjson,
smartmime,
smartpath,
smartpromise,
smartrequest,
smartstream,
};
// third party scope // third party scope
import * as fsExtra from 'fs-extra'; import fsExtra from 'fs-extra';
import glob from 'glob'; import glob from 'glob';
import yaml from 'js-yaml'; import yaml from 'js-yaml';

View File

@ -1,51 +0,0 @@
import plugins = require('./smartfile.plugins');
import SmartfileInterpreter = require('./smartfile.interpreter');
/* export let toFs = function (from: string, toPath: string) {
let done = plugins.q.defer()
let stream = plugins.smartrequest(from).pipe(plugins.fsExtra.createWriteStream(toPath))
stream.on('finish', function () {
done.resolve(toPath)
})
return done.promise
} */
/**
*
* @param fromArg
* @returns {any}
*/
export let toObject = (fromArg: string) => {
const done = plugins.smartpromise.defer();
plugins.smartrequest
.request(fromArg, {
method: 'get',
})
.then((res: any) => {
if (res.statusCode === 200) {
done.resolve(res.body);
} else {
console.log('could not get remote file from ' + fromArg);
done.reject(new Error('could not get remote file from ' + fromArg));
}
});
return done.promise;
};
/**
*
* @param fromArg
* @returns {any}
*/
export let toString = (fromArg: string): Promise<string> => {
const done = plugins.smartpromise.defer<string>();
plugins.smartrequest.getBinary(fromArg).then((res: any) => {
if (res.statusCode === 200) {
const encoding = plugins.smartmime.getEncoding(fromArg);
done.resolve(res.body.toString(encoding));
} else {
done.reject(new Error('could not get remote file from ' + fromArg));
}
});
return done.promise;
};

8
tsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"esModuleInterop": true,
"target": "ES2017",
"moduleResolution": "node"
}
}

View File

@ -1,17 +0,0 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}