Compare commits

..

199 Commits

Author SHA1 Message Date
493a235065 11.0.13 2024-04-12 15:00:56 +02:00
e4e48dc9db fix(core): update 2024-04-12 15:00:55 +02:00
7de647daa1 11.0.12 2024-04-12 14:51:23 +02:00
34bc92137b fix(core): update 2024-04-12 14:51:23 +02:00
954df5a0ee 11.0.11 2024-04-12 14:44:13 +02:00
b9c15b11ad fix(core): update 2024-04-12 14:44:12 +02:00
55e6e81957 11.0.10 2024-04-03 15:39:27 +02:00
f37956270c fix(core): update 2024-04-03 15:39:26 +02:00
0c985b9c00 11.0.9 2024-04-03 15:38:59 +02:00
85ff487809 fix(core): update 2024-04-03 15:38:58 +02:00
eb65c4e859 11.0.8 2024-04-02 21:37:32 +02:00
a1d6c37f18 fix(core): update 2024-04-02 21:37:31 +02:00
915ad00801 11.0.7 2024-04-02 20:58:34 +02:00
910671bfc6 fix(core): update 2024-04-02 20:58:33 +02:00
ae8835d430 11.0.6 2024-04-02 20:53:03 +02:00
d08cc0f350 fix(core): update 2024-04-02 20:53:02 +02:00
1311039127 update npmextra.json: githost 2024-04-01 21:35:01 +02:00
c267d2f226 update npmextra.json: githost 2024-04-01 19:58:14 +02:00
5a9e1b5798 11.0.5 2024-04-01 17:46:40 +02:00
b1ec86ee2d fix(core): update 2024-04-01 17:46:40 +02:00
a1353170f6 update npmextra.json: githost 2024-03-30 21:47:12 +01:00
3ff6de201d 11.0.4 2023-11-24 19:29:00 +01:00
f5c106b2ca fix(core): update 2023-11-24 19:28:59 +01:00
d3c26d0d46 11.0.3 2023-11-24 19:15:41 +01:00
9935fe2d3c fix(core): update 2023-11-24 19:15:41 +01:00
3b05aab39b 11.0.2 2023-11-07 21:32:00 +01:00
53be2eb59d fix(core): update 2023-11-07 21:32:00 +01:00
c92a0dddbd 11.0.1 2023-11-07 14:09:49 +01:00
27403a73b5 fix(core): update 2023-11-07 14:09:48 +01:00
b925e5e662 11.0.0 2023-11-06 11:15:12 +01:00
98a5d2c94d BREAKING CHANGE(core): update 2023-11-06 11:15:11 +01:00
0e735cba20 10.0.40 2023-11-04 20:54:14 +01:00
f815457801 fix(core): update 2023-11-04 20:54:13 +01:00
f7e47ae354 10.0.39 2023-11-04 20:43:55 +01:00
684e893801 fix(core): update 2023-11-04 20:43:54 +01:00
d4b381d33d 10.0.38 2023-11-04 20:14:21 +01:00
291a11aa60 fix(core): update 2023-11-04 20:14:20 +01:00
ca592afec9 update 2023-11-04 20:07:43 +01:00
8b07197224 10.0.37 2023-11-03 02:31:57 +01:00
b60fd15ec6 fix(core): update 2023-11-03 02:31:57 +01:00
853eccc780 10.0.36 2023-11-03 02:24:37 +01:00
c26aff85b5 fix(core): update 2023-11-03 02:24:36 +01:00
321e4d9dea 10.0.35 2023-11-03 01:25:38 +01:00
3d2789857c fix(core): update 2023-11-03 01:25:37 +01:00
07b88a078d 10.0.34 2023-11-03 00:41:06 +01:00
6fee0028d8 fix(core): update 2023-11-03 00:41:05 +01:00
629c52f9bc 10.0.33 2023-10-12 02:21:40 +02:00
fd056c29e9 fix(core): update 2023-10-12 02:21:39 +02:00
36c456b509 10.0.32 2023-09-22 17:05:35 +02:00
16f8c25557 fix(core): update 2023-09-22 17:05:35 +02:00
219e070ba2 10.0.31 2023-08-31 18:45:24 +02:00
ee97e1d88b fix(core): update 2023-08-31 18:45:23 +02:00
279db74568 10.0.30 2023-08-23 10:58:38 +02:00
b84c504f11 fix(core): update 2023-08-23 10:58:38 +02:00
7b3194cc13 10.0.29 2023-08-23 09:38:49 +02:00
e1e821efec fix(core): update 2023-08-23 09:38:49 +02:00
6b613d1b8a 10.0.28 2023-07-12 10:00:40 +02:00
70f1c58a82 fix(core): update 2023-07-12 10:00:40 +02:00
5df76ca94b 10.0.27 2023-07-10 23:07:51 +02:00
32cfda3c90 fix(core): update 2023-07-10 23:07:50 +02:00
dd521398ea switch to new org scheme 2023-07-10 02:55:52 +02:00
038e6cc33d 10.0.26 2023-07-08 16:24:53 +02:00
2fc37d6892 fix(core): update 2023-07-08 16:24:53 +02:00
3c1eb1ab70 10.0.25 2023-06-25 19:01:11 +02:00
5296e8859b fix(core): update 2023-06-25 19:01:10 +02:00
160e0ae451 10.0.24 2023-06-25 18:21:13 +02:00
373c6538ae fix(core): update 2023-06-25 18:21:12 +02:00
7a1476e106 10.0.23 2023-06-25 18:06:56 +02:00
b2a2035f00 fix(core): update 2023-06-25 18:06:56 +02:00
03e4f03035 10.0.22 2023-06-25 17:53:44 +02:00
d74bbb2b12 fix(core): update 2023-06-25 17:53:43 +02:00
22cfe1f5cb 10.0.21 2023-06-25 17:47:42 +02:00
5fc2c4586d fix(core): update 2023-06-25 17:47:42 +02:00
6ab81fb323 10.0.20 2023-06-25 13:55:04 +02:00
58ec27a1a0 fix(core): update 2023-06-25 13:55:03 +02:00
88811646b7 10.0.19 2023-06-25 01:36:06 +02:00
412bb52eee fix(core): update 2023-06-25 01:36:05 +02:00
b04750ecbd 10.0.18 2023-06-25 01:34:41 +02:00
0c99475888 fix(core): update 2023-06-25 01:34:40 +02:00
86317def88 10.0.17 2023-06-24 20:36:53 +02:00
0a5af0ba96 fix(core): update 2023-06-24 20:36:52 +02:00
cf73ff4a54 10.0.16 2023-06-24 11:20:50 +02:00
788897e765 fix(core): update 2023-06-24 11:20:50 +02:00
7fa3894f6e 10.0.15 2023-06-24 01:26:08 +02:00
afdd654664 fix(core): update 2023-06-24 01:26:08 +02:00
8277e0ca6d 10.0.14 2023-06-23 18:49:56 +02:00
0892c87a68 fix(core): update 2023-06-23 18:49:56 +02:00
841ba2e14d 10.0.13 2023-06-23 18:46:43 +02:00
5b2953bf02 fix(core): update 2023-06-23 18:46:42 +02:00
d3457fd65b 10.0.12 2023-06-23 18:43:50 +02:00
3bf1eafe6b fix(core): update 2023-06-23 18:43:49 +02:00
04a9b992d7 10.0.11 2023-06-23 18:39:02 +02:00
6206b55deb fix(core): update 2023-06-23 18:39:01 +02:00
6c05bf6ae3 10.0.10 2023-06-23 18:11:04 +02:00
371074afc1 fix(core): update 2023-06-23 18:11:04 +02:00
e0e665fe6d 10.0.9 2023-06-23 18:08:16 +02:00
5483202972 fix(core): update 2023-06-23 18:08:15 +02:00
24b3458888 10.0.8 2023-06-23 16:44:45 +02:00
cffa47ac3d fix(core): update 2023-06-23 16:44:44 +02:00
9dadf3f78f 10.0.7 2023-01-09 15:34:06 +01:00
b35a671fe9 fix(core): update 2023-01-09 15:34:05 +01:00
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
701b77eff5 8.0.0 2020-08-10 20:58:23 +00:00
e3c46cdd2c BREAKING CHANGE(Smartfile class): switch to a Buffer only approach 2020-08-10 20:58:22 +00:00
7204607c8a 7.0.12 2020-04-13 17:48:25 +00:00
039c6f7fc6 fix(core): update 2020-04-13 17:48:25 +00:00
b42595fccc 7.0.11 2020-03-15 19:08:42 +00:00
2d9a65d11c fix(core): update 2020-03-15 19:08:41 +00:00
b3ce66167e 7.0.10 2020-03-15 18:58:46 +00:00
c7f800fc88 fix(core): update 2020-03-15 18:58:46 +00:00
d8f4b011b7 7.0.9 2020-03-04 16:31:14 +00:00
b4add67f37 fix(core): update 2020-03-04 16:31:13 +00:00
f86f053bd5 7.0.8 2020-02-07 21:00:54 +00:00
a78ca67b43 fix(core): update 2020-02-07 21:00:54 +00:00
b1bedd0f54 7.0.7 2020-02-07 21:00:05 +00:00
ec58f7ac55 fix(core): update 2020-02-07 21:00:04 +00:00
80743576ad 7.0.6 2019-09-29 16:43:32 +02:00
32a6db645d fix(core): update 2019-09-29 16:43:31 +02:00
45dfa16ab7 7.0.5 2019-09-27 11:00:17 +02:00
4fc4cda786 fix(core): update 2019-09-27 11:00:17 +02:00
f889664e4d 7.0.4 2019-06-27 10:42:35 +02:00
f4129c04b2 fix(core): update 2019-06-27 10:42:35 +02:00
c6280eb6fc 7.0.3 2019-06-26 21:17:59 +02:00
4095738c6a fix(core): update 2019-06-26 21:17:58 +02:00
6170b37d29 7.0.2 2019-04-08 16:39:41 +02:00
4c23992681 fix(core): update 2019-04-08 16:39:41 +02:00
77c88f09cd 7.0.1 2019-04-08 16:36:21 +02:00
469a454fa6 fix(core): update dependencies 2019-04-08 16:36:21 +02:00
15044149f2 7.0.0 2019-02-17 21:07:23 +01:00
c92b759432 BREAKING CHANGE(smartfile.fs.fileExists now returns a Promise<boolean>): update 2019-02-17 21:07:22 +01:00
9b8f055ec2 6.0.12 2019-01-27 03:11:11 +01:00
69433b242b fix(core): update 2019-01-27 03:11:10 +01:00
db1d2acb47 6.0.11 2018-11-22 23:38:06 +01:00
920552ea23 fix(fs.listFolders): fix 2018-11-22 23:38:05 +01:00
dd05708f28 6.0.10 2018-11-22 23:26:28 +01:00
d97abe443d fix(snyk): add .snyk file 2018-11-22 23:26:27 +01:00
818767b7cc 6.0.9 2018-11-22 23:23:26 +01:00
52367f5c1a fix(fs.listFolders()): fix retuen type 2018-11-22 23:23:26 +01:00
b6b2101054 6.0.8 2018-08-19 21:21:27 +02:00
e322a41c45 fix(CI): update testing framework 2018-08-19 21:21:26 +02:00
f5e2c0c7d7 6.0.7 2018-08-19 17:10:27 +02:00
6733a156b8 fix(dependencies): update 2018-08-19 17:10:27 +02:00
ebac45a152 6.0.6 2018-08-08 22:22:48 +02:00
92ac410b96 fix(dependencies): update dependencies to latest standards 2018-08-08 22:22:47 +02:00
078bdda803 6.0.5 2018-08-06 09:37:10 +02:00
7b87adf3d9 fix(core): switch from npmts to @gitzone/tsbuild for bulding the module 2018-08-06 09:37:09 +02:00
908db4d847 6.0.4 2018-08-06 00:38:03 +02:00
87d047af42 fix(CI): switch to new testing framework 2018-08-06 00:38:02 +02:00
68 changed files with 6989 additions and 2822 deletions

View File

@ -0,0 +1,66 @@
name: Default (not tags)
on:
push:
tags-ignore:
- '**'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Install pnpm and npmci
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
- name: Run npm prepare
run: npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build

View File

@ -0,0 +1,124 @@
name: Default (tags)
on:
push:
tags:
- '*'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build
release:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Release
run: |
npmci node install stable
npmci npm publish
metadata:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
continue-on-error: true
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Code quality
run: |
npmci command npm install -g typescript
npmci npm install
- name: Trigger
run: npmci trigger
- name: Build docs and upload artifacts
run: |
npmci node install stable
npmci npm install
pnpm install -g @git.zone/tsdoc
npmci command tsdoc
continue-on-error: true

19
.gitignore vendored
View File

@ -1,7 +1,20 @@
node_modules/
.nogit/
# artifacts
coverage/
pages/
public/
pages/
test/temp/
# installs
node_modules/
# caches
.yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_*/
# custom

View File

@ -1,141 +0,0 @@
# gitzone standard
image: hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testLEGACY:
stage: test
script:
- npmci node install legacy
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
allow_failure: true
testLTS:
stage: test
script:
- npmci node install lts
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
testSTABLE:
stage: test
script:
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
image: docker:stable
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [codeclimate.json]
tags:
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmci
stage: metadata
script:
- npmci command npm install -g npmpage
- npmci command npmpage
tags:
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true
windowsCompatibility:
image: stefanscherer/node-windows:10-build-tools
stage: metadata
script:
- npm install & npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- windows
allow_failure: true

11
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "npm test",
"name": "Run npm test",
"request": "launch",
"type": "node-terminal"
}
]
}

26
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"schema": {
"type": "object",
"properties": {
"npmci": {
"type": "object",
"description": "settings for npmci"
},
"gitzone": {
"type": "object",
"description": "settings for gitzone",
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm", "wcc"]
}
}
}
}
}
}
]
}

View File

