{"_id":"@flowforge/file-server","_rev":"28-32143948fb5c57b9b1522acba213a48c","name":"@flowforge/file-server","dist-tags":{"latest":"1.14.0","nightly":"1.14.1-d7a56e2-202311231143.0"},"versions":{"0.0.1":{"name":"@flowforge/file-server","version":"0.0.1","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"c1534bdc2823a6aa106703d3b4b284bbacd4256a","_id":"@flowforge/file-server@0.0.1","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-IJg6AYTQsBOMkXN0EcEm8UzxieAvKJhQMBzpppkG6jsmK3q+cJamFP4fs+OyWXmhM8u9fiXNxLJ2WaZe/Kgrpg==","shasum":"38fdde289941c5270dbb9fd0bb222e719471b743","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-0.0.1.tgz","fileCount":16,"unpackedSize":40086,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDU0A/96pCfh0DbuvYUw8j2Rs3JvX8dgk2W41Z0chW6jAiBf5dZf+8VMCtNNh4mLfn+SIA4YKquLpl9LIc/bZc1EAw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJje2SyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrKvg//Wud6LvFCqpqETZ6fFdsGYsmHF+asxdeksJ+9kjmUPUdLPor/\r\nYjmpZOxVu9x4AOcXFYKhVXcmmvgKAv9pHvAhHmz3yAOOYNqBcq5/Kx9ios/H\r\nqn/hdjtzxBXf/v6Tgv7CrkC1riBBsX2guFBsDb4ctR7g6MByik1jrQImwazz\r\nQhQo70dkYFV60kp8hnjr4JDj3etcY4a9TX/bBkvdNrLMwtmzekmX4KFtQoXF\r\nf6rB59btBNkmFFIh6aTTXNlw5IsfMBYjkQe1ZCrDCb79PslibHaSgr+LbovV\r\n63CJ+SxkO8F9ITsMcsL0grRvuujEI6AMg92scpgGC655DOVzV7XrkI3KYYvC\r\nhhCrkbTf8xDNCkOTInO+sQeJ3s87nZbgO1XDg/AHWQwXGA1t9Y95MBcLPKVN\r\no65FBNQeiDKyIbqiAIXlM8k/mP69F8v68/uprIRCb9cuxafCiO2Ncm5f/3eX\r\ngvtXlP0vcPiX+cjnYsySFyCnqkL/s/SY5d8Tynw+GDYg71GiyKQKBg7Iz3ZW\r\n9USV/X+2N+Pzw7ETBPQ4WluPvG1TGRDsbUPg5zxLLdMoXpcbyBcjWgvW9Ig8\r\nr1wjO0tdrb61WSyetd+0y8rnWN7xdXtfqbuzlW7YOyKqFU+IBEaFgwNIUH6n\r\nQ9ynociVLaTFgtEG0LJye3kD+Lbir2Xgnjs=\r\n=kqL1\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_0.0.1_1669031090203_0.7159130928255892"},"_hasShrinkwrap":false},"0.0.3":{"name":"@flowforge/file-server","version":"0.0.3","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"20376755a7da7e201eb87b0324e698ebbaec0736","_id":"@flowforge/file-server@0.0.3","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-62nStGOirNg/jZ9n6Q5hIY4XKcHNPZWURF517HbpB8mGYX509cFezUohg584pgJU8t181UhkTkwIq1YE06lTeQ==","shasum":"b0704f1ad2d76ce92719bdf036482607219a54a4","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-0.0.3.tgz","fileCount":16,"unpackedSize":40357,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDF+qwo8gyZy+QmL+RdWoYk8OxvlPxu6siQznlJs/NWpAiAVaX+Oqh7apjU+F7cjoasaQradeuu3PoUGUWc5P0Hbng=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfkboACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoabBAAlnaey1NJdwTa3fTPhT/rVGKoNzk+yqwEm0TfJqyq3henD4zM\r\nup8EnPqOGOVr2zgVs2axja0qcmp3z7aXvOtdrJFWEALEv5YNSgeMEKBycy4W\r\n06H5lnOuCc2TOEXw3jAM7H52Nugqs/OSYXpdGY3Ig5xAWNS0TICUQI8adBBW\r\nCCDAv2mUkYSIF3WMu8qgq9jy7P5p83jU6uYXY3XH5PYL0Q/vGPYdKCHiE2J3\r\ndAKdGEqhXLA2CyGVEy9ubpMFAX8IjovxFBVVBzEBXosn6ZSJEKtTKwvwXO6t\r\nZiEEIRmEJLxEn0K9g3a2oMpKuLDkLLf+DtMlwyHxKhG6CGvDdhb7mZAbtTW6\r\nhglXfYIOWbv3UsPzalu+osiuKFNzVd0wDt3zcWO25IwNrfUR6EvbA77+l9Gc\r\nH5DIcOT0j/nkeXk+LnjMJRsTL+9vDXPX4YqRkq3IQoo6+ALINWLsbQwZPREF\r\n6nvg3nXegElGXXLHA/YLQX3611fKSnmhMM7RKs40jq/94JMD5/72JtKYqIor\r\nhB0WW28X8nmTImVRjMG3NOryw9XW3fhcVpvFf/+iumUQoH4pPW0tsq9NAOYX\r\nqim6WETDib36obdjsbOmxJJq61bxcoJZ2k6r/uq27euyjEsxG2JFjuH2PPK2\r\n+D+NAS9HTDA/rVNfs0PkI7f1lKZ9WcLe76Y=\r\n=CLP4\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_0.0.3_1669220072124_0.8614308688295811"},"_hasShrinkwrap":false},"0.0.4":{"name":"@flowforge/file-server","version":"0.0.4","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","redis":"^4.5.1","semver":"^7.3.8","sequelize":"^6.25.3","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"b9e978715389e4181e2e0c7ab1c3696799b261c0","_id":"@flowforge/file-server@0.0.4","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-bKrNUGsFq4oxH/ernQprpYnH0UghJb+bTZFh+py6k3G6n8qlu8iUlMR9MlBpPIKQr7b05lPtEHr1GN5uyuyUiQ==","shasum":"b5a8436e7ff51d5dd9f90d5de842951c6736a59a","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-0.0.4.tgz","fileCount":20,"unpackedSize":64753,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDg3x9BgD7Gxh3GHdNa6gpWrMk7pzkQDP4d91q3bj40gwIhAJZo+xu+3Ewuq+mV6um3Z24VdzL2O4XPtpjdeK8jnJ1r"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjl2LOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq6pw/8DzB8etVtj6YQShLEMQvF9dii9jgHuQ5tRhyUmQPtmybAeFc5\r\nGDx2wtZhFrcyXZmItWcdIJiPNQJMHJBoQ6uhmvSXaQblwyuPOfrUEZWx1lYL\r\nPRiAHx3f+9Vf0XpqPG/wZGyM26TJ3mBGmWJzfFOWTYr0yJnAijZILOL6dKOk\r\n/fC+DA5YfB1Xre0DQNfO3+r42G0J29MEs8iQBPDPvNpB4xV063lzW55h6MCA\r\nPYJk3fTLv83SWV8cGv33NpNkTPnDPvX7os3FjcBwlM8fcMWBKSi7IzJzJwqW\r\n8jtFLzS6ZbKDL7nUx0+L2aAihT43t9JhBfsN5Ed6EU88o0CTNsUtgFIfxf0b\r\npmiSnPZmSKXtLKbx6GjPIey6fqnaFi76KaFg5C+B+yyZ6syUdj2rfw86aH8C\r\nEdteCMWwo7zsKldTmsIJCMyBgOnlYjMPi6aUArjlXWn1jOXQI2nHIiF2Lov0\r\nRbKXWPZ9jFVCiPgkxcEgR1btcybeNh2zhUIO+jD5ffkACugAmnaVmP3gQVVM\r\nSTcBfjzCICS8hfJo3b2MGPPLsV9QeFwoXrM9LWchCSoRovCTTEBxzdSERZfC\r\n2sm1rOrYxttjYRzuZ2BbRmHrmwM48v8y0Xv4olf4RMVDL6LYPx50yHPwe20F\r\nRjioIRTMWIFHmufp2LTIqSEi/gedpviX9jk=\r\n=ML20\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_0.0.4_1670865613879_0.6236306531474498"},"_hasShrinkwrap":false},"0.0.5":{"name":"@flowforge/file-server","version":"0.0.5","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","redis":"^4.5.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"68e103818c01de3f3203530414ca8f8a595d80db","_id":"@flowforge/file-server@0.0.5","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-tizhKxsMLLYwr57x7Xb0Txj3bFcfraxZqGOJ16MLoVXc7w5Oa+gYrDZO8kGoTk1k5y2NF6ZbPCilFQ1utTHJRQ==","shasum":"e4f12a9a57e70d33f6c416e77611d18c55d343e0","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-0.0.5.tgz","fileCount":21,"unpackedSize":70868,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDNlDEOl4Auoh1R0a25tYj8l/0V5j/B0+k30Ie5DJFNcAIgK5k+9keXiTxQNtUH7VVuEPTtoJ/zpiDmnpyubZpjJFw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjnvviACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrR6g/+M6yOxQjurXBJRYuwqSKJllH3HUeJnJWbyjFf6fPVsfhky0Ll\r\nrAhDuPFfNXbiz6RFGKjJhYcvito4VaYsDEhvxWfyXql2FsUQoc6Gpmi9UvXl\r\n+yJdMfW8OuJIvxGnTHhTODQZSZNTqzaMlKa0HTcirVpVjwx4QXcD+zz1lATh\r\nMMtdeNrVY30Vc0B7ldM8vWPDtal1EILdflLcwTRwLr+i7wU5pT9NrObz4osK\r\nofS+BtMW7qVLabgofjnS+UnJexaJuDjgmdLXZv4Hj8XOCCaAoAnjIboL+vzm\r\npIbo9HS5Ssk/um5Hx7hYCI/myix1z81xnHhTFpFmV3BoyLOx4Pd7ESRcZu6v\r\nhXKTI4f/mITGuJWfL2CPt7+PXdFoLM1FPdMqg0UIpf47qMVS7qCzfgxUcO9c\r\nJ7AhmJCHqi1dNBu1Wh32HEEPB9DJ/0HN/LYf4h9I3BmwnHoweayF/Mme2e+3\r\nNu5aoarROMcZBcnuWk64HaDMEqRnpp89sUD1GJRDkGBDHILXefMdku5zVtmd\r\nLPpfRovN0mqVZy6Io8/D3MpFjXvl+paaqVHN7OQOvUbh8FRP5sosbHO7rg4F\r\nBMXf1RCsASdW3or9sykzLTWb+LIQYzUPbuexJd/XAgFVr1zfO8hojcYOV434\r\nxc+2Gk7zy8xkj8+kNfT1lBbUlSGNEvHzAi8=\r\n=1p9+\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_0.0.5_1671363554640_0.3622920072292848"},"_hasShrinkwrap":false},"1.2.0":{"name":"@flowforge/file-server","version":"1.2.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","redis":"^4.5.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"0a6470e451f4aa3bed0e436c63e1ffaa4d75e5c0","_id":"@flowforge/file-server@1.2.0","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-K/FNlWZD3wOHEwI867eaPrIz3Vl2A4a5x6GMVNNQP1m8jLJ5DJ3JcqMTGZSrBno3q06cfbUqatRWyC8kvGqqRw==","shasum":"0821c2b4ff31d0673b7a4a1d6f8688b5cd47546a","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.2.0.tgz","fileCount":22,"unpackedSize":71186,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICetx0d8jO7Z1MvJm716f37ReOh/nyUY5GAW8EQCgjkgAiA5Ay6C30xtTH25nKLmKEhn1SJ0yljKg7jfbEUU+HOstw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjpENSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrnRxAAgji8eH24hjWGYtYHzK5dPnmUy3EAup+7U7r9cQ21rGv+s5m1\r\nwpcHeVrMZQlONwPdn/+qIaXkz4Tj1d4Cb5/C4oZRK8110nE9dlUWEURksEI1\r\nABBRPyB0OB9xKUWx7OAbPT9M4XnY803JCL4/VHy7PzI1DfZt2Ha7iZYk59+L\r\natTowBeLka94KGa54c05HXZSxmn5UZhNdwMc6QW4hpe6j3pPrhz3aRIOzigF\r\nWMw7L2DgufiBcZ+sn1DEMQm3mc4qp8WgfIU3OlkZyLVreopivpy64XhGtUiU\r\n9NNx7KbqsvBzwT96ZOuL7gi52ScHZbfRwEIG0apA6+HjlEWFiXNbHzkbndU0\r\nVS5K97tyskheKr9Xsj6n/taQiczpSJCG+S13VlSCDNQR7LD/tDQXQdRAp02k\r\noP7qZtm5UX2HZ4d20TQamQIorZ/Q12sFmb0C1iXQGB3b6wCJe1MPMJsLha7F\r\nFO0EUV9gugjrZyDrh7r0qXlZeBY2hqhJ3GELCLvZ8+qiEMPqJRlNt+lg46nu\r\nY8XVhal+zSzQUH4dBLKgrjT80uISRkvg+Tc3jXCrhSdjRxKVbUrOTY8aeqC0\r\n6K4hL2orGAFXSIz1l1cjiodc1EPP39Kr6i2o6530MAzFBh27KGlHMtusalEb\r\nVja9k7jie4nuPpzjcgONI7D/fgvgjmNxTyk=\r\n=ptz5\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.2.0_1671709522625_0.18189767058441242"},"_hasShrinkwrap":false},"1.3.0":{"name":"@flowforge/file-server","version":"1.3.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","redis":"^4.5.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"0c908b9062b089137eac5a8a6ca8d2e52a4b9abf","_id":"@flowforge/file-server@1.3.0","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-CBgdqCKVdYhx9IgiJs0LnZFXf8DHwLJM6qV49rAODSnmSFj9W7wB4vwTUD+rrn0NO/D8f/zo8qV6xWKDtH5NcQ==","shasum":"67923213b3f1dd8df19a9f7cd0888228309b0a80","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.3.0.tgz","fileCount":22,"unpackedSize":71208,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCAk63hs/B/yJhI77MiOJ03+QoY/AV15SDsEeF3R5irVwIgV2g/iMqz708HB2/dqgTjTYwOzcYKwV31AQ1XD5tCtf8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjyRt/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmroZw//QNVRxs4BgHOg9cPsMB4tVb4Xw4/BRxyLskfpIhmw80iAZj0Y\r\nCgwKv8WB2b+nGNib0JlW3UP76/iCiPd9ksus1hxoxdI82rchNDEXARYnDC+U\r\nZfqVYvj2WaaQX73K77foVVOp6oYPCyoyfx9fqRQ9LGqIOOKIaET2pBmUb2xF\r\nbNDELsJq/oZrFvVsC8K5UDHKgvzaWOwEO0pr+/JOAKstqdher7LXNp9sCLm6\r\nd6YeYQdfOKurjs0h/TsLpihZjkep5N0YaAxc/J6tnUPjfUYTrgyW8VIN01Ib\r\n/N5D1Ipxt3FcKLuVcGXa+Xi4Ug20DueRwV5J96pmqaP2wGUl+C7v7YNL6xdO\r\nq77H3r8tZyVhG0Mdz3wVjhlbnVI6LEgKi7O4cI46Nlv8UWcxHsBInv0NuWdp\r\nTF5Fpbonxga5CkMYf2f80DJ/jxto+1OZdJhfcuJU9/DfgrPsR+LqXDf1gvtt\r\nTlMfY1AhAsMiXepMe17Id80BsTpaLm0IlEpxXOT2pSzJLkt3qg2NK7o0Nvbn\r\nIr5pvMGncvO4GfPNq98kbJjOX2keUEpMPaowW7Dz28kh4I3VxAGSSpEY7RVL\r\ntoN9CHa5ylcsHLy+YKc2eW2VoSc0pw0Y6CL8sYEPfRjxQCYeNiMSpMytOMY7\r\n59nMnn3mK0RL1S92+csudeVYFKI8vGUjs6Q=\r\n=2XrP\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.3.0_1674124159209_0.15532975254024994"},"_hasShrinkwrap":false},"1.4.0":{"name":"@flowforge/file-server","version":"1.4.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"80e78daa41e3fe9bbf52e145e945d76a45a8c548","_id":"@flowforge/file-server@1.4.0","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-I4VMTDKQ8HpBMkQNWYZA4oPLebIV5gyFbVA9ZprC8TyeUquOt6BfsDwEj7Rc/e6rKCbHJTfHZCwhKD1z6wgQfA==","shasum":"d8706183be8f453a9555fe50c58843a827927cdc","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.4.0.tgz","fileCount":20,"unpackedSize":66851,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD8sTWqCQ+uhVhL9czaFY1/SkZOhhU6fdQDj8SMVSaC0QIgRq3+BLVA6073c7B3iC83tvXGOHetUSU9tMs6n9InVJE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj7ftnACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpDIBAAgNuFXBjH2yYTovO9Tu+PnOEmnW9Al3ysg378/l2+Ms1kUKGq\r\nJOwSR1mkrF3O7CJ1lnGgotGnVhf6JGapF2U0/7EJ4hrjaXRdr/a9Y4+OzFln\r\nSqlWf9YOiPdbfCCZYPTogaYCx3++pQeQRIfAb8pkbadhVyd8yzH2KAQe2weU\r\nAvyj+oG+yerddu8vHcFfaiLYkvNpNjXX9MKDYJEumQQNIY9P3vFZYmQgCMD1\r\n2NdvEC5VrOPFmtgN/h3S+xj1/Q6Dm673pNq8b4kXkBa90C77HI1LUItFsxI6\r\nGbU2jKJwD1NGJaDYOne6i8MDClWFpJOtt1vzpL8OInshP5zKWgmBiwftFNpa\r\nVd096ZV39t40NOvpt3N+h6Pt9SBlToP1jmRR8qhj7BtXwugAp0K2HHMUHmh2\r\n9fGtyN4+ClHzVreeFIPu1+YjLN6Uy5krXD4X/+FGOA6gG3Oi+LfLLyX/3IHj\r\nE4nns2TGqzePpxYqeR2BQ4p1GdxX/F8OqfRoZxzNFRRH7eft3S1JjpaTvD4O\r\n9X7W0qTW8pGIaxRRfvSaCDPOdlhRst4qTaoo4+JpCeHjzUegJjcMK2nWL1LD\r\nE6ejQg4ddWHwpikLAfDM6KFbzJ3tcdjbYaTIdPI/Dfa+6zoyjHrQNqYSNOwt\r\n2qXW9hmyqs5jMZLKRffmImKegm0sRZAekUA=\r\n=j5Of\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.4.0_1676540775674_0.924153436762652"},"_hasShrinkwrap":false},"1.5.0":{"name":"@flowforge/file-server","version":"1.5.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"5c5435088c51b0205b847aa0231a9aca63b5ff6a","_id":"@flowforge/file-server@1.5.0","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-lM4mj4NbkvBZtObrQ7J5pZxDjdX2lK0ZeSVGnW3He1ZidPFqQmF7vhbkRCo/wgG1KkMLJGPlk40JiIl9MslYFQ==","shasum":"a19d4f5e529e11331d0b6d2386207dcc79dba7d5","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.5.0.tgz","fileCount":20,"unpackedSize":66873,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEWmi4ta5gGw0tGhqLBgr6YwPeZjo9XYQnCYu/Me81PMAiA6HSGv+esjcyEEj9kUmMtBNqG9XgbmzJpDanLAQwOsxg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkEu3iACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr3GBAAioX/y+nfK4uAVyuB3ca87z4LooP/4vxzTxQvhcn1oY4ZT6kS\r\njm5SOmeGjbk8kvh6QoarZq8VvUzao2aUG9JInngtEKAw+nBX33543wjdXcGg\r\nria+Yv/fKaiRQf/cHJ4ZPYejllcemyuw9ZIGSwznaTVbZKKN05YbxSgJD7PK\r\nV9tO5obRiBmpMM/E3TpaXlFw0iqPR99gw9ujaH6FP8eivSgW4iG8/1B2K/xS\r\nh7TzCIyk0CUFE9bV1hmrExn9VMmBp870nZguJcja1rifSDa7jqW2QI5Bwsb6\r\nL5BCJhHt2Pov9P36UCYbfLm2K9Mxm3bnNwqHTZbnPs+MIoH30+urxJt6tXaB\r\nKK0oV5sHt3jNDeS8t3CPft4+9f1Jxhq53bszAO/u6V07QAfa15clFEYlt+IE\r\nvU6nhH3ccH2lp5IeA4vHHMr6Q0u1Ldx9tpcQdhxVt9zDFVQ6WnrUUWBV/J2+\r\nSoNr3ifQziyFnZm5I16X79hCkPjmHbZi7dgy9TlqdaQgaTAn9aqUvMWkHUjb\r\nMizzndatZNbP1p2PTo/J4i2MOSHXgzRcLVpG+YreewQg9ADyg9klLScuazcs\r\nVvdrt9YhVaTOJ/e8fGharHd+NvNRC1eINU8DSjmcqKRhFhPIxQST2mE1nhSz\r\ngiFQn97K5HPzICNAbPxn+7ZbRPxLnXx6ll4=\r\n=Do6A\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.5.0_1678962145897_0.5915006601181803"},"_hasShrinkwrap":false},"1.6.0":{"name":"@flowforge/file-server","version":"1.6.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"bf334c7ade97b57aefd6b3c58b19bb4f204233d8","_id":"@flowforge/file-server@1.6.0","_nodeVersion":"16.20.0","_npmVersion":"8.19.4","dist":{"integrity":"sha512-FM0yHwnPuzs43c50+Epc4PXOhinOwHCWc+eZCVTQ9zabioTlz36XiFQaV4NReWrougQXXPIwLvHuksBwe7xJuw==","shasum":"2558620dc21f70f87e87b98f5d739dd506d7a8fc","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.6.0.tgz","fileCount":20,"unpackedSize":66895,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG/XEhOVrq+t3dQ6jCaJ7eIEvcLNMcmuU5hLEnd8wljfAiEAgNF/1shRpk7Sfclu+7TzpjbPyviPC/dTvD9Pwu8BBIk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkN94bACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo34Q/+J+21D3Kq7elU4EXFKbemSki+A37P7jYqHZ3inBA/E9anATww\r\nzaGTSyc/vhyzeYk8IrFitnFxscCIGWw5R7q5wwSesAeSI8o+mv4IpjdH2TXc\r\n2/M8q0mDQ2RSKlZ4Xr45GWNvpamHzqpEW51MrZk8w8Br4EvlNloahozmtJKO\r\nuu+ZNlXRH+A9YdpD31sGEgoMjVqHw+z/qg/2AWDlT12hKBywj+B6JI+d9eYZ\r\nAmLs7Bp2peGILsydoOtYM4fVjACCQJzVz19gqEL7YEvud9gyF3VPfPE2xP4i\r\n9uo2PQ8x6A6yNPK2400jcIODL1PEYaRL6irMLDRFfHFaqsirja+eHOEIkQgF\r\nzCAyCfjqUKLn826AxKvveBOCAXO0piXIZXRcrgO/Rel/Su5qnotdh1WpufRI\r\ns099nEdRQcSjwBjmo/f0/rto8zuXvV+UsxzivYLRfVG43XkMB0Hp8OIhlu6z\r\n85nE9RJUPTjdEszOwDBfZJh9hQWM9CzXF8g0XCn1BBK7XAy86YRavRgHpLn0\r\nyzJMyJrzjQRRfFCLT0vs9UpFhC2TS7EpdftooC5pAZSHSWAK5NrmA+JGWbdb\r\nmA18GNoyg9c/8TJrMRaQWatIGupe7tMXDus3Nt2uUm6/zEfbMxcrCRO8Fw+A\r\nETDLOsPom+aXbhnpQdfq7QKlhtIsIrMTXIc=\r\n=ab9i\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.6.0_1681382938834_0.879672334576374"},"_hasShrinkwrap":false},"1.7.0":{"name":"@flowforge/file-server","version":"1.7.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"bcc8fc81f39f20b16f182ad9ef6e3796e5daa5c0","_id":"@flowforge/file-server@1.7.0","_nodeVersion":"16.20.0","_npmVersion":"8.19.4","dist":{"integrity":"sha512-Meu3y42E3Oa3s9QN/fGeYnZSMyitsNAN/ZeNdsuT1VzInIEhiFxzDCLB44/+mtQw9XdCbPCfcq7L5EMQa6kvRA==","shasum":"20d0fee355e8f126d87d8d65e8b76ecbfb3d3b8c","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.7.0.tgz","fileCount":20,"unpackedSize":66917,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDfqAP8QTPtrFlW8LnonRV+rznZjpjnMwtneYHblYb36AiA0JKTgv3g47bOjuehsP8Sh8kvWupE/qfq5fXX4L40zdQ=="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.7.0_1683797495135_0.8867040647423066"},"_hasShrinkwrap":false},"1.8.0":{"name":"@flowforge/file-server","version":"1.8.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"e6ef8ec2a30b06fda1e072f3c9463882002289f5","_id":"@flowforge/file-server@1.8.0","_nodeVersion":"16.20.0","_npmVersion":"8.19.4","dist":{"integrity":"sha512-bPuqsG9HGCjPJyRzE94M+uuNyb825mU2NMu8wlAMLkJEEQt7muUB5EXLbZbSVfyQ4FT64uzuRVr6mbVLrDjXuQ==","shasum":"0fc81f01e364683cf37045b46144b584599669e9","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.8.0.tgz","fileCount":20,"unpackedSize":66935,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFA3Bsn9g3GDpwHVJ3GpHiPQcUjHX/pMEAzh47wtanIJAiAacDksK01lBRI4BOti3iq6hq32YMhTY7Wf8PEzx9k1qA=="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.8.0_1686216058812_0.19501843532397967"},"_hasShrinkwrap":false},"1.9.0":{"name":"@flowforge/file-server","version":"1.9.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"b45ff91cbc6c7b19ab3aac3a629c6e3e06583eba","_id":"@flowforge/file-server@1.9.0","_nodeVersion":"16.20.1","_npmVersion":"8.19.4","dist":{"integrity":"sha512-sSMKLDon5w4jm5DBgXYE7s1WfYz+YoOL/0oGSFozZ57vV1iQ8KYdQCtSvnQ9G8Ua7RdRIR0DNt+wQ/XjLbn5yg==","shasum":"6983a85ea9ead245cb60e3b382a539ccd9e7e460","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.9.0.tgz","fileCount":20,"unpackedSize":66995,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkDcDJr3bVgax6yQZREVluuY6qUgQqaVtlgMd2rClABAIgCRt2qRUD8HT+xgnqpQvfuUWDiluuwm6gQ3+fEGgsYj4="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.9.0_1688630114109_0.7033891745387761"},"_hasShrinkwrap":false},"1.10.0":{"name":"@flowforge/file-server","version":"1.10.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","docs":"jsdoc -c ./config/jsdoc.json","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.204.0","@fastify/helmet":"^10.0.2","@node-red/util":"^3.0.2","fastify":"^4.9.2","fastify-plugin":"^4.3.0","got":"^11.8.2","pg":"^8.7.3","pino-pretty":"^9.1.1","semver":"^7.3.8","sequelize":"^6.25.3","sqlite3":"^5.1.2","yaml":"^2.1.3"},"devDependencies":{"clean-jsdoc-theme":"^3.3.1","cross-env":"^7.0.3","eslint":"^8.26.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^2.0.20","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"b73105142d661803f33ac6c87d04ab499f0f1966","_id":"@flowforge/file-server@1.10.0","_nodeVersion":"16.20.1","_npmVersion":"8.19.4","dist":{"integrity":"sha512-HZm0Yns2RMo8KWrJwbG21JA9DFH1kny7UXgtDj0DTeO/FOpeXKHL/Gqj9XxPyLAdZ2M7W/LsZSjigDvtT21Ong==","shasum":"9bb88de8e50b6be81884fcc7b604a39b2675fc63","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.10.0.tgz","fileCount":20,"unpackedSize":67066,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCHmL1AXCtx+p+m7gU1kK8AengvbbpY5JO0esyvpOQwGAIgbo3Gmhr2mOa9wuulygGBhU9WFqjrZwFFqDl5GcwIdXE="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.10.0_1691051589414_0.2594398294447444"},"_hasShrinkwrap":false},"1.11.0":{"name":"@flowforge/file-server","version":"1.11.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.0.2","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.25.3","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.0.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"f3731aec268b5d2a293508a1f107c550348301a0","_id":"@flowforge/file-server@1.11.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-mONk6QPc+2uab1e+GJ4ah+YH5JSQEKbTc9t9ZZXCynHUw6zGYIJvPEFfsy7mJwF/vN4ESzN77d8KRnaxShBK8w==","shasum":"b38e9955923546945b86f8c7fca331f8ce4f5a1b","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.11.0.tgz","fileCount":20,"unpackedSize":68261,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBa4ZN5830f9/8xYXNdlFDiWvmVSgLC3whqlsyKLGph3AiA91N2r6DvkG50ciff6CsRfx62arIqonBXog+14mn3xKg=="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.11.0_1693478553517_0.5674987867755972"},"_hasShrinkwrap":false},"1.11.1-24c665d-202309181207.0":{"name":"@flowforge/file-server","version":"1.11.1-24c665d-202309181207.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowForge\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowForge platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"24c665dd64562871193c70433500fe2f39bb16bb","_id":"@flowforge/file-server@1.11.1-24c665d-202309181207.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-PVKeoG5Thz01yf46HEl9HjEEh0tDhfVGdof4w3MsYlWAe3/5H8W0IxGBEGRArBuIsrPNnnp7YodC79DAacsJAA==","shasum":"bd5ed83349de8d5c6bda5fd4c77a8f8c1c0a141f","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.11.1-24c665d-202309181207.0.tgz","fileCount":20,"unpackedSize":68284,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFuixiBTFUj2oVhPc4JEzTSyERI/5nyYQ2v712fmb62uAiAENoVOJrZPlNIjvnlFTbma4ri5CGrwaoMcNlstSMek7A=="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.11.1-24c665d-202309181207.0_1695038881333_0.5062036908191694"},"_hasShrinkwrap":false},"1.12.0":{"name":"@flowforge/file-server","version":"1.12.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"b80403d6827b9bde7cea08a97bff2ac30d308cdd","_id":"@flowforge/file-server@1.12.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-QWZeRAJNMqRJzMFmEEG+ARgILoWkpcEGut9fMBYwIdZ1tdfodMSpXLW/IADiVPzl6HGT9VescQhDRygbnuAaWw==","shasum":"be6235662eadbb93d36961b697916bc42996a5ab","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.0.tgz","fileCount":20,"unpackedSize":68540,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAENtynQqNQMgKhJKjNngrysxKatLMKHVoYRKnJwkgLOAiA+tz3rc6gr2EF8l+0pUd/PihodDXlGxe1i5/wMpc+y3Q=="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.0_1695898779574_0.6741187255802308"},"_hasShrinkwrap":false},"1.12.1-b80403d-202309281059.0":{"name":"@flowforge/file-server","version":"1.12.1-b80403d-202309281059.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowForge\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowForge platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"b80403d6827b9bde7cea08a97bff2ac30d308cdd","_id":"@flowforge/file-server@1.12.1-b80403d-202309281059.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-SLz2cVzAYU3PelEVMrCBfhtsGx+tZuBLnNj2Bdg/m8Qwz9S/k+Lq6LOPjBVUsBHM7DC/npRrpUlOI1Dtgxdvng==","shasum":"acbab2066b709afa7a33547c77d58a1d1a8959a7","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-b80403d-202309281059.0.tgz","fileCount":20,"unpackedSize":68563,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDFnDcVYheg+AQ1JnlSFYDYT189SK0Au1UCDlrfgY704gIhAL+WhLPmEsWF1ovldNPKJbxOpBF7rEYjJ7VkQHproeLO"}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-b80403d-202309281059.0_1695898781833_0.5558390464647471"},"_hasShrinkwrap":false},"1.12.1-f23874e-202309281543.0":{"name":"@flowforge/file-server","version":"1.12.1-f23874e-202309281543.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/flowforge/flowforge-file-server.git"},"author":{"name":"FlowForge Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/flowforge/flowforge-file-server/issues"},"homepage":"https://github.com/flowforge/flowforge-file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowForge\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowForge platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"f23874e9a50685159718a5825d117aad9fd68d90","_id":"@flowforge/file-server@1.12.1-f23874e-202309281543.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-53D30kmLpvQeaDra7HlVk5JTobQJzbyu73iQtwXAQn0XywJvGo8On0AnolgngzWOri5ZjIe2GPAdU5m1QpAZ9Q==","shasum":"071aa7a8aa8a426d3cddc386b77cd742ddd5452f","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-f23874e-202309281543.0.tgz","fileCount":20,"unpackedSize":68563,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC7efZ68BoGzpYvKVrH2Q4UF/10b9NDho9j0hKMoWcM2AIhAMyT3geFE8K0SA1+D+QcnmqTB6ucwj7DUo7tHFfCIm8Y"}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-f23874e-202309281543.0_1695915800391_0.6988950534466476"},"_hasShrinkwrap":false},"1.12.1-af42875-202309291538.0":{"name":"@flowforge/file-server","version":"1.12.1-af42875-202309291538.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"af42875a1856243b370eff07eefffa4581c3043a","_id":"@flowforge/file-server@1.12.1-af42875-202309291538.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-m5/Jpl/6uWSAe8QuGVB96WzxtGtkXAH4vFloTHuzhtTHUdXEN2EObQhYwsULPdJQoiSqt77ALv+q5h7ZwYLD+Q==","shasum":"f0233d47ef532cc1c8ef1356f05c84d13118631b","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-af42875-202309291538.0.tgz","fileCount":20,"unpackedSize":68527,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZEhRBQxX1DR6v0JNEMlhsfrfQKqaBivCL5IwMGXceSAIhAPN0qxFufFUFQMZ4q/RCVAdOAdeMiZ0DWdYRHQK3os89"}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-af42875-202309291538.0_1696001930917_0.27911314535973886"},"_hasShrinkwrap":false},"1.12.1-5cc1293-202310031604.0":{"name":"@flowforge/file-server","version":"1.12.1-5cc1293-202310031604.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"5cc12936a4485ecaef8b438c9fc22f48d8d39c96","_id":"@flowforge/file-server@1.12.1-5cc1293-202310031604.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-PsewI+54LcAtxxa6mFA2E+wP3k4cUEfW8qWAUbpLWZL7c5YVn/di1CUnQnkW2jhMEY+aTMajTh2ulfabuWZ/RA==","shasum":"f29c580502175f5620900c56d81c78009b965f11","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-5cc1293-202310031604.0.tgz","fileCount":20,"unpackedSize":72516,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiDOZsySQlh1t5n+OYlDAGowouzV2cmad8FuUpmbclUwIhAL8fRMzyARlpIrJxeVMjA2MUMDJJyH3rjX9HbjlU/0V8"}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-5cc1293-202310031604.0_1696349061362_0.2649322042460398"},"_hasShrinkwrap":false},"1.12.1-5cf07d6-202310031622.0":{"name":"@flowforge/file-server","version":"1.12.1-5cf07d6-202310031622.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"5cf07d6f0b5b595e6e709b29ba002ba56746df4d","_id":"@flowforge/file-server@1.12.1-5cf07d6-202310031622.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-R9O5MJOeVFKwWRSQaqxiNpWEyf1HHPnoSowEsXjXWG7UNSA51g8/AIgj+lNvftWOHqpkJwbas42pbYAM7wlZ+w==","shasum":"1dd4539b6c178f4dba3f3aa2bcb47304eefc2c56","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-5cf07d6-202310031622.0.tgz","fileCount":20,"unpackedSize":69443,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDTk4tPcmftbPQ4gGwl9d8aB3vDrgLiVl6pWHyl270/8AiEA8+ih0le0k0UmswWvIQ2RWMONbi4VosxLjpHTsicDLCY="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-5cf07d6-202310031622.0_1696350166376_0.87113254117219"},"_hasShrinkwrap":false},"1.12.1-27fd676-202310061133.0":{"name":"@flowforge/file-server","version":"1.12.1-27fd676-202310061133.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"27fd6761e7c686ef222d96b64b915b6c84bd2065","_id":"@flowforge/file-server@1.12.1-27fd676-202310061133.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-zqIHU1tAS/UA1ECpHha5sK5v0EW1wZ6cTVYoRQi9EbS8+eTTTOdaby6+lbvjNuWDqhNQllVwgVdUr5hwIRdghw==","shasum":"d3d77b182d4db24b3fba14d92a52ef3df2220641","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-27fd676-202310061133.0.tgz","fileCount":20,"unpackedSize":69440,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCRy/EB6RdTOgZaE5gD2f46IlWLtIrKeut8y7kOcUltsAIgY9fc6Wfiu9wONr2sKfqjeoOFNX2dATiHBBOXFYTaHsU="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-27fd676-202310061133.0_1696592034390_0.31590371500082837"},"_hasShrinkwrap":false},"1.12.1-ffc5162-202310181334.0":{"name":"@flowforge/file-server","version":"1.12.1-ffc5162-202310181334.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-metrics":"^10.3.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\ntelemetry:\n  backend:\n    prometheus:\n      enabled: true\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n- telemetry\n    - backend\n         - prometheus\n             - enabled - turns on the `/metrics` endpoint to track resource usage\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"ffc51629d750dc10230f065adc78589bef44bc33","_id":"@flowforge/file-server@1.12.1-ffc5162-202310181334.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-hmzh4sYIjymx4pbaZ/UqiTVWVL/65hIVfYz2htMC/TZ7WIvEXMu7nRczGVf1g7OtsawjwXqeyvy0w7ziYgc0yw==","shasum":"f8bd959b693e301f1e79ff270980883bc2686a33","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-ffc5162-202310181334.0.tgz","fileCount":20,"unpackedSize":70003,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFlnctiNsOIW4XiavTM8BLJi1topw9PZFRN6TT5KKNAUAiADlgcPZKAMVs/i3t6wx6jfaEWhtcYsSBoe4BRNHZYVqA=="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-ffc5162-202310181334.0_1697636094477_0.6690559480929033"},"_hasShrinkwrap":false},"1.12.1-41d1295-202310200835.0":{"name":"@flowforge/file-server","version":"1.12.1-41d1295-202310200835.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-metrics":"^10.3.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\ntelemetry:\n  backend:\n    prometheus:\n      enabled: true\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n- telemetry\n    - backend\n         - prometheus\n             - enabled - turns on the `/metrics` endpoint to track resource usage\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"41d129533e396324bfd036747c3f98575ba3cdc9","_id":"@flowforge/file-server@1.12.1-41d1295-202310200835.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-qL1xnX0W7AjxSv3evEy1rgyo13wTOUz2VgmXHnUqJ7mpAMkvAmoZaxwrizUmvgTKjIqgfH6vto3P2ICsZOW4ig==","shasum":"9d6d49f84a83c3e0fe6b95c42ca0e8e50477b541","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-41d1295-202310200835.0.tgz","fileCount":20,"unpackedSize":70531,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC5CiW1pmsjEjG1mNrQeNaht3LeLW7qjoQG1jl4Fsc8CgIgZ3tKJA1+gxNRgfl2VajY6XWE29OuyCmzq8uAoXA0v5o="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-41d1295-202310200835.0_1697790906658_0.19522421724747296"},"_hasShrinkwrap":false},"1.12.1-b844c4a-202310250909.0":{"name":"@flowforge/file-server","version":"1.12.1-b844c4a-202310250909.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-metrics":"^10.3.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\ntelemetry:\n  backend:\n    prometheus:\n      enabled: true\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n- telemetry\n    - backend\n         - prometheus\n             - enabled - turns on the `/metrics` endpoint to track resource usage\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"b844c4a145022f6a2e122b7f22ec52eb9c5a6f04","_id":"@flowforge/file-server@1.12.1-b844c4a-202310250909.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-0g/YQmqcpP4y3C+uGA2wQswEG7u7C1Dj99WjPcgdbfjuf1EfcPmLRlfgBdxSt4jMEB8Q9Teoj8f7UQmkvA43cQ==","shasum":"f1e98f121eb823fd2df3b03b52b35cbdc00fb5e6","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.12.1-b844c4a-202310250909.0.tgz","fileCount":20,"unpackedSize":70531,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEKWbm3K6yU0GpwgNFHRiuHVlySDfmI+49i4R1adyNohAiEA2YO44ye4n+9LZPJSBrRZmUnYU8Tt/L5ImiPe8rJCdjU="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.12.1-b844c4a-202310250909.0_1698224972554_0.2964917336407398"},"_hasShrinkwrap":false},"1.13.0":{"name":"@flowforge/file-server","version":"1.13.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-metrics":"^10.3.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"9e382026a4bae2a05d58cac006872a0c7363bb46","_id":"@flowforge/file-server@1.13.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-qgTmA2WeCvoneBdbSJTB6oaUeKC38jgMP9+4Om5vLdd3mDV8qMZdkMx11zYvPWdPKVUac0OSMLCXhL4mUbPb1w==","shasum":"a4a6679cbd6be8ba46868b494f8154ef11bdc883","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.13.0.tgz","fileCount":20,"unpackedSize":71024,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCzQpN2yWPIlPPEAkj/5sDco0WiVj1VSeziiosqHEk70QIgMI9yfDCAarovVOR78guHpDJddgXterC8kzXb9sOgLgs="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.13.0_1698312862028_0.46068643487099714"},"_hasShrinkwrap":false},"1.13.1-9e38202-202310260934.0":{"name":"@flowforge/file-server","version":"1.13.1-9e38202-202310260934.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-metrics":"^10.3.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\ntelemetry:\n  backend:\n    prometheus:\n      enabled: true\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n- telemetry\n    - backend\n         - prometheus\n             - enabled - turns on the `/metrics` endpoint to track resource usage\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"9e382026a4bae2a05d58cac006872a0c7363bb46","_id":"@flowforge/file-server@1.13.1-9e38202-202310260934.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-wcBYJt0YwzBRSKvgsnYM1JSn69zYYhv/gEg/rPMpCo5UplwgUouaXBChMFw/uczD7UiyuHuZIj0SZA3n0qZjuA==","shasum":"9fc6063494219645ee0d6ed838d70e9ee9742324","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.13.1-9e38202-202310260934.0.tgz","fileCount":20,"unpackedSize":71047,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID7gtySW6VnOOf+1yLzhNSAGXFS7eeyjFsuFsEV1Kx9+AiEAqBYteEdYxTVAeVPA1/2uryZJ9mxxtSr2nk2AIWpoaus="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.13.1-9e38202-202310260934.0_1698312884407_0.5282654517846144"},"_hasShrinkwrap":false},"1.14.0":{"name":"@flowforge/file-server","version":"1.14.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-metrics":"^10.3.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"gitHead":"d7a56e20caa69249194c52e7a028fd3494b011d0","_id":"@flowforge/file-server@1.14.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-HNmgaUSLXLQqZ1ZBPGKc98Li76kIREGHAaDjDfnCmRqTjUb1jQ5gAyEwIosZSv8ViF13rdT0lJpJiGPmsFsXZg==","shasum":"0fc2dd7f8a6e004fc0887c0b413c971f7421958c","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.14.0.tgz","fileCount":20,"unpackedSize":71047,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDiAcAHugXCVHVFdOGY74tVNvAzRnnjy1cm+0yMQ8V3AAIgbK9WqZN450tYFKK0zHY0nnhGC/y+PUEKpoOeQOPLCAk="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.14.0_1700739761289_0.5444349463250258"},"_hasShrinkwrap":false},"1.14.1-d7a56e2-202311231143.0":{"name":"@flowforge/file-server","version":"1.14.1-d7a56e2-202311231143.0","description":"A basic Object Storage backend","main":"index.js","scripts":{"start":"node index.js","serve":"cross-env NODE_ENV=development nodemon -w forge index.js","lint":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js","lint:fix":"eslint -c .eslintrc \"forge/**/*.js\" \"test/**/*.js\" index.js --fix","test":"mocha test/unit/**/*_spec.js --timeout 5000","test:nopg":"cross-env TEST_POSTGRES=false mocha test/unit/**/*_spec.js --timeout 5000"},"bin":{"ff-file-storage":"index.js"},"keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"license":"Apache-2.0","bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"homepage":"https://github.com/FlowFuse/file-server#readme","dependencies":{"@aws-sdk/client-s3":"^3.388.0","@fastify/helmet":"^11.0.0","@node-red/util":"^3.1.0","fastify":"^4.21.0","fastify-metrics":"^10.3.0","fastify-plugin":"^4.5.1","got":"^11.8.6","pg":"^8.11.2","pino":"^8.15.1","pino-pretty":"^10.2.0","semver":"^7.5.4","sequelize":"^6.33.0","sqlite3":"^5.1.6","yaml":"^2.1.3"},"devDependencies":{"cross-env":"^7.0.3","eslint":"^8.47.0","eslint-config-standard":"^17.1.0","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-promise":"^6.1.1","mocha":"^10.1.0","mocha-cli":"^1.0.1","nodemon":"^3.0.1","should":"^13.2.3"},"engines":{"node":">=16.x"},"readme":"# A Basic Object Store for use with FlowFuse\n\n## Authorisation\n\nAll requests should include a `Authorization` header with a Bearer token assigned by the FlowFuse platform to identify\n## End Points\n\n### File Storage\n\n- Create/Replace\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Append\n\n    **POST** */v1/files/:teamId/:projectId/[path and filename]*\n\n    With Header `FF_MODE: append`\n\n    Content-Type: application/octet-stream\n- Read File\n\n    **GET** */v1/files/:teamId/:projectId/[path and filename]*\n\n    Content-Type: application/octet-stream\n\n- Delete File\n\n    **DELETE** */v1/files/:teamId/:projectId/[path and filename]*\n\n- Check team quota usage\n\n    **GET** */v1/quota/:teamId*\n\n    Content-Type: application/json\n\n### Context Store\n\n- Set stored values\n\n    **POST** */v1/context/:projectId/:scope*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 },\n    ]\n    ```\n\n- Get stored values\n\n    **GET** */v1/context/:projectId/:scope?key=x[&key=y.y]*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        { \"key\": \"x\", \"value\": { \"foo\": \"bar\" } },\n        { \"key\": \"y.y\", \"value\": 100 }\n    ]\n    ```\n\n- Get keys for a scope\n\n    **GET** */v1/context/:projectId/:scope/keys*\n\n    Content-Type: application/json\n\n    Response:\n    ```json\n    [\n        \"x\",\n        \"y\"\n    ]\n    ```\n\n- Delete scope\n\n    **DELETE** */v1/context/:projectId/:scope*\n\n- Clean unused scopes from the store\n\n    **POST** */v1/context/:projectId/clean*\n\n    Content-Type: application/json\n\n    Body:\n    ```json\n    [\n        \"nodeId\", \"flowId\"\n    ]\n    ```\n\n## Configuration\n\nConfiguration is read from `etc/flowforge-storage.yml`\n\n```yaml\nhost: 0.0.0.0\nport: 3001\nbase_url: http://flowforge:3000\ndriver:\n  type: localfs\n  options:\n    root: var/root\ntelemetry:\n  backend:\n    prometheus:\n      enabled: true\n```\n\n- base_url - Where to reach the core FlowForge platform\n- driver\n    - type - can be `s3`, `localfs` or `memory` (for testing)\n    - options - will vary by driver\n- telemetry\n    - backend\n         - prometheus\n             - enabled - turns on the `/metrics` endpoint to track resource usage\n\n### File Storage\n#### S3\n\nThe following can be any of the options for the S3Client Contructor, see [here](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/s3clientconfig.html)\n\n- options\n    - bucket - name of S3 Bucket (required)\n    - region - AWS Region\n    - endpoint - S3 ObjectStore Endpoint (if not using AWS S3)\n    - forcePathStyle: true/false\n    - credential\n        - accessKeyId - AccountID/Username\n        - secretAccessKey - SecretKey/Password\n\n```yaml\nhost: '0.0.0.0'\nport: 3001\nbase_url: http://forge.default\ndriver:\n  type: s3\n  options:\n    bucket: flowforge-files\n    credentials:\n      accessKeyId: XXXXXXXXXXXXXXXXXXX\n      secretAccessKey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n    forcePathStyle: true\n    region: us-east-1\n```\n\n#### LocalFS\n\n- options\n    - root - path to store team files, relative path will apply to FLOWFORGE_HOME\n\n#### Memory\n\nThis driver is purely to make testing easier, it has no configuration\noptions.\n\n### Context Storage\n\n#### Sequelize\n\nThis driver can use either PostgreSQL or SQLite to hold context values.\n\nTo use with PostgreSQL configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: postgres\n    host: 127.0.0.1\n    port: 5432\n    database: ff-context\n    username: user\n    password: password\n```\n\nTo use with SQLite configure as follows:\n\n```yaml\ncontext:\n  type: sequelize\n  options:\n    type: sqlite\n    storage: ff-context.db\n```\n\nWhere `context.options.storage` is the filename of the SQLite database, by default it will be written to \nthe `var` directory if a fully qualified path is not provided.\n\n### Environment variables\n\n- FLOWFORGE_HOME default `/opt/flowforge-file-storage`\n- PORT overrides value in config file, default 3001\n\n## Development\n\n### Testing\n\n```bash\nnpm run test\n```\n\nNOTE: This will run all tests for all backends and requires a running postgres database\n\nTo prepare postgres for the tests, use the following procedure (tested on Linux and WSL2 ubuntu + docker)...\n\n```bash\ndocker run --rm --name postgres -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=postgres -p 5432:5432 postgres:14\n```\n\n\n### Testing (without postgres)\n\n```\nnpm run test:nopg\n```\n\nAlternatively, you can set env variable TEST_POSTGRES=false\n```\nexport TEST_POSTGRES=false\nnpm run test\n```\n","readmeFilename":"README.md","gitHead":"d7a56e20caa69249194c52e7a028fd3494b011d0","_id":"@flowforge/file-server@1.14.1-d7a56e2-202311231143.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-N6qD3dhED5rPsKPNuK69ud6Wnk2qYZFSBsgWcObmvTBru2cPyhK7k7ZbO0docmCgDvfsQGwsw/tDcMS6EwrQNw==","shasum":"2cc4bb4fdb8f53c4d01fbf7fffb589010f1aa743","tarball":"https://registry.npmjs.org/@flowforge/file-server/-/file-server-1.14.1-d7a56e2-202311231143.0.tgz","fileCount":20,"unpackedSize":71070,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGQ3NoOxuX+eacRnHgRsdgOxnlvknnLIf/MwksuCYtP1AiEAlRSvnY63tuvjDmld+TuAk0jlY12gZUDyCT79WBqpvuI="}]},"_npmUser":{"name":"flowforge","email":"ben@flowforge.com"},"directories":{},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-server_1.14.1-d7a56e2-202311231143.0_1700739795009_0.0636739787606897"},"_hasShrinkwrap":false}},"time":{"created":"2022-11-21T11:44:50.155Z","0.0.1":"2022-11-21T11:44:50.339Z","modified":"2023-11-23T11:43:15.335Z","0.0.3":"2022-11-23T16:14:32.365Z","0.0.4":"2022-12-12T17:20:14.013Z","0.0.5":"2022-12-18T11:39:14.817Z","1.2.0":"2022-12-22T11:45:22.809Z","1.3.0":"2023-01-19T10:29:19.372Z","1.4.0":"2023-02-16T09:46:15.844Z","1.5.0":"2023-03-16T10:22:26.114Z","1.6.0":"2023-04-13T10:48:59.078Z","1.7.0":"2023-05-11T09:31:35.317Z","1.8.0":"2023-06-08T09:20:58.995Z","1.9.0":"2023-07-06T07:55:14.265Z","1.10.0":"2023-08-03T08:33:09.626Z","1.11.0":"2023-08-31T10:42:33.711Z","1.11.1-24c665d-202309181207.0":"2023-09-18T12:08:01.604Z","1.12.0":"2023-09-28T10:59:39.762Z","1.12.1-b80403d-202309281059.0":"2023-09-28T10:59:42.039Z","1.12.1-f23874e-202309281543.0":"2023-09-28T15:43:20.681Z","1.12.1-af42875-202309291538.0":"2023-09-29T15:38:51.124Z","1.12.1-5cc1293-202310031604.0":"2023-10-03T16:04:21.539Z","1.12.1-5cf07d6-202310031622.0":"2023-10-03T16:22:46.584Z","1.12.1-27fd676-202310061133.0":"2023-10-06T11:33:54.611Z","1.12.1-ffc5162-202310181334.0":"2023-10-18T13:34:54.771Z","1.12.1-41d1295-202310200835.0":"2023-10-20T08:35:06.951Z","1.12.1-b844c4a-202310250909.0":"2023-10-25T09:09:32.753Z","1.13.0":"2023-10-26T09:34:22.286Z","1.13.1-9e38202-202310260934.0":"2023-10-26T09:34:44.597Z","1.14.0":"2023-11-23T11:42:41.519Z","1.14.1-d7a56e2-202311231143.0":"2023-11-23T11:43:15.157Z"},"maintainers":[{"name":"flowforge","email":"ben@flowforge.com"}],"description":"A basic Object Storage backend","homepage":"https://github.com/FlowFuse/file-server#readme","keywords":["flowforge","object-store"],"repository":{"type":"git","url":"git+https://github.com/FlowFuse/file-server.git"},"author":{"name":"FlowFuse Inc."},"bugs":{"url":"https://github.com/FlowFuse/file-server/issues"},"license":"Apache-2.0","readme":"","readmeFilename":""}