commit 7f1d3a6e7cb29242e52990c82bb1f94993265cb0 Author: realaravinth Date: Thu Apr 8 19:38:26 2021 +0530 hash and copy diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml new file mode 100644 index 0000000..1eb0a67 --- /dev/null +++ b/.github/workflows/linux.yml @@ -0,0 +1,80 @@ +name: CI (Linux) + +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: + - master + + +jobs: + build_and_test: + strategy: + fail-fast: false + matrix: + version: + - stable + - nightly + + name: ${{ matrix.version }} - x86_64-unknown-linux-gnu + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: ⚡ Cache + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Install ${{ matrix.version }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.version }}-x86_64-unknown-linux-gnu + profile: minimal + override: true + + - name: check build + uses: actions-rs/cargo@v1 + with: + command: check + args: --all --bins --examples --tests + + - name: tests + uses: actions-rs/cargo@v1 + timeout-minutes: 40 + with: + command: test + args: --all --all-features --no-fail-fast + + - name: Generate coverage file + if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request') + uses: actions-rs/tarpaulin@v0.1 + with: + version: '0.15.0' + args: '-t 1200' + + - name: Upload to Codecov + if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request') + uses: codecov/codecov-action@v1 + with: + file: cobertura.xml + + - name: generate documentation + if: matrix.version == 'stable' && (github.repository == 'realaravinth/cache-buster') + uses: actions-rs/cargo@v1 + with: + command: doc + args: --no-deps --workspace --all-features + + - name: Deploy to GitHub Pages + if: matrix.version == 'stable' && (github.repository == 'realaravinth/cache-buster') + uses: JamesIves/github-pages-deploy-action@3.7.1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: gh-pages + FOLDER: target/doc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aec297f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +prod diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..3863fda --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,286 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cache-buster" +version = "0.1.0" +dependencies = [ + "data-encoding", + "derive_builder", + "mime", + "mime_guess", + "sha2", + "walkdir", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + +[[package]] +name = "darling" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06d4a9551359071d1890820e3571252b91229e0712e7c36b08940e603c5a8fc" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b443e5fb0ddd56e0c9bfa47dc060c5306ee500cb731f2b91432dd65589a77684" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0220073ce504f12a70efc4e7cdaea9e9b1b324872e7ad96a208056d7a638b81" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "data-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" + +[[package]] +name = "derive_builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ef25735c9f0d0c547d2794701600c94abf030ecb740fad1673fa64461f3573" +dependencies = [ + "derive_builder_core", + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3150f1e84602847b99d3eeb702487fc364f7d6c94f634e944a68fdbaea09e457" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca1008bddefdc08d1e734aeb27b94f384390af261b4d1a8fb51fe19c577f05c" +dependencies = [ + "derive_builder_core", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "proc-macro2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sha2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" +dependencies = [ + "block-buffer", + "cfg-if", + "cpuid-bool", + "digest", + "opaque-debug", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..73f2cea --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "cache-buster" +version = "0.1.0" +authors = ["realaravinth "] +edition = "2018" +license = "MIT OR Apache-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "cache_buster" +path = "src/lib.rs" + +[dependencies] +mime_guess = "2.0.3" +mime = "0.3.16" +sha2 = "0.9.3" +derive_builder = "0.10.0" +data-encoding = "2.3.2" +walkdir = "2" diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..8f5ba39 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017-NOW Actix Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..95938ef --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Actix Team + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..72a38df --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +
+

cache-buster

+

+ cache-buster - A library that aids in staticfile cache busting with SHA-258 hashes +

+ +[![Documentation](https://img.shields.io/badge/docs-master-blue)](https://realaravinth.github.io/cache-buster/cache_buster/index.html) +![CI (Linux)]() +[![dependency status](https://deps.rs/repo/github/realaravinth/cache-buster/status.svg)](https://deps.rs/repo/github/realaravinth/cache-buster) +
+[![codecov](https://codecov.io/gh/realaravinth/cache-buster/branch/master/graph/badge.svg)](https://codecov.io/gh/realaravinth/cache-buster) + +
+ +## Features + +- [x] `SHA-256` based name generation during compile-time +- [x] Processes files based on provided MIME filters +- [ ] Exposes modified names to program during runtime + +## Usage: + +Add this to your `Cargo.toml`: + +```toml +cache-buster = { version = "0.2", git = "https://github.com/realaravinth/cache-buster" } +``` + +## Examples: + +TODO diff --git a/dist/a/b/c/d/s/d/svg/1.svg b/dist/a/b/c/d/s/d/svg/1.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/10.svg b/dist/a/b/c/d/s/d/svg/10.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/10.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/2.svg b/dist/a/b/c/d/s/d/svg/2.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/3.svg b/dist/a/b/c/d/s/d/svg/3.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/4.svg b/dist/a/b/c/d/s/d/svg/4.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/5.svg b/dist/a/b/c/d/s/d/svg/5.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/6.svg b/dist/a/b/c/d/s/d/svg/6.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/7.svg b/dist/a/b/c/d/s/d/svg/7.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/8.svg b/dist/a/b/c/d/s/d/svg/8.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/9.svg b/dist/a/b/c/d/s/d/svg/9.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/credit-card.svg b/dist/a/b/c/d/s/d/svg/credit-card.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/credit-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/eye.svg b/dist/a/b/c/d/s/d/svg/eye.svg new file mode 100644 index 0000000..44f107a --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/file-text.svg b/dist/a/b/c/d/s/d/svg/file-text.svg new file mode 100644 index 0000000..85186e3 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/file-text.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/file.svg b/dist/a/b/c/d/s/d/svg/file.svg new file mode 100644 index 0000000..fa1ecc8 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/filter.svg b/dist/a/b/c/d/s/d/svg/filter.svg new file mode 100644 index 0000000..3ae2cfc --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/filter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/github.svg b/dist/a/b/c/d/s/d/svg/github.svg new file mode 100644 index 0000000..8a1c9c0 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/github.svg @@ -0,0 +1 @@ + diff --git a/dist/a/b/c/d/s/d/svg/globe.svg b/dist/a/b/c/d/s/d/svg/globe.svg new file mode 100644 index 0000000..4306cdc --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/help-circle.svg b/dist/a/b/c/d/s/d/svg/help-circle.svg new file mode 100644 index 0000000..1bbf397 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/help-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/home.svg b/dist/a/b/c/d/s/d/svg/home.svg new file mode 100644 index 0000000..867f079 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/log-out.svg b/dist/a/b/c/d/s/d/svg/log-out.svg new file mode 100644 index 0000000..625d272 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/log-out.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/menu.svg b/dist/a/b/c/d/s/d/svg/menu.svg new file mode 100644 index 0000000..0ea1741 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/moon.svg b/dist/a/b/c/d/s/d/svg/moon.svg new file mode 100644 index 0000000..3d94f16 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/moon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/settings.svg b/dist/a/b/c/d/s/d/svg/settings.svg new file mode 100644 index 0000000..0318f2c --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/shield-off.svg b/dist/a/b/c/d/s/d/svg/shield-off.svg new file mode 100644 index 0000000..47805ee --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/shield-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/shield.svg b/dist/a/b/c/d/s/d/svg/shield.svg new file mode 100644 index 0000000..18c6ed2 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/tag.svg b/dist/a/b/c/d/s/d/svg/tag.svg new file mode 100644 index 0000000..0c7a770 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/tag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/toggle-left.svg b/dist/a/b/c/d/s/d/svg/toggle-left.svg new file mode 100644 index 0000000..cd4b4e6 --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/toggle-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/toggle-right.svg b/dist/a/b/c/d/s/d/svg/toggle-right.svg new file mode 100644 index 0000000..01392ab --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/toggle-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/a/b/c/d/s/d/svg/user.svg b/dist/a/b/c/d/s/d/svg/user.svg new file mode 100644 index 0000000..7b5bc4a --- /dev/null +++ b/dist/a/b/c/d/s/d/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/bell.svg b/dist/bell.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/bell.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/credit-card.svg b/dist/credit-card.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/credit-card.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/eye-off.svg b/dist/eye-off.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/eye-off.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/eye.svg b/dist/eye.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/eye.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/file-text.svg b/dist/file-text.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/file-text.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/file.svg b/dist/file.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/file.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/filter.svg b/dist/filter.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/filter.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/github.svg b/dist/github.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/github.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/globe.svg b/dist/globe.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/globe.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/help-circle.svg b/dist/help-circle.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/help-circle.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/home.svg b/dist/home.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/home.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/icon.png b/dist/icon.png new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/icon.png @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/log-out.svg b/dist/log-out.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/log-out.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/main.1ed8da86f47dbdff4959.bundle.js b/dist/main.1ed8da86f47dbdff4959.bundle.js new file mode 100644 index 0000000..ec9fc73 --- /dev/null +++ b/dist/main.1ed8da86f47dbdff4959.bundle.js @@ -0,0 +1 @@ +!function(e){var t={};function a(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,a),r.l=!0,r.exports}a.m=e,a.c=t,a.d=function(e,t,n){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(a.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)a.d(n,r,function(t){return e[t]}.bind(null,r));return n},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=1)}([function(e,t,a){},function(e,t,a){"use strict";a.r(t);const n=e=>{if(!e)throw new Error("uri is empty");if("string"!=typeof e)throw new TypeError("URI must be a string");let t=e.length;return"/"==e[t-1]&&(e=e.slice(0,t-1)),e};var r={registerUser:"/api/v1/signup",loginUser:"/api/v1/signin",signoutUser:"/api/v1/signout",deleteAccount:"/api/v1/account/delete",usernameExists:"/api/v1/account/username/exists",emailExists:"/api/v1/account/email/exists",healthCheck:"/api/v1/meta/health",buildDetails:"/api/v1/meta/build",addDomain:"/api/v1/mcaptcha/domain/add",challengeDomain:"/api/v1/mcaptcha/domain/domain/verify/challenge/get",proveDomain:"/api/v1/mcaptcha/domain/domain/verify/challenge/prove",deleteDomain:"/api/v1/mcaptcha/domain/delete",addToken:"/api/v1/mcaptcha/domain/token/add",updateTokenKey:"/api/v1/mcaptcha/domain/token/update",getTokenKey:"/api/v1/mcaptcha/domain/token/get",deleteToken:"/api/v1/mcaptcha/domain/token/delete",addTokenLevels:"/api/v1/mcaptcha/domain/token/levels/add",updateTokenLevels:"/api/v1/mcaptcha/domain/token/levels/update",deleteTokenLevels:"/api/v1/mcaptcha/domain/token/levels/delete",getTokenLevels:"/api/v1/mcaptcha/domain/token/levels/get",getTokenDuration:"/api/v1/mcaptcha/domain/token/token/get",updateTokenDuration:"/api/v1/mcaptcha/domain/token/token/update"};var o=e=>({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});a(0);const i=e=>{e.preventDefault();let t=document.getElementById("username").value;o(e,t,"username");let a=document.getElementById("password").value;fetch(r.loginUser,o({username:t,password:a})).then(e=>{e.ok?alert("success"):e.json().then(e=>alert("error: "+e.error))})};var s=async function(){let e=document.getElementById("username"),t={val:e.value},a=await fetch(r.usernameExists,o(t));if(a.ok){let t=await a.json();return t.exists&&(e.className+=" form__in-field--warn",alert("Username taken")),t.exists}{let e=await a.json();alert("error: "+e.error)}return!1};const l=async e=>{e.preventDefault();let t=document.getElementById("username").value;o(e,t,"username");let a=document.getElementById("password").value;if(a!=document.getElementById("password-check").value)return alert("passwords don't match, check again!");let n=document.getElementById("email").value;o(e,n,"email");let i=await checkUsernameExists();if(i)return;if(i=await(async()=>{let e=document.getElementById("email"),t={val:e.value},a=await fetch(r.emailExists,o(t));if(a.ok){let t=await a.json();return t.exists&&(e.className+=" form__in-field--warn",alert("Email taken")),t.exists}{let e=await a.json();alert("error: "+e.error)}})(),i)return;let s={username:t,password:a,email:n},l=await fetch(r.registerUser,o(s));if(l.ok)alert("success");else{let e=await l.json();alert("error: "+e.error)}},u=()=>{},c=new class{constructor(){this.routes=[]}register(e,t){if(!e)throw new Error("uri is empty");if(!t)throw new Error("fn is empty");if("string"!=typeof e)throw new TypeError("URI must be a string");if("function"!=typeof t)throw new TypeError("a callback fn must be provided");this.routes.forEach(t=>{if(t.uri==e)throw new Error(`URI exists. provided URI: ${e}, registered config: ${t}`)});const a={uri:e=n(e),fn:t};this.routes.push(a)}route(){this.routes.forEach(e=>{let t=new RegExp(`^${e.uri}$`),a=window.location.pathname;if(a=n(a),a.match(t))return e.fn.call()})}};c.register("/",()=>{document.getElementById("form").addEventListener("submit",i,!0)}),c.register("/register",()=>{document.getElementById("form").addEventListener("submit",l,!0),document.getElementById("username").addEventListener("input",s,!1)}),c.register("/panel/",u),c.register("/panel/layout.html/",u),c.route()}]); \ No newline at end of file diff --git a/dist/main.78421bba57d23c4c0969.css b/dist/main.78421bba57d23c4c0969.css new file mode 100644 index 0000000..31ca5b0 --- /dev/null +++ b/dist/main.78421bba57d23c4c0969.css @@ -0,0 +1 @@ +*{padding:0;margin:0}.form__logo{width:110px;padding-top:50px;display:block;margin:auto;transform:translateY(-40.9%)}.form__brand,.form__logo{position:relative;top:20%}.form__brand{padding:10px 0;text-align:center;transform:translateY(-90.9%)}.form-container{max-width:40%;min-width:20%;position:absolute;top:50%;left:50%;transform:translate(-50%,-49.9%);box-sizing:border-box;margin:auto;padding:20px 0}.form__box{border:1px solid #eaecef;background-color:#f6f8fa;border-radius:5px;padding:20px 0}.form__in-group{display:block;position:relative;margin:auto;max-width:80%;padding:10px 0;box-sizing:content-box;align-items:center;align-content:center}.form__in-field{display:block;box-sizing:border-box;margin:10px 0;padding:10px 0;width:100%}.form__in-field--warn{border:1px solid red}.form__in-field--success{border:1px solid #2ea44f}.form__pw-recovery{text-decoration:none;color:#0366d6;font-size:.8rem}.form__submit-button{display:block;border:1px solid #87ceeb;background:#2ea44f;color:#fff;height:40px;border-radius:5px;width:80%;margin:auto}.form__secondary-action{display:block;margin-top:10px}.form__secondary-action__banner{display:block;margin:auto;max-width:80%;text-align:center}.form__secondary-action__link{text-decoration:none;color:#0366d6} \ No newline at end of file diff --git a/dist/menu.svg b/dist/menu.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/menu.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/moon.svg b/dist/moon.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/moon.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/settings.svg b/dist/settings.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/settings.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/shield-off.svg b/dist/shield-off.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/shield-off.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/shield.svg b/dist/shield.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/shield.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/svg/bell.svg b/dist/svg/bell.svg new file mode 100644 index 0000000..c0ed0e1 --- /dev/null +++ b/dist/svg/bell.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/credit-card.svg b/dist/svg/credit-card.svg new file mode 100644 index 0000000..9429a63 --- /dev/null +++ b/dist/svg/credit-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/eye-off.svg b/dist/svg/eye-off.svg new file mode 100644 index 0000000..9d28c18 --- /dev/null +++ b/dist/svg/eye-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/eye.svg b/dist/svg/eye.svg new file mode 100644 index 0000000..44f107a --- /dev/null +++ b/dist/svg/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/file-text.svg b/dist/svg/file-text.svg new file mode 100644 index 0000000..85186e3 --- /dev/null +++ b/dist/svg/file-text.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/file.svg b/dist/svg/file.svg new file mode 100644 index 0000000..fa1ecc8 --- /dev/null +++ b/dist/svg/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/filter.svg b/dist/svg/filter.svg new file mode 100644 index 0000000..3ae2cfc --- /dev/null +++ b/dist/svg/filter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/github.svg b/dist/svg/github.svg new file mode 100644 index 0000000..8a1c9c0 --- /dev/null +++ b/dist/svg/github.svg @@ -0,0 +1 @@ + diff --git a/dist/svg/globe.svg b/dist/svg/globe.svg new file mode 100644 index 0000000..4306cdc --- /dev/null +++ b/dist/svg/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/help-circle.svg b/dist/svg/help-circle.svg new file mode 100644 index 0000000..1bbf397 --- /dev/null +++ b/dist/svg/help-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/home.svg b/dist/svg/home.svg new file mode 100644 index 0000000..867f079 --- /dev/null +++ b/dist/svg/home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/log-out.svg b/dist/svg/log-out.svg new file mode 100644 index 0000000..625d272 --- /dev/null +++ b/dist/svg/log-out.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/menu.svg b/dist/svg/menu.svg new file mode 100644 index 0000000..0ea1741 --- /dev/null +++ b/dist/svg/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/moon.svg b/dist/svg/moon.svg new file mode 100644 index 0000000..3d94f16 --- /dev/null +++ b/dist/svg/moon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/settings.svg b/dist/svg/settings.svg new file mode 100644 index 0000000..0318f2c --- /dev/null +++ b/dist/svg/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/shield-off.svg b/dist/svg/shield-off.svg new file mode 100644 index 0000000..47805ee --- /dev/null +++ b/dist/svg/shield-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/shield.svg b/dist/svg/shield.svg new file mode 100644 index 0000000..18c6ed2 --- /dev/null +++ b/dist/svg/shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/tag.svg b/dist/svg/tag.svg new file mode 100644 index 0000000..0c7a770 --- /dev/null +++ b/dist/svg/tag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/toggle-left.svg b/dist/svg/toggle-left.svg new file mode 100644 index 0000000..cd4b4e6 --- /dev/null +++ b/dist/svg/toggle-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/toggle-right.svg b/dist/svg/toggle-right.svg new file mode 100644 index 0000000..01392ab --- /dev/null +++ b/dist/svg/toggle-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/svg/user.svg b/dist/svg/user.svg new file mode 100644 index 0000000..7b5bc4a --- /dev/null +++ b/dist/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/tag.svg b/dist/tag.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/tag.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/toggle-left.svg b/dist/toggle-left.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/toggle-left.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/toggle-right.svg b/dist/toggle-right.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/toggle-right.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/dist/user.svg b/dist/user.svg new file mode 100644 index 0000000..f69302f --- /dev/null +++ b/dist/user.svg @@ -0,0 +1,3 @@ +Rust +💖 +Fun \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..c9a48b1 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,191 @@ +/* +* Copyright (C) 2021 Aravinth Manivannan +* +* Use of this source code is governed by the Apache 2.0 and/or the MIT +* License. +*/ + +//! ```rust +//! use cache_buster::BusterBuilder; +//! +//! fn main() { +//! // note: add error checking yourself. +//! // println!("cargo:rustc-env=GIT_HASH={}", git_hash); +//! let types = vec![ +//! mime::IMAGE_PNG, +//! mime::IMAGE_SVG, +//! mime::IMAGE_JPEG, +//! mime::IMAGE_GIF, +//! ]; +//! +//! let config = BusterBuilder::default() +//! .source("./dist") +//! .result("./prod") +//! .mime_types(types) +//! .copy(true) +//! .follow_links(true) +//! .build() +//! .unwrap(); +//! +//! config.init().unwrap(); +//! config.hash().unwrap(); +//! } +//! ``` + +use std::fs; +use std::io::Error; +use std::path::Path; + +use derive_builder::Builder; +use walkdir::WalkDir; + +#[derive(Debug, Clone, Builder)] +pub struct Buster { + // source directory + #[builder(setter(into))] + source: String, + // mime_types for hashing + mime_types: Vec, + // directory for writing results + #[builder(setter(into))] + result: String, + // copy other non-hashed files from source dire to result dir? + copy: bool, + follow_links: bool, +} + +impl Buster { + pub fn init(&self) -> Result<(), Error> { + let res = Path::new(&self.result); + if res.exists() { + fs::remove_dir_all(&self.result).unwrap(); + } + + fs::create_dir(&self.result).unwrap(); + self.create_dir_structure(Path::new(&self.source))?; + Ok(()) + } + + fn hasher(payload: &str) -> String { + use data_encoding::HEXUPPER; + use sha2::{Digest, Sha256}; + let mut hasher = Sha256::new(); + hasher.update(payload); + HEXUPPER.encode(&hasher.finalize()) + } + + // if mime types are common, then you shoud be fine using this + // use [hash] when when they aren't + // + // doesn't process files for which mime is not resolved + pub fn try_hash(&self) -> Result<(), Error> { + for entry in WalkDir::new(&self.source) + .follow_links(self.follow_links) + .into_iter() + { + let entry = entry?; + let path = entry.path(); + let path = Path::new(&path); + + for mime_type in self.mime_types.iter() { + if let Some(file_mime) = mime_guess::from_path(path).first() { + if &file_mime == mime_type { + let contents = Self::read_to_string(&path).unwrap(); + let hash = Self::hasher(&contents); + let new_name = format!( + "{}.{}.{}", + path.file_stem().unwrap().to_str().unwrap(), + hash, + path.extension().unwrap().to_str().unwrap() + ); + // println!("{}", &new_name); + self.copy(path, &new_name); + // let data = fs::copy(path, new_name); + } + } + } + } + + Ok(()) + } + + // panics when mimetypes are detected. This way you'll know which files are ignored + // from processing + pub fn hash(&self) -> Result<(), Error> { + for entry in WalkDir::new(&self.source) + .follow_links(self.follow_links) + .into_iter() + { + let entry = entry?; + + let path = entry.path(); + if !path.is_dir() { + let path = Path::new(&path); + + for mime_type in self.mime_types.iter() { + let file_mime = mime_guess::from_path(path) + .first() + .expect(&format!("couldn't resolve MIME for file: {:?}", &path)); + if &file_mime == mime_type { + let contents = Self::read_to_string(&path).unwrap(); + let hash = Self::hasher(&contents); + let new_name = format!( + "{}.{}.{}", + path.file_stem().unwrap().to_str().unwrap(), + hash, + path.extension().unwrap().to_str().unwrap() + ); + self.copy(path, &new_name); + } + } + } + } + + Ok(()) + } + + fn read_to_string(path: &Path) -> Result { + use std::fs::File; + use std::io::{BufRead, BufReader}; + + let input = File::open(path)?; + let buffered = BufReader::new(input); + + let mut res = String::new(); + for line in buffered.lines() { + res.push_str(&line?) + } + + Ok(res) + } + + fn copy(&self, source: &Path, name: &str) { + let rel_location = source.strip_prefix(&self.source).unwrap().parent().unwrap(); + let destination = Path::new(&self.result).join(rel_location).join(name); + fs::copy(source, &destination).unwrap(); + } + + fn create_dir_structure(&self, path: &Path) -> Result<(), Error> { + for entry in WalkDir::new(&path) + .follow_links(self.follow_links) + .into_iter() + { + let entry = entry?; + let entry_path = entry.path(); + let entry_path = Path::new(&entry_path); + + if entry_path.is_dir() && path != entry_path { + Self::create_dir_structure(&self, entry_path)?; + } else { + if entry_path.is_dir() { + let rel_location = entry_path.strip_prefix(&self.source).unwrap(); + let destination = Path::new(&self.result).join(rel_location); + if !destination.exists() { + fs::create_dir(destination)? + } + } + } + } + Ok(()) + } +}