@ -1,43 +0,0 @@
# @pushrocks/smartfile
make files easily accessible for processing in javascript.
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartfile)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://gitlab.com/pushrocks/smartfile)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartfile)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartfile/)
## Status for master
[![build status](https://gitlab.com/pushrocks/smartfile/badges/master/build.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)
[![Dependency Status](https://david-dm.org/pushrocks/smartfile.svg)](https://david-dm.org/pushrocks/smartfile)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartfile/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartfile/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartfile/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartfile)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
smartfile is an approach of being one tool to handle files in diverse environments.
### Smartfile Sections
smartfile thinks in sections:
| section | description |
| ----------- | ---------------------------------------------------------------------------- |
| fs | (object) gets data from fs to somewhere |
| memory | gets data from memory to somewhere |
| remote | gets data from remote locations to somewhere |
| interpreter | (object) handles yaml and json |
| smartfile | (class) a virtual representation of a file, alternative to vinyl file format |
For further information read the linked docs at the top of this README.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
[![npm](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

10
dist/index.d.ts vendored
View File

@ -1,10 +0,0 @@
import * as SmartfileFs from './smartfile.fs';
import * as SmartfileInterpreter from './smartfile.interpreter';
import * as SmartfileMemory from './smartfile.memory';
import * as SmartfileRemote from './smartfile.remote';
export { Smartfile } from './smartfile.classes.smartfile';
export declare let fs: typeof SmartfileFs;
export declare let interpreter: typeof SmartfileInterpreter;
export declare let memory: typeof SmartfileMemory;
export declare let remote: typeof SmartfileRemote;
export declare let requireReload: (path: string) => any;

14
dist/index.js vendored
View File

@ -1,14 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const SmartfileFs = require("./smartfile.fs");
const SmartfileInterpreter = require("./smartfile.interpreter");
const SmartfileMemory = require("./smartfile.memory");
const SmartfileRemote = require("./smartfile.remote");
var smartfile_classes_smartfile_1 = require("./smartfile.classes.smartfile");
exports.Smartfile = smartfile_classes_smartfile_1.Smartfile;
exports.fs = SmartfileFs;
exports.interpreter = SmartfileInterpreter;
exports.memory = SmartfileMemory;
exports.remote = SmartfileRemote;
exports.requireReload = SmartfileFs.requireReload;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLDhDQUE4QztBQUM5QyxnRUFBZ0U7QUFDaEUsc0RBQXNEO0FBQ3RELHNEQUFzRDtBQUV0RCw2RUFBMEQ7QUFBakQsa0RBQUEsU0FBUyxDQUFBO0FBRVAsUUFBQSxFQUFFLEdBQUcsV0FBVyxDQUFDO0FBQ2pCLFFBQUEsV0FBVyxHQUFHLG9CQUFvQixDQUFDO0FBQ25DLFFBQUEsTUFBTSxHQUFHLGVBQWUsQ0FBQztBQUN6QixRQUFBLE1BQU0sR0FBRyxlQUFlLENBQUM7QUFDekIsUUFBQSxhQUFhLEdBQUcsV0FBVyxDQUFDLGFBQWEsQ0FBQyJ9

View File

@ -1,79 +0,0 @@
/// <reference types="node" />
import * as plugins from './smartfile.plugins';
export interface ISmartfileConstructorOptions {
path?: string;
contentString?: string;
contentBuffer?: Buffer;
base?: string;
}
/**
* class Smartfile
* -> is vinyl file compatible
*/
export declare class Smartfile {
/**
* the full path of the file on disk
*/
path: string;
/**
*
*/
parsedPath: plugins.path.ParsedPath;
/**
* the content of the file as Buffer
*/
contentBuffer: Buffer;
/**
* The current working directory of the file
* Note:this is similar to gulp and different from native node path base
*/
base: string;
/**
* sync the file with disk
*/
sync: boolean;
/**
* the constructor of Smartfile
* @param optionsArg
*/
constructor(optionsArg: ISmartfileConstructorOptions);
/**
* set contents from string
* @param contentString
*/
setContentsFromString(contentString: string): void;
/**
* write file to disk
* Behaviours:
* - no argument write to exactly where the file was picked up
*/
write(pathArg?: string): Promise<void>;
/**
* read file from disk
*/
read(): Promise<void>;
/**
* vinyl-compatibility: alias of this.contentBuffer
*/
contents: Buffer;
/**
* vinyl-compatibility
*/
readonly cwd: string;
/**
* return relative path of file
*/
readonly relative: string;
/**
* return truw when the file has content
*/
isNull(): boolean;
/**
* return true if contents are Buffer
*/
isBuffer(): boolean;
isDirectory(): boolean;
isStream(): boolean;
isSymbolic(): boolean;
updateFileName(fileNameArg: string): void;
}

View File

@ -1,118 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartfile.plugins");
const memory = require("./smartfile.memory");
/**
* class Smartfile
* -> is vinyl file compatible
*/
class Smartfile {
/**
* the constructor of Smartfile
* @param optionsArg
*/
constructor(optionsArg) {
if (optionsArg.contentBuffer) {
this.contentBuffer = optionsArg.contentBuffer;
}
else if (optionsArg.contentString) {
this.setContentsFromString(optionsArg.contentString);
}
else {
console.log('created empty Smartfile?');
}
this.path = optionsArg.path;
this.parsedPath = plugins.path.parse(this.path);
this.base = optionsArg.base;
}
/**
* set contents from string
* @param contentString
*/
setContentsFromString(contentString) {
this.contents = new Buffer(contentString);
}
/**
* write file to disk
* Behaviours:
* - no argument write to exactly where the file was picked up
*/
write(pathArg) {
return __awaiter(this, void 0, void 0, function* () {
const stringToWrite = this.contentBuffer.toString();
yield memory.toFs(stringToWrite, this.path);
});
}
/**
* read file from disk
*/
read() {
return __awaiter(this, void 0, void 0, function* () { });
}
// -----------------------------------------------
// vinyl compatibility
// -----------------------------------------------
/**
* vinyl-compatibility: alias of this.contentBuffer
*/
get contents() {
return this.contentBuffer;
}
set contents(contentsArg) {
this.contentBuffer = contentsArg;
}
/**
* vinyl-compatibility
*/
get cwd() {
return process.cwd();
}
/**
* return relative path of file
*/
get relative() {
return plugins.path.relative(this.base, this.path);
}
/**
* return truw when the file has content
*/
isNull() {
if (!this.contentBuffer) {
return true;
}
return false;
}
/**
* return true if contents are Buffer
*/
isBuffer() {
if (this.contents instanceof Buffer) {
return true;
}
return false;
}
isDirectory() {
return false;
}
isStream() {
return false;
}
isSymbolic() {
return false;
}
// update things
updateFileName(fileNameArg) {
let oldFileName = this.parsedPath.base;
this.path = this.path.replace(new RegExp(oldFileName + '$'), fileNameArg);
}
}
exports.Smartfile = Smartfile;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRmaWxlLmNsYXNzZXMuc21hcnRmaWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRmaWxlLmNsYXNzZXMuc21hcnRmaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSwrQ0FBK0M7QUFFL0MsNkNBQTZDO0FBUzdDOzs7R0FHRztBQUNIO0lBMkJFOzs7T0FHRztJQUVILFlBQVksVUFBd0M7UUFDbEQsSUFBSSxVQUFVLENBQUMsYUFBYSxFQUFFO1lBQzVCLElBQUksQ0FBQyxhQUFhLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQztTQUMvQzthQUFNLElBQUksVUFBVSxDQUFDLGFBQWEsRUFBRTtZQUNuQyxJQUFJLENBQUMscUJBQXFCLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1NBQ3REO2FBQU07WUFDTCxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixDQUFDLENBQUM7U0FDekM7UUFDRCxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxxQkFBcUIsQ0FBQyxhQUFxQjtRQUN6QyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0csS0FBSyxDQUFDLE9BQWdCOztZQUMxQixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3BELE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzlDLENBQUM7S0FBQTtJQUVEOztPQUVHO0lBQ0csSUFBSTs4REFBSSxDQUFDO0tBQUE7SUFFZixrREFBa0Q7SUFDbEQsc0JBQXNCO0lBQ3RCLGtEQUFrRDtJQUNsRDs7T0FFRztJQUNILElBQUksUUFBUTtRQUNWLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBQ0QsSUFBSSxRQUFRLENBQUMsV0FBVztRQUN0QixJQUFJLENBQUMsYUFBYSxHQUFHLFdBQVcsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLEdBQUc7UUFDTCxPQUFPLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLFFBQVE7UUFDVixPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU07UUFDSixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN2QixPQUFPLElBQUksQ0FBQztTQUNiO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQ7O09BRUc7SUFDSCxRQUFRO1FBQ04sSUFBSSxJQUFJLENBQUMsUUFBUSxZQUFZLE1BQU0sRUFBRTtZQUNuQyxPQUFPLElBQUksQ0FBQztTQUNiO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsV0FBVztRQUNULE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELFFBQVE7UUFDTixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxVQUFVO1FBQ1IsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsZ0JBQWdCO0lBQ2hCLGNBQWMsQ0FBQyxXQUFtQjtRQUNoQyxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztRQUN2QyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksTUFBTSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM1RSxDQUFDO0NBQ0Y7QUFwSUQsOEJBb0lDIn0=

143
dist/smartfile.fs.d.ts vendored
View File

@ -1,143 +0,0 @@
import { Smartfile } from './smartfile.classes.smartfile';
/**
*
* @param filePath
* @returns {boolean}
*/
export declare let fileExistsSync: (filePath: any) => boolean;
/**
*
* @param filePath
* @returns {any}
*/
export declare let fileExists: (filePath: any) => Promise<{}>;
/**
* Checks if given path points to an existing directory
*/
export declare let isDirectory: (pathArg: any) => boolean;
/**
* Checks if a given path points to an existing file
*/
export declare let isFile: (pathArg: any) => boolean;
/**
* copies a file from A to B on the local disk
*/
export declare let copy: (fromArg: string, toArg: string) => Promise<{}>;
/**
* copies a file SYNCHRONOUSLY from A to B on the local disk
*/
export declare let copySync: (fromArg: string, toArg: string) => boolean;
/**
* ensures that a directory is in place
*/
export declare let ensureDir: (dirPathArg: string) => Promise<{}>;
/**
* ensures that a directory is in place
*/
export declare let ensureDirSync: (dirPathArg: string) => void;
/**
* ensure an empty directory
* @executes ASYNC
*/
export declare let ensureEmptyDir: (dirPathArg: string) => Promise<{}>;
/**
* ensure an empty directory
* @executes SYNC
*/
export declare let ensureEmptyDirSync: (dirPathArg: string) => void;
/**
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec ASYNC
*/
export declare let ensureFile: (filePathArg: any, initFileStringArg: any) => Promise<void>;
/**
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec SYNC
*/
export declare let ensureFileSync: (filePathArg: string, initFileStringArg: string) => void;
/**
* removes a file or folder from local disk
*/
export declare let remove: (pathArg: string) => Promise<void>;
/**
* removes a file SYNCHRONOUSLY from local disk
*/
export declare let removeSync: (pathArg: string) => boolean;
/**
* removes an array of filePaths from disk
*/
export declare let removeMany: (filePathArrayArg: string[]) => Promise<void[]>;
/**
* like removeFilePathArray but SYNCHRONOUSLY
*/
export declare let removeManySync: (filePathArrayArg: string[]) => void;
/**
*
* @param filePathArg
* @param fileTypeArg
* @returns {any}
*/
export declare let toObjectSync: (filePathArg: any, fileTypeArg?: any) => any;
/**
* reads a file content to a String
* @param filePath
* @returns {string|Buffer|any}
*/
export declare let toStringSync: (filePath: string) => string;
export declare let fileTreeToObject: (dirPathArg: string, miniMatchFilter: string) => Promise<Smartfile[]>;
/**
*
* @param filePathArg
* @param options
* @returns {number}
*/
export declare let toVinylSync: (filePathArg: any, options?: {}) => any;
/**
* lets you reload files hot.
* @param path
* @returns {any}
*/
export declare let requireReload: (path: string) => any;
/**
* lists Folders in a directory on local disk
* @returns Promise
*/
export declare let listFolders: (pathArg: string, regexFilter?: RegExp) => Promise<{}>;
/**
* lists Folders SYNCHRONOUSLY in a directory on local disk
* @returns an array with the folder names as strings
*/
export declare let listFoldersSync: (pathArg: string, regexFilter?: RegExp) => string[];
/**
* lists Files in a directory on local disk
* @returns Promise
*/
export declare let listFiles: (pathArg: string, regexFilter?: RegExp) => Promise<{}>;
/**
* lists Files SYNCHRONOUSLY in a directory on local disk
* @returns an array with the folder names as strings
*/
export declare let listFilesSync: (pathArg: string, regexFilter?: RegExp) => string[];
/**
* lists all items (folders AND files) in a directory on local disk
* @returns Promise<string[]>
*/
export declare let listAllItems: (pathArg: string, regexFilter?: RegExp) => Promise<string[]>;
/**
* lists all items (folders AND files) in a directory on local disk
* @returns an array with the folder names as strings
* @executes SYNC
*/
export declare let listAllItemsSync: (pathArg: string, regexFilter?: RegExp) => string[];
/**
* lists a file tree using a miniMatch filter
* note: if the miniMatch Filter is an absolute path, the cwdArg will be omitted
* @returns Promise<string[]> string array with the absolute paths of all matching files
*/
export declare let listFileTree: (dirPathArg: string, miniMatchFilter: string) => Promise<string[]>;

374
dist/smartfile.fs.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
export declare let filetype: (pathArg: string) => string;
export declare let objectFile: (fileStringArg: string, fileTypeArg: any) => any;

View File

@ -1,21 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartfile.plugins");
exports.filetype = (pathArg) => {
let extName = plugins.path.extname(pathArg);
let fileType = extName.replace(/\.([a-z]*)/, '$1'); // remove . form fileType
return fileType;
};
exports.objectFile = (fileStringArg, fileTypeArg) => {
switch (fileTypeArg) {
case 'yml':
case 'yaml':
return plugins.yaml.safeLoad(fileStringArg);
case 'json':
return JSON.parse(fileStringArg);
default:
console.error('file type ' + fileTypeArg.blue + ' not supported');
break;
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRmaWxlLmludGVycHJldGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRmaWxlLmludGVycHJldGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0NBQWdEO0FBRXJDLFFBQUEsUUFBUSxHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUU7SUFDaEQsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyx5QkFBeUI7SUFDN0UsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyxDQUFDO0FBRVMsUUFBQSxVQUFVLEdBQUcsQ0FBQyxhQUFxQixFQUFFLFdBQVcsRUFBRSxFQUFFO0lBQzdELFFBQVEsV0FBVyxFQUFFO1FBQ25CLEtBQUssS0FBSyxDQUFDO1FBQ1gsS0FBSyxNQUFNO1lBQ1QsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM5QyxLQUFLLE1BQU07WUFDVCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDbkM7WUFDRSxPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsSUFBSSxHQUFHLGdCQUFnQixDQUFDLENBQUM7WUFDbEUsTUFBTTtLQUNUO0FBQ0gsQ0FBQyxDQUFDIn0=

View File

@ -1,25 +0,0 @@
import { Smartfile } from './smartfile.classes.smartfile';
/**
* converts file to Object
* @param fileStringArg
* @param fileTypeArg
* @returns {any|any}
*/
export declare let toObject: (fileStringArg: string, fileTypeArg: string) => any;
export interface IToFsOptions {
respectRelative?: boolean;
}
/**
* writes string or Smartfile to disk.
* @param fileArg
* @param fileNameArg
* @param fileBaseArg
*/
export declare let toFs: (fileContentArg: string | Smartfile, filePathArg: any, optionsArg?: IToFsOptions) => Promise<{}>;
/**
* writes a string or a Smartfile to disk synchronously, only supports string
* @param fileArg
* @param filePathArg
*/
export declare let toFsSync: (fileArg: string, filePathArg: string) => void;
export declare let smartfileArrayToFs: (smartfileArrayArg: Smartfile[], dirArg: string) => Promise<void>;

View File

@ -1,87 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartfile.plugins");
const smartfile_classes_smartfile_1 = require("./smartfile.classes.smartfile");
const smartfileFs = require("./smartfile.fs");
const SmartfileInterpreter = require("./smartfile.interpreter");
/**
* converts file to Object
* @param fileStringArg
* @param fileTypeArg
* @returns {any|any}
*/
exports.toObject = function (fileStringArg, fileTypeArg) {
return SmartfileInterpreter.objectFile(fileStringArg, fileTypeArg);
};
/**
* writes string or Smartfile to disk.
* @param fileArg
* @param fileNameArg
* @param fileBaseArg
*/
exports.toFs = (fileContentArg, filePathArg, optionsArg = {}) => __awaiter(this, void 0, void 0, function* () {
let done = plugins.smartpromise.defer();
// check args
if (!fileContentArg || !filePathArg) {
throw new Error('expected valid arguments');
}
// prepare actual write action
let fileString;
let filePath = filePathArg;
// handle Smartfile
if (fileContentArg instanceof smartfile_classes_smartfile_1.Smartfile) {
let fileContentArg2 = fileContentArg;
fileString = fileContentArg.contentBuffer.toString();
// handle options
if (optionsArg.respectRelative) {
filePath = plugins.path.join(filePath, fileContentArg.path);
}
}
else if (typeof fileContentArg === 'string') {
fileString = fileContentArg;
}
else {
throw new Error('fileContent is neither string nor Smartfile');
}
yield smartfileFs.ensureDir(plugins.path.parse(filePath).dir);
plugins.fsExtra.writeFile(filePath, fileString, { encoding: 'utf8' }, done.resolve);
return yield done.promise;
});
/**
* writes a string or a Smartfile to disk synchronously, only supports string
* @param fileArg
* @param filePathArg
*/
exports.toFsSync = function (fileArg, filePathArg) {
// function checks to abort if needed
if (!fileArg || !filePathArg) {
throw new Error('expected a valid arguments');
}
// prepare actual write action
let fileString;
let filePath = filePathArg;
if (typeof fileArg !== 'string') {
throw new Error('fileArg is not of type String.');
}
else if (typeof fileArg === 'string') {
fileString = fileArg;
}
plugins.fsExtra.writeFileSync(filePath, fileString, { encoding: 'utf8' });
};
exports.smartfileArrayToFs = (smartfileArrayArg, dirArg) => __awaiter(this, void 0, void 0, function* () {
yield smartfileFs.ensureDir(dirArg);
for (let smartfile of smartfileArrayArg) {
yield exports.toFs(smartfile, dirArg, {
respectRelative: true
});
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRmaWxlLm1lbW9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0ZmlsZS5tZW1vcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLCtDQUFnRDtBQUNoRCwrRUFBMEQ7QUFDMUQsOENBQThDO0FBRTlDLGdFQUFpRTtBQUVqRTs7Ozs7R0FLRztBQUNRLFFBQUEsUUFBUSxHQUFHLFVBQVMsYUFBcUIsRUFBRSxXQUFtQjtJQUN2RSxPQUFPLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDckUsQ0FBQyxDQUFDO0FBTUY7Ozs7O0dBS0c7QUFDUSxRQUFBLElBQUksR0FBRyxDQUNoQixjQUFrQyxFQUNsQyxXQUFXLEVBQ1gsYUFBMkIsRUFBRSxFQUM3QixFQUFFO0lBQ0YsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUV4QyxhQUFhO0lBQ2IsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLFdBQVcsRUFBRTtRQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7S0FDN0M7SUFFRCw4QkFBOEI7SUFDOUIsSUFBSSxVQUFrQixDQUFDO0lBQ3ZCLElBQUksUUFBUSxHQUFXLFdBQVcsQ0FBQztJQUVuQyxtQkFBbUI7SUFDbkIsSUFBSSxjQUFjLFlBQVksdUNBQVMsRUFBRTtRQUN2QyxJQUFJLGVBQWUsR0FBUSxjQUFjLENBQUM7UUFDMUMsVUFBVSxHQUFHLGNBQWMsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckQsaUJBQWlCO1FBQ2pCLElBQUksVUFBVSxDQUFDLGVBQWUsRUFBRTtZQUM5QixRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM3RDtLQUNGO1NBQU0sSUFBSSxPQUFPLGNBQWMsS0FBSyxRQUFRLEVBQUU7UUFDN0MsVUFBVSxHQUFHLGNBQWMsQ0FBQztLQUM3QjtTQUFNO1FBQ0wsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO0tBQ2hFO0lBQ0QsTUFBTSxXQUFXLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlELE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BGLE9BQU8sTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQzVCLENBQUMsQ0FBQSxDQUFDO0FBRUY7Ozs7R0FJRztBQUNRLFFBQUEsUUFBUSxHQUFHLFVBQVMsT0FBZSxFQUFFLFdBQW1CO0lBQ2pFLHFDQUFxQztJQUNyQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFO1FBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztLQUMvQztJQUVELDhCQUE4QjtJQUM5QixJQUFJLFVBQWtCLENBQUM7SUFDdkIsSUFBSSxRQUFRLEdBQVcsV0FBVyxDQUFDO0lBRW5DLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO1FBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztLQUNuRDtTQUFNLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO1FBQ3RDLFVBQVUsR0FBRyxPQUFPLENBQUM7S0FDdEI7SUFDRCxPQUFPLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDNUUsQ0FBQyxDQUFDO0FBRVMsUUFBQSxrQkFBa0IsR0FBRyxDQUFPLGlCQUE4QixFQUFFLE1BQWMsRUFBRSxFQUFFO0lBQ3ZGLE1BQU0sV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNwQyxLQUFLLElBQUksU0FBUyxJQUFJLGlCQUFpQixFQUFFO1FBQ3ZDLE1BQU0sWUFBSSxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUU7WUFDNUIsZUFBZSxFQUFFLElBQUk7U0FDdEIsQ0FBQyxDQUFDO0tBQ0o7QUFDSCxDQUFDLENBQUEsQ0FBQyJ9

View File

@ -1,10 +0,0 @@
export import fs = require('fs');
export import fsExtra = require('fs-extra');
export declare let glob: any;
export import path = require('path');
export import smartpromise = require('@pushrocks/smartpromise');
export import smartrequest = require('@pushrocks/smartrequest');
export declare let requireReload: any;
export import smartpath = require('smartpath');
export declare let vinylFile: any;
export declare let yaml: any;

View File

@ -1,13 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fs = require("fs");
exports.fsExtra = require("fs-extra");
exports.glob = require('glob');
exports.path = require("path");
exports.smartpromise = require("@pushrocks/smartpromise");
exports.smartrequest = require("@pushrocks/smartrequest");
exports.requireReload = require('require-reload');
exports.smartpath = require("smartpath");
exports.vinylFile = require('vinyl-file');
exports.yaml = require('js-yaml');
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRmaWxlLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGZpbGUucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDJCQUFpQztBQUNqQyxzQ0FBNEM7QUFDakMsUUFBQSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2xDLCtCQUFxQztBQUNyQywwREFBZ0U7QUFDaEUsMERBQWdFO0FBQ3JELFFBQUEsYUFBYSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3JELHlDQUErQztBQUNwQyxRQUFBLFNBQVMsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDbEMsUUFBQSxJQUFJLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDIn0=

View File

@ -1,12 +0,0 @@
/**
*
* @param fromArg
* @returns {any}
*/
export declare let toObject: (fromArg: string) => Promise<{}>;
/**
*
* @param fromArg
* @returns {any}
*/
export declare let toString: (fromArg: string) => Promise<{}>;

View File

@ -1,51 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartfile.plugins");
/* 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}
*/
exports.toObject = function (fromArg) {
let done = plugins.smartpromise.defer();
plugins.smartrequest
.request(fromArg, {
method: 'get'
})
.then((res) => {
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}
*/
exports.toString = (fromArg) => {
let done = plugins.smartpromise.defer();
plugins.smartrequest.get(fromArg).then((res) => {
if (res.statusCode === 200) {
done.resolve(res.body);
}
else {
done.reject(new Error('could not get remote file from ' + fromArg));
}
});
return done.promise;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRmaWxlLnJlbW90ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0ZmlsZS5yZW1vdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQ0FBZ0Q7QUFHaEQ7Ozs7Ozs7SUFPSTtBQUVKOzs7O0dBSUc7QUFDUSxRQUFBLFFBQVEsR0FBRyxVQUFTLE9BQWU7SUFDNUMsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QyxPQUFPLENBQUMsWUFBWTtTQUNqQixPQUFPLENBQUMsT0FBTyxFQUFFO1FBQ2hCLE1BQU0sRUFBRSxLQUFLO0tBQ2QsQ0FBQztTQUNELElBQUksQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFO1FBQ2pCLElBQUksR0FBRyxDQUFDLFVBQVUsS0FBSyxHQUFHLEVBQUU7WUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDeEI7YUFBTTtZQUNMLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUNBQWlDLEdBQUcsT0FBTyxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO1NBQ3JFO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDdEIsQ0FBQyxDQUFDO0FBRUY7Ozs7R0FJRztBQUNRLFFBQUEsUUFBUSxHQUFHLENBQUMsT0FBZSxFQUFFLEVBQUU7SUFDeEMsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtRQUNsRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLEtBQUssR0FBRyxFQUFFO1lBQzFCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3hCO2FBQU07WUFDTCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLGlDQUFpQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUM7U0FDckU7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUN0QixDQUFDLENBQUMifQ==

View File

@ -1,43 +0,0 @@
# smartfile
make files easily accessible for processing in javascript.
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartfile)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://gitlab.com/pushrocks/smartfile)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartfile)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartfile/)
## Status for master
[![build status](https://gitlab.com/pushrocks/smartfile/badges/master/build.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)
[![Dependency Status](https://david-dm.org/pushrocks/smartfile.svg)](https://david-dm.org/pushrocks/smartfile)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartfile/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartfile/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartfile/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartfile)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
smartfile is an approach of being one tool to handle files in diverse environments.
### Smartfile Sections
smartfile thinks in sections:
| section | description |
| ----------- | ---------------------------------------------------------------------------- |
| fs | (object) gets data from fs to somewhere |
| memory | gets data from memory to somewhere |
| remote | gets data from remote locations to somewhere |
| interpreter | (object) handles yaml and json |
| smartfile | (class) a virtual representation of a file, alternative to vinyl file format |
For further information read the linked docs at the top of this README.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
[![npm](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

View File

View File

@ -1,15 +1,42 @@
{
"npmts":{
"mode":"default",
"coverageTreshold":70
},
"npmdocker":{
},
"npmdocker": {},
"npmci": {
"npmGlobalTools": [
"npmts"
],
"npmGlobalTools": [],
"npmAccessLevel": "public"
},
"gitzone": {
"projectType": "npm",
"module": {
"githost": "code.foss.global",
"gitscope": "push.rocks",
"gitrepo": "smartfile",
"description": "provides a robust suite of tools for managing files in Node.js using TypeScript.",
"npmPackagename": "@push.rocks/smartfile",
"license": "MIT",
"keywords": [
"files management",
"TypeScript",
"Node.js",
"read files",
"write files",
"copy files",
"file streaming",
"directories manipulation",
"virtual file system",
"filesystem utilities",
"ESM syntax",
"memory-efficient streaming"
]
}
},
"tsdoc": {
"classes": [
"SmartFile",
"StreamFile"
],
"descriptions": [
"the purpose of the StreamFile class is to provide a hybrid interface between streaming files and simple handling when writing and reading those files multiple times."
],
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
}
}
}

874
package-lock.json generated
View File

@ -1,874 +0,0 @@
{
"name": "@pushrocks/smartfile",
"version": "6.0.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@airbnb/node-memwatch": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@airbnb/node-memwatch/-/node-memwatch-1.0.2.tgz",
"integrity": "sha512-2R+MEEMSTUdKwQ6NFWkyA/UNoSjL1tMldZqJbZpgXSwNMBzlNlkUWEXKu9RqTTMkDqJRfGJ2VDs8gPlPK2APDQ==",
"dev": true,
"requires": {
"bindings": "^1.3.0",
"nan": "^2.9.2"
}
},
"@gitzone/tsrun": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@gitzone/tsrun/-/tsrun-1.1.1.tgz",
"integrity": "sha512-/hocNkbpcm65MrSdF3V28lBH2iNcZThtbvKuISdCVgKejQUugTe9uNzLn//UCuCbbXODSVmjMbbYU4nMksssUw==",
"dev": true,
"requires": {
"smartfile": "^4.2.28",
"ts-node": "^7.0.0",
"typescript": "^2.9.1"
}
},
"@pushrocks/smartpromise": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@pushrocks/smartpromise/-/smartpromise-2.0.5.tgz",
"integrity": "sha512-9j/chLtIiNkR0MDw7Mpxg9slxAVvAQwUZuiaPYX5KpHdKxQaHLI1VZ8IN0vPhwlfgNO4i4vGXV0wB8BvSDj03g=="
},
"@pushrocks/smartrequest": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/@pushrocks/smartrequest/-/smartrequest-1.0.15.tgz",
"integrity": "sha512-nM+ctwMOs3gPJvw3cGouBimKQxCM93bnmv2+Jk9cbT29/UVVI/UjIdAU3OnUYFpzq496/QUAQD0kNsmYNkqmhQ==",
"requires": {
"smartq": "^1.1.1"
}
},
"@types/chai": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.4.tgz",
"integrity": "sha512-h6+VEw2Vr3ORiFCyyJmcho2zALnUq9cvdB/IO8Xs9itrJVCenC7o26A6+m7D0ihTTr65eS259H5/Ghl/VjYs6g==",
"dev": true
},
"@types/chai-as-promised": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz",
"integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==",
"dev": true,
"requires": {
"@types/chai": "*"
}
},
"@types/chai-string": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@types/chai-string/-/chai-string-1.4.1.tgz",
"integrity": "sha512-aRNMs6TKgjgPlCHwDfq/YNy5VtRR2hJ4AUWByddrT0TRVVD8eX4MiHW6/iHvmQHRlVuuPZcwnTUE7b4yFt7bEA==",
"dev": true,
"requires": {
"@types/chai": "*"
}
},
"@types/fs-extra": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.3.tgz",
"integrity": "sha512-m2QKoRrJnei1s10e1ZfMIa7QcABBVLdQhVUv5+bMRaHhPzxO/IWMmREiags59AqFbI+piWPq/PupTahNS/0kyA==",
"requires": {
"@types/node": "*"
},
"dependencies": {
"@types/node": {
"version": "10.5.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.1.tgz",
"integrity": "sha512-AFLl1IALIuyt6oK4AYZsgWVJ/5rnyzQWud7IebaZWWV3YmgtPZkQmYio9R5Ze/2pdd7XfqF5bP+hWS11mAKoOQ=="
}
}
},
"@types/node": {
"version": "10.5.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.1.tgz",
"integrity": "sha512-AFLl1IALIuyt6oK4AYZsgWVJ/5rnyzQWud7IebaZWWV3YmgtPZkQmYio9R5Ze/2pdd7XfqF5bP+hWS11mAKoOQ=="
},
"@types/through2": {
"version": "2.0.33",
"resolved": "https://registry.npmjs.org/@types/through2/-/through2-2.0.33.tgz",
"integrity": "sha1-H/LoihAN+1sUDnu5h5HxGUQA0TE=",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/vinyl": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz",
"integrity": "sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw==",
"requires": {
"@types/node": "*"
}
},
"ansi-256-colors": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz",
"integrity": "sha1-kQ3lDvzHwJ49gvL4er1rcAwYgYo=",
"dev": true
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"requires": {
"sprintf-js": "~1.0.2"
}
},
"arrify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true
},
"assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"beautycolor": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/beautycolor/-/beautycolor-1.0.11.tgz",
"integrity": "sha512-Uxl/39+2uqixPzsrV+0NOHf0sJlWmsKnRTV0oz8+bfwnHPA/E+SZuh3Upn3OXobv0W7LZg5BVoLj1nkMj7m5jA==",
"dev": true,
"requires": {
"ansi-256-colors": "^1.1.0",
"typings-global": "^1.0.14"
}
},
"bindings": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
"integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"buffer-from": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
"integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
"dev": true
},
"chai": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
"integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
"dev": true,
"requires": {
"assertion-error": "^1.0.1",
"check-error": "^1.0.1",
"deep-eql": "^3.0.0",
"get-func-name": "^2.0.0",
"pathval": "^1.0.0",
"type-detect": "^4.0.0"
}
},
"chai-as-promised": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz",
"integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==",
"dev": true,
"requires": {
"check-error": "^1.0.2"
}
},
"chai-string": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/chai-string/-/chai-string-1.4.0.tgz",
"integrity": "sha1-NZFAwFHTak5LGl/GuRAVL0OKjUk=",
"dev": true
},
"check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
"dev": true
},
"clone": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
"integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs="
},
"clone-buffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
"integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg="
},
"clone-stats": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
"integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA="
},
"cloneable-readable": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
"integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
"requires": {
"inherits": "^2.0.1",
"process-nextick-args": "^2.0.0",
"readable-stream": "^2.3.5"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"deep-eql": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
"integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
"dev": true,
"requires": {
"type-detect": "^4.0.0"
}
},
"define-properties": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
"integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
"requires": {
"foreach": "^2.0.5",
"object-keys": "^1.0.8"
}
},
"diff": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"dev": true
},
"early": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/early/-/early-2.1.1.tgz",
"integrity": "sha1-hB4jJU6l3FTYr67ugvWrZcAO4jw=",
"dev": true,
"requires": {
"beautycolor": "^1.0.7",
"smartq": "^1.1.1",
"typings-global": "^1.0.16"
}
},
"es-abstract": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
"integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
"requires": {
"es-to-primitive": "^1.1.1",
"function-bind": "^1.1.1",
"has": "^1.0.1",
"is-callable": "^1.1.3",
"is-regex": "^1.0.4"
}
},
"es-to-primitive": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
"integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
"requires": {
"is-callable": "^1.1.1",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.1"
}
},
"es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
"dev": true
},
"esprima": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
"integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
},
"first-chunk-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz",
"integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=",
"requires": {
"readable-stream": "^2.0.2"
}
},
"foreach": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
},
"fs-extra": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
"integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
"dev": true
},
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
},
"gulp-function": {
"version": "2.2.14",
"resolved": "https://registry.npmjs.org/gulp-function/-/gulp-function-2.2.14.tgz",
"integrity": "sha512-tNNqKklcSia6AbOyPfvSUSXc3dOq7ZSuCN/o3YE0IcJVZdzftqgSFeeqTgyzvWMpPldo2lZ7D4jeW+kr52fUxw==",
"dev": true,
"requires": {
"@types/through2": "^2.0.32",
"smartq": "^1.1.6",
"through2": "^2.0.3"
},
"dependencies": {
"smartq": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/smartq/-/smartq-1.1.8.tgz",
"integrity": "sha512-FURlYW/C3bLeZjJcBVyw7bxCyQoCXiXbLCZcDUKznhXHaLu35c8m33/a2H8CA0rtb82lvzN8dRLnBZAcNMzNHQ==",
"dev": true,
"requires": {
"util.promisify": "^1.0.0"
}
}
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"home": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/home/-/home-1.0.1.tgz",
"integrity": "sha1-lqQjzrSbmDeP9e886uBZpVf53TU=",
"requires": {
"os-homedir": "^1.0.1"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"is-callable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
"integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI="
},
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"requires": {
"has": "^1.0.1"
}
},
"is-symbol": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
"integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI="
},
"is-utf8": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"js-yaml": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
"integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"requires": {
"graceful-fs": "^4.1.6"
}
},
"leakage": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/leakage/-/leakage-0.4.0.tgz",
"integrity": "sha512-x7gYK5n5dPkHDZWJ2Kh8Ag1hZNzUh+HtXn8Bv1aDdN6o6ONPCJ8sOfFq+kxcULJFp3lXaCjXb3iXOLmQRbBLwA==",
"dev": true,
"requires": {
"@airbnb/node-memwatch": "^1.0.2",
"es6-error": "^4.0.2",
"left-pad": "^1.1.3",
"minimist": "^1.2.0",
"pretty-bytes": "^4.0.2"
}
},
"left-pad": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
"dev": true
},
"make-error": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz",
"integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
"minimist": "0.0.8"
},
"dependencies": {
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
}
}
},
"nan": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
"dev": true
},
"object-keys": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
"integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag=="
},
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.1"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"pathval": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
"integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
"dev": true
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
},
"pretty-bytes": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz",
"integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=",
"dev": true
},
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
},
"replace-ext": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
"integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs="
},
"require-reload": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/require-reload/-/require-reload-0.2.2.tgz",
"integrity": "sha1-KadZGEbK+RtuijzamRaD+V+NfUI=",
"dev": true
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"smartchai": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/smartchai/-/smartchai-2.0.1.tgz",
"integrity": "sha512-9M+R56OhAHXScxgr2vzQqxGx0XMS0QXriNZuP7hjlbVbo2FUT+l60iEzbwPt9Ga+5u2cEEjSSoZEQVqlROaddA==",
"dev": true,
"requires": {
"@types/chai": "^4.1.2",
"@types/chai-as-promised": "^7.1.0",
"@types/chai-string": "^1.4.0",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chai-string": "^1.4.0"
}
},
"smartdelay": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/smartdelay/-/smartdelay-1.0.4.tgz",
"integrity": "sha512-ab+d8ADiMMPKwrQNhoJYjmOR20VIIIxjknoEF9/PfMryic7tmvTmFrDMdcnMRohGNw/pN+4/I5dSUBdsDya7uw==",
"dev": true,
"requires": {
"smartq": "^1.1.1",
"typings-global": "^1.0.16"
}
},
"smartfile": {
"version": "4.2.28",
"resolved": "https://registry.npmjs.org/smartfile/-/smartfile-4.2.28.tgz",
"integrity": "sha512-zUeAOLYftz8xLfKTs9U1NOuNPTA9jlvTQNr7lDIv84kXnr1AEpDb2Xwy1MdK1w733sBil/RkxtezrkvgRVAnNg==",
"dev": true,
"requires": {
"@types/fs-extra": "5.0.0",
"@types/vinyl": "^2.0.2",
"fs-extra": "^5.0.0",
"glob": "^7.1.2",
"js-yaml": "^3.10.0",
"require-reload": "0.2.2",
"smartpath": "^3.2.8",
"smartq": "^1.1.6",
"smartrequest": "^1.0.8",
"vinyl-file": "^3.0.0"
},
"dependencies": {
"@types/fs-extra": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.0.tgz",
"integrity": "sha512-qtxDULQKUenuaDLW003CgC+0T0eiAfH3BrH+vSt87GLzbz5EZ6Ox6mv9rMttvhDOatbb9nYh0E1m7ydoYwUrAg==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"fs-extra": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
}
}
},
"smartpath": {
"version": "3.2.8",
"resolved": "https://registry.npmjs.org/smartpath/-/smartpath-3.2.8.tgz",
"integrity": "sha1-SDS9OouuIpW6rK26I8h6UBlS+UA=",
"requires": {
"home": "^1.0.1",
"typings-global": "^1.0.14"
}
},
"smartq": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/smartq/-/smartq-1.1.8.tgz",
"integrity": "sha512-FURlYW/C3bLeZjJcBVyw7bxCyQoCXiXbLCZcDUKznhXHaLu35c8m33/a2H8CA0rtb82lvzN8dRLnBZAcNMzNHQ==",
"requires": {
"util.promisify": "^1.0.0"
}
},
"smartrequest": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/smartrequest/-/smartrequest-1.0.13.tgz",
"integrity": "sha512-OHrvzaxaA8Z8bJr33yxnyJF35nrWyaumsajqXm2Zkv0/2hfWO1NQAj02VVV51rLQfmtU0Hex7Nk19SoC8nOmYg==",
"dev": true,
"requires": {
"smartq": "^1.1.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-support": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz",
"integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
},
"strip-bom": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
"requires": {
"is-utf8": "^0.2.0"
}
},
"strip-bom-buf": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz",
"integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=",
"requires": {
"is-utf8": "^0.2.1"
}
},
"strip-bom-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz",
"integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=",
"requires": {
"first-chunk-stream": "^2.0.0",
"strip-bom": "^2.0.0"
}
},
"tapbundle": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/tapbundle/-/tapbundle-2.0.2.tgz",
"integrity": "sha512-y3ulfK4GKoVkuqF2QsrwVMWLXHqXeoDEzsw/Q9ZTJumNINbx4bcWPAdg2IcTHYgJHeSdF03HiB9EbHoUTRjD9Q==",
"dev": true,
"requires": {
"early": "^2.1.1",
"leakage": "^0.4.0",
"smartchai": "^2.0.1",
"smartdelay": "^1.0.4",
"smartq": "^1.1.8"
}
},
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
"readable-stream": "^2.1.5",
"xtend": "~4.0.1"
}
},
"ts-node": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.0.tgz",
"integrity": "sha512-klJsfswHP0FuOLsvBZ/zzCfUvakOSSxds78mVeK7I+qP76YWtxf16hEZsp3U+b0kIo82R5UatGFeblYMqabb2Q==",
"dev": true,
"requires": {
"arrify": "^1.0.0",
"buffer-from": "^1.1.0",
"diff": "^3.1.0",
"make-error": "^1.1.1",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"source-map-support": "^0.5.6",
"yn": "^2.0.0"
}
},
"type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true
},
"typescript": {
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
"dev": true
},
"typings-global": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/typings-global/-/typings-global-1.0.28.tgz",
"integrity": "sha512-6VOwJWEY2971HOMHu/7sURzUXiD4/LiMJPsMAOqkHHAtS3MVpLFE5gzTiHilsH9KY5VE1mBQirWIgWFsDuo90A=="
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"util.promisify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
"integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
"requires": {
"define-properties": "^1.1.2",
"object.getownpropertydescriptors": "^2.0.3"
}
},
"vinyl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
"integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
"requires": {
"clone": "^2.1.1",
"clone-buffer": "^1.0.0",
"clone-stats": "^1.0.0",
"cloneable-readable": "^1.0.0",
"remove-trailing-separator": "^1.0.1",
"replace-ext": "^1.0.0"
}
},
"vinyl-file": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-3.0.0.tgz",
"integrity": "sha1-sQTZ5ECf+jJfqt1SBkLQo7SIs2U=",
"requires": {
"graceful-fs": "^4.1.2",
"pify": "^2.3.0",
"strip-bom-buf": "^1.0.0",
"strip-bom-stream": "^2.0.0",
"vinyl": "^2.0.1"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
"dev": true
},
"yn": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
"integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
"dev": true
}
}
}

