Compare commits
335 Commits
Author | SHA1 | Date | |
---|---|---|---|
5a9e1b5798 | |||
b1ec86ee2d | |||
a1353170f6 | |||
3ff6de201d | |||
f5c106b2ca | |||
d3c26d0d46 | |||
9935fe2d3c | |||
3b05aab39b | |||
53be2eb59d | |||
c92a0dddbd | |||
27403a73b5 | |||
b925e5e662 | |||
98a5d2c94d | |||
0e735cba20 | |||
f815457801 | |||
f7e47ae354 | |||
684e893801 | |||
d4b381d33d | |||
291a11aa60 | |||
ca592afec9 | |||
8b07197224 | |||
b60fd15ec6 | |||
853eccc780 | |||
c26aff85b5 | |||
321e4d9dea | |||
3d2789857c | |||
07b88a078d | |||
6fee0028d8 | |||
629c52f9bc | |||
fd056c29e9 | |||
36c456b509 | |||
16f8c25557 | |||
219e070ba2 | |||
ee97e1d88b | |||
279db74568 | |||
b84c504f11 | |||
7b3194cc13 | |||
e1e821efec | |||
6b613d1b8a | |||
70f1c58a82 | |||
5df76ca94b | |||
32cfda3c90 | |||
dd521398ea | |||
038e6cc33d | |||
2fc37d6892 | |||
3c1eb1ab70 | |||
5296e8859b | |||
160e0ae451 | |||
373c6538ae | |||
7a1476e106 | |||
b2a2035f00 | |||
03e4f03035 | |||
d74bbb2b12 | |||
22cfe1f5cb | |||
5fc2c4586d | |||
6ab81fb323 | |||
58ec27a1a0 | |||
88811646b7 | |||
412bb52eee | |||
b04750ecbd | |||
0c99475888 | |||
86317def88 | |||
0a5af0ba96 | |||
cf73ff4a54 | |||
788897e765 | |||
7fa3894f6e | |||
afdd654664 | |||
8277e0ca6d | |||
0892c87a68 | |||
841ba2e14d | |||
5b2953bf02 | |||
d3457fd65b | |||
3bf1eafe6b | |||
04a9b992d7 | |||
6206b55deb | |||
6c05bf6ae3 | |||
371074afc1 | |||
e0e665fe6d | |||
5483202972 | |||
24b3458888 | |||
cffa47ac3d | |||
9dadf3f78f | |||
b35a671fe9 | |||
0ca38c109e | |||
4e2321e1ee | |||
a640ab3d7b | |||
37d6d56287 | |||
443a026502 | |||
9644c5b7e3 | |||
25faa8c697 | |||
982387aaa3 | |||
4a11f50efe | |||
0ddec29392 | |||
df484d54e8 | |||
f637c20241 | |||
ed0c1a9181 | |||
0e22999f69 | |||
38f001ab23 | |||
d1429c5a41 | |||
403a0f4fae | |||
91ade8a4d4 | |||
1a571bba90 | |||
bcb66b2ccf | |||
0000984e4b | |||
b391e54083 | |||
b32c06aef2 | |||
27f60f6719 | |||
b2482ab8a5 | |||
9c614bd2f3 | |||
b12de7aed4 | |||
d6eb54d21c | |||
6646f173c6 | |||
f20657ff71 | |||
7f3f2da702 | |||
1e60ab375b | |||
98fa607c43 | |||
12b1672e58 | |||
9fca2c3aa4 | |||
5b7d822cfc | |||
ce57478e39 | |||
292c2699ea | |||
afb7fa8e89 | |||
e2c3005a08 | |||
53e595a023 | |||
93702dca78 | |||
0a95ae6284 | |||
de09f85c34 | |||
b9fefc7c95 | |||
76eae15f7d | |||
2e457f6011 | |||
e83c63fd2a | |||
c01006e365 | |||
a7adec8275 | |||
2eddbf5751 | |||
eca3e141d2 | |||
701b77eff5 | |||
e3c46cdd2c | |||
7204607c8a | |||
039c6f7fc6 | |||
b42595fccc | |||
2d9a65d11c | |||
b3ce66167e | |||
c7f800fc88 | |||
d8f4b011b7 | |||
b4add67f37 | |||
f86f053bd5 | |||
a78ca67b43 | |||
b1bedd0f54 | |||
ec58f7ac55 | |||
80743576ad | |||
32a6db645d | |||
45dfa16ab7 | |||
4fc4cda786 | |||
f889664e4d | |||
f4129c04b2 | |||
c6280eb6fc | |||
4095738c6a | |||
6170b37d29 | |||
4c23992681 | |||
77c88f09cd | |||
469a454fa6 | |||
15044149f2 | |||
c92b759432 | |||
9b8f055ec2 | |||
69433b242b | |||
db1d2acb47 | |||
920552ea23 | |||
dd05708f28 | |||
d97abe443d | |||
818767b7cc | |||
52367f5c1a | |||
b6b2101054 | |||
e322a41c45 | |||
f5e2c0c7d7 | |||
6733a156b8 | |||
ebac45a152 | |||
92ac410b96 | |||
078bdda803 | |||
7b87adf3d9 | |||
908db4d847 | |||
87d047af42 | |||
610a70079d | |||
2c24cdc9f4 | |||
459bd662f4 | |||
0613b7c3ed | |||
d78ee87a82 | |||
fadf8782df | |||
8fcdc5ce44 | |||
878da9ff3a | |||
168136bebb | |||
16cecbefac | |||
24b890956e | |||
fe73e8edf7 | |||
5b2089044d | |||
9fa98c3804 | |||
f49c5af339 | |||
61a6cfd452 | |||
769a1a707e | |||
0408cff3fc | |||
533d71a6cd | |||
b3fd13506c | |||
4052337626 | |||
d823229bee | |||
5bdc6e1dc9 | |||
625f540978 | |||
459d2531b4 | |||
b5993560b1 | |||
b800957f19 | |||
d79e1180d8 | |||
ac99ecf743 | |||
897a46e12d | |||
64219f8f09 | |||
42c6c1eec5 | |||
ef3ca28a66 | |||
3beff3320c | |||
0343287775 | |||
e4180022b1 | |||
7909bd1a38 | |||
495c3afdc3 | |||
73ad2d6193 | |||
f5ffb7fc67 | |||
36364bb490 | |||
52f8fd2469 | |||
65dda3bcf1 | |||
d29dcc5a1c | |||
d22e0cde8f | |||
c8a21e8228 | |||
72bb3f33ac | |||
7694cc9c08 | |||
679c870229 | |||
30bc489822 | |||
5493d3cd5d | |||
bd50c122eb | |||
51f9d76a64 | |||
c2f809f9cf | |||
9f311984ac | |||
7515ecf9ce | |||
fb9766e93b | |||
9cfd147fdc | |||
18ff99aef7 | |||
46b1151201 | |||
8e19586e47 | |||
9fc581b866 | |||
dcc85a56b8 | |||
4899d454eb | |||
9d02fccc01 | |||
a5b24a7c33 | |||
06fb0acd52 | |||
97bf5ff74b | |||
531f169c11 | |||
e25675cc49 | |||
32cdac5b38 | |||
7457093476 | |||
f560b6b7bb | |||
ed01ebeee8 | |||
7eed9dd6d3 | |||
d9852e18a5 | |||
0be281746d | |||
6ac60cb3a5 | |||
eb3c720d4e | |||
c29084f000 | |||
b53240a2ea | |||
2ba39cf2ac | |||
675934d049 | |||
dda4c1af07 | |||
214bae9931 | |||
fde809eb02 | |||
9f3a71f0b9 | |||
e9c9e95118 | |||
943a0c30c2 | |||
2dad3707ee | |||
cd35d110a9 | |||
257939462b | |||
8104188b90 | |||
02842f1d0f | |||
f753c2c491 | |||
4ecb817bac | |||
909fcd6e2a | |||
d1538f939d | |||
3fef2a4ab9 | |||
77603ee736 | |||
353058ed73 | |||
bf618512e2 | |||
b276c5639d | |||
779c62dcbb | |||
3e1101c5e1 | |||
395504127c | |||
6dee92a3df | |||
0ba3c1794e | |||
0a810a3ac1 | |||
fc23f221eb | |||
cfcd1f7aaf | |||
2cb8c5117a | |||
2c52dec8ea | |||
1fdd492eff | |||
38354d2944 | |||
760913bad3 | |||
f7b8fe5498 | |||
37fbf9a409 | |||
49aba4c85f | |||
37d81fa4c6 | |||
0256166c2f | |||
bef2bd6b3a | |||
759e1655da | |||
d732d1ba97 | |||
eeab2cf0cd | |||
ab76cae75e | |||
f39daca6aa | |||
e70db71ec4 | |||
50ef41d5d4 | |||
2a417ba18f | |||
3516189940 | |||
10e3628a89 | |||
86eafe4568 | |||
fddde78b92 | |||
2a365b04a6 | |||
df1d82cb7c | |||
d20742f881 | |||
db2a0c2992 | |||
7d806f313b | |||
ff2e34696a | |||
23188dfe3f | |||
38f10e0d04 | |||
2e2b8351f8 | |||
8c386ee91c | |||
9828689f31 | |||
8205da5284 | |||
2fc132ab20 | |||
e948d08f2e | |||
4362e94a88 | |||
fea9675b2a | |||
4522907af3 | |||
163eb5a70c | |||
fa5371a6bd | |||
5ff7f8c3ac |
66
.gitea/workflows/default_nottags.yaml
Normal file
66
.gitea/workflows/default_nottags.yaml
Normal 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
|
124
.gitea/workflows/default_tags.yaml
Normal file
124
.gitea/workflows/default_tags.yaml
Normal 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
|
24
.gitignore
vendored
24
.gitignore
vendored
@ -1,12 +1,20 @@
|
|||||||
node_modules/
|
.nogit/
|
||||||
.settings/
|
|
||||||
.idea/
|
# artifacts
|
||||||
coverage/
|
coverage/
|
||||||
docs/
|
public/
|
||||||
|
pages/
|
||||||
|
|
||||||
ts/*.js
|
# installs
|
||||||
ts/*.js.map
|
node_modules/
|
||||||
ts/typings/
|
|
||||||
|
|
||||||
test/temp/
|
# caches
|
||||||
|
.yarn/
|
||||||
|
.cache/
|
||||||
|
.rpt2_cache
|
||||||
|
|
||||||
|
# builds
|
||||||
|
dist/
|
||||||
|
dist_*/
|
||||||
|
|
||||||
|
# custom
|
@ -1,36 +0,0 @@
|
|||||||
image: hosttoday/ht-docker-node:npmts
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- test
|
|
||||||
- release
|
|
||||||
|
|
||||||
testLEGACY:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci test legacy
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
testLTS:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci test lts
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
testSTABLE:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci test stable
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
release:
|
|
||||||
stage: release
|
|
||||||
script:
|
|
||||||
- npmci publish
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
15
.travis.yml
15
.travis.yml
@ -1,15 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- 4
|
|
||||||
- stable
|
|
||||||
deploy:
|
|
||||||
provider: npm
|
|
||||||
email: npm@lossless.digital
|
|
||||||
api_key:
|
|
||||||
secure: wIOQHE7Jbck2j5lcv1Rc8T9/1wbHNGLxqJ6pttNZ+hG1+w77TYnjNYuGtM2xQCXitXSFDoogU8MpiYieOQHYypFgJ6Ns8MTeKIzNJSnlOWdCSN/lVptscT8pyC6qD4IBAyi8m5F2HoGQR+IzcdDBPjXLaPbH7jn8hc9rNY+LNktmYOXfOr37P40pxYrf16GLwrkjQIK8pbkdIbNA0D0k3apTGqw+HsneN2D/O/zAYaB3ojm40ttgPAGYF5PO5t6uqIbPFgIPkMWsO1HbV6I+vOAuIf0KYUqnR/YZd5yFcxFt3c+bfyc8/LP4vy5FyKMLXHe4IXIjXPYetOSiVHgMMYaxawU51OqwIKO+87FJ1TdaVmacMFO0wagl2QS0ceQBn8KBUhljHu/fDInK82uy15Iddk44EhnTx1MIxxgH5WMM6aQB2vuqnViPghs4nA0Y/Dz2U69267fhvmZvEWWUndz058EksHdZsIt5WCqQErI/dWLXMGom94CuZv6nkoVHCw8CO5dqVvfqUFL7Qyw59kRbiUPItFVoiV8ptLUX9tnQ5xBukNRkFX34ViM9YvBRlGt5e//f+cWjUpXFvbrwkqusXArplpxIaUSsQKh7XaMB5DcZ5jDDdjKzIMDf6QWsMTU1rjfQS5ZS3eV5LPy0UlfpDGK28oK2/o8fM+yydVk=
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
repo: pushrocks/smartfile
|
|
||||||
notifications:
|
|
||||||
slack:
|
|
||||||
secure: f5Uss0z9RPl/QcA/DroB8loyE93aOYI6bqCkrsiUscmZtlv/TVQtT4dxqGA6uvcG6iTQDBi3Ul88dQxWkRm4IqbhY35/iMaV2dHW4FVYMAh8GQMbsfL2sALCcufxD9blw47awv3iFcwhV1EeyesscjgL0JIjduk96v/7G/6QIO2838M1lzlgtj+kRUkim8qkaEs1je3gRrhMUIjLuAdscMXyUKYFMjWo9ACSjVUl30R/ZNemb18itIja6i92GotreBgcfEMczvy58ovDC7xdJUsY8LjMI01DwY+WPRnI0tAhsuI8moBwwcdM4e3bAjKjucQRjO33O5bMWRZ6QCiYd0DnCEFyCPQLJ4GSy/tkD00n8ijLHAOSV3AH1zNbdK1EAdSPQXDvlI36KJn/2hyQLoitGHVUPr76ujJWP82ypO2tgIp3XQU0dJVCxDuHnwJO2+hjdI+gCPqxNTpjeujHx3UdkTGNRjuuf9dlZ/D08fApjYxy2fxItTqo3QjP/nrqvBXUOPP8yPHpjIT4H2t5Pr4SJjBGI6X4qhKyFj6s9rA/Xu1rL+45zu1C3uC3z+u3T9UwrbzJ/cZM6r6UQvQmUvIfBNaMlg4I/diQCDIPL+Rhop2nylY3IcHmJnk2itn7kOqj1tohCpFEml5pRuSZy4udWywkdtyBAsHWFLF7oiQ=
|
|
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal 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
26
.vscode/settings.json
vendored
Normal 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"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
14
README.md
14
README.md
@ -1,14 +0,0 @@
|
|||||||
# smartfile
|
|
||||||
make files easily accessible for processing in javascript.
|
|
||||||
|
|
||||||
## Status
|
|
||||||
[](https://travis-ci.org/pushrocks/smartfile)
|
|
||||||
[](https://ci.appveyor.com/project/philkunz/smartfile/branch/master)
|
|
||||||
[](https://david-dm.org/pushrocks/smartfile)
|
|
||||||
[](https://www.bithound.io/github/pushrocks/smartfile/master/dependencies/npm)
|
|
||||||
[](https://www.bithound.io/github/pushrocks/smartfile)
|
|
||||||
[](https://codecov.io/github/pushrocks/smartfile?branch=master)
|
|
||||||
|
|
||||||
## Supported file types:
|
|
||||||
* .yml .yaml
|
|
||||||
* .json
|
|
10
appveyor.yml
10
appveyor.yml
@ -1,10 +0,0 @@
|
|||||||
environment:
|
|
||||||
nodejs_version: "4"
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node $env:nodejs_version
|
|
||||||
- npm install
|
|
||||||
test_script:
|
|
||||||
- node --version
|
|
||||||
- npm --version
|
|
||||||
- npm test
|
|
||||||
build: off
|
|
11
dist/index.d.ts
vendored
11
dist/index.d.ts
vendored
@ -1,11 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
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;
|
|
15
dist/index.js
vendored
15
dist/index.js
vendored
@ -1,15 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
require("typings-global");
|
|
||||||
var SmartfileFs = require("./smartfile.fs");
|
|
||||||
var SmartfileInterpreter = require("./smartfile.interpreter");
|
|
||||||
var SmartfileMemory = require("./smartfile.memory");
|
|
||||||
var 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;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFHeEIsSUFBWSxXQUFXLFdBQU0sZ0JBQWdCLENBQUMsQ0FBQTtBQUM5QyxJQUFZLG9CQUFvQixXQUFNLHlCQUN0QyxDQUFDLENBRDhEO0FBQy9ELElBQVksZUFBZSxXQUFNLG9CQUFvQixDQUFDLENBQUE7QUFDdEQsSUFBWSxlQUFlLFdBQU0sb0JBQW9CLENBQUMsQ0FBQTtBQUV0RCw0Q0FBd0IsK0JBQStCLENBQUM7QUFBaEQsNERBQWdEO0FBRTdDLFVBQUUsR0FBRyxXQUFXLENBQUM7QUFDakIsbUJBQVcsR0FBRyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFNLEdBQUcsZUFBZSxDQUFDO0FBQ3pCLGNBQU0sR0FBRyxlQUFlLENBQUM7QUFDekIscUJBQWEsR0FBRyxXQUFXLENBQUMsYUFBYSxDQUFDIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIjtcblxuaW1wb3J0ICogYXMgcGx1Z2lucyBmcm9tIFwiLi9zbWFydGZpbGUucGx1Z2luc1wiO1xuaW1wb3J0ICogYXMgU21hcnRmaWxlRnMgZnJvbSBcIi4vc21hcnRmaWxlLmZzXCI7XG5pbXBvcnQgKiBhcyBTbWFydGZpbGVJbnRlcnByZXRlciBmcm9tIFwiLi9zbWFydGZpbGUuaW50ZXJwcmV0ZXJcIiBcbmltcG9ydCAqIGFzIFNtYXJ0ZmlsZU1lbW9yeSBmcm9tIFwiLi9zbWFydGZpbGUubWVtb3J5XCI7XG5pbXBvcnQgKiBhcyBTbWFydGZpbGVSZW1vdGUgZnJvbSBcIi4vc21hcnRmaWxlLnJlbW90ZVwiO1xuXG5leHBvcnQge1NtYXJ0ZmlsZX0gZnJvbSBcIi4vc21hcnRmaWxlLmNsYXNzZXMuc21hcnRmaWxlXCI7XG5cbmV4cG9ydCBsZXQgZnMgPSBTbWFydGZpbGVGcztcbmV4cG9ydCBsZXQgaW50ZXJwcmV0ZXIgPSBTbWFydGZpbGVJbnRlcnByZXRlcjtcbmV4cG9ydCBsZXQgbWVtb3J5ID0gU21hcnRmaWxlTWVtb3J5O1xuZXhwb3J0IGxldCByZW1vdGUgPSBTbWFydGZpbGVSZW1vdGU7XG5leHBvcnQgbGV0IHJlcXVpcmVSZWxvYWQgPSBTbWFydGZpbGVGcy5yZXF1aXJlUmVsb2FkO1xuIl19
|
|
3
dist/smartfile.classes.smartfile.d.ts
vendored
3
dist/smartfile.classes.smartfile.d.ts
vendored
@ -1,3 +0,0 @@
|
|||||||
export declare class Smartfile {
|
|
||||||
constructor();
|
|
||||||
}
|
|
10
dist/smartfile.classes.smartfile.js
vendored
10
dist/smartfile.classes.smartfile.js
vendored
@ -1,10 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var Smartfile = (function () {
|
|
||||||
function Smartfile() {
|
|
||||||
}
|
|
||||||
;
|
|
||||||
return Smartfile;
|
|
||||||
}());
|
|
||||||
exports.Smartfile = Smartfile;
|
|
||||||
|
|
||||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0ZmlsZS5jbGFzc2VzLnNtYXJ0ZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7SUFDSTtJQUVBLENBQUM7O0lBQ0wsZ0JBQUM7QUFBRCxDQUpBLEFBSUMsSUFBQTtBQUpZLGlCQUFTLFlBSXJCLENBQUEiLCJmaWxlIjoic21hcnRmaWxlLmNsYXNzZXMuc21hcnRmaWxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIFNtYXJ0ZmlsZSB7XG4gICAgY29uc3RydWN0b3IoKXtcbiAgICAgICAgXG4gICAgfTtcbn0iXX0=
|
|
76
dist/smartfile.fs.d.ts
vendored
76
dist/smartfile.fs.d.ts
vendored
@ -1,76 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
/**
|
|
||||||
* copies a file from A to B on the local disk
|
|
||||||
*/
|
|
||||||
export declare let copy: (fromArg: string, toArg: string) => any;
|
|
||||||
/**
|
|
||||||
* copies a file SYNCHRONOUSLY from A to B on the local disk
|
|
||||||
*/
|
|
||||||
export declare let copySync: (fromArg: string, toArg: string) => boolean;
|
|
||||||
/**
|
|
||||||
* removes a file or folder from local disk
|
|
||||||
*/
|
|
||||||
export declare let remove: (pathArg: string) => any;
|
|
||||||
/**
|
|
||||||
* removes a file SYNCHRONOUSLY from local disk
|
|
||||||
*/
|
|
||||||
export declare let removeSync: (pathArg: string) => boolean;
|
|
||||||
export declare let toFS: (options: {
|
|
||||||
from: string;
|
|
||||||
toPath: string;
|
|
||||||
}, cb?: any) => void;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathArg
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
export declare let toGulpStreamSync: (filePathArg: string) => any;
|
|
||||||
export declare let toGulpDestSync: (folderPathArg: string) => any;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @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: any) => any;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
export declare let listFolders: (pathArg: string) => any;
|
|
||||||
/**
|
|
||||||
* lists Folders SYNCHRONOUSLY in a directory on local disk
|
|
||||||
*/
|
|
||||||
export declare let listFoldersSync: (pathArg: any) => any;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
export declare let fileExistsSync: (filePath: any) => boolean;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export declare let fileExists: (filePath: any) => any;
|
|
||||||
export declare let isDirectory: (pathArg: any) => boolean;
|
|
||||||
export declare let isFile: (pathArg: any) => boolean;
|
|
154
dist/smartfile.fs.js
vendored
154
dist/smartfile.fs.js
vendored
File diff suppressed because one or more lines are too long
3
dist/smartfile.interpreter.d.ts
vendored
3
dist/smartfile.interpreter.d.ts
vendored
@ -1,3 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
export declare let filetype: (pathArg: string) => string;
|
|
||||||
export declare let objectFile: (fileStringArg: string, fileTypeArg: any) => any;
|
|
22
dist/smartfile.interpreter.js
vendored
22
dist/smartfile.interpreter.js
vendored
@ -1,22 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
require("typings-global");
|
|
||||||
var plugins = require("./smartfile.plugins");
|
|
||||||
exports.filetype = function (pathArg) {
|
|
||||||
var extName = plugins.path.extname(pathArg);
|
|
||||||
var fileType = extName.replace(/\.([a-z]*)/, "$1"); //remove . form fileType
|
|
||||||
return fileType;
|
|
||||||
};
|
|
||||||
exports.objectFile = function (fileStringArg, fileTypeArg) {
|
|
||||||
switch (fileTypeArg) {
|
|
||||||
case "yml":
|
|
||||||
case "yaml":
|
|
||||||
return plugins.yaml.safeLoad(fileStringArg);
|
|
||||||
case "json":
|
|
||||||
return JSON.parse(fileStringArg);
|
|
||||||
default:
|
|
||||||
plugins.beautylog.error("file type " + fileTypeArg.blue + " not supported");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0ZmlsZS5pbnRlcnByZXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsUUFBTyxnQkFBZ0IsQ0FBQyxDQUFBO0FBRXhCLElBQU8sT0FBTyxXQUFXLHFCQUFxQixDQUFDLENBQUM7QUFFckMsZ0JBQVEsR0FBRyxVQUFDLE9BQWM7SUFDakMsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyx3QkFBd0I7SUFDM0UsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQUNwQixDQUFDLENBQUM7QUFFUyxrQkFBVSxHQUFHLFVBQUMsYUFBb0IsRUFBRSxXQUFXO0lBQ3RELE1BQU0sQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDbEIsS0FBSyxLQUFLLENBQUU7UUFDWixLQUFLLE1BQU07WUFDUCxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDaEQsS0FBSyxNQUFNO1lBQ1AsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDckM7WUFDSSxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDLElBQUksR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzVFLEtBQUssQ0FBQztJQUNkLENBQUM7QUFDTCxDQUFDLENBQUEiLCJmaWxlIjoic21hcnRmaWxlLmludGVycHJldGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIjtcblxuaW1wb3J0IHBsdWdpbnMgPSByZXF1aXJlKFwiLi9zbWFydGZpbGUucGx1Z2luc1wiKTtcblxuZXhwb3J0IGxldCBmaWxldHlwZSA9IChwYXRoQXJnOnN0cmluZyk6c3RyaW5nID0+IHtcbiAgICBsZXQgZXh0TmFtZSA9IHBsdWdpbnMucGF0aC5leHRuYW1lKHBhdGhBcmcpO1xuICAgIGxldCBmaWxlVHlwZSA9IGV4dE5hbWUucmVwbGFjZSgvXFwuKFthLXpdKikvLFwiJDFcIik7IC8vcmVtb3ZlIC4gZm9ybSBmaWxlVHlwZVxuICAgIHJldHVybiBmaWxlVHlwZTtcbn07XG5cbmV4cG9ydCBsZXQgb2JqZWN0RmlsZSA9IChmaWxlU3RyaW5nQXJnOnN0cmluZywgZmlsZVR5cGVBcmcpID0+IHtcbiAgICBzd2l0Y2ggKGZpbGVUeXBlQXJnKSB7XG4gICAgICAgIGNhc2UgXCJ5bWxcIiA6XG4gICAgICAgIGNhc2UgXCJ5YW1sXCI6XG4gICAgICAgICAgICByZXR1cm4gcGx1Z2lucy55YW1sLnNhZmVMb2FkKGZpbGVTdHJpbmdBcmcpO1xuICAgICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZmlsZVN0cmluZ0FyZyk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBwbHVnaW5zLmJlYXV0eWxvZy5lcnJvcihcImZpbGUgdHlwZSBcIiArIGZpbGVUeXBlQXJnLmJsdWUgKyBcIiBub3Qgc3VwcG9ydGVkXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxufSJdfQ==
|
|
55
dist/smartfile.memory.d.ts
vendored
55
dist/smartfile.memory.d.ts
vendored
@ -1,55 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
import plugins = require("./smartfile.plugins");
|
|
||||||
/**
|
|
||||||
* allows you to create a gulp stream
|
|
||||||
* from String, from an Array of Strings, from Vinyl File, from an Array of VinylFiles
|
|
||||||
* @param fileArg
|
|
||||||
* @returns stream.Readable
|
|
||||||
* @TODO: make it async;
|
|
||||||
*/
|
|
||||||
export declare let toGulpStream: (fileArg: string | string[] | plugins.vinyl | plugins.vinyl[], baseArg?: string) => any;
|
|
||||||
/**
|
|
||||||
* converts file to Object
|
|
||||||
* @param fileStringArg
|
|
||||||
* @param fileTypeArg
|
|
||||||
* @returns {any|any}
|
|
||||||
*/
|
|
||||||
export declare let toObject: (fileStringArg: string, fileTypeArg: string) => any;
|
|
||||||
/**
|
|
||||||
* takes a string and converts it to vinyl file
|
|
||||||
* @param fileArg
|
|
||||||
* @param optionsArg
|
|
||||||
*/
|
|
||||||
export declare let toVinylFileSync: (fileArg: string, optionsArg?: {
|
|
||||||
filename?: string;
|
|
||||||
base?: string;
|
|
||||||
relPath?: string;
|
|
||||||
}) => plugins.vinyl;
|
|
||||||
/**
|
|
||||||
* takes a string array and some options and returns a vinylfile array
|
|
||||||
* @param arrayArg
|
|
||||||
* @param optionsArg
|
|
||||||
*/
|
|
||||||
export declare let toVinylArraySync: (arrayArg: string[], optionsArg?: {
|
|
||||||
filename?: string;
|
|
||||||
base?: string;
|
|
||||||
relPath?: string;
|
|
||||||
}) => any[];
|
|
||||||
/**
|
|
||||||
* takes a vinylFile object and converts it to String
|
|
||||||
*/
|
|
||||||
export declare let toStringSync: (fileArg: plugins.vinyl) => string;
|
|
||||||
/**
|
|
||||||
* writes string or vinyl file to disk.
|
|
||||||
* @param fileArg
|
|
||||||
* @param fileNameArg
|
|
||||||
* @param fileBaseArg
|
|
||||||
*/
|
|
||||||
export declare let toFs: (fileArg: any, optionsArg: {
|
|
||||||
fileName: string;
|
|
||||||
filePath: string;
|
|
||||||
}) => any;
|
|
||||||
export declare let toFsSync: (fileArg: any, optionsArg: {
|
|
||||||
fileName: string;
|
|
||||||
filePath: string;
|
|
||||||
}) => void;
|
|
128
dist/smartfile.memory.js
vendored
128
dist/smartfile.memory.js
vendored
File diff suppressed because one or more lines are too long
14
dist/smartfile.plugins.d.ts
vendored
14
dist/smartfile.plugins.d.ts
vendored
@ -1,14 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
export declare let beautylog: any;
|
|
||||||
export declare let fs: any;
|
|
||||||
export declare let gulp: any;
|
|
||||||
export declare let g: {
|
|
||||||
remoteSrc: any;
|
|
||||||
};
|
|
||||||
export import path = require("path");
|
|
||||||
export declare let q: any;
|
|
||||||
export import vinyl = require("vinyl");
|
|
||||||
export declare let vinylFile: any;
|
|
||||||
export declare let yaml: any;
|
|
||||||
export declare let request: any;
|
|
||||||
export declare let requireReload: any;
|
|
17
dist/smartfile.plugins.js
vendored
17
dist/smartfile.plugins.js
vendored
@ -1,17 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
require("typings-global");
|
|
||||||
exports.beautylog = require("beautylog");
|
|
||||||
exports.fs = require("fs-extra");
|
|
||||||
exports.gulp = require("gulp");
|
|
||||||
exports.g = {
|
|
||||||
remoteSrc: require("gulp-remote-src")
|
|
||||||
};
|
|
||||||
exports.path = require("path");
|
|
||||||
exports.q = require("q");
|
|
||||||
exports.vinyl = require("vinyl");
|
|
||||||
exports.vinylFile = require("vinyl-file");
|
|
||||||
exports.yaml = require("js-yaml");
|
|
||||||
exports.request = require("request");
|
|
||||||
exports.requireReload = require("require-reload");
|
|
||||||
|
|
||||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0ZmlsZS5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFDYixpQkFBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUNqQyxVQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3pCLFlBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdkIsU0FBQyxHQUFHO0lBQ1gsU0FBUyxFQUFFLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQztDQUN4QyxDQUFDO0FBQ1ksWUFBSSxXQUFXLE1BQU0sQ0FBQyxDQUFDO0FBQzFCLFNBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxhQUFLLFdBQVcsT0FBTyxDQUFDLENBQUM7QUFDNUIsaUJBQVMsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDbEMsWUFBSSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMxQixlQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzdCLHFCQUFhLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUMiLCJmaWxlIjoic21hcnRmaWxlLnBsdWdpbnMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXCJ0eXBpbmdzLWdsb2JhbFwiO1xuZXhwb3J0IGxldCBiZWF1dHlsb2cgPSByZXF1aXJlKFwiYmVhdXR5bG9nXCIpO1xuZXhwb3J0IGxldCBmcyA9IHJlcXVpcmUoXCJmcy1leHRyYVwiKTtcbmV4cG9ydCBsZXQgZ3VscCA9IHJlcXVpcmUoXCJndWxwXCIpO1xuZXhwb3J0IGxldCBnID0ge1xuICAgIHJlbW90ZVNyYzogcmVxdWlyZShcImd1bHAtcmVtb3RlLXNyY1wiKVxufTtcbmV4cG9ydCBpbXBvcnQgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xuZXhwb3J0IGxldCBxID0gcmVxdWlyZShcInFcIik7XG5leHBvcnQgaW1wb3J0IHZpbnlsID0gcmVxdWlyZShcInZpbnlsXCIpO1xuZXhwb3J0IGxldCB2aW55bEZpbGUgPSByZXF1aXJlKFwidmlueWwtZmlsZVwiKTtcbmV4cG9ydCBsZXQgeWFtbCA9IHJlcXVpcmUoXCJqcy15YW1sXCIpO1xuZXhwb3J0IGxldCByZXF1ZXN0ID0gcmVxdWlyZShcInJlcXVlc3RcIik7XG5leHBvcnQgbGV0IHJlcXVpcmVSZWxvYWQgPSByZXF1aXJlKFwicmVxdWlyZS1yZWxvYWRcIik7XG4iXX0=
|
|
20
dist/smartfile.remote.d.ts
vendored
20
dist/smartfile.remote.d.ts
vendored
@ -1,20 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
export declare let toFs: (from: string, toPath: string) => any;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathArg
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
export declare let toGulpStreamSync: (filePathArg: string, baseArg: string) => any;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param fromArg
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export declare let toObject: (fromArg: string) => any;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param fromArg
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export declare let toString: (fromArg: string) => any;
|
|
67
dist/smartfile.remote.js
vendored
67
dist/smartfile.remote.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2015 Push.Rocks
|
Copyright (c) 2015 Lossless GmbH
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
18
npmextra.json
Normal file
18
npmextra.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"npmdocker": {},
|
||||||
|
"npmci": {
|
||||||
|
"npmGlobalTools": [],
|
||||||
|
"npmAccessLevel": "public"
|
||||||
|
},
|
||||||
|
"gitzone": {
|
||||||
|
"projectType": "npm",
|
||||||
|
"module": {
|
||||||
|
"githost": "code.foss.global",
|
||||||
|
"gitscope": "push.rocks",
|
||||||
|
"gitrepo": "smartfile",
|
||||||
|
"description": "smart ways to work with files in nodejs",
|
||||||
|
"npmPackagename": "@push.rocks/smartfile",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"mode":"default",
|
|
||||||
"codecov":true,
|
|
||||||
"coverageTreshold":80
|
|
||||||
}
|
|
79
package.json
79
package.json
@ -1,47 +1,68 @@
|
|||||||
{
|
{
|
||||||
"name": "smartfile",
|
"name": "@push.rocks/smartfile",
|
||||||
"version": "4.0.2",
|
"private": false,
|
||||||
|
"version": "11.0.5",
|
||||||
"description": "offers smart ways to work with files in nodejs",
|
"description": "offers smart ways to work with files in nodejs",
|
||||||
"main": "dist/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(npmts)",
|
"test": "(tstest test/)",
|
||||||
"reinstall": "(rm -r node_modules && npm install)",
|
"build": "(tsbuild --web --allowimplicitany)",
|
||||||
"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)",
|
"buildDocs": "tsdoc"
|
||||||
"update": "(git checkout master && git pull origin master && npm install)",
|
|
||||||
"upgrade": "(npm run update) && (ncu upgradeAll && npm install)"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/pushrocks/smartfile.git"
|
"url": "git+https://gitlab.com/push.rocks/smartfile.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"filesystem",
|
"filesystem",
|
||||||
"json"
|
"json"
|
||||||
],
|
],
|
||||||
"author": "Smart Coordination GmbH <office@push.rocks> (https://push.rocks)",
|
"author": "Lossless GmbH <hello@lossless.com> (https://lossless.com)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/pushrocks/smartfile/issues"
|
"url": "https://gitlab.com/push.rocks/smartfile/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/pushrocks/smartfile",
|
"homepage": "https://gitlab.com/push.rocks/smartfile#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"beautylog": "^5.0.12",
|
"@push.rocks/lik": "^6.0.12",
|
||||||
"fs-extra": "^0.30.0",
|
"@push.rocks/smartdelay": "^3.0.5",
|
||||||
"gulp": "^3.9.1",
|
"@push.rocks/smartfile-interfaces": "^1.0.7",
|
||||||
"gulp-remote-src": "^0.4.1",
|
"@push.rocks/smarthash": "^3.0.4",
|
||||||
"js-yaml": "^3.6.1",
|
"@push.rocks/smartjson": "^5.0.10",
|
||||||
"q": "^1.4.1",
|
"@push.rocks/smartmime": "^1.0.5",
|
||||||
"request": "^2.72.0",
|
"@push.rocks/smartpath": "^5.0.11",
|
||||||
"require-reload": "0.2.2",
|
"@push.rocks/smartpromise": "^4.0.2",
|
||||||
"typings-global": "^1.0.3",
|
"@push.rocks/smartrequest": "^2.0.21",
|
||||||
"vinyl": "^1.1.1",
|
"@push.rocks/smartstream": "^3.0.30",
|
||||||
"vinyl-file": "^2.0.0"
|
"@types/fs-extra": "^11.0.4",
|
||||||
|
"@types/glob": "^8.1.0",
|
||||||
|
"@types/js-yaml": "^4.0.9",
|
||||||
|
"fs-extra": "^11.1.1",
|
||||||
|
"glob": "^10.3.10",
|
||||||
|
"js-yaml": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp-function": "^1.3.6",
|
"@git.zone/tsbuild": "^2.1.70",
|
||||||
"npmts-g": "^5.2.6",
|
"@git.zone/tsrun": "^1.2.46",
|
||||||
"should": "^9.0.2",
|
"@git.zone/tstest": "^1.0.84",
|
||||||
"typings-test": "^1.0.1"
|
"@push.rocks/tapbundle": "^5.0.15",
|
||||||
}
|
"@types/node": "^20.10.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"ts/**/*",
|
||||||
|
"ts_web/**/*",
|
||||||
|
"dist/**/*",
|
||||||
|
"dist_*/**/*",
|
||||||
|
"dist_ts/**/*",
|
||||||
|
"dist_ts_web/**/*",
|
||||||
|
"assets/**/*",
|
||||||
|
"cli.js",
|
||||||
|
"npmextra.json",
|
||||||
|
"readme.md"
|
||||||
|
],
|
||||||
|
"browserslist": [
|
||||||
|
"last 1 chrome versions"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
5735
pnpm-lock.yaml
generated
Normal file
5735
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
126
readme.md
Normal file
126
readme.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
# SmartFile
|
||||||
|
> SmartFile offers smart ways to work with files in nodejs.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
To install SmartFile, use npm or Yarn as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install @push.rocks/smartfile --save
|
||||||
|
```
|
||||||
|
Or:
|
||||||
|
```
|
||||||
|
yarn add @push.rocks/smartfile
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
SmartFile is a comprehensive toolkit for file manipulation in Node.js. It provides functionalities for working with the filesystem, in-memory operations, streaming, and handling virtual directories. Below, you will find examples showcasing how to utilize these functionalities effectively.
|
||||||
|
|
||||||
|
### Basic File Operations
|
||||||
|
|
||||||
|
For reading and writing files, SmartFile provides synchronous and asynchronous methods. Here’s how you can use them:
|
||||||
|
|
||||||
|
#### Async Write to File
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { memory } from '@push.rocks/smartfile';
|
||||||
|
|
||||||
|
const myData: string = 'Hello, SmartFile!';
|
||||||
|
|
||||||
|
// Writing string data to a file asynchronously
|
||||||
|
memory.toFs(myData, './data/hello.txt');
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sync Write to File
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { memory } from '@push.rocks/smartfile';
|
||||||
|
|
||||||
|
const myData: string = 'Hello, World!';
|
||||||
|
|
||||||
|
// Writing string data to a file synchronously
|
||||||
|
memory.toFsSync(myData, './data/helloSync.txt');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Working with Streams
|
||||||
|
|
||||||
|
Streaming files to and from the filesystem is made easy with SmartFile. Here’s an example:
|
||||||
|
|
||||||
|
#### Creating Read and Write Streams
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { fsStream } from '@push.rocks/smartfile';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
// Creating a read stream
|
||||||
|
const readStream = fsStream.createReadStream('./data/readme.txt');
|
||||||
|
|
||||||
|
// Creating a write stream
|
||||||
|
const writeStream = fsStream.createWriteStream('./data/copy.txt');
|
||||||
|
|
||||||
|
// Piping the read stream to the write stream
|
||||||
|
readStream.pipe(writeStream);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dealing with Virtual Directories
|
||||||
|
|
||||||
|
Virtual directories allow you to group and manipulate files as if they were in a filesystem structure without actually writing them to disk.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { VirtualDirectory } from '@push.rocks/smartfile';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
// Creating a virtual directory from the file system
|
||||||
|
const virtualDir = await VirtualDirectory.fromFsDirPath('./myDirectory');
|
||||||
|
|
||||||
|
// Adding files from another virtual directory
|
||||||
|
const anotherVirtualDir = await VirtualDirectory.fromFsDirPath('./anotherDirectory');
|
||||||
|
await virtualDir.addVirtualDirectory(anotherVirtualDir, 'merged');
|
||||||
|
|
||||||
|
// Saving the virtual directory to disk
|
||||||
|
await virtualDir.saveToDisk('./outputDirectory');
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced File Manipulation
|
||||||
|
|
||||||
|
SmartFile also allows for more advanced file manipulation techniques through the `SmartFile` class.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { SmartFile } from '@push.rocks/smartfile';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
// Create a SmartFile instance from a file path
|
||||||
|
const smartFile = await SmartFile.fromFilePath('./data/example.txt');
|
||||||
|
|
||||||
|
// Edit the file content
|
||||||
|
await smartFile.editContentAsString(async (currentContent: string) => {
|
||||||
|
return currentContent.toUpperCase();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Write the changes back to disk
|
||||||
|
await smartFile.write();
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conversion and Interpretation
|
||||||
|
|
||||||
|
You can easily convert file contents to objects or interpret file types for further processing:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { memory } from '@push.rocks/smartfile';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const fileString: string = await fs.promises.readFile('./data/example.json', 'utf8');
|
||||||
|
const fileObject = memory.toObject(fileString, 'json');
|
||||||
|
|
||||||
|
console.log(fileObject);
|
||||||
|
// Proceed with the object...
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
SmartFile simplifies handling files in a Node.js environment, providing a concise, promise-based API for various file operations, stream handling, and in-memory file manipulation. Whether you're dealing with physical files on the disk, manipulating file streams, or managing virtual files and directories, SmartFile has got you covered.
|
||||||
|
|
||||||
|
## Information on Licensing
|
||||||
|
|
||||||
|
SmartFile is licensed under the MIT License. This permissive license is short and to the point. It lets people do anything they want with your code as long as they provide attribution back to you and don’t hold you liable.
|
1
test/test.d.ts
vendored
1
test/test.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
import "typings-test";
|
|
186
test/test.js
186
test/test.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
67
test/test.streamfile.ts
Normal file
67
test/test.streamfile.ts
Normal 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();
|
420
test/test.ts
420
test/test.ts
@ -1,204 +1,224 @@
|
|||||||
import "typings-test";
|
import * as smartfile from '../ts/index.js';
|
||||||
import * as smartfile from "../dist/index";
|
import * as path from 'path';
|
||||||
let beautylog = require("beautylog");
|
|
||||||
let gulp = require("gulp");
|
|
||||||
let gFunction = require("gulp-function");
|
|
||||||
import should = require("should");
|
|
||||||
let vinyl = require("vinyl");
|
|
||||||
|
|
||||||
describe("smartfile".yellow,function(){
|
import { expect, tap } from '@push.rocks/tapbundle';
|
||||||
|
|
||||||
|
// ---------------------------
|
||||||
|
// smartfile.fs
|
||||||
|
// ---------------------------
|
||||||
|
|
||||||
describe(".fs".yellow,function(){
|
tap.test('.fs.fileExistsSync -> should return an accurate boolean', async () => {
|
||||||
describe(".fileExistsSync".yellow,function(){
|
// tslint:disable-next-line: no-unused-expression
|
||||||
it("should return an accurate boolean",function(){
|
expect(smartfile.fs.fileExistsSync('./test/testassets/mytest.json')).toBeTrue();
|
||||||
(smartfile.fs.fileExistsSync("./test/mytest.json")).should.be.true();
|
// tslint:disable-next-line: no-unused-expression
|
||||||
(smartfile.fs.fileExistsSync("./test/notthere.json")).should.be.false();
|
expect(smartfile.fs.fileExistsSync('./test/testassets/notthere.json')).toBeFalse();
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".fileExists".yellow,function(){
|
|
||||||
it("should return a working promise",function(){
|
|
||||||
(smartfile.fs.fileExists("./test/mytest.json")).should.be.Promise();
|
|
||||||
(smartfile.fs.fileExists("./test/mytest.json")).should.be.fulfilled();
|
|
||||||
(smartfile.fs.fileExists("./test/notthere.json")).should.not.be.fulfilled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".listFoldersSync()",function(){
|
|
||||||
it("should get the file type from a string",function(){
|
|
||||||
smartfile.fs.listFoldersSync("./test/").should.containDeep([ "testfolder"]);
|
|
||||||
smartfile.fs.listFoldersSync("./test/").should.not.containDeep([ "notExistentFolder"]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".listFolders()",function(){
|
|
||||||
it("should get the file type from a string",function(done){
|
|
||||||
smartfile.fs.listFolders("./test/")
|
|
||||||
.then(function(folderArrayArg){
|
|
||||||
folderArrayArg.should.containDeep([ "testfolder"]);
|
|
||||||
folderArrayArg.should.not.containDeep([ "notExistentFolder"]);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".copy()".yellow,function(){
|
|
||||||
it("should copy a directory",function(){
|
|
||||||
smartfile.fs.copy("./test/testfolder/","./test/temp/")
|
|
||||||
});
|
|
||||||
it("should copy a file",function(){
|
|
||||||
smartfile.fs.copy("./test/mytest.yaml","./test/temp/")
|
|
||||||
});
|
|
||||||
it("should copy a file and rename it",function(){
|
|
||||||
smartfile.fs.copy("./test/mytest.yaml","./test/temp/mytestRenamed.yaml")
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".remove()",function(){
|
|
||||||
it("should remove an entire directory",function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
it("should remove single files",function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe(".interpreter",function(){
|
|
||||||
describe(".filetype()",function(){
|
|
||||||
it("should get the file type from a string",function(){
|
|
||||||
smartfile.interpreter.filetype("./somefolder/data.json").should.equal("json");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe(".fs".yellow,function(){
|
|
||||||
describe("toGulpStreamSync() and toGulpDestSync",function(){
|
|
||||||
it("should produce a gulp stream",function(done){
|
|
||||||
smartfile.fs.toGulpStreamSync("./test/my*")
|
|
||||||
.pipe(smartfile.fs.toGulpDestSync("./test/temp/"))
|
|
||||||
.pipe(gFunction(done,"atEnd"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".toObjectSync()".yellow,function(){
|
|
||||||
it("should read an " + ".yaml".blue + " file to an object",function(){
|
|
||||||
let testData = smartfile.fs.toObjectSync("./test/mytest.yaml");
|
|
||||||
testData.should.have.property("key1","this works");
|
|
||||||
testData.should.have.property("key2","this works too");
|
|
||||||
|
|
||||||
});
|
|
||||||
it("should state unknown file type for unknown file types",function(){
|
|
||||||
let testData = smartfile.fs.toObjectSync("./test/mytest.txt");
|
|
||||||
});
|
|
||||||
it("should read an " + ".json".blue + " file to an object",function(){
|
|
||||||
let testData = smartfile.fs.toObjectSync("./test/mytest.json");
|
|
||||||
testData.should.have.property("key1","this works");
|
|
||||||
testData.should.have.property("key2","this works too");
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".toStringSync()".yellow,function(){
|
|
||||||
it("should read a file to a string",function(){
|
|
||||||
should.equal(
|
|
||||||
smartfile.fs.toStringSync("./test/mytest.txt"),
|
|
||||||
"Some TestString &&%$"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".toVinylSync".yellow,function(){
|
|
||||||
it("should read an " + ".json OR .yaml".blue + " file to an " + "vinyl file object".cyan,function(){
|
|
||||||
let testData = smartfile.fs.toVinylSync("./test/mytest.json");
|
|
||||||
(vinyl.isVinyl(testData)).should.be.true();
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe(".memory",function(){
|
|
||||||
describe(".toGulpStream()",function(){
|
|
||||||
it("should produce a valid gulp stream",function(){
|
|
||||||
let localArray = ["test1","test2","test3"];
|
|
||||||
smartfile.memory.toGulpStream(localArray)
|
|
||||||
.pipe(gulp.dest("./test/temp/"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("toVinylFileSync()",function(){
|
|
||||||
it("should produce a vinylFile",function(){
|
|
||||||
let localString = "myString";
|
|
||||||
let localOptions = {filename:"vinylfile2",base:"/someDir"};
|
|
||||||
(smartfile.memory.toVinylFileSync(localString,localOptions) instanceof vinyl).should.be.true();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("toVinylArraySync()",function(){
|
|
||||||
it("should produce a an array of vinylfiles",function(){
|
|
||||||
let localStringArray = ["string1","string2","string3"];
|
|
||||||
let localOptions = {filename:"vinylfile2",base:"/someDir"};
|
|
||||||
let testResult = smartfile.memory.toVinylArraySync(localStringArray,localOptions);
|
|
||||||
testResult.should.be.Array();
|
|
||||||
(testResult.length === 3).should.be.true();
|
|
||||||
for (let myKey in testResult){
|
|
||||||
(testResult[myKey] instanceof vinyl).should.be.true();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("toStringSync()",function(){
|
|
||||||
it("should produce a String from vinyl file",function(){
|
|
||||||
let localString = smartfile.memory.toStringSync(new vinyl({
|
|
||||||
base:"/",
|
|
||||||
path:"/test.txt",
|
|
||||||
contents: new Buffer("myString")
|
|
||||||
}));
|
|
||||||
localString.should.equal("myString");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("toFs()",function(){
|
|
||||||
it("should write a file to disk and return a promise",function(done){
|
|
||||||
let localString = "myString";
|
|
||||||
smartfile.memory.toFs(
|
|
||||||
localString,
|
|
||||||
{
|
|
||||||
fileName:"./test/temp/testMemToFs.txt",
|
|
||||||
filePath:process.cwd()
|
|
||||||
}
|
|
||||||
).then(done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("toFsSync()",function(){
|
|
||||||
it("should write a file to disk and return true if successfull",function(){
|
|
||||||
let localString = "myString";
|
|
||||||
smartfile.memory.toFsSync(
|
|
||||||
localString,{
|
|
||||||
fileName:"./test/temp/testMemToFsSync.txt",
|
|
||||||
filePath:process.cwd()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe(".remote",function(){
|
|
||||||
describe("toGulpStreamSync()",function(){
|
|
||||||
it("should produce a gulp stream",function(done){
|
|
||||||
smartfile.remote.toGulpStreamSync("mytest.txt","https://raw.githubusercontent.com/pushrocks/smartfile/master/test/")
|
|
||||||
.pipe(smartfile.fs.toGulpDestSync("./test/temp/"))
|
|
||||||
.pipe(gFunction(done,"atEnd"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe(".toString()",function(){
|
|
||||||
it("should load a remote file to a variable",function(done){
|
|
||||||
this.timeout(5000);
|
|
||||||
smartfile.remote.toString("https://raw.githubusercontent.com/pushrocks/smartfile/master/test/mytest.txt")
|
|
||||||
.then(function(responseString){
|
|
||||||
should.equal(responseString,"Some TestString &&%$");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("should reject a Promise when the link is false",function(done){
|
|
||||||
this.timeout(10000);
|
|
||||||
smartfile.remote.toString("https://push.rocks/doesnotexist.txt")
|
|
||||||
.then(function(){
|
|
||||||
throw new Error("this test should not be resolved");
|
|
||||||
},function(){
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('.fs.fileExists -> should resolve or reject a promise', async () => {
|
||||||
|
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/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 () => {
|
||||||
|
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/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 () => {
|
||||||
|
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 () => {
|
||||||
|
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 () => {
|
||||||
|
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 () => {
|
||||||
|
await smartfile.fs.copy('./test/testassets/testfolder/', './test/testassets/temp/');
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('.fs.copy() -> should copy a file', async () => {
|
||||||
|
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 () => {
|
||||||
|
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/testassets/temp/mytestRenamed.yaml');
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('.fs.removeSync -> should remove single files synchronouly', async () => {
|
||||||
|
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/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/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 () => {
|
||||||
|
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 () => {
|
||||||
|
const testData = smartfile.fs.toObjectSync('./test/testassets/mytest.txt');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
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/testassets/mytest.txt')).toEqual('Some TestString &&%$');
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------
|
||||||
|
// smartfile.interpreter
|
||||||
|
// ---------------------------
|
||||||
|
|
||||||
|
tap.test('.interpreter.filetype() -> should get the file type from a string', async () => {
|
||||||
|
expect(smartfile.interpreter.filetype('./somefolder/data.json')).toEqual('json');
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------
|
||||||
|
// smartfile.memory
|
||||||
|
// ---------------------------
|
||||||
|
|
||||||
|
tap.test('.memory.toFs() -> should write a file to disk and return a promise', async () => {
|
||||||
|
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 () => {
|
||||||
|
const localString = 'myString';
|
||||||
|
smartfile.memory.toFsSync(
|
||||||
|
localString,
|
||||||
|
path.join(process.cwd(), './test/testassets/temp/testMemToFsSync.txt')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ---------------------------
|
||||||
|
// smartfile.Smartfile
|
||||||
|
// ---------------------------
|
||||||
|
|
||||||
|
tap.test('.Smartfile -> should produce vinyl compatible files', async () => {
|
||||||
|
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()).toBeTrue();
|
||||||
|
// tslint:disable-next-line:no-unused-expression
|
||||||
|
expect(localSmartfile.isDirectory()).toBeFalse();
|
||||||
|
// tslint:disable-next-line:no-unused-expression
|
||||||
|
expect(localSmartfile.isNull()).toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should output a smartfile array to disk', async () => {
|
||||||
|
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/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();
|
||||||
|
15
test/test.virtualdirectory.ts
Normal file
15
test/test.virtualdirectory.ts
Normal 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();
|
8
test/testassets/temp/mytest.json
Normal file
8
test/testassets/temp/mytest.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"key1": "this works",
|
||||||
|
"key2": "this works too",
|
||||||
|
"key3": {
|
||||||
|
"nestedkey1": "hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
4
test/testassets/temp/mytest.yaml
Normal file
4
test/testassets/temp/mytest.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
key1: this works
|
||||||
|
key2: this works too
|
||||||
|
key3:
|
||||||
|
nestedkey1: hello
|
@ -0,0 +1 @@
|
|||||||
|
okidoks
|
1
test/testassets/temp/subfolder/subtestfile.txt
Normal file
1
test/testassets/temp/subfolder/subtestfile.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
hi
|
8
test/testassets/temp/test/testassets/mytest.json
Normal file
8
test/testassets/temp/test/testassets/mytest.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"key1": "this works",
|
||||||
|
"key2": "this works too",
|
||||||
|
"key3": {
|
||||||
|
"nestedkey1": "hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1
test/testassets/temp/testMemToFs.txt
Normal file
1
test/testassets/temp/testMemToFs.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
myString
|
1
test/testassets/temp/testMemToFsSync.txt
Normal file
1
test/testassets/temp/testMemToFsSync.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
myString
|
@ -0,0 +1 @@
|
|||||||
|
okidoks
|
1
test/testassets/test/subfolder/subtestfile.txt
Normal file
1
test/testassets/test/subfolder/subtestfile.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
hi
|
0
test/testassets/test/testfile1.txt
Normal file
0
test/testassets/test/testfile1.txt
Normal file
0
test/testassets/test/testfile2.txt
Normal file
0
test/testassets/test/testfile2.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
okidoks
|
1
test/testassets/testfolder/subfolder/subtestfile.txt
Normal file
1
test/testassets/testfolder/subfolder/subtestfile.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
hi
|
0
test/testassets/testfolder/testfile1.txt
Normal file
0
test/testassets/testfolder/testfile1.txt
Normal file
0
test/testassets/testfolder/testfile2.txt
Normal file
0
test/testassets/testfolder/testfile2.txt
Normal file
1
test/testassets/utf8.txt
Normal file
1
test/testassets/utf8.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
hi there
|
8
ts/00_commitinfo_data.ts
Normal file
8
ts/00_commitinfo_data.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* autocreated commitinfo by @pushrocks/commitinfo
|
||||||
|
*/
|
||||||
|
export const commitinfo = {
|
||||||
|
name: '@push.rocks/smartfile',
|
||||||
|
version: '11.0.5',
|
||||||
|
description: 'offers smart ways to work with files in nodejs'
|
||||||
|
}
|
307
ts/classes.smartfile.ts
Normal file
307
ts/classes.smartfile.ts
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
import * as plugins from './smartfile.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() {
|
||||||
|
await memory.toFs(this.contentBuffer, plugins.path.join(this.base, this.path));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes the file to path given as argument
|
||||||
|
* note: if the path is not absolute, takes process.cwd() as base
|
||||||
|
* @param filePathArg
|
||||||
|
*/
|
||||||
|
public async writeToDiskAtPath(filePathArg: string) {
|
||||||
|
if (!plugins.path.isAbsolute(filePathArg)) {
|
||||||
|
filePathArg = plugins.path.join(process.cwd(), filePathArg);
|
||||||
|
}
|
||||||
|
await memory.toFs(this.contentBuffer, filePathArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes the file to a directory combined with the relative path portion
|
||||||
|
* @param dirPathArg
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public async writeToDir(dirPathArg: string) {
|
||||||
|
dirPathArg = plugins.smartpath.transform.toAbsolute(dirPathArg) as string;
|
||||||
|
const filePath = plugins.path.join(dirPathArg, this.path);
|
||||||
|
await memory.toFs(this.contentBuffer, filePath);
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read file from disk
|
||||||
|
*/
|
||||||
|
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
152
ts/classes.streamfile.ts
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import * as plugins from './smartfile.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);
|
||||||
|
}
|
||||||
|
}
|
87
ts/classes.virtualdirectory.ts
Normal file
87
ts/classes.virtualdirectory.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { SmartFile } from './classes.smartfile.js';
|
||||||
|
import * as plugins from './smartfile.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);
|
||||||
|
}
|
||||||
|
}
|
446
ts/fs.ts
Normal file
446
ts/fs.ts
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
import * as plugins from './smartfile.plugins.js';
|
||||||
|
import * as interpreter from './interpreter.js';
|
||||||
|
|
||||||
|
import { SmartFile } from './classes.smartfile.js';
|
||||||
|
|
||||||
|
import * as memory from './memory.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();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
195
ts/fsstream.ts
Normal file
195
ts/fsstream.ts
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
This file contains logic for streaming things from and to the filesystem
|
||||||
|
*/
|
||||||
|
import * as plugins from './smartfile.plugins.js';
|
||||||
|
|
||||||
|
export const createReadStream = (pathArg: string) => {
|
||||||
|
return plugins.fs.createReadStream(pathArg);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createWriteStream = (pathArg: string) => {
|
||||||
|
return plugins.fs.createWriteStream(pathArg);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
25
ts/index.ts
25
ts/index.ts
@ -1,15 +1,14 @@
|
|||||||
import "typings-global";
|
import * as plugins from './smartfile.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';
|
||||||
|
|
||||||
import * as plugins from "./smartfile.plugins";
|
export * from './classes.smartfile.js';
|
||||||
import * as SmartfileFs from "./smartfile.fs";
|
export * from './classes.streamfile.js';
|
||||||
import * as SmartfileInterpreter from "./smartfile.interpreter"
|
export * from './classes.virtualdirectory.js';
|
||||||
import * as SmartfileMemory from "./smartfile.memory";
|
|
||||||
import * as SmartfileRemote from "./smartfile.remote";
|
|
||||||
|
|
||||||
export {Smartfile} from "./smartfile.classes.smartfile";
|
export const fs = fsMod;
|
||||||
|
export const fsStream = fsStreamMod;
|
||||||
export let fs = SmartfileFs;
|
export const interpreter = interpreterMod;
|
||||||
export let interpreter = SmartfileInterpreter;
|
export const memory = memoryMod;
|
||||||
export let memory = SmartfileMemory;
|
|
||||||
export let remote = SmartfileRemote;
|
|
||||||
export let requireReload = SmartfileFs.requireReload;
|
|
||||||
|
20
ts/interpreter.ts
Normal file
20
ts/interpreter.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import * as plugins from './smartfile.plugins.js';
|
||||||
|
|
||||||
|
export let filetype = (pathArg: string): string => {
|
||||||
|
const extName = plugins.path.extname(pathArg);
|
||||||
|
const fileType = extName.replace(/\.([a-z]*)/, '$1'); // remove . form fileType
|
||||||
|
return fileType;
|
||||||
|
};
|
||||||
|
|
||||||
|
export let objectFile = (fileStringArg: string, fileTypeArg) => {
|
||||||
|
switch (fileTypeArg) {
|
||||||
|
case 'yml':
|
||||||
|
case 'yaml':
|
||||||
|
return plugins.yaml.load(fileStringArg);
|
||||||
|
case 'json':
|
||||||
|
return JSON.parse(fileStringArg);
|
||||||
|
default:
|
||||||
|
console.error('file type ' + fileTypeArg.blue + ' not supported');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
94
ts/memory.ts
Normal file
94
ts/memory.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import * as plugins from './smartfile.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
|
||||||
|
* @param fileStringArg
|
||||||
|
* @param fileTypeArg
|
||||||
|
* @returns {any|any}
|
||||||
|
*/
|
||||||
|
export let toObject = (fileStringArg: string, fileTypeArg: string) => {
|
||||||
|
return interpreter.objectFile(fileStringArg, fileTypeArg);
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface IToFsOptions {
|
||||||
|
respectRelative?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes string or Smartfile to disk.
|
||||||
|
* @param fileArg
|
||||||
|
* @param fileNameArg
|
||||||
|
* @param fileBaseArg
|
||||||
|
*/
|
||||||
|
export let toFs = async (
|
||||||
|
fileContentArg: string | Buffer | SmartFile | StreamFile,
|
||||||
|
filePathArg: string,
|
||||||
|
optionsArg: IToFsOptions = {}
|
||||||
|
) => {
|
||||||
|
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 smartfileFs.ensureDir(plugins.path.parse(filePath).dir);
|
||||||
|
plugins.fsExtra.writeFile(filePath, fileContent, { encoding: fileEncoding }, done.resolve);
|
||||||
|
return await done.promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes a string or a Smartfile to disk synchronously, only supports string
|
||||||
|
* @param fileArg
|
||||||
|
* @param filePathArg
|
||||||
|
*/
|
||||||
|
export const toFsSync = (fileArg: string, filePathArg: string) => {
|
||||||
|
// function checks to abort if needed
|
||||||
|
if (!fileArg || !filePathArg) {
|
||||||
|
throw new Error('expected a valid arguments');
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare actual write action
|
||||||
|
let fileString: string;
|
||||||
|
const filePath: string = 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' });
|
||||||
|
};
|
||||||
|
|
||||||
|
export let smartfileArrayToFs = async (smartfileArrayArg: SmartFile[], dirArg: string) => {
|
||||||
|
await smartfileFs.ensureDir(dirArg);
|
||||||
|
for (const smartfile of smartfileArrayArg) {
|
||||||
|
await toFs(smartfile, dirArg, {
|
||||||
|
respectRelative: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -1,5 +0,0 @@
|
|||||||
export class Smartfile {
|
|
||||||
constructor(){
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,172 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
|
|
||||||
import plugins = require("./smartfile.plugins");
|
|
||||||
import SmartfileInterpreter = require("./smartfile.interpreter");
|
|
||||||
|
|
||||||
/*===============================================================
|
|
||||||
============================ FS ACTIONS =========================
|
|
||||||
===============================================================*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* copies a file from A to B on the local disk
|
|
||||||
*/
|
|
||||||
export let copy = function(fromArg:string, toArg:string){
|
|
||||||
var done = plugins.q.defer();
|
|
||||||
plugins.fs.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.fs.copySync(fromArg,toArg);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* removes a file or folder from local disk
|
|
||||||
*/
|
|
||||||
export let remove = function(pathArg:string){
|
|
||||||
var done = plugins.q.defer();
|
|
||||||
plugins.fs.remove(pathArg,function(){
|
|
||||||
done.resolve();
|
|
||||||
});
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* removes a file SYNCHRONOUSLY from local disk
|
|
||||||
*/
|
|
||||||
export let removeSync = function(pathArg:string):boolean{
|
|
||||||
plugins.fs.removeSync(pathArg);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*===============================================================
|
|
||||||
============================ Write/Read =========================
|
|
||||||
===============================================================*/
|
|
||||||
|
|
||||||
|
|
||||||
export let toFS = function(options:{from:string,toPath:string}, cb=undefined){
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathArg
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
export let toGulpStreamSync = function(filePathArg:string){
|
|
||||||
let stream = plugins.gulp.src(filePathArg);
|
|
||||||
return stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
export let toGulpDestSync = function(folderPathArg:string){
|
|
||||||
return plugins.gulp.dest(folderPathArg);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathArg
|
|
||||||
* @param fileTypeArg
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export let toObjectSync = function(filePathArg,fileTypeArg?) {
|
|
||||||
let fileString = plugins.fs.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) {
|
|
||||||
let fileString;
|
|
||||||
fileString = plugins.fs.readFileSync(filePath, "utf8");
|
|
||||||
return fileString;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathArg
|
|
||||||
* @param options
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
export let toVinylSync = function(filePathArg,options = {}) {
|
|
||||||
return plugins.vinylFile.readSync(filePathArg,options);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* lets you reload files hot.
|
|
||||||
* @param path
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export let requireReload = function(path:string){
|
|
||||||
return plugins.requireReload(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* lists Folders in a directory on local disk
|
|
||||||
*/
|
|
||||||
export let listFolders = function(pathArg:string){
|
|
||||||
let done = plugins.q.defer();
|
|
||||||
let folderArray = plugins.fs.readdirSync(pathArg).filter(function(file) {
|
|
||||||
return plugins.fs.statSync(plugins.path.join(pathArg, file)).isDirectory();
|
|
||||||
});
|
|
||||||
done.resolve(folderArray);
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* lists Folders SYNCHRONOUSLY in a directory on local disk
|
|
||||||
*/
|
|
||||||
export let listFoldersSync = function(pathArg){
|
|
||||||
return plugins.fs.readdirSync(pathArg).filter(function(file) {
|
|
||||||
return plugins.fs.statSync(plugins.path.join(pathArg, file)).isDirectory();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
export let fileExistsSync = function(filePath):boolean {
|
|
||||||
let fileExistsBool:boolean = false;
|
|
||||||
try {
|
|
||||||
plugins.fs.readFileSync(filePath);
|
|
||||||
fileExistsBool = true
|
|
||||||
}
|
|
||||||
catch(err){
|
|
||||||
fileExistsBool = false;
|
|
||||||
}
|
|
||||||
return fileExistsBool;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export let fileExists = function(filePath){
|
|
||||||
let done = plugins.q.defer();
|
|
||||||
plugins.fs.access(filePath, plugins.fs.R_OK, function (err) {
|
|
||||||
err ? done.reject() : done.resolve();
|
|
||||||
});
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
export let isDirectory = function(pathArg):boolean{
|
|
||||||
return plugins.fs.statSync(pathArg).isDirectory();
|
|
||||||
};
|
|
||||||
|
|
||||||
export let isFile = function(pathArg):boolean{
|
|
||||||
return plugins.fs.statSync(pathArg).isFile();
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
|
|
||||||
import plugins = require("./smartfile.plugins");
|
|
||||||
|
|
||||||
export let filetype = (pathArg:string):string => {
|
|
||||||
let extName = plugins.path.extname(pathArg);
|
|
||||||
let fileType = extName.replace(/\.([a-z]*)/,"$1"); //remove . form fileType
|
|
||||||
return fileType;
|
|
||||||
};
|
|
||||||
|
|
||||||
export let objectFile = (fileStringArg:string, fileTypeArg) => {
|
|
||||||
switch (fileTypeArg) {
|
|
||||||
case "yml" :
|
|
||||||
case "yaml":
|
|
||||||
return plugins.yaml.safeLoad(fileStringArg);
|
|
||||||
case "json":
|
|
||||||
return JSON.parse(fileStringArg);
|
|
||||||
default:
|
|
||||||
plugins.beautylog.error("file type " + fileTypeArg.blue + " not supported");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,134 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
|
|
||||||
import plugins = require("./smartfile.plugins");
|
|
||||||
import SmartfileInterpreter = require("./smartfile.interpreter");
|
|
||||||
let Readable = require("stream").Readable;
|
|
||||||
/**
|
|
||||||
* allows you to create a gulp stream
|
|
||||||
* from String, from an Array of Strings, from Vinyl File, from an Array of VinylFiles
|
|
||||||
* @param fileArg
|
|
||||||
* @returns stream.Readable
|
|
||||||
* @TODO: make it async;
|
|
||||||
*/
|
|
||||||
export let toGulpStream = function(fileArg:string|string[]|plugins.vinyl|plugins.vinyl[],baseArg:string = "/"){
|
|
||||||
let fileArray = [];
|
|
||||||
|
|
||||||
if(typeof fileArg === "string" || fileArg instanceof plugins.vinyl){ // make sure we work with an array later on
|
|
||||||
fileArray.push(fileArg);
|
|
||||||
} else if (Array.isArray(fileArg)){
|
|
||||||
fileArray = fileArg;
|
|
||||||
} else {
|
|
||||||
throw new Error("fileArg has unknown format");
|
|
||||||
}
|
|
||||||
|
|
||||||
let vinylFileArray:plugins.vinyl[] = []; //we want to have an array of vinylFiles
|
|
||||||
|
|
||||||
for (let fileIndexArg in fileArray){ //convert fileArray in vinylArray
|
|
||||||
let file = fileArray[fileIndexArg];
|
|
||||||
file instanceof plugins.vinyl ?
|
|
||||||
vinylFileArray.push(file) :
|
|
||||||
vinylFileArray.push(toVinylFileSync(file,{filename:fileIndexArg,base:baseArg}));
|
|
||||||
};
|
|
||||||
|
|
||||||
let stream = new Readable({ objectMode: true });
|
|
||||||
for(let vinylFileIndexArg in vinylFileArray){
|
|
||||||
let vinylFile = vinylFileArray[vinylFileIndexArg];
|
|
||||||
stream.push(vinylFile);
|
|
||||||
};
|
|
||||||
stream.push(null); //signal end of stream;
|
|
||||||
return stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* converts file to Object
|
|
||||||
* @param fileStringArg
|
|
||||||
* @param fileTypeArg
|
|
||||||
* @returns {any|any}
|
|
||||||
*/
|
|
||||||
export let toObject = function(fileStringArg:string,fileTypeArg:string){
|
|
||||||
return SmartfileInterpreter.objectFile(fileStringArg,fileTypeArg);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* takes a string and converts it to vinyl file
|
|
||||||
* @param fileArg
|
|
||||||
* @param optionsArg
|
|
||||||
*/
|
|
||||||
export let toVinylFileSync = function(fileArg:string,optionsArg?:{filename?:string,base?:string,relPath?:string}){
|
|
||||||
optionsArg? void(0) : optionsArg = {filename: "vinylfile", base: "/"};
|
|
||||||
optionsArg.filename ? void(0) : optionsArg.filename = "vinylfile";
|
|
||||||
optionsArg.base ? void(0) : optionsArg.base = "/";
|
|
||||||
optionsArg.relPath ? void("0") : optionsArg.relPath = "";
|
|
||||||
let vinylFile = new plugins.vinyl({
|
|
||||||
base: optionsArg.base,
|
|
||||||
path: plugins.path.join(optionsArg.base,optionsArg.relPath,optionsArg.filename),
|
|
||||||
contents: new Buffer(fileArg)
|
|
||||||
});
|
|
||||||
return vinylFile;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* takes a string array and some options and returns a vinylfile array
|
|
||||||
* @param arrayArg
|
|
||||||
* @param optionsArg
|
|
||||||
*/
|
|
||||||
export let toVinylArraySync = function(arrayArg:string[],optionsArg?:{filename?:string,base?:string,relPath?:string}){
|
|
||||||
let vinylArray = [];
|
|
||||||
for(let stringIndexArg in arrayArg){
|
|
||||||
let myString = arrayArg[stringIndexArg];
|
|
||||||
vinylArray.push(toVinylFileSync(myString,optionsArg));
|
|
||||||
}
|
|
||||||
return vinylArray;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* takes a vinylFile object and converts it to String
|
|
||||||
*/
|
|
||||||
export let toStringSync = function(fileArg:plugins.vinyl){
|
|
||||||
return fileArg.contents.toString("utf8");
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* writes string or vinyl file to disk.
|
|
||||||
* @param fileArg
|
|
||||||
* @param fileNameArg
|
|
||||||
* @param fileBaseArg
|
|
||||||
*/
|
|
||||||
export let toFs = function(fileArg,optionsArg:{fileName:string,filePath:string}){
|
|
||||||
let done = plugins.q.defer();
|
|
||||||
|
|
||||||
//function checks to abort if needed
|
|
||||||
if (!fileArg || !optionsArg || !(typeof optionsArg.fileName === "string"))
|
|
||||||
throw new Error("expected a valid arguments");
|
|
||||||
if (!(typeof optionsArg.filePath === "string")) optionsArg.filePath = "/";
|
|
||||||
|
|
||||||
let filePath:string = plugins.path.join(optionsArg.filePath,optionsArg.fileName);
|
|
||||||
let fileString:string;
|
|
||||||
if (fileArg instanceof plugins.vinyl){
|
|
||||||
fileString = toStringSync(fileArg);
|
|
||||||
} else if (typeof fileArg === "string") {
|
|
||||||
fileString = fileArg;
|
|
||||||
}
|
|
||||||
plugins.fs.writeFile(filePath,fileString,"utf8",done.resolve);
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
export let toFsSync = function(fileArg,optionsArg:{fileName:string,filePath:string}){
|
|
||||||
//function checks to abort if needed
|
|
||||||
if (!fileArg || !optionsArg || !(typeof optionsArg.fileName === "string"))
|
|
||||||
throw new Error("expected a valid arguments");
|
|
||||||
if (!(typeof optionsArg.filePath === "string")) optionsArg.filePath = "/";
|
|
||||||
|
|
||||||
let filePath = plugins.path.join(optionsArg.filePath,optionsArg.fileName);
|
|
||||||
let fileString:string;
|
|
||||||
|
|
||||||
if (fileArg instanceof plugins.vinyl){
|
|
||||||
fileString = toStringSync(fileArg);
|
|
||||||
} else if (typeof fileArg === "string") {
|
|
||||||
fileString = fileArg;
|
|
||||||
}
|
|
||||||
plugins.fs.writeFileSync(filePath,fileString,"utf8");
|
|
||||||
};
|
|
||||||
|
|
@ -1,14 +1,38 @@
|
|||||||
import "typings-global";
|
// node native scope
|
||||||
export let beautylog = require("beautylog");
|
import * as fs from 'fs';
|
||||||
export let fs = require("fs-extra");
|
import * as path from 'path';
|
||||||
export let gulp = require("gulp");
|
import * as stream from 'stream';
|
||||||
export let g = {
|
|
||||||
remoteSrc: require("gulp-remote-src")
|
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,
|
||||||
};
|
};
|
||||||
export import path = require("path");
|
|
||||||
export let q = require("q");
|
// third party scope
|
||||||
export import vinyl = require("vinyl");
|
import fsExtra from 'fs-extra';
|
||||||
export let vinylFile = require("vinyl-file");
|
import * as glob from 'glob';
|
||||||
export let yaml = require("js-yaml");
|
import yaml from 'js-yaml';
|
||||||
export let request = require("request");
|
|
||||||
export let requireReload = require("require-reload");
|
export { fsExtra, glob, yaml };
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
import "typings-global";
|
|
||||||
import plugins = require("./smartfile.plugins");
|
|
||||||
import SmartfileInterpreter = require("./smartfile.interpreter");
|
|
||||||
|
|
||||||
export let toFs = function(from:string,toPath:string) {
|
|
||||||
var done = plugins.q.defer();
|
|
||||||
var stream = plugins.request(from).pipe(plugins.fs.createWriteStream(toPath));
|
|
||||||
stream.on('finish',function(){
|
|
||||||
done.resolve(toPath);
|
|
||||||
});
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param filePathArg
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
export let toGulpStreamSync = function(filePathArg:string,baseArg:string){
|
|
||||||
let stream = plugins.g.remoteSrc(filePathArg, {
|
|
||||||
base: baseArg
|
|
||||||
});
|
|
||||||
return stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param fromArg
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export let toObject = function(fromArg:string){
|
|
||||||
let done = plugins.q.defer();
|
|
||||||
plugins.request.get(fromArg, function (error, response, bodyString) {
|
|
||||||
let returnObject;
|
|
||||||
if (!error && response.statusCode == 200) {
|
|
||||||
returnObject = SmartfileInterpreter.objectFile(bodyString,SmartfileInterpreter.filetype(fromArg));
|
|
||||||
done.resolve(returnObject);
|
|
||||||
} else {
|
|
||||||
console.log('could not get remote file from ' + fromArg);
|
|
||||||
returnObject = undefined;
|
|
||||||
done.reject(returnObject);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param fromArg
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export let toString = (fromArg:string) => {
|
|
||||||
let done = plugins.q.defer();
|
|
||||||
plugins.request.get(fromArg, function (error, response, bodyString) {
|
|
||||||
if (!error && response.statusCode == 200) {
|
|
||||||
done.resolve(bodyString);
|
|
||||||
} else {
|
|
||||||
plugins.beautylog.error('could not get remote file from ' + fromArg);
|
|
||||||
bodyString = undefined;
|
|
||||||
done.reject(bodyString);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"globalDependencies": {
|
|
||||||
"colors": "github:DefinitelyTyped/DefinitelyTyped/colors/colors.d.ts",
|
|
||||||
"mocha": "github:Bartvds/tsd-deftools/typings/DefinitelyTyped/mocha/mocha.d.ts",
|
|
||||||
"node": "registry:dt/node",
|
|
||||||
"should": "registry:dt/should"
|
|
||||||
}
|
|
||||||
}
|
|
11
tsconfig.json
Normal file
11
tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ES2022",
|
||||||
|
"moduleResolution": "nodenext",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user