View File

@ -1,47 +1,78 @@
{
"name": "@pushrocks/smartfile",
"name": "@push.rocks/smartfile",
"private": false,
"version": "6.0.3",
"description": "offers smart ways to work with files in nodejs",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"version": "11.0.13",
"description": "provides a robust suite of tools for managing files in Node.js using TypeScript.",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"type": "module",
"scripts": {
"test": "(tsrun test/test.ts)",
"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": "(npmts)"
"test": "(tstest test/)",
"build": "(tsbuild --web --allowimplicitany)",
"buildDocs": "tsdoc"
},
"repository": {
"type": "git",
"url": "https://gitlab.com/pushrocks/smartfile.git"
"url": "git+https://gitlab.com/push.rocks/smartfile.git"
},
"keywords": [
"filesystem",
"json"
"files management",
"TypeScript",
"Node.js",
"read files",
"write files",
"copy files",
"file streaming",
"directories manipulation",
"virtual file system",
"filesystem utilities",
"ESM syntax",
"memory-efficient streaming"
],
"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"
"url": "https://gitlab.com/push.rocks/smartfile/issues"
},
"homepage": "https://gitlab.com/pushrocks/smartfile",
"homepage": "https://gitlab.com/push.rocks/smartfile#readme",
"dependencies": {
"@pushrocks/smartpromise": "^2.0.5",
"@pushrocks/smartrequest": "^1.0.15",
"@types/fs-extra": "^5.0.3",
"@types/vinyl": "^2.0.2",
"fs-extra": "^6.0.1",
"glob": "^7.1.2",
"js-yaml": "^3.10.0",
"smartpath": "^3.2.8",
"vinyl-file": "^3.0.0"
"@push.rocks/lik": "^6.0.14",
"@push.rocks/smartdelay": "^3.0.5",
"@push.rocks/smartfile-interfaces": "^1.0.7",
"@push.rocks/smarthash": "^3.0.4",
"@push.rocks/smartjson": "^5.0.16",
"@push.rocks/smartmime": "^1.0.5",
"@push.rocks/smartpath": "^5.0.13",
"@push.rocks/smartpromise": "^4.0.2",
"@push.rocks/smartrequest": "^2.0.21",
"@push.rocks/smartstream": "^3.0.34",
"@types/fs-extra": "^11.0.4",
"@types/glob": "^8.1.0",
"@types/js-yaml": "^4.0.9",
"fs-extra": "^11.2.0",
"glob": "^10.3.12",
"js-yaml": "^4.1.0"
},
"devDependencies": {
"@gitzone/tsrun": "^1.1.1",
"@types/node": "^10.5.1",
"gulp-function": "^2.2.14",
"tapbundle": "^2.0.2"
}
"@git.zone/tsbuild": "^2.1.72",
"@git.zone/tsrun": "^1.2.46",
"@git.zone/tstest": "^1.0.88",
"@push.rocks/tapbundle": "^5.0.22",
"@types/node": "^20.12.7"
},
"files": [
"ts/**/*",
"ts_web/**/*",
"dist/**/*",
"dist_*/**/*",
"dist_ts/**/*",
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
"npmextra.json",
"readme.md"
],
"browserslist": [
"last 1 chrome versions"
]
}

4808
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

279
readme.md Normal file
View File

@ -0,0 +1,279 @@
# @push.rocks/smartfile
> Provides a robust suite of tools for managing files in Node.js using TypeScript.
## Install
To integrate `@push.rocks/smartfile` into your project, run:
```bash
npm install @push.rocks/smartfile
```
## Usage
`@push.rocks/smartfile` offers a comprehensive set of utilities for handling files in Node.js projects using modern TypeScript and ESM syntax. It simplifies various file operations such as reading, writing, copying, and streaming files, as well as working with directories and virtual file systems.
### Key Features and Classes
- **`SmartFile`**: Facilitates reading from and writing to individual files, managing metadata.
- **`StreamFile`**: Optimizes memory usage by enabling efficient file streaming.
- **`VirtualDirectory`**: Allows manipulation of a group of files or directories as a virtual file system.
### Getting Started with ESM and TypeScript
First, ensure your project supports ESM syntax and TypeScript. Then, begin by importing the desired features from `@push.rocks/smartfile`:
```typescript
import { SmartFile, StreamFile, VirtualDirectory, memory, fs as smartFs } from '@push.rocks/smartfile';
```
### Reading and Writing Files
#### Reading Files
Reading a JSON file:
```typescript
const myJsonFile: SmartFile = await SmartFile.fromFilePath('./data.json');
const jsonData = JSON.parse(myJsonFile.contents.toString());
console.log(jsonData);
```
#### Writing Files
Writing content to a file:
```typescript
const filePath: string = './output.txt';
const content: string = 'Hello, SmartFile!';
await memory.toFs(content, filePath);
console.log('File saved successfully.');
```
### Streaming Large Files
For large files, `StreamFile` provides a memory-efficient streaming solution:
```typescript
import { createReadStream } from 'fs';
const sourceStream = createReadStream('./large-video.mp4');
const myStreamFile = await StreamFile.fromStream(sourceStream, 'large-video.mp4');
await myStreamFile.writeToDir('./storage');
console.log('Large file streamed to disk successfully.');
```
### Working with Virtual Directories
`VirtualDirectory` abstracts a collection of files allowing operations to be performed as if they were on disk:
```typescript
const virtualDir = new VirtualDirectory();
virtualDir.addSmartfiles([smartFile1, smartFile2]); // Assuming these are SmartFile instances
await virtualDir.saveToDisk('./virtual-output');
console.log('Virtual directory saved to disk.');
```
### Advanced File Operations
`@push.rocks/smartfile` simplifies complex file operations, including:
- Copying directories and files
- Removing files or directories
- Listing files and directories with filters
- Reading file content directly into JavaScript objects
### Web File Handling
Handling files from HTTP requests:
`@push.rocks/smartfile` offers utilities to work with files from web sources, making it simpler to manage downloads and uploads.
### Comprehensive File Management
Whether you're dealing with local files, directories, or files over the internet, `@push.rocks/smartfile` provides a comprehensive set of tools to streamline your workflow and reduce the complexity of file management in your Node.js projects.
## API Reference
### `SmartFile` Class
#### Static Methods
- `SmartFile.fromFilePath(filePath: string, baseArg?: string): Promise<SmartFile>`
- Creates a `SmartFile` instance from a file path.
- `SmartFile.fromBuffer(filePath: string, contentBufferArg: Buffer, baseArg?: string): Promise<SmartFile>`
- Creates a `SmartFile` instance from a `Buffer`.
- `SmartFile.fromString(filePath: string, contentStringArg: string, encodingArg: 'utf8' | 'binary', baseArg?: string): Promise<SmartFile>`
- Creates a `SmartFile` instance from a string.
- `SmartFile.fromFoldedJson(foldedJsonArg: string): Promise<SmartFile>`
- Creates a `SmartFile` instance from a folded JSON string.
- `SmartFile.fromStream(stream: Readable, filePath: string, baseArg?: string): Promise<SmartFile>`
- Creates a `SmartFile` instance from a `Readable` stream.
- `SmartFile.fromUrl(urlArg: string): Promise<SmartFile>`
- Creates a `SmartFile` instance from a URL.
#### Instance Properties
- `path: string`
- The relative path of the file.
- `parsedPath: path.ParsedPath`
- A parsed path object.
- `absolutePath: string`
- The absolute path of the file.
- `absoluteParsedPath: path.ParsedPath`
- A parsed absolute path object.
- `contentBuffer: Buffer`
- The content of the file as a `Buffer`.
- `base: string`
- The current working directory of the file.
- `sync: boolean`
- Indicates whether the file is synced with the disk.
#### Instance Methods
- `setContentsFromString(contentString: string, encodingArg?: 'utf8' | 'binary'): void`
- Sets the contents of the file from a string.
- `write(): Promise<void>`
- Writes the file to disk at its original location.
- `writeToDiskAtPath(filePathArg: string): Promise<void>`
- Writes the file to the specified path on disk.
- `writeToDir(dirPathArg: string): Promise<string>`
- Writes the file to a directory combined with the relative path portion.
- `read(): Promise<void>`
- Reads the file from disk.
- `delete(): Promise<void>`
- Deletes the file from disk at its original location.
- `getHash(typeArg?: 'path' | 'content' | 'all'): Promise<string>`
- Returns a hash of the file based on the specified type.
- `updateFileName(fileNameArg: string): void`
- Updates the file name of the `SmartFile` instance.
- `editContentAsString(editFuncArg: (fileStringArg: string) => Promise<string>): Promise<void>`
- Edits the content of the file as a string using the provided edit function.
- `getStream(): Readable`
- Returns a `Readable` stream from the file's content buffer.
### `StreamFile` Class
#### Static Methods
- `StreamFile.fromPath(filePath: string): Promise<StreamFile>`
- Creates a `StreamFile` instance from a file path.
- `StreamFile.fromUrl(url: string): Promise<StreamFile>`
- Creates a `StreamFile` instance from a URL.
- `StreamFile.fromBuffer(buffer: Buffer, relativeFilePath?: string): StreamFile`
- Creates a `StreamFile` instance from a `Buffer`.
- `StreamFile.fromStream(stream: Readable, relativeFilePath?: string, multiUse?: boolean): StreamFile`
- Creates a `StreamFile` instance from a `Readable` stream.
#### Instance Properties
- `relativeFilePath?: string`
- The relative file path of the `StreamFile`.
- `multiUse: boolean`
- Indicates whether the `StreamFile` can be used multiple times.
- `used: boolean`
- Indicates whether the `StreamFile` has been used.
#### Instance Methods
- `createReadStream(): Promise<Readable>`
- Creates a new `Readable` stream from the source.
- `writeToDisk(filePathArg: string): Promise<void>`
- Writes the stream to the disk at the specified path.
- `writeToDir(dirPathArg: string): Promise<void>`
- Writes the stream to a directory combined with the relative path portion.
- `getContentAsBuffer(): Promise<Buffer>`
- Returns the content of the `StreamFile` as a `Buffer`.
- `getContentAsString(formatArg?: 'utf8' | 'binary'): Promise<string>`
- Returns the content of the `StreamFile` as a string.
### `VirtualDirectory` Class
#### Static Methods
- `VirtualDirectory.fromFsDirPath(pathArg: string): Promise<VirtualDirectory>`
- Creates a `VirtualDirectory` instance from a file system directory path.
- `VirtualDirectory.fromVirtualDirTransferableObject(virtualDirTransferableObjectArg: VirtualDirTransferableObject): Promise<VirtualDirectory>`
- Creates a `VirtualDirectory` instance from a `VirtualDirTransferableObject`.
#### Instance Properties
- `smartfileArray: SmartFile[]`
- An array of `SmartFile` instances in the `VirtualDirectory`.
#### Instance Methods
- `addSmartfiles(smartfileArrayArg: SmartFile[]): void`
- Adds an array of `SmartFile` instances to the `VirtualDirectory`.
- `getFileByPath(pathArg: string): Promise<SmartFile | undefined>`
- Retrieves a `SmartFile` instance from the `VirtualDirectory` by its path.
- `toVirtualDirTransferableObject(): Promise<VirtualDirTransferableObject>`
- Converts the `VirtualDirectory` to a `VirtualDirTransferableObject`.
- `saveToDisk(dirArg: string): Promise<void>`
- Saves the `VirtualDirectory` to the disk at the specified directory.
- `shiftToSubdirectory(subDir: string): Promise<VirtualDirectory>`
- Shifts the `VirtualDirectory` to a subdirectory.
- `addVirtualDirectory(virtualDir: VirtualDirectory, newRoot: string): Promise<void>`
- Adds another `VirtualDirectory` to the current `VirtualDirectory` with a new root path.
### `fs` Module
The `fs` module provides various file system utility functions. Some notable functions include:
- `fileExistsSync(filePath: string): boolean`
- Checks if a file exists synchronously.
- `fileExists(filePath: string): Promise<boolean>`
- Checks if a file exists asynchronously.
- `listFoldersSync(pathArg: string, regexFilter?: RegExp): string[]`
- Lists folders in a directory synchronously.
- `listFolders(pathArg: string, regexFilter?: RegExp): Promise<string[]>`
- Lists folders in a directory asynchronously.
- `listFilesSync(pathArg: string, regexFilter?: RegExp): string[]`
- Lists files in a directory synchronously.
- `listFiles(pathArg: string, regexFilter?: RegExp): Promise<string[]>`
- Lists files in a directory asynchronously.
- `listFileTree(dirPathArg: string, miniMatchFilter: string, absolutePathsBool?: boolean): Promise<string[]>`
- Lists a file tree using a minimatch filter.
- `waitForFileToBeReady(filePathArg: string): Promise<void>`
- Waits for a file to be ready (exists and is not empty).
- `toFs(filePathArg: string, fileContentArg: string | Buffer | SmartFile | StreamFile, optionsArg?: { respectRelative?: boolean }): Promise<void>`
- Writes a string, `Buffer`, `SmartFile`, or `StreamFile` to the file system.
### `memory` Module
The `memory` module provides utility functions for working with files in memory. Some notable functions include:
- `toObject(fileStringArg: string, fileTypeArg: string): any`
- Converts a file string to an object based on the file type.
- `toFs(fileContentArg: string | Buffer | SmartFile | StreamFile, filePathArg: string, optionsArg?: IToFsOptions): Promise<void>`
- Writes a string, `Buffer`, `SmartFile`, or `StreamFile` to the file system.
- `toFsSync(fileArg: string, filePathArg: string): void`
- Writes a string to the file system synchronously.
- `smartfileArrayToFs(smartfileArrayArg: SmartFile[], dirArg: string): Promise<void>`
- Writes an array of `SmartFile` instances to the file system.
### `interpreter` Module
The `interpreter` module provides utility functions for interpreting file types and contents. Some notable functions include:
- `filetype(pathArg: string): string`
- Determines the file type based on the file path.
- `objectFile(fileStringArg: string, fileTypeArg: any): any`
- Converts a file string to an object based on the file type.
## License and Legal Information
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
### Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
### Company Information
Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

67
test/test.streamfile.ts Normal file
View File

@ -0,0 +1,67 @@
import * as path from 'path';
import { expect, tap } from '@push.rocks/tapbundle';
import * as smartfile from '../ts/index.js'; // adjust the import path as needed
// Test assets path
const testAssetsPath = './test/testassets/';
// ---------------------------
// StreamFile tests
// ---------------------------
tap.test('StreamFile.fromPath should create a StreamFile from a file path', async () => {
const streamFile = await smartfile.StreamFile.fromPath(path.join(testAssetsPath, 'mytest.json'));
expect(streamFile).toBeInstanceOf(smartfile.StreamFile);
const contentBuffer = await streamFile.getContentAsBuffer();
expect(contentBuffer).toBeInstanceOf(Buffer);
});
tap.test('StreamFile.fromUrl should create a StreamFile from a URL', async () => {
const streamFile = await smartfile.StreamFile.fromUrl('http://example.com/somefile.json');
expect(streamFile).toBeInstanceOf(smartfile.StreamFile);
});
tap.test('StreamFile.fromBuffer should create a StreamFile from a Buffer', async () => {
const buffer = Buffer.from('Some content');
const streamFile = smartfile.StreamFile.fromBuffer(buffer, 'bufferfile.txt');
expect(streamFile).toBeInstanceOf(smartfile.StreamFile);
});
tap.test('StreamFile should write the stream to disk', async () => {
const streamFile = await smartfile.StreamFile.fromPath(path.join(testAssetsPath, 'mytest.json'));
await streamFile.writeToDisk(path.join(testAssetsPath, 'temp', 'mytest.json'));
// Verify the file was written
expect(
// We'll use the fileExists method from your smartfile library
// Replace with the actual method you use to check file existence
await smartfile.fs.fileExists(path.join(testAssetsPath, 'temp', 'mytest.json'))
).toBeTrue();
});
tap.test('StreamFile should write to a directory', async () => {
const streamFile = await smartfile.StreamFile.fromPath(path.join(testAssetsPath, 'mytest.json'));
await streamFile.writeToDir(path.join(testAssetsPath, 'temp'));
// Verify the file was written
expect(
await smartfile.fs.fileExists(path.join(testAssetsPath, 'temp', 'mytest.json'))
).toBeTrue();
});
tap.test('StreamFile should return content as a buffer', async () => {
const streamFile = await smartfile.StreamFile.fromPath(path.join(testAssetsPath, 'mytest.json'));
const contentBuffer = await streamFile.getContentAsBuffer();
expect(contentBuffer).toBeInstanceOf(Buffer);
// Further checks on the content can be added here if necessary
});
tap.test('StreamFile should return content as a string', async () => {
const streamFile = await smartfile.StreamFile.fromPath(path.join(testAssetsPath, 'mytest.json'));
const contentString = await streamFile.getContentAsString();
expect(typeof contentString).toBeTypeofString();
// Verify the content matches what's expected
// This assumes the file contains a JSON object with a key 'key1' with value 'this works'
expect(JSON.parse(contentString).key1).toEqual('this works');
});
// Start the test sequence
tap.start();

View File

@ -1,119 +1,137 @@
import * as smartfile from '../ts/index';
import path = require('path');
import * as smartfile from '../ts/index.js';
import * as path from 'path';
import { expect, tap } from 'tapbundle';
import { expect, tap } from '@push.rocks/tapbundle';
// ---------------------------
// smartfile.fs
// ---------------------------
tap.test('.fs.fileExistsSync -> should return an accurate boolean', async () => {
expect(smartfile.fs.fileExistsSync('./test/mytest.json')).to.be.true;
expect(smartfile.fs.fileExistsSync('./test/notthere.json')).be.false;
// tslint:disable-next-line: no-unused-expression
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 () => {
expect(smartfile.fs.fileExists('./test/mytest.json')).to.be.instanceof(Promise);
await smartfile.fs.fileExists('./test/mytest.json');
await smartfile.fs.fileExists('./test/notthere.json').catch(err => {
return expect(err.message).to.equal(
"ENOENT: no such file or directory, access './test/notthere.json'"
expect(smartfile.fs.fileExists('./test/testassets/mytest.json')).toBeInstanceOf(Promise);
await smartfile.fs.fileExists('./test/testassets/mytest.json');
await smartfile.fs.fileExists('./test/testassets/notthere.json').catch((err) => {
return expect(err.message).toEqual(
"ENOENT: no such file or directory, access './test/testassets/notthere.json'"
);
});
});
tap.test('.fs.listFoldersSync() -> should get the file type from a string', async () => {
expect(smartfile.fs.listFoldersSync('./test/')).to.include('testfolder');
expect(smartfile.fs.listFoldersSync('./test/')).to.not.include('notExistentFolder');
expect(smartfile.fs.listFoldersSync('./test/testassets/')).toContain('testfolder');
expect(smartfile.fs.listFoldersSync('./test/testassets/')).not.toContain('notExistentFolder');
});
tap.test('.fs.listFolders() -> should get the file type from a string', async () => {
let folderArrayArg = await smartfile.fs.listFolders('./test/');
expect(folderArrayArg).to.include('testfolder');
expect(folderArrayArg).to.not.include('notExistentFolder');
const folderArrayArg = await smartfile.fs.listFolders('./test/testassets/');
expect(folderArrayArg).toContain('testfolder');
expect(folderArrayArg).not.toContain('notExistentFolder');
});
tap.test('.fs.listFilesSync() -> should get the file type from a string', async () => {
expect(smartfile.fs.listFilesSync('./test/')).to.include('mytest.json');
expect(smartfile.fs.listFilesSync('./test/')).to.not.include('notExistentFile');
expect(smartfile.fs.listFilesSync('./test/', /mytest\.json/)).to.include('mytest.json');
expect(smartfile.fs.listFilesSync('./test/', /mytests.json/)).to.not.include('mytest.json');
expect(smartfile.fs.listFilesSync('./test/testassets/')).toContain('mytest.json');
expect(smartfile.fs.listFilesSync('./test/testassets/')).not.toContain('notExistentFile');
expect(smartfile.fs.listFilesSync('./test/testassets/', /mytest\.json/)).toContain('mytest.json');
expect(smartfile.fs.listFilesSync('./test/testassets/', /mytests.json/)).not.toContain(
'mytest.json'
);
});
tap.test('.fs.listFiles() -> should get the file type from a string', async () => {
let folderArrayArg = await smartfile.fs.listFiles('./test/');
expect(folderArrayArg).to.include('mytest.json');
expect(folderArrayArg).to.not.include('notExistentFile');
const folderArrayArg = await smartfile.fs.listFiles('./test/testassets/');
expect(folderArrayArg).toContain('mytest.json');
expect(folderArrayArg).not.toContain('notExistentFile');
});
tap.test('.fs.listFileTree() -> should get a file tree', async () => {
let folderArrayArg = await smartfile.fs.listFileTree(path.resolve('./test/'), '**/*.txt');
expect(folderArrayArg).to.include('testfolder/testfile1.txt');
expect(folderArrayArg).to.not.include('mytest.json');
const folderArrayArg = await smartfile.fs.listFileTree(
path.resolve('./test/testassets/'),
'**/*.txt'
);
expect(folderArrayArg).toContain('testfolder/testfile1.txt');
expect(folderArrayArg).not.toContain('mytest.json');
});
tap.test('.fs.fileTreeToObject -> should read a file tree into an Object', async () => {
let fileArrayArg = await smartfile.fs.fileTreeToObject(path.resolve('./test/'), '**/*.txt');
expect(fileArrayArg[0]).to.be.instanceof(smartfile.Smartfile);
expect(fileArrayArg[0].contents.toString()).to.equal(fileArrayArg[0].contentBuffer.toString());
const fileArrayArg = await smartfile.fs.fileTreeToObject(
path.resolve('./test/testassets/'),
'**/*.txt'
);
expect(fileArrayArg[0]).toBeInstanceOf(smartfile.SmartFile);
expect(fileArrayArg[0].contents.toString()).toEqual(fileArrayArg[0].contentBuffer.toString());
});
tap.test('.fs.copy() -> should copy a directory', async () => {
smartfile.fs.copy('./test/testfolder/', './test/temp/');
await smartfile.fs.copy('./test/testassets/testfolder/', './test/testassets/temp/');
});
tap.test('.fs.copy() -> should copy a file', async () => {
smartfile.fs.copy('./test/mytest.yaml', './test/temp/');
await smartfile.fs.copy('./test/testassets/mytest.yaml', './test/testassets/temp/mytest.yaml');
});
tap.test('.fs.copy() -> should copy a file and rename it', async () => {
smartfile.fs.copy('./test/mytest.yaml', './test/temp/mytestRenamed.yaml');
await smartfile.fs.copy(
'./test/testassets/mytest.yaml',
'./test/testassets/temp/mytestRenamed.yaml'
);
});
tap.test('.fs.remove() -> should remove an entire directory', async () => {});
tap.test('.fs.remove -> should remove single files', async () => {
await smartfile.fs.remove('./test/temp/mytestRenamed.yaml');
await smartfile.fs.remove('./test/testassets/temp/mytestRenamed.yaml');
});
tap.test('.fs.removeSync -> should remove single files synchronouly', async () => {
smartfile.fs.removeSync('./test/temp/testfile1.txt');
expect(smartfile.fs.fileExistsSync('./test/temp/testfile1.txt')).to.be.false;
smartfile.fs.removeSync('./test/testassets/temp/testfile1.txt');
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).toBeFalse();
});
tap.test('.fs.removeMany -> should remove and array of files', async () => {
smartfile.fs.removeMany(['./test/temp/testfile1.txt', './test/temp/testfile2.txt']).then(() => {
expect(smartfile.fs.fileExistsSync('./test/temp/testfile1.txt')).to.be.false;
expect(smartfile.fs.fileExistsSync('./test/temp/testfile2.txt')).to.be.false;
});
smartfile.fs
.removeMany(['./test/testassets/temp/testfile1.txt', './test/testassets/temp/testfile2.txt'])
.then(() => {
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).toBeFalse();
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile2.txt')).toBeFalse();
});
});
tap.test('.fs.removeManySync -> should remove and array of single files synchronouly', async () => {
smartfile.fs.removeManySync(['./test/temp/testfile1.txt', './test/temp/testfile2.txt']);
expect(smartfile.fs.fileExistsSync('./test/temp/testfile1.txt')).to.be.false;
expect(smartfile.fs.fileExistsSync('./test/temp/testfile2.txt')).to.be.false;
smartfile.fs.removeManySync([
'./test/testassets/temp/testfile1.txt',
'./test/testassets/temp/testfile2.txt',
]);
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile1.txt')).toBeFalse();
expect(smartfile.fs.fileExistsSync('./test/testassets/temp/testfile2.txt')).toBeFalse();
});
tap.test('.fs.toObjectSync() -> should read an ' + '.yaml' + ' file to an object', async () => {
let testData = smartfile.fs.toObjectSync('./test/mytest.yaml');
expect(testData).to.include({ key1: 'this works' });
expect(testData).to.include({ key2: 'this works too' });
tap.test('.fs.toObjectSync() -> should read an .yaml file to an object', async () => {
const testData = smartfile.fs.toObjectSync('./test/testassets/mytest.yaml');
expect(testData.key1).toEqual('this works');
expect(testData.key2).toEqual('this works too');
});
tap.test(
'.fs.toObjectSync() -> should state unknown file type for unknown file types',
async () => {
let testData = smartfile.fs.toObjectSync('./test/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/mytest.json');
expect(testData).to.include({ key1: 'this works' });
expect(testData).to.include({ key2: 'this works too' });
tap.test('.fs.toObjectSync() -> should read an .json file to an object', async () => {
const testData = smartfile.fs.toObjectSync('./test/testassets/mytest.json');
expect(testData.key1).toEqual('this works');
expect(testData.key2).toEqual('this works too');
});
tap.test('.fs.toStringSync() -> should read a file to a string', async () => {
expect(smartfile.fs.toStringSync('./test/mytest.txt')).to.equal('Some TestString &&%$');
expect(smartfile.fs.toStringSync('./test/testassets/mytest.txt')).toEqual('Some TestString &&%$');
});
// ---------------------------
@ -121,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 () => {
expect(smartfile.interpreter.filetype('./somefolder/data.json')).equal('json');
expect(smartfile.interpreter.filetype('./somefolder/data.json')).toEqual('json');
});
// ---------------------------
@ -129,66 +147,78 @@ 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';
await smartfile.memory.toFs(localString, path.join(process.cwd(), './test/temp/testMemToFs.txt'));
const localString = 'myString';
await smartfile.memory.toFs(
localString,
path.join(process.cwd(), './test/testassets/temp/testMemToFs.txt')
);
});
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/temp/testMemToFsSync.txt')
path.join(process.cwd(), './test/testassets/temp/testMemToFsSync.txt')
);
}
);
tap.test('.remote.toString() -> should load a remote file to a variable', async () => {
let responseString = await smartfile.remote.toString(
'https://raw.githubusercontent.com/pushrocks/smartfile/master/test/mytest.txt'
);
expect(responseString).to.equal('Some TestString &&%$');
});
tap.test('.remote.toString() -> should reject a Promise when the link is false', async tools => {
tools.returnError;
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
// ---------------------------
tap.test('.Smartfile -> should produce vinyl compatible files', async () => {
let smartfileArray = await smartfile.fs.fileTreeToObject(process.cwd(), './test/testfolder/**/*');
let localSmartfile = smartfileArray[0];
expect(localSmartfile).to.be.instanceof(smartfile.Smartfile);
expect(localSmartfile.contents).to.be.instanceof(Buffer);
const smartfileArray = await smartfile.fs.fileTreeToObject(
process.cwd(),
'./test/testassets/testfolder/**/*'
);
const localSmartfile = smartfileArray[0];
expect(localSmartfile).toBeInstanceOf(smartfile.SmartFile);
expect(localSmartfile.contents).toBeInstanceOf(Buffer);
// tslint:disable-next-line:no-unused-expression
expect(localSmartfile.isBuffer()).to.be.true;
expect(localSmartfile.isBuffer()).toBeTrue();
// tslint:disable-next-line:no-unused-expression
expect(localSmartfile.isDirectory()).to.be.false;
expect(localSmartfile.isDirectory()).toBeFalse();
// 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 () => {
let smartfileArray = await smartfile.fs.fileTreeToObject('./test/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,
path.resolve('./test/temp/testoutput/')
path.resolve('./test/testassets/temp/testoutput/')
);
});
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).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();

View File

@ -0,0 +1,15 @@
import { tap, expect } from '@push.rocks/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,8 @@
{
"key1": "this works",
"key2": "this works too",
"key3": {
"nestedkey1": "hello"
}
}

View File

@ -0,0 +1,4 @@
key1: this works
key2: this works too
key3:
nestedkey1: hello

View File

@ -0,0 +1,8 @@
{
"key1": "this works",
"key2": "this works too",
"key3": {
"nestedkey1": "hello"
}
}

View File

@ -0,0 +1 @@
myString

View File

@ -0,0 +1 @@
myString

View File

@ -0,0 +1 @@
okidoks

View File

@ -0,0 +1 @@
hi

View File

View File

View File

@ -0,0 +1 @@
okidoks

View File

@ -0,0 +1 @@
hi

View File

View File

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

@ -0,0 +1 @@
hi there

8
ts/00_commitinfo_data.ts Normal file
View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartfile',
version: '11.0.13',
description: 'provides a robust suite of tools for managing files in Node.js using TypeScript.'
}

309
ts/classes.smartfile.ts Normal file
View File

@ -0,0 +1,309 @@
import * as plugins from './plugins.js';
import * as fs from './fs.js';
import * as memory from './memory.js';
export interface ISmartfileConstructorOptions {
path: string;
contentBuffer: Buffer;
base: string;
}
/**
* an vinyl file compatible in memory file class
*/
export class SmartFile extends plugins.smartjson.Smartjson {
// ======
// STATIC
// ======
/**
* creates a Smartfile from a filePath
* @param filePath
*/
public static async fromFilePath(filePath: string, baseArg: string = process.cwd()) {
filePath = plugins.path.resolve(filePath);
const fileBuffer = fs.toBufferSync(filePath);
const smartfile = new SmartFile({
contentBuffer: fileBuffer,
base: baseArg,
path: plugins.path.relative(baseArg, filePath),
});
return smartfile;
}
public static async fromBuffer(
filePath: string,
contentBufferArg: Buffer,
baseArg: string = process.cwd()
) {
const smartfile = new SmartFile({
contentBuffer: contentBufferArg,
base: baseArg,
path: plugins.path.relative(baseArg, filePath),
});
return smartfile;
}
public static async fromString(
filePath: string,
contentStringArg: string,
encodingArg: 'utf8' | 'binary',
baseArg = process.cwd()
) {
const smartfile = new SmartFile({
contentBuffer: Buffer.from(contentStringArg, encodingArg),
base: baseArg,
path: plugins.path.relative(baseArg, filePath),
});
return smartfile;
}
public static async fromFoldedJson(foldedJsonArg: string) {
return new SmartFile(plugins.smartjson.parse(foldedJsonArg));
}
/**
* creates a Smartfile from a ReadableStream
* @param stream a readable stream that provides file content
* @param filePath the file path to associate with the content
* @param baseArg the base path to use for the file
*/
public static async fromStream(
stream: plugins.stream.Readable,
filePath: string,
baseArg: string = process.cwd()
): Promise<SmartFile> {
return new Promise<SmartFile>((resolve, reject) => {
const chunks: Buffer[] = [];
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
stream.on('error', (error) => reject(error));
stream.on('end', () => {
const contentBuffer = Buffer.concat(chunks);
const smartfile = new SmartFile({
contentBuffer: contentBuffer,
base: baseArg,
path: plugins.path.relative(baseArg, filePath),
});
resolve(smartfile);
});
});
}
public static async fromUrl (urlArg: string) {
const response = await plugins.smartrequest.getBinary(urlArg);
const smartfile = await SmartFile.fromBuffer(urlArg, response.body);
return smartfile;
}
// ========
// INSTANCE
// ========
/**
* the relative path of the file
*/
@plugins.smartjson.foldDec()
public path: string;
/**
* a parsed path
*/
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
*/
@plugins.smartjson.foldDec()
public contentBuffer: Buffer;
/**
* The current working directory of the file
* Note:this is similar to gulp and different from native node path base
*/
@plugins.smartjson.foldDec()
public base: string;
/**
* sync the file with disk
*/
@plugins.smartjson.foldDec()
public sync: boolean;
/**
* the constructor of Smartfile
* @param optionsArg
*/
constructor(optionsArg: ISmartfileConstructorOptions) {
super();
if (optionsArg.contentBuffer) {
this.contentBuffer = optionsArg.contentBuffer;
} else {
console.log('created empty Smartfile?');
}
this.path = optionsArg.path;
this.base = optionsArg.base;
}
/**
* set contents from string
* @param contentString
*/
public setContentsFromString(contentString: string, encodingArg: 'utf8' | 'binary' = 'utf8') {
this.contents = Buffer.from(contentString, encodingArg);
}
/**
* write file to disk at its original location
* Behaviours:
* - no argument write to exactly where the file was picked up
*/
public async write() {
let writePath = plugins.smartpath.transform.makeAbsolute(this.path, this.base);
console.log(`writing to ${writePath}`);
await memory.toFs(this.contentBuffer, writePath);
}
/**
* 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
*/
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: alias of this.contentBuffer
*/
get contents(): Buffer {
return this.contentBuffer;
}
set contents(contentsArg) {
this.contentBuffer = contentsArg;
}
/**
* vinyl-compatibility
*/
public get cwd() {
return process.cwd();
}
/**
* return relative path of file
*/
public get relative(): string {
return this.path;
}
/**
* return truw when the file has content
*/
public isNull(): boolean {
if (!this.contentBuffer) {
return true;
}
return false;
}
/**
* return true if contents are Buffer
*/
public isBuffer(): boolean {
if (this.contents instanceof Buffer) {
return true;
}
return false;
}
public isDirectory() {
return false;
}
public isStream() {
return false;
}
public isSymbolic() {
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
public updateFileName(fileNameArg: string) {
const oldFileName = this.parsedPath.base;
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);
}
/**
* Returns a ReadableStream from the file's content buffer
*/
public getStream(): plugins.stream.Readable {
const stream = new plugins.stream.Readable();
stream.push(this.contentBuffer); // Push the content buffer to the stream
stream.push(null); // Push null to signify the end of the stream (EOF)
return stream;
}
}

152
ts/classes.streamfile.ts Normal file
View File

@ -0,0 +1,152 @@
import * as plugins from './plugins.js';
import * as smartfileFs from './fs.js';
import * as smartfileFsStream from './fsstream.js';
import { Readable } from 'stream';
type TStreamSource = (streamFile: StreamFile) => Promise<Readable>;
/**
* The StreamFile class represents a file as a stream.
* It allows creating streams from a file path, a URL, or a buffer.
*/
export class StreamFile {
// INSTANCE
relativeFilePath?: string;
private streamSource: TStreamSource;
// enable stream based multi use
private cachedStreamBuffer?: Buffer;
public multiUse: boolean;
public used: boolean = false;
private constructor(streamSource: TStreamSource, relativeFilePath?: string) {
this.streamSource = streamSource;
this.relativeFilePath = relativeFilePath;
}
// STATIC
public static async fromPath(filePath: string): Promise<StreamFile> {
const streamSource: TStreamSource = async (stremFileArg) => smartfileFsStream.createReadStream(filePath);
const streamFile = new StreamFile(streamSource, filePath);
streamFile.multiUse = true;
return streamFile;
}
public static async fromUrl(url: string): Promise<StreamFile> {
const streamSource: TStreamSource = async (streamFileArg) => plugins.smartrequest.getStream(url); // Replace with actual plugin method
const streamFile = new StreamFile(streamSource);
streamFile.multiUse = true;
return streamFile;
}
public static fromBuffer(buffer: Buffer, relativeFilePath?: string): StreamFile {
const streamSource: TStreamSource = async (streamFileArg) => {
const stream = new Readable();
stream.push(buffer);
stream.push(null); // End of stream
return stream;
};
const streamFile = new StreamFile(streamSource, relativeFilePath);
streamFile.multiUse = true;
return streamFile;
}
/**
* Creates a StreamFile from an existing Readable stream with an option for multiple uses.
* @param stream A Node.js Readable stream.
* @param relativeFilePath Optional file path for the stream.
* @param multiUse If true, the stream can be read multiple times, caching its content.
* @returns A StreamFile instance.
*/
public static fromStream(stream: Readable, relativeFilePath?: string, multiUse: boolean = false): StreamFile {
const streamSource: TStreamSource = (streamFileArg) => {
if (streamFileArg.multiUse) {
// If multi-use is enabled and we have cached content, create a new readable stream from the buffer
const bufferedStream = new Readable();
bufferedStream.push(streamFileArg.cachedStreamBuffer);
bufferedStream.push(null); // No more data to push
return Promise.resolve(bufferedStream);
} else {
return Promise.resolve(stream);
}
};
const streamFile = new StreamFile(streamSource, relativeFilePath);
streamFile.multiUse = multiUse;
// If multi-use is enabled, cache the stream when it's first read
if (multiUse) {
const chunks: Buffer[] = [];
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
stream.on('end', () => {
streamFile.cachedStreamBuffer = Buffer.concat(chunks);
});
// It's important to handle errors that may occur during streaming
stream.on('error', (err) => {
console.error('Error while caching stream:', err);
});
}
return streamFile;
}
// METHODS
private checkMultiUse() {
if (!this.multiUse && this.used) {
throw new Error('This stream can only be used once.');
}
this.used = true;
}
/**
* Creates a new readable stream from the source.
*/
public async createReadStream(): Promise<Readable> {
return this.streamSource(this);
}
/**
* Writes the stream to the disk at the specified path.
* @param filePathArg The file path where the stream should be written.
*/
public async writeToDisk(filePathArg: string): Promise<void> {
this.checkMultiUse();
const readStream = await this.createReadStream();
const writeStream = smartfileFsStream.createWriteStream(filePathArg);
return new Promise((resolve, reject) => {
readStream.pipe(writeStream);
readStream.on('error', reject);
writeStream.on('error', reject);
writeStream.on('finish', resolve);
});
}
public async writeToDir(dirPathArg: string) {
this.checkMultiUse();
const filePath = plugins.path.join(dirPathArg, this.relativeFilePath);
await smartfileFs.ensureDir(plugins.path.parse(filePath).dir);
return this.writeToDisk(filePath);
}
public async getContentAsBuffer() {
this.checkMultiUse();
const done = plugins.smartpromise.defer<Buffer>();
const readStream = await this.createReadStream();
const chunks: Buffer[] = [];
readStream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
readStream.on('error', done.reject);
readStream.on('end', () => {
const contentBuffer = Buffer.concat(chunks);
done.resolve(contentBuffer);
});
return done.promise;
}
public async getContentAsString(formatArg: 'utf8' | 'binary' = 'utf8') {
const contentBuffer = await this.getContentAsBuffer();
return contentBuffer.toString(formatArg);
}
}

View File

@ -0,0 +1,87 @@
import { SmartFile } from './classes.smartfile.js';
import * as plugins from './plugins.js';
import * as fs from './fs.js';
export interface IVirtualDirectoryConstructorOptions {
mode: ''
}
/**
* a virtual directory exposes a fs api
*/
export class VirtualDirectory {
consstructor(options = {}) {
}
// 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} files to directory:
--> ${dirArg}`);
for (const smartfileArg of this.smartfileArray) {
const filePath = await smartfileArg.writeToDir(dirArg);
console.log(`wrote ${smartfileArg.relative} to
--> ${filePath}`);
}
}
public async shiftToSubdirectory(subDir: string): Promise<VirtualDirectory> {
const newVirtualDir = new VirtualDirectory();
for (const file of this.smartfileArray) {
if (file.path.startsWith(subDir)) {
const adjustedFilePath = plugins.path.relative(subDir, file.path);
file.path = adjustedFilePath;
newVirtualDir.addSmartfiles([file]);
}
}
return newVirtualDir;
}
public async addVirtualDirectory(virtualDir: VirtualDirectory, newRoot: string): Promise<void> {
for (const file of virtualDir.smartfileArray) {
file.path = plugins.path.join(newRoot, file.path);
}
this.addSmartfiles(virtualDir.smartfileArray);
}
}

491
ts/fs.ts Normal file
View File

@ -0,0 +1,491 @@
import * as plugins from './plugins.js';
import * as interpreter from './interpreter.js';
import { SmartFile } from './classes.smartfile.js';
import * as memory from './memory.js';
import type { StreamFile } from './classes.streamfile.js';
/*===============================================================
============================ Checks =============================
===============================================================*/
/**
*
* @param filePath
* @returns {boolean}
*/
export const fileExistsSync = (filePath): boolean => {
let fileExistsBool: boolean = false;
try {
plugins.fsExtra.readFileSync(filePath);
fileExistsBool = true;
} catch (err) {
fileExistsBool = false;
}
return fileExistsBool;
};
/**
*
* @param filePath
* @returns {any}
*/
export const fileExists = async (filePath): Promise<boolean> => {
const done = plugins.smartpromise.defer<boolean>();
plugins.fs.access(filePath, 4, (err) => {
err ? done.resolve(false) : done.resolve(true);
});
return done.promise;
};
/**
* Checks if given path points to an existing directory
*/
export const isDirectory = (pathArg: string): boolean => {
try {
return plugins.fsExtra.statSync(pathArg).isDirectory();
} catch (err) {
return false;
}
};
/**
* Checks if given path points to an existing directory
*/
export const isDirectorySync = (pathArg: string): boolean => {
try {
return plugins.fsExtra.statSync(pathArg).isDirectory();
} catch (err) {
return false;
}
};
/**
* Checks if a given path points to an existing file
*/
export const isFile = (pathArg): boolean => {
return plugins.fsExtra.statSync(pathArg).isFile();
};
/*===============================================================
============================ FS ACTIONS =========================
===============================================================*/
/**
* copies a file from A to B on the local disk
*/
export const copy = async (fromArg: string, toArg: string): Promise<boolean> => {
const done = plugins.smartpromise.defer<boolean>();
plugins.fsExtra.copy(fromArg, toArg, {}, (err) => {
if (err) {
throw new Error(`Could not copy from ${fromArg} to ${toArg}: ${err}`);
}
done.resolve(true);
});
return done.promise;
};
/**
* copies a file SYNCHRONOUSLY from A to B on the local disk
*/
export const copySync = (fromArg: string, toArg: string): boolean => {
plugins.fsExtra.copySync(fromArg, toArg);
return true;
};
/**
* ensures that a directory is in place
*/
export const ensureDir = async (dirPathArg: string) => {
await plugins.fsExtra.ensureDir(dirPathArg);
};
/**
* ensures that a directory is in place
*/
export const ensureDirSync = (dirPathArg: string) => {
plugins.fsExtra.ensureDirSync(dirPathArg);
};
/**
* ensure an empty directory
* @executes ASYNC
*/
export const ensureEmptyDir = async (dirPathArg: string) => {
await plugins.fsExtra.ensureDir(dirPathArg);
await plugins.fsExtra.emptyDir(dirPathArg);
};
/**
* ensure an empty directory
* @executes SYNC
*/
export const ensureEmptyDirSync = (dirPathArg: string) => {
plugins.fsExtra.ensureDirSync(dirPathArg);
plugins.fsExtra.emptyDirSync(dirPathArg);
};
/**
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec ASYNC
*/
export const ensureFile = async (filePathArg, initFileStringArg): Promise<void> => {
ensureFileSync(filePathArg, initFileStringArg);
};
/**
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec SYNC
*/
export const ensureFileSync = (filePathArg: string, initFileStringArg: string): void => {
if (fileExistsSync(filePathArg)) {
return null;
} else {
memory.toFsSync(initFileStringArg, filePathArg);
}
};
/**
* removes a file or folder from local disk
*/
export const remove = async (pathArg: string): Promise<void> => {
await plugins.fsExtra.remove(pathArg);
};
/**
* removes a file SYNCHRONOUSLY from local disk
*/
export const removeSync = (pathArg: string): void => {
plugins.fsExtra.removeSync(pathArg);
};
/**
* removes an array of filePaths from disk
*/
export const removeMany = async (filePathArrayArg: string[]) => {
const promiseArray: Array<Promise<void>> = [];
for (const filePath of filePathArrayArg) {
promiseArray.push(remove(filePath));
}
await Promise.all(promiseArray);
};
/**
* like removeFilePathArray but SYNCHRONOUSLY
*/
export const removeManySync = (filePathArrayArg: string[]): void => {
for (const filePath of filePathArrayArg) {
removeSync(filePath);
}
};
/*===============================================================
============================ Write/Read =========================
===============================================================*/
/**
*
* @param filePathArg
* @param fileTypeArg
* @returns {any}
*/
export const toObjectSync = (filePathArg, fileTypeArg?) => {
const fileString = plugins.fsExtra.readFileSync(filePathArg, 'utf8');
let fileType;
fileTypeArg ? (fileType = fileTypeArg) : (fileType = interpreter.filetype(filePathArg));
return interpreter.objectFile(fileString, fileType);
};
/**
* reads a file content to a String
*/
export const toStringSync = (filePath: string): string => {
const encoding = plugins.smartmime.getEncoding(filePath);
let fileString: string | Buffer = plugins.fsExtra.readFileSync(filePath, encoding);
if (Buffer.isBuffer(fileString)) {
fileString = fileString.toString('binary');
}
return fileString;
};
export const toBuffer = async (filePath: string): Promise<Buffer> => {
return plugins.fsExtra.readFile(filePath);
};
export const toBufferSync = (filePath: string): Buffer => {
return plugins.fsExtra.readFileSync(filePath);
};
/**
* Creates a Readable Stream from a file path.
* @param filePath The path to the file.
* @returns {fs.ReadStream}
*/
export const toReadStream = (filePath: string): plugins.fs.ReadStream => {
if (!fileExistsSync(filePath)) {
throw new Error(`File does not exist at path: ${filePath}`);
}
return plugins.fsExtra.createReadStream(filePath);
};
export const fileTreeToHash = async (dirPathArg: string, miniMatchFilter: string) => {
const fileTreeObject = await fileTreeToObject(dirPathArg, miniMatchFilter);
let combinedString = '';
for (const smartfile of fileTreeObject) {
combinedString += await smartfile.getHash();
}
const hash = await plugins.smarthash.sha256FromString(combinedString);
return hash;
};
/**
* creates a smartfile array from a directory
* @param dirPathArg the directory to start from
* @param miniMatchFilter a minimatch filter of what files to include
*/
export const fileTreeToObject = async (dirPathArg: string, miniMatchFilter: string) => {
// handle absolute miniMatchFilter
let dirPath: string;
if (plugins.path.isAbsolute(miniMatchFilter)) {
dirPath = '/';
} else {
dirPath = plugins.smartpath.transform.toAbsolute(dirPathArg) as string;
}
const fileTree = await listFileTree(dirPath, miniMatchFilter);
const smartfileArray: SmartFile[] = [];
for (const filePath of fileTree) {
const readPath = ((): string => {
if (!plugins.path.isAbsolute(filePath)) {
return plugins.path.join(dirPath, filePath);
} else {
return filePath;
}
})();
const fileBuffer = plugins.fs.readFileSync(readPath);
// push a read file as Smartfile
smartfileArray.push(
new SmartFile({
contentBuffer: fileBuffer,
base: dirPath,
path: filePath,
})
);
}
return smartfileArray;
};
/**
* lists Folders in a directory on local disk
* @returns Promise with an array that contains the folder names
*/
export const listFolders = async (pathArg: string, regexFilter?: RegExp): Promise<string[]> => {
return listFoldersSync(pathArg, regexFilter);
};
/**
* lists Folders SYNCHRONOUSLY in a directory on local disk
* @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) => {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isDirectory();
});
if (regexFilter) {
folderArray = folderArray.filter((fileItem) => {
return regexFilter.test(fileItem);
});
}
return folderArray;
};
/**
* lists Files in a directory on local disk
* @returns Promise
*/
export const listFiles = async (pathArg: string, regexFilter?: RegExp): Promise<string[]> => {
return listFilesSync(pathArg, regexFilter);
};
/**
* lists Files SYNCHRONOUSLY in a directory on local disk
* @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) => {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
fileArray = fileArray.filter((fileItem) => {
return regexFilter.test(fileItem);
});
}
return fileArray;
};
/**
* lists all items (folders AND files) in a directory on local disk
* @returns Promise<string[]>
*/
export const listAllItems = async (pathArg: string, regexFilter?: RegExp): Promise<string[]> => {
return listAllItemsSync(pathArg, regexFilter);
};
/**
* lists all items (folders AND files) in a directory on local disk
* @returns an array with the folder names as strings
* @executes SYNC
*/
export const listAllItemsSync = (pathArg: string, regexFilter?: RegExp): string[] => {
let allItmesArray = plugins.fsExtra.readdirSync(pathArg).filter((file) => {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
allItmesArray = allItmesArray.filter((fileItem) => {
return regexFilter.test(fileItem);
});
}
return allItmesArray;
};
/**
* lists a file tree using a miniMatch filter
* note: if the miniMatch Filter is an absolute path, the cwdArg will be omitted
* @returns Promise<string[]> string array with the absolute paths of all matching files
*/
export const listFileTree = async (
dirPathArg: string,
miniMatchFilter: string,
absolutePathsBool: boolean = false
): Promise<string[]> => {
// handle absolute miniMatchFilter
let dirPath: string;
if (plugins.path.isAbsolute(miniMatchFilter)) {
dirPath = '/';
} else {
dirPath = dirPathArg;
}
const options = {
cwd: dirPath,
nodir: true,
dot: true,
};
let fileList = await plugins.glob.glob(miniMatchFilter, options);
if (absolutePathsBool) {
fileList = fileList.map((filePath) => {
return plugins.path.resolve(plugins.path.join(dirPath, filePath));
});
}
return fileList;
};
/**
* Watches for file stability before resolving the promise.
*/
export const waitForFileToBeReady = (filePathArg: string): Promise<void> => {
return new Promise(async (resolve, reject) => {
let lastFileSize = -1;
let fileIsStable = false;
const checkFileStability = async () => {
let currentFileSize: number;
const deferred = plugins.smartpromise.defer();
plugins.fs.stat(filePathArg, (err, stats) => {
if (err) {
fileIsStable = true;
watcher.close();
reject(err);
return;
}
currentFileSize = stats.size;
deferred.resolve();
});
await deferred.promise;
if (currentFileSize === lastFileSize) {
fileIsStable = true;
await plugins.smartdelay.delayFor(100);
resolve();
}
lastFileSize = currentFileSize;
};
const watcher = plugins.fs.watch(filePathArg, (eventType, filename) => {
if (eventType === 'change') {
checkFileStability();
}
});
watcher.on('error', (error) => {
watcher.close();
reject(error);
});
while (!fileIsStable) {
await checkFileStability();
if (!fileIsStable) {
await plugins.smartdelay.delayFor(5000);
}
}
watcher.close();
});
};
/**
* writes string or Smartfile to disk.
* @param fileArg
* @param fileNameArg
* @param fileBaseArg
*/
export let toFs = async (
filePathArg: string,
fileContentArg: string | Buffer | SmartFile | StreamFile,
optionsArg: {
respectRelative?: boolean;
} = {}
) => {
const done = plugins.smartpromise.defer();
// check args
if (!fileContentArg || !filePathArg) {
throw new Error('expected valid arguments');
}
// prepare actual write action
let fileContent: string | Buffer;
let fileEncoding: 'utf8' | 'binary' = 'utf8';
let filePath: string = filePathArg;
// handle Smartfile
if (fileContentArg instanceof SmartFile) {
fileContent = fileContentArg.contentBuffer;
// handle options
if (optionsArg.respectRelative) {
filePath = plugins.path.join(filePath, fileContentArg.path);
}
} else if (Buffer.isBuffer(fileContentArg)) {
fileContent = fileContentArg;
fileEncoding = 'binary';
} else if (typeof fileContentArg === 'string') {
fileContent = fileContentArg;
} else {
throw new Error('fileContent is neither string nor Smartfile');
}
await ensureDir(plugins.path.parse(filePath).dir);
plugins.fsExtra.writeFile(filePath, fileContent, { encoding: fileEncoding }, done.resolve);
return await done.promise;
};

195
ts/fsstream.ts Normal file
View File

@ -0,0 +1,195 @@
/*
This file contains logic for streaming things from and to the filesystem
*/
import * as plugins from './plugins.js';
export const createReadStream = (pathArg: string) => {
return plugins.fs.createReadStream(pathArg);
};
export const createWriteStream = (pathArg: string) => {
return plugins.fs.createWriteStream(pathArg);
};
export const processFile = async (
filePath: string,
asyncFunc: (fileStream: plugins.stream.Readable) => Promise<void>
): Promise<void> => {
return new Promise((resolve, reject) => {
const fileStream = createReadStream(filePath);
asyncFunc(fileStream).then(resolve).catch(reject);
});
}
export const processDirectory = async (
directoryPath: string,
asyncFunc: (fileStream: plugins.stream.Readable) => Promise<void>
): Promise<void> => {
const files = plugins.fs.readdirSync(directoryPath, { withFileTypes: true });
for (const file of files) {
const fullPath = plugins.path.join(directoryPath, file.name);
if (file.isDirectory()) {
await processDirectory(fullPath, asyncFunc); // Recursively call processDirectory for directories
} else if (file.isFile()) {
await processFile(fullPath, asyncFunc); // Call async function with the file stream and wait for it
}
}
};
/**
* Checks if a file is ready to be streamed (exists and is not empty).
*/
export const isFileReadyForStreaming = async (filePathArg: string): Promise<boolean> => {
try {
const stats = await plugins.fs.promises.stat(filePathArg);
return stats.size > 0;
} catch (error) {
if (error.code === 'ENOENT') { // File does not exist
return false;
}
throw error; // Rethrow other unexpected errors
}
};
/**
* Waits for a file to be ready for streaming (exists and is not empty).
*/
export const waitForFileToBeReadyForStreaming = (filePathArg: string): Promise<void> => {
return new Promise((resolve, reject) => {
// Normalize and resolve the file path
const filePath = plugins.path.resolve(filePathArg);
// Function to check file stats
const checkFile = (resolve: () => void, reject: (reason: any) => void) => {
plugins.fs.stat(filePath, (err, stats) => {
if (err) {
if (err.code === 'ENOENT') {
// File not found, wait and try again
return;
}
// Some other error occurred
return reject(err);
}
if (stats.size > 0) {
// File exists and is not empty, resolve the promise
resolve();
}
});
};
// Set up file watcher
const watcher = plugins.fs.watch(filePath, { persistent: false }, (eventType) => {
if (eventType === 'change' || eventType === 'rename') {
checkFile(resolve, reject);
}
});
// Check file immediately in case it's already ready
checkFile(resolve, reject);
// Error handling
watcher.on('error', (error) => {
watcher.close();
reject(error);
});
});
};
export class SmartReadStream extends plugins.stream.Readable {
private watcher: plugins.fs.FSWatcher | null = null;
private lastReadSize: number = 0;
private endTimeout: NodeJS.Timeout | null = null;
private filePath: string;
private endDelay: number;
private reading: boolean = false;
constructor(filePath: string, endDelay = 60000, opts?: plugins.stream.ReadableOptions) {
super(opts);
this.filePath = filePath;
this.endDelay = endDelay;
}
private startWatching(): void {
this.watcher = plugins.fs.watch(this.filePath, (eventType) => {
if (eventType === 'change') {
this.resetEndTimeout();
}
});
this.watcher.on('error', (error) => {
this.cleanup();
this.emit('error', error);
});
}
private resetEndTimeout(): void {
if (this.endTimeout) clearTimeout(this.endTimeout);
this.endTimeout = setTimeout(() => this.checkForEnd(), this.endDelay);
}
private checkForEnd(): void {
plugins.fs.stat(this.filePath, (err, stats) => {
if (err) {
this.emit('error', err);
return;
}
if (this.lastReadSize === stats.size) {
this.push(null); // Signal the end of the stream
this.cleanup();
} else {
this.lastReadSize = stats.size;
this.resetEndTimeout();
if (!this.reading) {
// We only want to continue reading if we were previously waiting for more data
this.reading = true;
this._read(10000); // Try to read more data
}
}
});
}
private cleanup(): void {
if (this.endTimeout) clearTimeout(this.endTimeout);
if (this.watcher) this.watcher.close();
}
_read(size: number): void {
this.reading = true;
const chunkSize = Math.min(size, 16384); // Read in chunks of 16KB
const buffer = Buffer.alloc(chunkSize);
plugins.fs.open(this.filePath, 'r', (err, fd) => {
if (err) {
this.emit('error', err);
return;
}
plugins.fs.read(fd, buffer, 0, chunkSize, this.lastReadSize, (err, bytesRead, buffer) => {
if (err) {
this.emit('error', err);
return;
}
if (bytesRead > 0) {
this.lastReadSize += bytesRead;
this.push(buffer.slice(0, bytesRead)); // Push the data onto the stream
} else {
this.reading = false; // No more data to read for now
this.resetEndTimeout();
}
plugins.fs.close(fd, (err) => {
if (err) {
this.emit('error', err);
}
});
});
});
}
_destroy(error: Error | null, callback: (error: Error | null) => void): void {
this.cleanup();
callback(error);
}
}

View File

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

View File

@ -1,8 +1,8 @@
import plugins = require('./smartfile.plugins');
import * as plugins from './plugins.js';
export let filetype = (pathArg: string): string => {
let extName = plugins.path.extname(pathArg);
let fileType = extName.replace(/\.([a-z]*)/, '$1'); // remove . form fileType
const extName = plugins.path.extname(pathArg);
const fileType = extName.replace(/\.([a-z]*)/, '$1'); // remove . form fileType
return fileType;
};
@ -10,7 +10,7 @@ export let objectFile = (fileStringArg: string, fileTypeArg) => {
switch (fileTypeArg) {
case 'yml':
case 'yaml':
return plugins.yaml.safeLoad(fileStringArg);
return plugins.yaml.load(fileStringArg);
case 'json':
return JSON.parse(fileStringArg);
default:

View File

@ -1,8 +1,8 @@
import plugins = require('./smartfile.plugins');
import { Smartfile } from './smartfile.classes.smartfile';
import * as smartfileFs from './smartfile.fs';
import SmartfileInterpreter = require('./smartfile.interpreter');
import * as plugins from './plugins.js';
import { SmartFile } from './classes.smartfile.js';
import * as smartfileFs from './fs.js';
import * as interpreter from './interpreter.js';
import type { StreamFile } from './classes.streamfile.js';
/**
* converts file to Object
@ -10,8 +10,8 @@ import SmartfileInterpreter = require('./smartfile.interpreter');
* @param fileTypeArg
* @returns {any|any}
*/
export let toObject = function(fileStringArg: string, fileTypeArg: string) {
return SmartfileInterpreter.objectFile(fileStringArg, fileTypeArg);
export let toObject = (fileStringArg: string, fileTypeArg: string) => {
return interpreter.objectFile(fileStringArg, fileTypeArg);
};
export interface IToFsOptions {
@ -25,11 +25,11 @@ export interface IToFsOptions {
* @param fileBaseArg
*/
export let toFs = async (
fileContentArg: string | Smartfile,
filePathArg,
fileContentArg: string | Buffer | SmartFile | StreamFile,
filePathArg: string,
optionsArg: IToFsOptions = {}
) => {
let done = plugins.smartpromise.defer();
const done = plugins.smartpromise.defer();
// check args
if (!fileContentArg || !filePathArg) {
@ -37,24 +37,27 @@ export let toFs = async (
}
// prepare actual write action
let fileString: string;
let fileContent: string | Buffer;
let fileEncoding: 'utf8' | 'binary' = 'utf8';
let filePath: string = filePathArg;
// handle Smartfile
if (fileContentArg instanceof Smartfile) {
let fileContentArg2: any = fileContentArg;
fileString = fileContentArg.contentBuffer.toString();
if (fileContentArg instanceof SmartFile) {
fileContent = fileContentArg.contentBuffer;
// handle options
if (optionsArg.respectRelative) {
filePath = plugins.path.join(filePath, fileContentArg.path);
}
} else if (Buffer.isBuffer(fileContentArg)) {
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: 'utf8' }, done.resolve);
plugins.fsExtra.writeFile(filePath, fileContent, { encoding: fileEncoding }, done.resolve);
return await done.promise;
};
@ -63,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');
@ -71,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.');
@ -81,11 +84,11 @@ export let toFsSync = function(fileArg: string, filePathArg: string) {
plugins.fsExtra.writeFileSync(filePath, fileString, { encoding: 'utf8' });
};
export let smartfileArrayToFs = async (smartfileArrayArg: Smartfile[], dirArg: 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,
});
}
};

38
ts/plugins.ts Normal file
View File

@ -0,0 +1,38 @@
// node native scope
import * as fs from 'fs';
import * as path from 'path';
import * as stream from 'stream';
export { fs, path, stream };
// @pushrocks scope
import * as lik from '@push.rocks/lik';
import * as smartfileInterfaces from '@push.rocks/smartfile-interfaces';
import * as smartdelay from '@push.rocks/smartdelay';
import * as smarthash from '@push.rocks/smarthash';
import * as smartjson from '@push.rocks/smartjson';
import * as smartmime from '@push.rocks/smartmime';
import * as smartpath from '@push.rocks/smartpath';
import * as smartpromise from '@push.rocks/smartpromise';
import * as smartrequest from '@push.rocks/smartrequest';
import * as smartstream from '@push.rocks/smartstream';
export {
lik,
smartfileInterfaces,
smartdelay,
smarthash,
smartjson,
smartmime,
smartpath,
smartpromise,
smartrequest,
smartstream,
};
// third party scope
import fsExtra from 'fs-extra';
import * as glob from 'glob';
import yaml from 'js-yaml';
export { fsExtra, glob, yaml };

View File

@ -1,148 +0,0 @@
import * as plugins from './smartfile.plugins';
import * as fs from './smartfile.fs';
import * as memory from './smartfile.memory';
export interface ISmartfileConstructorOptions {
path?: string;
contentString?: string;
contentBuffer?: Buffer;
base?: string;
}
/**
* class Smartfile
* -> is vinyl file compatible
*/
export class Smartfile {
/**
* the full path of the file on disk
*/
path: string;
/**
*
*/
parsedPath: plugins.path.ParsedPath;
/**
* the content of the file as Buffer
*/
contentBuffer: Buffer;
/**
* The current working directory of the file
* Note:this is similar to gulp and different from native node path base
*/
base: string;
/**
* sync the file with disk
*/
sync: boolean;
/**
* the constructor of Smartfile
* @param optionsArg
*/
constructor(optionsArg: ISmartfileConstructorOptions) {
if (optionsArg.contentBuffer) {
this.contentBuffer = optionsArg.contentBuffer;
} else if (optionsArg.contentString) {
this.setContentsFromString(optionsArg.contentString);
} else {
console.log('created empty Smartfile?');
}
this.path = optionsArg.path;
this.parsedPath = plugins.path.parse(this.path);
this.base = optionsArg.base;
}
/**
* set contents from string
* @param contentString
*/
setContentsFromString(contentString: string) {
this.contents = new Buffer(contentString);
}
/**
* write file to disk
* Behaviours:
* - no argument write to exactly where the file was picked up
*/
async write(pathArg?: string) {
const stringToWrite = this.contentBuffer.toString();
await memory.toFs(stringToWrite, this.path);
}
/**
* read file from disk
*/
async read() {}
// -----------------------------------------------
// vinyl compatibility
// -----------------------------------------------
/**
* vinyl-compatibility: alias of this.contentBuffer
*/
get contents(): Buffer {
return this.contentBuffer;
}
set contents(contentsArg) {
this.contentBuffer = contentsArg;
}
/**
* vinyl-compatibility
*/
get cwd() {
return process.cwd();
}
/**
* return relative path of file
*/
get relative(): string {
return plugins.path.relative(this.base, this.path);
}
/**
* return truw when the file has content
*/
isNull(): boolean {
if (!this.contentBuffer) {
return true;
}
return false;
}
/**
* return true if contents are Buffer
*/
isBuffer(): boolean {
if (this.contents instanceof Buffer) {
return true;
}
return false;
}
isDirectory() {
return false;
}
isStream() {
return false;
}
isSymbolic() {
return false;
}
// update things
updateFileName(fileNameArg: string) {
let oldFileName = this.parsedPath.base;
this.path = this.path.replace(new RegExp(oldFileName + '$'), fileNameArg);
}
}

View File

@ -1,386 +0,0 @@
import plugins = require('./smartfile.plugins');
import SmartfileInterpreter = require('./smartfile.interpreter');
import { Smartfile } from './smartfile.classes.smartfile';
import * as memory from './smartfile.memory';
/*===============================================================
============================ Checks =============================
===============================================================*/
/**
*
* @param filePath
* @returns {boolean}
*/
export let fileExistsSync = function(filePath): boolean {
let fileExistsBool: boolean = false;
try {
plugins.fsExtra.readFileSync(filePath);
fileExistsBool = true;
} catch (err) {
fileExistsBool = false;
}
return fileExistsBool;
};
/**
*
* @param filePath
* @returns {any}
*/
export let fileExists = function(filePath) {
let done = plugins.smartpromise.defer();
plugins.fs.access(filePath, 4, function(err) {
err ? done.reject(err) : done.resolve();
});
return done.promise;
};
/**
* Checks if given path points to an existing directory
*/
export let isDirectory = function(pathArg): boolean {
try {
return plugins.fsExtra.statSync(pathArg).isDirectory();
} catch (err) {
return false;
}
};
/**
* Checks if a given path points to an existing file
*/
export let isFile = function(pathArg): boolean {
return plugins.fsExtra.statSync(pathArg).isFile();
};
/*===============================================================
============================ FS ACTIONS =========================
===============================================================*/
/**
* copies a file from A to B on the local disk
*/
export let copy = function(fromArg: string, toArg: string) {
let done = plugins.smartpromise.defer();
plugins.fsExtra.copy(fromArg, toArg, {}, function() {
done.resolve();
});
return done.promise;
};
/**
* copies a file SYNCHRONOUSLY from A to B on the local disk
*/
export let copySync = function(fromArg: string, toArg: string): boolean {
plugins.fsExtra.copySync(fromArg, toArg);
return true;
};
/**
* ensures that a directory is in place
*/
export let ensureDir = (dirPathArg: string) => {
let done = plugins.smartpromise.defer();
plugins.fsExtra.ensureDir(dirPathArg, done.resolve);
return done.promise;
};
/**
* ensures that a directory is in place
*/
export let ensureDirSync = (dirPathArg: string) => {
plugins.fsExtra.ensureDirSync(dirPathArg);
};
/**
* ensure an empty directory
* @executes ASYNC
*/
export let ensureEmptyDir = (dirPathArg: string) => {
let done = plugins.smartpromise.defer();
plugins.fsExtra.ensureDir(dirPathArg, () => {
plugins.fsExtra.emptyDir(dirPathArg, done.resolve);
});
return done.promise;
};
/**
* ensure an empty directory
* @executes SYNC
*/
export let ensureEmptyDirSync = (dirPathArg: string) => {
plugins.fsExtra.ensureDirSync(dirPathArg);
plugins.fsExtra.emptyDirSync(dirPathArg);
};
/**
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec ASYNC
*/
export let ensureFile = (filePathArg, initFileStringArg): Promise<void> => {
let done = plugins.smartpromise.defer<void>();
ensureFileSync(filePathArg, initFileStringArg);
done.resolve();
return done.promise;
};
/**
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec SYNC
*/
export let ensureFileSync = (filePathArg: string, initFileStringArg: string): void => {
if (fileExistsSync(filePathArg)) {
return null;
} else {
memory.toFsSync(initFileStringArg, filePathArg);
}
};
/**
* removes a file or folder from local disk
*/
export let remove = function(pathArg: string): Promise<void> {
let done = plugins.smartpromise.defer<void>();
plugins.fsExtra.remove(pathArg, function() {
done.resolve();
});
return done.promise;
};
/**
* removes a file SYNCHRONOUSLY from local disk
*/
export let removeSync = function(pathArg: string): boolean {
plugins.fsExtra.removeSync(pathArg);
return true;
};
/**
* removes an array of filePaths from disk
*/
export let removeMany = function(filePathArrayArg: string[]) {
let promiseArray: Promise<void>[] = [];
for (let filePath of filePathArrayArg) {
promiseArray.push(remove(filePath));
}
return Promise.all(promiseArray);
};
/**
* like removeFilePathArray but SYNCHRONOUSLY
*/
export let removeManySync = function(filePathArrayArg: string[]): void {
for (let filePath of filePathArrayArg) {
removeSync(filePath);
}
};
/*===============================================================
============================ Write/Read =========================
===============================================================*/
/**
*
* @param filePathArg
* @param fileTypeArg
* @returns {any}
*/
export let toObjectSync = function(filePathArg, fileTypeArg?) {
let fileString = plugins.fsExtra.readFileSync(filePathArg, 'utf8');
let fileType;
fileTypeArg ? (fileType = fileTypeArg) : (fileType = SmartfileInterpreter.filetype(filePathArg));
return SmartfileInterpreter.objectFile(fileString, fileType);
};
/**
* reads a file content to a String
* @param filePath
* @returns {string|Buffer|any}
*/
export let toStringSync = function(filePath: string): string {
let fileString: any = plugins.fsExtra.readFileSync(filePath, 'utf8');
return fileString;
};
export let fileTreeToObject = async (dirPathArg: string, miniMatchFilter: string) => {
// handle absolute miniMatchFilter
let dirPath: string;
if (plugins.path.isAbsolute(miniMatchFilter)) {
dirPath = '/';
} else {
dirPath = dirPathArg;
}
let fileTree = await listFileTree(dirPath, miniMatchFilter);
let smartfileArray: Smartfile[] = [];
for (let filePath of fileTree) {
let readPath = ((): string => {
if (!plugins.path.isAbsolute(filePath)) {
return plugins.path.join(dirPath, filePath);
} else {
return filePath;
}
})();
let fileContentString = toStringSync(readPath);
// push a read file as Smartfile
smartfileArray.push(
new Smartfile({
contentBuffer: new Buffer(fileContentString),
base: dirPath,
path: filePath
})
);
}
return smartfileArray;
};
/**
*
* @param filePathArg
* @param options
* @returns {number}
*/
export let toVinylSync = function(filePathArg, options = {}) {
return plugins.vinylFile.readSync(filePathArg, options);
};
/**
* lists Folders in a directory on local disk
* @returns Promise
*/
export let listFolders = function(pathArg: string, regexFilter?: RegExp) {
let done = plugins.smartpromise.defer();
let folderArray = plugins.fsExtra.readdirSync(pathArg).filter(function(file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isDirectory();
});
if (regexFilter) {
folderArray = folderArray.filter(fileItem => {
return regexFilter.test(fileItem);
});
}
done.resolve(folderArray);
return done.promise;
};
/**
* lists Folders SYNCHRONOUSLY in a directory on local disk
* @returns an array with the folder names as strings
*/
export let listFoldersSync = function(pathArg: string, regexFilter?: RegExp): string[] {
let folderArray = plugins.fsExtra.readdirSync(pathArg).filter(function(file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isDirectory();
});
if (regexFilter) {
folderArray = folderArray.filter(fileItem => {
return regexFilter.test(fileItem);
});
}
return folderArray;
};
/**
* lists Files in a directory on local disk
* @returns Promise
*/
export let listFiles = function(pathArg: string, regexFilter?: RegExp) {
let done = plugins.smartpromise.defer();
let fileArray = plugins.fsExtra.readdirSync(pathArg).filter(function(file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
fileArray = fileArray.filter(fileItem => {
return regexFilter.test(fileItem);
});
}
done.resolve(fileArray);
return done.promise;
};
/**
* lists Files SYNCHRONOUSLY in a directory on local disk
* @returns an array with the folder names as strings
*/
export let listFilesSync = function(pathArg: string, regexFilter?: RegExp): string[] {
let fileArray = plugins.fsExtra.readdirSync(pathArg).filter(function(file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
fileArray = fileArray.filter(fileItem => {
return regexFilter.test(fileItem);
});
}
return fileArray;
};
/**
* lists all items (folders AND files) in a directory on local disk
* @returns Promise<string[]>
*/
export let listAllItems = function(pathArg: string, regexFilter?: RegExp): Promise<string[]> {
let done = plugins.smartpromise.defer<string[]>();
let allItmesArray = plugins.fsExtra.readdirSync(pathArg);
if (regexFilter) {
allItmesArray = allItmesArray.filter(fileItem => {
return regexFilter.test(fileItem);
});
}
done.resolve(allItmesArray);
return done.promise;
};
/**
* lists all items (folders AND files) in a directory on local disk
* @returns an array with the folder names as strings
* @executes SYNC
*/
export let listAllItemsSync = function(pathArg: string, regexFilter?: RegExp): string[] {
let allItmesArray = plugins.fsExtra.readdirSync(pathArg).filter(function(file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
allItmesArray = allItmesArray.filter(fileItem => {
return regexFilter.test(fileItem);
});
}
return allItmesArray;
};
/**
* lists a file tree using a miniMatch filter
* note: if the miniMatch Filter is an absolute path, the cwdArg will be omitted
* @returns Promise<string[]> string array with the absolute paths of all matching files
*/
export let listFileTree = (dirPathArg: string, miniMatchFilter: string): Promise<string[]> => {
let done = plugins.smartpromise.defer<string[]>();
// handle absolute miniMatchFilter
let dirPath: string;
if (plugins.path.isAbsolute(miniMatchFilter)) {
dirPath = '/';
} else {
dirPath = dirPathArg;
}
let options = {
cwd: dirPath,
nodir: true,
dot: true
};
plugins.glob(miniMatchFilter, options, (err, files: string[]) => {
if (err) {
console.log(err);
done.reject(err);
}
done.resolve(files);
});
return done.promise;
};

View File

@ -1,9 +0,0 @@
export import fs = require('fs');
export import fsExtra = require('fs-extra');
export let glob = require('glob');
export import path = require('path');
export import smartpromise = require('@pushrocks/smartpromise');
export import smartrequest = require('@pushrocks/smartrequest');
export import smartpath = require('smartpath');
export let vinylFile = require('vinyl-file');
export let yaml = require('js-yaml');

View File

@ -1,50 +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 = function(fromArg: string) {
let 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) => {
let done = plugins.smartpromise.defer();
plugins.smartrequest.getBinary(fromArg).then((res: any) => {
if (res.statusCode === 200) {
done.resolve(res.body);
} else {
done.reject(new Error('could not get remote file from ' + fromArg));
}
});
return done.promise;
};

14
tsconfig.json Normal file
View File

@ -0,0 +1,14 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true
},
"exclude": [
"dist_*/**/*.d.ts"
]
}

View File

@ -1,3 +0,0 @@
{
"extends": "tslint-config-standard"
}