This commit is contained in:
472
node_modules/decap-cms-backend-git-gateway/CHANGELOG.md
generated
vendored
Normal file
472
node_modules/decap-cms-backend-git-gateway/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,472 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.2.2](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.2.1...decap-cms-backend-git-gateway@3.2.2) (2024-08-13)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "Update dependencies (#7264)" ([22d483a](https://github.com/decaporg/decap-cms/commit/22d483a5b0c654071ae05735ac4f49abdc13d38c)), closes [#7264](https://github.com/decaporg/decap-cms/issues/7264)
|
||||
|
||||
## [3.2.1](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.2.0...decap-cms-backend-git-gateway@3.2.1) (2024-08-13)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [3.2.0](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.1.1...decap-cms-backend-git-gateway@3.2.0) (2024-08-07)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [3.1.1](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.1.0-beta.1...decap-cms-backend-git-gateway@3.1.1) (2024-03-21)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [3.1.0](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.1.0-beta.1...decap-cms-backend-git-gateway@3.1.0) (2024-02-01)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [3.1.0-beta.1](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.1.0-beta.0...decap-cms-backend-git-gateway@3.1.0-beta.1) (2024-01-31)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [3.1.0-beta.0](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.1.0...decap-cms-backend-git-gateway@3.1.0-beta.0) (2023-10-20)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([b89fc89](https://github.com/decaporg/decap-cms/commit/b89fc894dfbb5f4136b2e5427fd25a29378a58c6))
|
||||
|
||||
## [3.0.3](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.0.2...decap-cms-backend-git-gateway@3.0.3) (2023-10-13)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [3.0.2](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.0.1...decap-cms-backend-git-gateway@3.0.2) (2023-09-06)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- filter by path when loading collection from github backend ([#6898](https://github.com/decaporg/decap-cms/issues/6898)) ([18ef773](https://github.com/decaporg/decap-cms/commit/18ef773f35db1b7ef3ab5a0f25527d87745b9c73))
|
||||
|
||||
## [3.0.1](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@3.0.0...decap-cms-backend-git-gateway@3.0.1) (2023-08-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- update peer dependencies ([#6886](https://github.com/decaporg/decap-cms/issues/6886)) ([e580ce5](https://github.com/decaporg/decap-cms/commit/e580ce52ce5f80fa040e8fbcab7fed0744f4f695))
|
||||
|
||||
# [3.0.0](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@2.14.0...decap-cms-backend-git-gateway@3.0.0) (2023-08-18)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [2.14.0](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@2.14.0-beta.0...decap-cms-backend-git-gateway@2.14.0) (2023-08-18)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# 2.14.0-beta.0 (2023-08-18)
|
||||
|
||||
### Features
|
||||
|
||||
- rename packages ([#6863](https://github.com/decaporg/decap-cms/issues/6863)) ([d515e7b](https://github.com/decaporg/decap-cms/commit/d515e7bd33216a775d96887b08c4f7b1962941bb))
|
||||
|
||||
## [2.13.2-beta.0](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@2.13.1...decap-cms-backend-git-gateway@2.13.2-beta.0) (2023-07-27)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.13.1](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@2.13.0...decap-cms-backend-git-gateway@2.13.1) (2022-03-08)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [2.13.0](https://github.com/decaporg/decap-cms/compare/decap-cms-backend-git-gateway@2.12.2...decap-cms-backend-git-gateway@2.13.0) (2021-12-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **decap-cms-ui-default:** use grayDark for button ([#6069](https://github.com/decaporg/decap-cms/issues/6069)) ([ad85514](https://github.com/decaporg/decap-cms/commit/ad85514cba607f066ab7071bee5932b2192466ee)), closes [/github.com/decaporg/decap-cms/issues/1333#issuecomment-998115794](https://github.com//github.com/decaporg/decap-cms/issues/1333/issues/issuecomment-998115794)
|
||||
|
||||
### Features
|
||||
|
||||
- **backend-gitlab:** initial GraphQL support ([#6059](https://github.com/decaporg/decap-cms/issues/6059)) ([1523a41](https://github.com/decaporg/decap-cms/commit/1523a4140a3d2f4cc01a1548514ae17bc1ad504e))
|
||||
- disable 'Save' button when there are no changes ([#5595](https://github.com/decaporg/decap-cms/issues/5595)) ([4b566a7](https://github.com/decaporg/decap-cms/commit/4b566a78f4282a6f04caf3deafaaac4d74acfd63))
|
||||
|
||||
## [2.12.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.12.1...decap-cms-backend-git-gateway@2.12.2) (2021-06-01)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.12.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.12.0...decap-cms-backend-git-gateway@2.12.1) (2021-05-31)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [2.12.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.11...decap-cms-backend-git-gateway@2.12.0) (2021-05-04)
|
||||
|
||||
### Features
|
||||
|
||||
- added react 17 as peer dependency in packages ([#5316](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/5316)) ([9e42380](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/9e423805707321396eec137f5b732a5b07a0dd3f))
|
||||
|
||||
## [2.11.11](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.10...decap-cms-backend-git-gateway@2.11.11) (2021-02-25)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.11.10](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.9...decap-cms-backend-git-gateway@2.11.10) (2021-02-23)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.11.9](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.8...decap-cms-backend-git-gateway@2.11.9) (2021-02-10)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.11.8](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.7...decap-cms-backend-git-gateway@2.11.8) (2020-12-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **deps:** update dependency ini to v2 ([#4722](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/4722)) ([e14ace3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/e14ace373b11510159a9b4d3f977d27ed886b288))
|
||||
|
||||
## [2.11.7](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.6...decap-cms-backend-git-gateway@2.11.7) (2020-12-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **large-media:** mark pointer files as binary ([#4678](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/4678)) ([7697b90](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/7697b907d7bae750f4ec041a184188aa46995320))
|
||||
|
||||
## [2.11.6](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.5...decap-cms-backend-git-gateway@2.11.6) (2020-10-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **deps:** update dependency jwt-decode to v3 ([#4408](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/4408)) ([03492e4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/03492e4e684ffce3a541ef15edb591d1fd5b5854))
|
||||
|
||||
## [2.11.5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.4...decap-cms-backend-git-gateway@2.11.5) (2020-09-20)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.11.4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.11.3...decap-cms-backend-git-gateway@2.11.4) (2020-09-15)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## 2.11.3 (2020-09-08)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([828bb16](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae))
|
||||
|
||||
## 2.11.2 (2020-08-20)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([8262487](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/82624879ccbcb16610090041db28f00714d924c8))
|
||||
|
||||
## 2.11.1 (2020-07-27)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "chore(release): publish" ([118d50a](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/118d50a7a70295f25073e564b5161aa2b9883056))
|
||||
|
||||
# [2.11.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.10.5...decap-cms-backend-git-gateway@2.11.0) (2020-06-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- handle token expiry ([#3847](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3847)) ([285c940](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/285c940562548d7bc88de244123ba87ff66fba65))
|
||||
|
||||
### Features
|
||||
|
||||
- add backend status down indicator ([#3889](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3889)) ([a50edc7](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/a50edc70553ad6afa1acee6a51996ad226443f8c))
|
||||
- **backend-gitgateway:** improve deploy preview visibility ([#3882](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3882)) ([afc9bf4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/afc9bf4f3fe14ccb60851fc24e68922a6e4a85a9))
|
||||
|
||||
## [2.10.5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.10.4...decap-cms-backend-git-gateway@2.10.5) (2020-05-19)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.10.4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.10.3...decap-cms-backend-git-gateway@2.10.4) (2020-05-04)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **git-gateway:** wait for identity widget to initialize ([#3660](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3660)) ([6c229c5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/6c229c5149e3beff05bcfb42ca286d3e9170e54e))
|
||||
|
||||
## [2.10.3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.10.2...decap-cms-backend-git-gateway@2.10.3) (2020-04-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **large-media:** match netlify.app as lfs host ([#3642](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3642)) ([9b79623](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/9b79623bc8b8fe212fb2d15dec8a75328cde9c64))
|
||||
|
||||
## [2.10.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.10.1...decap-cms-backend-git-gateway@2.10.2) (2020-04-01)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.10.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.10.0...decap-cms-backend-git-gateway@2.10.1) (2020-03-30)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [2.10.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.9.1...decap-cms-backend-git-gateway@2.10.0) (2020-03-12)
|
||||
|
||||
### Features
|
||||
|
||||
- add media lib virtualization ([#3381](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3381)) ([92e7601](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/92e76011e7a9e8b5370088b0a2c065df66b5f7fb))
|
||||
- **backend-github:** add pagination ([#3379](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3379)) ([39f1307](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/39f1307e3a36447da8c9b3ca79b1d7db52ea1a19))
|
||||
|
||||
## [2.9.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.9.0...decap-cms-backend-git-gateway@2.9.1) (2020-03-03)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **locale:** Remove hard coded string literals ([#3333](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3333)) ([7c45a3c](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/7c45a3cda983be427864a56e58791565eb9232e2))
|
||||
|
||||
# [2.9.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.8.1...decap-cms-backend-git-gateway@2.9.0) (2020-02-25)
|
||||
|
||||
### Features
|
||||
|
||||
- **core:** align GitHub metadata handling with other backends ([#3316](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3316)) ([7e0a8ad](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/7e0a8ad532012576dc5e40bd4e9d54522e307123)), closes [#3292](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3292)
|
||||
|
||||
## [2.8.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.8.0...decap-cms-backend-git-gateway@2.8.1) (2020-02-22)
|
||||
|
||||
### Reverts
|
||||
|
||||
- Revert "feat(core): Align GitHub metadata handling with other backends (#3292)" ([5bdd3df](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/5bdd3df9ccbb5149c22d79987ebdcd6cab4b261f)), closes [#3292](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3292)
|
||||
|
||||
# [2.8.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.7.2...decap-cms-backend-git-gateway@2.8.0) (2020-02-22)
|
||||
|
||||
### Features
|
||||
|
||||
- **core:** Align GitHub metadata handling with other backends ([#3292](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3292)) ([8193b5a](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/8193b5ace89d6f14a6c756235a50b186a763b6b1))
|
||||
|
||||
## [2.7.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.7.1...decap-cms-backend-git-gateway@2.7.2) (2020-02-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- stringify error message ([#3233](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3233)) ([249bd7e](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/249bd7ec1ed2197106cbb01f8c05e1b8830aa5bc))
|
||||
|
||||
## [2.7.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.7.0...decap-cms-backend-git-gateway@2.7.1) (2020-01-24)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **backend-git-gateway:** re-write GitHub pagination links ([#3135](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3135)) ([834f6b9](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/834f6b9e457f3738ce0f240ddd4cc160aff9e2f5))
|
||||
|
||||
# [2.7.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.6.2...decap-cms-backend-git-gateway@2.7.0) (2020-01-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **git-gateway-gitlab:** fix large media support for editorial workflow ([#3105](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3105)) ([038803c](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/038803c9f249de386812652372c35c4c53935295))
|
||||
|
||||
### Features
|
||||
|
||||
- **backend-bitbucket:** Add Git-LFS support ([#3118](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3118)) ([a48c02d](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/a48c02d852ca5e11055da3a14cefae8d17a68498))
|
||||
|
||||
## [2.6.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.6.1...decap-cms-backend-git-gateway@2.6.2) (2020-01-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- don't fail on malformed pointer files ([#3095](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3095)) ([9210843](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/92108431f0c3df3e99b5aa7f462006ec3fa7777e))
|
||||
|
||||
## [2.6.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.6.0...decap-cms-backend-git-gateway@2.6.1) (2020-01-14)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [2.6.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.6.0-beta.0...decap-cms-backend-git-gateway@2.6.0) (2020-01-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- rebase open authoring branches ([#2975](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2975)) ([8c175f6](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/8c175f6132fa18a13763cc563f7d3201c1e3580e))
|
||||
|
||||
### Features
|
||||
|
||||
- **backend-git-gateway:** handle identity disabled error message ([#3002](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/3002)) ([b5ffccd](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/b5ffccdac506db416c09aaebb38611783487c52a))
|
||||
|
||||
# [2.6.0-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.5.1...decap-cms-backend-git-gateway@2.6.0-beta.0) (2019-12-18)
|
||||
|
||||
### Features
|
||||
|
||||
- bundle assets with content ([#2958](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2958)) ([2b41d8a](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298))
|
||||
|
||||
## [2.5.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.5.0...decap-cms-backend-git-gateway@2.5.1) (2019-11-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **git-gateway:** unpublished entries not loaded for git-gateway(GitHub) ([#2856](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2856)) ([4a2328b](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/4a2328b2f10ea678184391e4caf235b41323cd3e))
|
||||
|
||||
# [2.5.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.6...decap-cms-backend-git-gateway@2.5.0) (2019-11-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **backend-git-gateway:** omit /repos/ when no repo ([#2846](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2846)) ([da2dab3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/da2dab305ab7f0655791ef0fb5376e3d5e72897c))
|
||||
|
||||
### Features
|
||||
|
||||
- add go back to site button ([#2538](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2538)) ([f206e7e](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/f206e7e5a13fb48ec6b27dce0dbb3a59b61de8f9))
|
||||
- enable specifying custom open authoring commit message ([#2810](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2810)) ([2841ff9](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/2841ff9ffe58afcf4dba45514a84a262ad370f1d))
|
||||
|
||||
## [2.4.6](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.5...decap-cms-backend-git-gateway@2.4.6) (2019-09-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **git-gateway:** pass api URL instead of constructing it from repo value ([#2631](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2631)) ([922c0f3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/922c0f3))
|
||||
|
||||
## [2.4.5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.4...decap-cms-backend-git-gateway@2.4.5) (2019-07-24)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.4.4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.3...decap-cms-backend-git-gateway@2.4.4) (2019-06-26)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.4.3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.2...decap-cms-backend-git-gateway@2.4.3) (2019-06-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **core:** address new entries error for non-github backends ([#2390](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2390)) ([a5bd6b3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/a5bd6b3))
|
||||
|
||||
## [2.4.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.2-beta.0...decap-cms-backend-git-gateway@2.4.2) (2019-04-10)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.4.2-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.1...decap-cms-backend-git-gateway@2.4.2-beta.0) (2019-04-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **backend-git-gateway:** fix image display w/o large media ([#2271](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2271)) ([6c3506b](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/6c3506b))
|
||||
|
||||
## [2.4.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.1-beta.1...decap-cms-backend-git-gateway@2.4.1) (2019-03-29)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.4.1-beta.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.1-beta.0...decap-cms-backend-git-gateway@2.4.1-beta.1) (2019-03-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- export on decap-cms and maps on esm ([#2244](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2244)) ([6ffd13b](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/6ffd13b))
|
||||
|
||||
## [2.4.1-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.4.0...decap-cms-backend-git-gateway@2.4.1-beta.0) (2019-03-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- update peer dep versions ([#2234](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2234)) ([7987091](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/7987091))
|
||||
|
||||
# [2.4.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.3.1-beta.0...decap-cms-backend-git-gateway@2.4.0) (2019-03-22)
|
||||
|
||||
### Features
|
||||
|
||||
- add ES module builds ([#2215](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2215)) ([d142b32](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/d142b32))
|
||||
|
||||
## [2.3.1-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.3.0...decap-cms-backend-git-gateway@2.3.1-beta.0) (2019-03-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **editorial-workflow:** fix LM pointers changing to binary files ([#2228](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2228)) ([d39a361](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/d39a361))
|
||||
|
||||
# [2.3.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.3.0-beta.0...decap-cms-backend-git-gateway@2.3.0) (2019-03-22)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [2.3.0-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.2.5-beta.0...decap-cms-backend-git-gateway@2.3.0-beta.0) (2019-03-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- fix umd builds ([#2214](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2214)) ([e04f6be](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/e04f6be))
|
||||
|
||||
### Features
|
||||
|
||||
- provide usable UMD builds for all packages ([#2141](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2141)) ([82cc794](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/82cc794))
|
||||
|
||||
## [2.2.5-beta.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.2.4...decap-cms-backend-git-gateway@2.2.5-beta.0) (2019-03-15)
|
||||
|
||||
### Features
|
||||
|
||||
- upgrade to Emotion 10 ([#2166](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2166)) ([ccef446](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/ccef446))
|
||||
|
||||
## [2.2.4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.2.3...decap-cms-backend-git-gateway@2.2.4) (2019-03-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **backend-github:** make non-Large Media previews work with Git Gateway+GitHub ([#2151](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2151)) ([63582dc](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/63582dc))
|
||||
|
||||
## [2.2.3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.2.2...decap-cms-backend-git-gateway@2.2.3) (2019-03-08)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
## [2.2.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.2.1...decap-cms-backend-git-gateway@2.2.2) (2019-02-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **git-gateway:** fix previews for GitHub images not in Large Media ([#2125](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2125)) ([d17f896](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/d17f896))
|
||||
|
||||
## [2.2.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.2.0...decap-cms-backend-git-gateway@2.2.1) (2019-02-26)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
# [2.2.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.1.2...decap-cms-backend-git-gateway@2.2.0) (2019-02-08)
|
||||
|
||||
### Features
|
||||
|
||||
- **workflow:** add deploy preview links ([#2028](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/2028)) ([15d221d](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/15d221d))
|
||||
|
||||
## [2.1.2](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.1.1...decap-cms-backend-git-gateway@2.1.2) (2018-12-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **decap-cms-backend-git-gateway:** content-type may have charset ([#1951](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/1951)) ([c74dbae](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/c74dbae))
|
||||
|
||||
## [2.1.1](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.1.0...decap-cms-backend-git-gateway@2.1.1) (2018-11-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **backend-git-gateway:** double slashes when gateway_url contained a backend ([#1712](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/1712)) ([6de47cd](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/6de47cd))
|
||||
|
||||
# [2.1.0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.0.8...decap-cms-backend-git-gateway@2.1.0) (2018-11-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **identity:** switch user name reference to full_name ([#1809](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/1809)) ([55d45a8](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/55d45a8))
|
||||
|
||||
### Features
|
||||
|
||||
- allow custom logo on auth page ([#1818](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/1818)) ([c6ae1e8](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/c6ae1e8))
|
||||
|
||||
<a name="2.0.8"></a>
|
||||
|
||||
## [2.0.8](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.0.7...decap-cms-backend-git-gateway@2.0.8) (2018-09-06)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
<a name="2.0.7"></a>
|
||||
|
||||
## [2.0.7](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.0.6...decap-cms-backend-git-gateway@2.0.7) (2018-08-27)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
<a name="2.0.6"></a>
|
||||
|
||||
## [2.0.6](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.0.5...decap-cms-backend-git-gateway@2.0.6) (2018-08-24)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
<a name="2.0.5"></a>
|
||||
|
||||
## [2.0.5](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.0.4...decap-cms-backend-git-gateway@2.0.5) (2018-08-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **workflow:** fix workflow entries not appearing ([#1581](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/1581)) ([95c8de0](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/95c8de0))
|
||||
|
||||
<a name="2.0.4"></a>
|
||||
|
||||
## [2.0.4](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.0.3...decap-cms-backend-git-gateway@2.0.4) (2018-08-01)
|
||||
|
||||
**Note:** Version bump only for package decap-cms-backend-git-gateway
|
||||
|
||||
<a name="2.0.3"></a>
|
||||
|
||||
## [2.0.3](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/compare/decap-cms-backend-git-gateway@2.0.2...decap-cms-backend-git-gateway@2.0.3) (2018-07-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **git-gateway:** correct `proxied` value for proxied backends ([#1540](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/issues/1540)) ([f7dba87](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway/commit/f7dba87))
|
||||
|
||||
<a name="2.0.2"></a>
|
||||
|
||||
## 2.0.2 (2018-07-27)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **git-gateway:** pass options through git-gateway backend ([#1532](https://github.com/decaporg/decap-cms/issues/1532)) ([4c5436a](https://github.com/decaporg/decap-cms/commit/4c5436a))
|
||||
|
||||
<a name="2.0.1"></a>
|
||||
|
||||
## 2.0.1 (2018-07-26)
|
||||
|
||||
<a name="2.0.0"></a>
|
||||
|
||||
# 2.0.0 (2018-07-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **bitbucket:** fix rebasing mistakes in bitbucket backend and deps ([#1522](https://github.com/decaporg/decap-cms/issues/1522)) ([bdfd944](https://github.com/decaporg/decap-cms/commit/bdfd944))
|
||||
22
node_modules/decap-cms-backend-git-gateway/LICENSE
generated
vendored
Normal file
22
node_modules/decap-cms-backend-git-gateway/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2016 Netlify <decap@p-m.si>
|
||||
|
||||
MIT License
|
||||
|
||||
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.
|
||||
26
node_modules/decap-cms-backend-git-gateway/README.md
generated
vendored
Normal file
26
node_modules/decap-cms-backend-git-gateway/README.md
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Git Gateway
|
||||
|
||||
Netlify's [gateway](https://github.com/netlify/git-gateway) to hosted git APIs.
|
||||
|
||||
## Code structure
|
||||
|
||||
`Implementation` for [File Management System API](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-lib-util/README.md) based on `Api`.
|
||||
|
||||
`Api` and `Implementation` from backend-[github](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-github/README.md)/[gitlab](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-gitlab/README.md)/[bitbacket](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-bitbacket/README.md) extended with Netlify-specific `LargeMedia(LFS)` and `JWT` auth.
|
||||
|
||||
`AuthenticationPage` - uses [lib-auth](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-lib-auth/README.md) and implements Netlify Identity authentication flow.
|
||||
|
||||
Look at tests or types for more info.
|
||||
|
||||
## Debugging
|
||||
|
||||
When debugging the CMS with Git Gateway you must:
|
||||
|
||||
1. Have a Netlify site with [Git Gateway](https://docs.netlify.com/visitor-access/git-gateway/) and [Netlify Identity](https://docs.netlify.com/visitor-access/identity/) enabled. An easy way to create such a site is to use a [template](https://www.decapcms.org/docs/start-with-a-template/), for example the [Gatsby template](https://app.netlify.com/start/deploy?repository=https://github.com/decaporg/gatsby-starter-decap-cms&stack=cms)
|
||||
2. Tell the CMS the URL of your Netlify site using a local storage item. To do so:
|
||||
|
||||
1. Open `http://localhost:8080/` in the browser
|
||||
2. Write the below command and press enter: `localStorage.setItem('netlifySiteURL', 'https://yourwebsiteurl.netlify.app/')`
|
||||
3. To be sure, you can run this command as well: `localStorage.getItem('netlifySiteURL')`
|
||||
4. Refresh the page
|
||||
5. You should be able to log in via your Netlify Identity email/password
|
||||
2
node_modules/decap-cms-backend-git-gateway/dist/decap-cms-backend-git-gateway.js
generated
vendored
Normal file
2
node_modules/decap-cms-backend-git-gateway/dist/decap-cms-backend-git-gateway.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/decap-cms-backend-git-gateway/dist/decap-cms-backend-git-gateway.js.map
generated
vendored
Normal file
1
node_modules/decap-cms-backend-git-gateway/dist/decap-cms-backend-git-gateway.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
206
node_modules/decap-cms-backend-git-gateway/dist/esm/AuthenticationPage.js
generated
vendored
Normal file
206
node_modules/decap-cms-backend-git-gateway/dist/esm/AuthenticationPage.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
101
node_modules/decap-cms-backend-git-gateway/dist/esm/GitHubAPI.js
generated
vendored
Normal file
101
node_modules/decap-cms-backend-git-gateway/dist/esm/GitHubAPI.js
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _decapCmsBackendGithub = require("decap-cms-backend-github");
|
||||
var _decapCmsLibUtil = require("decap-cms-lib-util");
|
||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
||||
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||
class API extends _decapCmsBackendGithub.API {
|
||||
constructor(config) {
|
||||
super(_objectSpread({
|
||||
getUser: () => Promise.reject('Never used')
|
||||
}, config));
|
||||
_defineProperty(this, "tokenPromise", void 0);
|
||||
_defineProperty(this, "commitAuthor", void 0);
|
||||
_defineProperty(this, "isLargeMedia", void 0);
|
||||
this.apiRoot = config.apiRoot;
|
||||
this.tokenPromise = config.tokenPromise;
|
||||
this.commitAuthor = config.commitAuthor;
|
||||
this.isLargeMedia = config.isLargeMedia;
|
||||
this.repoURL = '';
|
||||
this.originRepoURL = '';
|
||||
}
|
||||
hasWriteAccess() {
|
||||
return this.getDefaultBranch().then(() => true).catch(error => {
|
||||
if (error.status === 401) {
|
||||
if (error.message === 'Bad credentials') {
|
||||
throw new _decapCmsLibUtil.APIError('Git Gateway Error: Please ask your site administrator to reissue the Git Gateway token.', error.status, 'Git Gateway');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (error.status === 404 && (error.message === undefined || error.message === 'Unable to locate site configuration')) {
|
||||
throw new _decapCmsLibUtil.APIError(`Git Gateway Error: Please make sure Git Gateway is enabled on your site.`, error.status, 'Git Gateway');
|
||||
} else {
|
||||
console.error('Problem fetching repo data from Git Gateway');
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
requestHeaders(headers = {}) {
|
||||
return this.tokenPromise().then(jwtToken => {
|
||||
const baseHeader = _objectSpread({
|
||||
Authorization: `Bearer ${jwtToken}`,
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
}, headers);
|
||||
return baseHeader;
|
||||
});
|
||||
}
|
||||
handleRequestError(error, responseStatus) {
|
||||
throw new _decapCmsLibUtil.APIError(error.message || error.msg, responseStatus, 'Git Gateway');
|
||||
}
|
||||
user() {
|
||||
return Promise.resolve(_objectSpread({
|
||||
login: ''
|
||||
}, this.commitAuthor));
|
||||
}
|
||||
async getHeadReference(head) {
|
||||
if (!this.repoOwner) {
|
||||
// get the repo owner from the branch url
|
||||
// this is required for returning the full head reference, e.g. owner:head
|
||||
// when filtering pull requests based on the head
|
||||
const branch = await this.getDefaultBranch();
|
||||
const self = branch._links.self;
|
||||
const regex = new RegExp('https?://.+?/repos/(.+?)/');
|
||||
const owner = self.match(regex);
|
||||
this.repoOwner = owner ? owner[1] : '';
|
||||
}
|
||||
return super.getHeadReference(head);
|
||||
}
|
||||
commit(message, changeTree) {
|
||||
const commitParams = {
|
||||
message,
|
||||
tree: changeTree.sha,
|
||||
parents: changeTree.parentSha ? [changeTree.parentSha] : []
|
||||
};
|
||||
if (this.commitAuthor) {
|
||||
commitParams.author = _objectSpread(_objectSpread({}, this.commitAuthor), {}, {
|
||||
date: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
return this.request('/git/commits', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(commitParams)
|
||||
});
|
||||
}
|
||||
nextUrlProcessor() {
|
||||
return url => url.replace(/^(?:[a-z]+:\/\/.+?\/.+?\/.+?\/)/, `${this.apiRoot}/`);
|
||||
}
|
||||
async diffFromFile(file) {
|
||||
const diff = await super.diffFromFile(file);
|
||||
return _objectSpread(_objectSpread({}, diff), {}, {
|
||||
binary: diff.binary || (await this.isLargeMedia(file.filename))
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.default = API;
|
||||
28
node_modules/decap-cms-backend-git-gateway/dist/esm/GitLabAPI.js
generated
vendored
Normal file
28
node_modules/decap-cms-backend-git-gateway/dist/esm/GitLabAPI.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _decapCmsBackendGitlab = require("decap-cms-backend-gitlab");
|
||||
var _decapCmsLibUtil = require("decap-cms-lib-util");
|
||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
||||
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||
class API extends _decapCmsBackendGitlab.API {
|
||||
constructor(config) {
|
||||
super(config);
|
||||
_defineProperty(this, "tokenPromise", void 0);
|
||||
_defineProperty(this, "withAuthorizationHeaders", async req => {
|
||||
const token = await this.tokenPromise();
|
||||
return _decapCmsLibUtil.unsentRequest.withHeaders({
|
||||
Authorization: `Bearer ${token}`
|
||||
}, req);
|
||||
});
|
||||
_defineProperty(this, "hasWriteAccess", () => Promise.resolve(true));
|
||||
this.tokenPromise = config.tokenPromise;
|
||||
this.commitAuthor = config.commitAuthor;
|
||||
this.repoURL = '';
|
||||
}
|
||||
}
|
||||
exports.default = API;
|
||||
589
node_modules/decap-cms-backend-git-gateway/dist/esm/implementation.js
generated
vendored
Normal file
589
node_modules/decap-cms-backend-git-gateway/dist/esm/implementation.js
generated
vendored
Normal file
@@ -0,0 +1,589 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _intersection2 = _interopRequireDefault(require("lodash/intersection"));
|
||||
var _pick2 = _interopRequireDefault(require("lodash/pick"));
|
||||
var _get2 = _interopRequireDefault(require("lodash/get"));
|
||||
var _gotrueJs = _interopRequireDefault(require("gotrue-js"));
|
||||
var _jwtDecode = _interopRequireDefault(require("jwt-decode"));
|
||||
var _ini = _interopRequireDefault(require("ini"));
|
||||
var _decapCmsLibUtil = require("decap-cms-lib-util");
|
||||
var _decapCmsBackendGithub = require("decap-cms-backend-github");
|
||||
var _decapCmsBackendGitlab = require("decap-cms-backend-gitlab");
|
||||
var _decapCmsBackendBitbucket = require("decap-cms-backend-bitbucket");
|
||||
var _GitHubAPI = _interopRequireDefault(require("./GitHubAPI"));
|
||||
var _GitLabAPI = _interopRequireDefault(require("./GitLabAPI"));
|
||||
var _AuthenticationPage = _interopRequireDefault(require("./AuthenticationPage"));
|
||||
var _netlifyLfsClient = require("./netlify-lfs-client");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
||||
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||
const STATUS_PAGE = 'https://www.netlifystatus.com';
|
||||
const GIT_GATEWAY_STATUS_ENDPOINT = `${STATUS_PAGE}/api/v2/components.json`;
|
||||
const GIT_GATEWAY_OPERATIONAL_UNITS = ['Git Gateway'];
|
||||
const localHosts = {
|
||||
localhost: true,
|
||||
'127.0.0.1': true,
|
||||
'0.0.0.0': true
|
||||
};
|
||||
const defaults = {
|
||||
identity: '/.netlify/identity',
|
||||
gateway: '/.netlify/git',
|
||||
largeMedia: '/.netlify/large-media'
|
||||
};
|
||||
function getEndpoint(endpoint, netlifySiteURL) {
|
||||
if (localHosts[document.location.host.split(':').shift()] && netlifySiteURL && endpoint.match(/^\/\.netlify\//)) {
|
||||
const parts = [];
|
||||
if (netlifySiteURL) {
|
||||
parts.push(netlifySiteURL);
|
||||
if (!netlifySiteURL.match(/\/$/)) {
|
||||
parts.push('/');
|
||||
}
|
||||
}
|
||||
parts.push(endpoint.replace(/^\//, ''));
|
||||
return parts.join('');
|
||||
}
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
// wait for identity widget to initialize
|
||||
// force init on timeout
|
||||
let initPromise = Promise.resolve();
|
||||
if (window.netlifyIdentity) {
|
||||
let initialized = false;
|
||||
initPromise = Promise.race([new Promise(resolve => {
|
||||
var _window$netlifyIdenti;
|
||||
(_window$netlifyIdenti = window.netlifyIdentity) === null || _window$netlifyIdenti === void 0 ? void 0 : _window$netlifyIdenti.on('init', () => {
|
||||
initialized = true;
|
||||
resolve();
|
||||
});
|
||||
}), new Promise(resolve => setTimeout(resolve, 2500)).then(() => {
|
||||
if (!initialized) {
|
||||
var _window$netlifyIdenti2;
|
||||
console.log('Manually initializing identity widget');
|
||||
(_window$netlifyIdenti2 = window.netlifyIdentity) === null || _window$netlifyIdenti2 === void 0 ? void 0 : _window$netlifyIdenti2.init();
|
||||
}
|
||||
})]);
|
||||
}
|
||||
async function apiGet(path) {
|
||||
const apiRoot = 'https://api.netlify.com/api/v1/sites';
|
||||
const response = await fetch(`${apiRoot}/${path}`).then(res => res.json());
|
||||
return response;
|
||||
}
|
||||
class GitGateway {
|
||||
constructor(config, options = {}) {
|
||||
var _config$backend$branc;
|
||||
_defineProperty(this, "config", void 0);
|
||||
_defineProperty(this, "api", void 0);
|
||||
_defineProperty(this, "branch", void 0);
|
||||
_defineProperty(this, "squashMerges", void 0);
|
||||
_defineProperty(this, "cmsLabelPrefix", void 0);
|
||||
_defineProperty(this, "mediaFolder", void 0);
|
||||
_defineProperty(this, "transformImages", void 0);
|
||||
_defineProperty(this, "gatewayUrl", void 0);
|
||||
_defineProperty(this, "netlifyLargeMediaURL", void 0);
|
||||
_defineProperty(this, "backendType", void 0);
|
||||
_defineProperty(this, "apiUrl", void 0);
|
||||
_defineProperty(this, "authClient", void 0);
|
||||
_defineProperty(this, "backend", void 0);
|
||||
_defineProperty(this, "acceptRoles", void 0);
|
||||
_defineProperty(this, "tokenPromise", void 0);
|
||||
_defineProperty(this, "_largeMediaClientPromise", void 0);
|
||||
_defineProperty(this, "options", void 0);
|
||||
_defineProperty(this, "requestFunction", req => this.tokenPromise().then(token => _decapCmsLibUtil.unsentRequest.withHeaders({
|
||||
Authorization: `Bearer ${token}`
|
||||
}, req)).then(_decapCmsLibUtil.unsentRequest.performRequest));
|
||||
this.options = _objectSpread({
|
||||
proxied: true,
|
||||
API: null,
|
||||
initialWorkflowStatus: ''
|
||||
}, options);
|
||||
this.config = config;
|
||||
this.branch = ((_config$backend$branc = config.backend.branch) === null || _config$backend$branc === void 0 ? void 0 : _config$backend$branc.trim()) || 'master';
|
||||
this.squashMerges = config.backend.squash_merges || false;
|
||||
this.cmsLabelPrefix = config.backend.cms_label_prefix || '';
|
||||
this.mediaFolder = config.media_folder;
|
||||
const {
|
||||
use_large_media_transforms_in_media_library: transformImages = true
|
||||
} = config.backend;
|
||||
this.transformImages = transformImages;
|
||||
const netlifySiteURL = localStorage.getItem('netlifySiteURL');
|
||||
this.apiUrl = getEndpoint(config.backend.identity_url || defaults.identity, netlifySiteURL);
|
||||
this.gatewayUrl = getEndpoint(config.backend.gateway_url || defaults.gateway, netlifySiteURL);
|
||||
this.netlifyLargeMediaURL = getEndpoint(config.backend.large_media_url || defaults.largeMedia, netlifySiteURL);
|
||||
const backendTypeRegex = /\/(github|gitlab|bitbucket)\/?$/;
|
||||
const backendTypeMatches = this.gatewayUrl.match(backendTypeRegex);
|
||||
if (backendTypeMatches) {
|
||||
this.backendType = backendTypeMatches[1];
|
||||
this.gatewayUrl = this.gatewayUrl.replace(backendTypeRegex, '');
|
||||
} else {
|
||||
this.backendType = null;
|
||||
}
|
||||
this.backend = null;
|
||||
_AuthenticationPage.default.authClient = () => this.getAuthClient();
|
||||
}
|
||||
isGitBackend() {
|
||||
return true;
|
||||
}
|
||||
async status() {
|
||||
const api = await fetch(GIT_GATEWAY_STATUS_ENDPOINT).then(res => res.json()).then(res => {
|
||||
return res['components'].filter(statusComponent => GIT_GATEWAY_OPERATIONAL_UNITS.includes(statusComponent.name)).every(statusComponent => statusComponent.status === 'operational');
|
||||
}).catch(e => {
|
||||
console.warn('Failed getting Git Gateway status', e);
|
||||
return true;
|
||||
});
|
||||
let auth = false;
|
||||
// no need to check auth if api is down
|
||||
if (api) {
|
||||
var _this$tokenPromise;
|
||||
auth = (await ((_this$tokenPromise = this.tokenPromise) === null || _this$tokenPromise === void 0 ? void 0 : _this$tokenPromise.call(this).then(token => !!token).catch(e => {
|
||||
console.warn('Failed getting Identity token', e);
|
||||
return false;
|
||||
}))) || false;
|
||||
}
|
||||
return {
|
||||
auth: {
|
||||
status: auth
|
||||
},
|
||||
api: {
|
||||
status: api,
|
||||
statusPage: STATUS_PAGE
|
||||
}
|
||||
};
|
||||
}
|
||||
async getAuthClient() {
|
||||
if (this.authClient) {
|
||||
return this.authClient;
|
||||
}
|
||||
await initPromise;
|
||||
if (window.netlifyIdentity) {
|
||||
this.authClient = {
|
||||
logout: () => {
|
||||
var _window$netlifyIdenti3;
|
||||
return (_window$netlifyIdenti3 = window.netlifyIdentity) === null || _window$netlifyIdenti3 === void 0 ? void 0 : _window$netlifyIdenti3.logout();
|
||||
},
|
||||
currentUser: () => {
|
||||
var _window$netlifyIdenti4;
|
||||
return (_window$netlifyIdenti4 = window.netlifyIdentity) === null || _window$netlifyIdenti4 === void 0 ? void 0 : _window$netlifyIdenti4.currentUser();
|
||||
},
|
||||
clearStore: () => {
|
||||
var _window$netlifyIdenti5;
|
||||
const store = (_window$netlifyIdenti5 = window.netlifyIdentity) === null || _window$netlifyIdenti5 === void 0 ? void 0 : _window$netlifyIdenti5.store;
|
||||
if (store) {
|
||||
store.user = null;
|
||||
store.modal.page = 'login';
|
||||
store.saving = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
const goTrue = new _gotrueJs.default({
|
||||
APIUrl: this.apiUrl
|
||||
});
|
||||
this.authClient = {
|
||||
logout: () => {
|
||||
const user = goTrue.currentUser();
|
||||
if (user) {
|
||||
return user.logout();
|
||||
}
|
||||
},
|
||||
currentUser: () => goTrue.currentUser(),
|
||||
login: goTrue.login.bind(goTrue),
|
||||
clearStore: () => undefined
|
||||
};
|
||||
}
|
||||
return this.authClient;
|
||||
}
|
||||
authenticate(credentials) {
|
||||
const user = credentials;
|
||||
this.tokenPromise = async () => {
|
||||
try {
|
||||
const func = user.jwt.bind(user);
|
||||
const token = await func();
|
||||
return token;
|
||||
} catch (error) {
|
||||
throw new _decapCmsLibUtil.AccessTokenError(`Failed getting access token: ${error.message}`);
|
||||
}
|
||||
};
|
||||
return this.tokenPromise().then(async token => {
|
||||
if (!this.backendType) {
|
||||
const {
|
||||
github_enabled: githubEnabled,
|
||||
gitlab_enabled: gitlabEnabled,
|
||||
bitbucket_enabled: bitbucketEnabled,
|
||||
roles
|
||||
} = await _decapCmsLibUtil.unsentRequest.fetchWithTimeout(`${this.gatewayUrl}/settings`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}).then(async res => {
|
||||
const contentType = res.headers.get('Content-Type') || '';
|
||||
if (!contentType.includes('application/json') && !contentType.includes('text/json')) {
|
||||
throw new _decapCmsLibUtil.APIError(`Your Git Gateway backend is not returning valid settings. Please make sure it is enabled.`, res.status, 'Git Gateway');
|
||||
}
|
||||
const body = await res.json();
|
||||
if (!res.ok) {
|
||||
throw new _decapCmsLibUtil.APIError(`Git Gateway Error: ${body.message ? body.message : body}`, res.status, 'Git Gateway');
|
||||
}
|
||||
return body;
|
||||
});
|
||||
this.acceptRoles = roles;
|
||||
if (githubEnabled) {
|
||||
this.backendType = 'github';
|
||||
} else if (gitlabEnabled) {
|
||||
this.backendType = 'gitlab';
|
||||
} else if (bitbucketEnabled) {
|
||||
this.backendType = 'bitbucket';
|
||||
}
|
||||
}
|
||||
if (this.acceptRoles && this.acceptRoles.length > 0) {
|
||||
const userRoles = (0, _get2.default)((0, _jwtDecode.default)(token), 'app_metadata.roles', []);
|
||||
const validRole = (0, _intersection2.default)(userRoles, this.acceptRoles).length > 0;
|
||||
if (!validRole) {
|
||||
throw new Error("You don't have sufficient permissions to access Decap CMS");
|
||||
}
|
||||
}
|
||||
const userData = {
|
||||
name: user.user_metadata.full_name || user.email.split('@').shift(),
|
||||
email: user.email,
|
||||
avatar_url: user.user_metadata.avatar_url,
|
||||
metadata: user.user_metadata
|
||||
};
|
||||
const apiConfig = {
|
||||
apiRoot: `${this.gatewayUrl}/${this.backendType}`,
|
||||
branch: this.branch,
|
||||
tokenPromise: this.tokenPromise,
|
||||
commitAuthor: (0, _pick2.default)(userData, ['name', 'email']),
|
||||
isLargeMedia: filename => this.isLargeMediaFile(filename),
|
||||
squashMerges: this.squashMerges,
|
||||
cmsLabelPrefix: this.cmsLabelPrefix,
|
||||
initialWorkflowStatus: this.options.initialWorkflowStatus
|
||||
};
|
||||
if (this.backendType === 'github') {
|
||||
this.api = new _GitHubAPI.default(apiConfig);
|
||||
this.backend = new _decapCmsBackendGithub.GitHubBackend(this.config, _objectSpread(_objectSpread({}, this.options), {}, {
|
||||
API: this.api
|
||||
}));
|
||||
} else if (this.backendType === 'gitlab') {
|
||||
this.api = new _GitLabAPI.default(apiConfig);
|
||||
this.backend = new _decapCmsBackendGitlab.GitLabBackend(this.config, _objectSpread(_objectSpread({}, this.options), {}, {
|
||||
API: this.api
|
||||
}));
|
||||
} else if (this.backendType === 'bitbucket') {
|
||||
this.api = new _decapCmsBackendBitbucket.API(_objectSpread(_objectSpread({}, apiConfig), {}, {
|
||||
requestFunction: this.requestFunction,
|
||||
hasWriteAccess: async () => true
|
||||
}));
|
||||
this.backend = new _decapCmsBackendBitbucket.BitbucketBackend(this.config, _objectSpread(_objectSpread({}, this.options), {}, {
|
||||
API: this.api
|
||||
}));
|
||||
}
|
||||
if (!(await this.api.hasWriteAccess())) {
|
||||
throw new Error("You don't have sufficient permissions to access Decap CMS");
|
||||
}
|
||||
return {
|
||||
name: userData.name,
|
||||
login: userData.email,
|
||||
avatar_url: userData.avatar_url
|
||||
};
|
||||
});
|
||||
}
|
||||
async restoreUser() {
|
||||
const client = await this.getAuthClient();
|
||||
const user = client.currentUser();
|
||||
if (!user) return Promise.reject();
|
||||
return this.authenticate(user);
|
||||
}
|
||||
authComponent() {
|
||||
return _AuthenticationPage.default;
|
||||
}
|
||||
async logout() {
|
||||
const client = await this.getAuthClient();
|
||||
try {
|
||||
client.logout();
|
||||
} catch (e) {
|
||||
// due to a bug in the identity widget (gotrue-js actually) the store is not reset if logout fails
|
||||
// TODO: remove after https://github.com/netlify/gotrue-js/pull/83 is merged
|
||||
client.clearStore();
|
||||
}
|
||||
}
|
||||
getToken() {
|
||||
return this.tokenPromise();
|
||||
}
|
||||
async entriesByFolder(folder, extension, depth) {
|
||||
return this.backend.entriesByFolder(folder, extension, depth);
|
||||
}
|
||||
allEntriesByFolder(folder, extension, depth, pathRegex) {
|
||||
return this.backend.allEntriesByFolder(folder, extension, depth, pathRegex);
|
||||
}
|
||||
entriesByFiles(files) {
|
||||
return this.backend.entriesByFiles(files);
|
||||
}
|
||||
getEntry(path) {
|
||||
return this.backend.getEntry(path);
|
||||
}
|
||||
async unpublishedEntryDataFile(collection, slug, path, id) {
|
||||
return this.backend.unpublishedEntryDataFile(collection, slug, path, id);
|
||||
}
|
||||
async isLargeMediaFile(path) {
|
||||
const client = await this.getLargeMediaClient();
|
||||
return client.enabled && client.matchPath(path);
|
||||
}
|
||||
async unpublishedEntryMediaFile(collection, slug, path, id) {
|
||||
const isLargeMedia = await this.isLargeMediaFile(path);
|
||||
if (isLargeMedia) {
|
||||
const branch = this.backend.getBranch(collection, slug);
|
||||
const {
|
||||
url,
|
||||
blob
|
||||
} = await this.getLargeMediaDisplayURL({
|
||||
path,
|
||||
id
|
||||
}, branch);
|
||||
return {
|
||||
id,
|
||||
name: (0, _decapCmsLibUtil.basename)(path),
|
||||
path,
|
||||
url,
|
||||
displayURL: url,
|
||||
file: new File([blob], (0, _decapCmsLibUtil.basename)(path)),
|
||||
size: blob.size
|
||||
};
|
||||
} else {
|
||||
return this.backend.unpublishedEntryMediaFile(collection, slug, path, id);
|
||||
}
|
||||
}
|
||||
getMedia(mediaFolder = this.mediaFolder) {
|
||||
return this.backend.getMedia(mediaFolder);
|
||||
}
|
||||
|
||||
// this method memoizes this._getLargeMediaClient so that there can
|
||||
// only be one client at a time
|
||||
getLargeMediaClient() {
|
||||
if (this._largeMediaClientPromise) {
|
||||
return this._largeMediaClientPromise;
|
||||
}
|
||||
this._largeMediaClientPromise = this._getLargeMediaClient();
|
||||
return this._largeMediaClientPromise;
|
||||
}
|
||||
_getLargeMediaClient() {
|
||||
const netlifyLargeMediaEnabledPromise = this.api.readFile('.lfsconfig').then(config => _ini.default.decode(config)).then(({
|
||||
lfs: {
|
||||
url
|
||||
}
|
||||
}) => new URL(url)).then(lfsURL => ({
|
||||
enabled: lfsURL.hostname.endsWith('netlify.com') || lfsURL.hostname.endsWith('netlify.app')
|
||||
})).catch(err => ({
|
||||
enabled: false,
|
||||
err
|
||||
}));
|
||||
const lfsPatternsPromise = this.api.readFile('.gitattributes').then(attributes => (0, _decapCmsLibUtil.getLargeMediaPatternsFromGitAttributesFile)(attributes)).then(patterns => ({
|
||||
err: null,
|
||||
patterns
|
||||
})).catch(err => {
|
||||
if (err.message.includes('404')) {
|
||||
console.log('This 404 was expected and handled appropriately.');
|
||||
return {
|
||||
err: null,
|
||||
patterns: []
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
err,
|
||||
patterns: []
|
||||
};
|
||||
}
|
||||
});
|
||||
return Promise.all([netlifyLargeMediaEnabledPromise, lfsPatternsPromise]).then(([{
|
||||
enabled: maybeEnabled
|
||||
}, {
|
||||
patterns,
|
||||
err: patternsErr
|
||||
}]) => {
|
||||
const enabled = maybeEnabled && !patternsErr;
|
||||
|
||||
// We expect LFS patterns to exist when the .lfsconfig states
|
||||
// that we're using Netlify Large Media
|
||||
if (maybeEnabled && patternsErr) {
|
||||
console.error(patternsErr);
|
||||
}
|
||||
return (0, _netlifyLfsClient.getClient)({
|
||||
enabled,
|
||||
rootURL: this.netlifyLargeMediaURL,
|
||||
makeAuthorizedRequest: this.requestFunction,
|
||||
patterns,
|
||||
transformImages: this.transformImages ? {
|
||||
nf_resize: 'fit',
|
||||
w: 560,
|
||||
h: 320
|
||||
} : false
|
||||
});
|
||||
});
|
||||
}
|
||||
async getLargeMediaDisplayURL({
|
||||
path,
|
||||
id
|
||||
}, branch = this.branch) {
|
||||
const readFile = (path, id, {
|
||||
parseText
|
||||
}) => this.api.readFile(path, id, {
|
||||
branch,
|
||||
parseText
|
||||
});
|
||||
const items = await (0, _decapCmsLibUtil.entriesByFiles)([{
|
||||
path,
|
||||
id
|
||||
}], readFile, this.api.readFileMetadata.bind(this.api), 'Git-Gateway');
|
||||
const entry = items[0];
|
||||
const pointerFile = (0, _decapCmsLibUtil.parsePointerFile)(entry.data);
|
||||
if (!pointerFile.sha) {
|
||||
console.warn(`Failed parsing pointer file ${path}`);
|
||||
return {
|
||||
url: path,
|
||||
blob: new Blob()
|
||||
};
|
||||
}
|
||||
const client = await this.getLargeMediaClient();
|
||||
const {
|
||||
url,
|
||||
blob
|
||||
} = await client.getDownloadURL(pointerFile);
|
||||
return {
|
||||
url,
|
||||
blob
|
||||
};
|
||||
}
|
||||
async getMediaDisplayURL(displayURL) {
|
||||
const {
|
||||
path,
|
||||
id
|
||||
} = displayURL;
|
||||
const isLargeMedia = await this.isLargeMediaFile(path);
|
||||
if (isLargeMedia) {
|
||||
const {
|
||||
url
|
||||
} = await this.getLargeMediaDisplayURL({
|
||||
path,
|
||||
id
|
||||
});
|
||||
return url;
|
||||
}
|
||||
if (typeof displayURL === 'string') {
|
||||
return displayURL;
|
||||
}
|
||||
const url = await this.backend.getMediaDisplayURL(displayURL);
|
||||
return url;
|
||||
}
|
||||
async getMediaFile(path) {
|
||||
const isLargeMedia = await this.isLargeMediaFile(path);
|
||||
if (isLargeMedia) {
|
||||
const {
|
||||
url,
|
||||
blob
|
||||
} = await this.getLargeMediaDisplayURL({
|
||||
path,
|
||||
id: null
|
||||
});
|
||||
return {
|
||||
id: url,
|
||||
name: (0, _decapCmsLibUtil.basename)(path),
|
||||
path,
|
||||
url,
|
||||
displayURL: url,
|
||||
file: new File([blob], (0, _decapCmsLibUtil.basename)(path)),
|
||||
size: blob.size
|
||||
};
|
||||
}
|
||||
return this.backend.getMediaFile(path);
|
||||
}
|
||||
async persistEntry(entry, options) {
|
||||
const client = await this.getLargeMediaClient();
|
||||
if (client.enabled) {
|
||||
const assets = await (0, _decapCmsLibUtil.getLargeMediaFilteredMediaFiles)(client, entry.assets);
|
||||
return this.backend.persistEntry(_objectSpread(_objectSpread({}, entry), {}, {
|
||||
assets
|
||||
}), options);
|
||||
} else {
|
||||
return this.backend.persistEntry(entry, options);
|
||||
}
|
||||
}
|
||||
async persistMedia(mediaFile, options) {
|
||||
const {
|
||||
fileObj,
|
||||
path
|
||||
} = mediaFile;
|
||||
const displayURL = fileObj ? URL.createObjectURL(fileObj) : '';
|
||||
const client = await this.getLargeMediaClient();
|
||||
const fixedPath = path.startsWith('/') ? path.slice(1) : path;
|
||||
const isLargeMedia = await this.isLargeMediaFile(fixedPath);
|
||||
if (isLargeMedia) {
|
||||
const persistMediaArgument = await (0, _decapCmsLibUtil.getPointerFileForMediaFileObj)(client, fileObj, path);
|
||||
return _objectSpread(_objectSpread({}, await this.backend.persistMedia(persistMediaArgument, options)), {}, {
|
||||
displayURL
|
||||
});
|
||||
}
|
||||
return await this.backend.persistMedia(mediaFile, options);
|
||||
}
|
||||
deleteFiles(paths, commitMessage) {
|
||||
return this.backend.deleteFiles(paths, commitMessage);
|
||||
}
|
||||
async getDeployPreview(collection, slug) {
|
||||
let preview = await this.backend.getDeployPreview(collection, slug);
|
||||
if (!preview) {
|
||||
try {
|
||||
// if the commit doesn't have a status, try to use Netlify API directly
|
||||
// this is useful when builds are queue up in Netlify and don't have a commit status yet
|
||||
// and only works with public logs at the moment
|
||||
// TODO: get Netlify API Token and use it to access private logs
|
||||
const siteId = new URL(localStorage.getItem('netlifySiteURL') || '').hostname;
|
||||
const site = await apiGet(siteId);
|
||||
const deploys = await apiGet(`${site.id}/deploys?per_page=100`);
|
||||
if (deploys.length > 0) {
|
||||
const ref = await this.api.getUnpublishedEntrySha(collection, slug);
|
||||
const deploy = deploys.find(d => d.commit_ref === ref);
|
||||
if (deploy) {
|
||||
preview = {
|
||||
status: deploy.state === 'ready' ? _decapCmsLibUtil.PreviewState.Success : _decapCmsLibUtil.PreviewState.Other,
|
||||
url: deploy.deploy_url
|
||||
};
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
}
|
||||
return preview;
|
||||
}
|
||||
unpublishedEntries() {
|
||||
return this.backend.unpublishedEntries();
|
||||
}
|
||||
unpublishedEntry({
|
||||
id,
|
||||
collection,
|
||||
slug
|
||||
}) {
|
||||
return this.backend.unpublishedEntry({
|
||||
id,
|
||||
collection,
|
||||
slug
|
||||
});
|
||||
}
|
||||
updateUnpublishedEntryStatus(collection, slug, newStatus) {
|
||||
return this.backend.updateUnpublishedEntryStatus(collection, slug, newStatus);
|
||||
}
|
||||
deleteUnpublishedEntry(collection, slug) {
|
||||
return this.backend.deleteUnpublishedEntry(collection, slug);
|
||||
}
|
||||
publishUnpublishedEntry(collection, slug) {
|
||||
return this.backend.publishUnpublishedEntry(collection, slug);
|
||||
}
|
||||
traverseCursor(cursor, action) {
|
||||
return this.backend.traverseCursor(cursor, action);
|
||||
}
|
||||
}
|
||||
exports.default = GitGateway;
|
||||
25
node_modules/decap-cms-backend-git-gateway/dist/esm/index.js
generated
vendored
Normal file
25
node_modules/decap-cms-backend-git-gateway/dist/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "AuthenticationPage", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _AuthenticationPage.default;
|
||||
}
|
||||
});
|
||||
exports.DecapCmsBackendGitGateway = void 0;
|
||||
Object.defineProperty(exports, "GitGatewayBackend", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _implementation.default;
|
||||
}
|
||||
});
|
||||
var _implementation = _interopRequireDefault(require("./implementation"));
|
||||
var _AuthenticationPage = _interopRequireDefault(require("./AuthenticationPage"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
const DecapCmsBackendGitGateway = exports.DecapCmsBackendGitGateway = {
|
||||
GitGatewayBackend: _implementation.default,
|
||||
AuthenticationPage: _AuthenticationPage.default
|
||||
};
|
||||
186
node_modules/decap-cms-backend-git-gateway/dist/esm/netlify-lfs-client.js
generated
vendored
Normal file
186
node_modules/decap-cms-backend-git-gateway/dist/esm/netlify-lfs-client.js
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getClient = getClient;
|
||||
exports.matchPath = matchPath;
|
||||
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
|
||||
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject"));
|
||||
var _map2 = _interopRequireDefault(require("lodash/fp/map"));
|
||||
var _fromPairs2 = _interopRequireDefault(require("lodash/fp/fromPairs"));
|
||||
var _flow2 = _interopRequireDefault(require("lodash/fp/flow"));
|
||||
var _minimatch = _interopRequireDefault(require("minimatch"));
|
||||
var _decapCmsLibUtil = require("decap-cms-lib-util");
|
||||
const _excluded = ["sha"];
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
||||
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
||||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||
function matchPath({
|
||||
patterns
|
||||
}, path) {
|
||||
return patterns.some(pattern => (0, _minimatch.default)(path, pattern, {
|
||||
matchBase: true
|
||||
}));
|
||||
}
|
||||
|
||||
//
|
||||
// API interactions
|
||||
|
||||
const defaultContentHeaders = {
|
||||
Accept: 'application/vnd.git-lfs+json',
|
||||
['Content-Type']: 'application/vnd.git-lfs+json'
|
||||
};
|
||||
async function resourceExists({
|
||||
rootURL,
|
||||
makeAuthorizedRequest
|
||||
}, {
|
||||
sha,
|
||||
size
|
||||
}) {
|
||||
const response = await makeAuthorizedRequest({
|
||||
url: `${rootURL}/verify`,
|
||||
method: 'POST',
|
||||
headers: defaultContentHeaders,
|
||||
body: JSON.stringify({
|
||||
oid: sha,
|
||||
size
|
||||
})
|
||||
});
|
||||
if (response.ok) {
|
||||
return true;
|
||||
}
|
||||
if (response.status === 404) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: what kind of error to throw here? APIError doesn't seem
|
||||
// to fit
|
||||
}
|
||||
function getTransofrmationsParams(t) {
|
||||
if ((0, _isPlainObject2.default)(t) && !(0, _isEmpty2.default)(t)) {
|
||||
const {
|
||||
nf_resize: resize,
|
||||
w,
|
||||
h
|
||||
} = t;
|
||||
return `?nf_resize=${resize}&w=${w}&h=${h}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
async function getDownloadURL({
|
||||
rootURL,
|
||||
transformImages: t,
|
||||
makeAuthorizedRequest
|
||||
}, {
|
||||
sha
|
||||
}) {
|
||||
try {
|
||||
const transformation = getTransofrmationsParams(t);
|
||||
const transformedPromise = makeAuthorizedRequest(`${rootURL}/origin/${sha}${transformation}`);
|
||||
const [transformed, original] = await Promise.all([transformedPromise,
|
||||
// if transformation is defined, we need to load the original so we have the correct meta data
|
||||
transformation ? makeAuthorizedRequest(`${rootURL}/origin/${sha}`) : transformedPromise]);
|
||||
if (!transformed.ok) {
|
||||
const error = await transformed.json();
|
||||
throw new Error(`Failed getting large media for sha '${sha}': '${error.code} - ${error.msg}'`);
|
||||
}
|
||||
const transformedBlob = await transformed.blob();
|
||||
const url = URL.createObjectURL(transformedBlob);
|
||||
return {
|
||||
url,
|
||||
blob: transformation ? await original.blob() : transformedBlob
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
url: '',
|
||||
blob: new Blob()
|
||||
};
|
||||
}
|
||||
}
|
||||
function uploadOperation(objects) {
|
||||
return {
|
||||
operation: 'upload',
|
||||
transfers: ['basic'],
|
||||
objects: objects.map(_ref => {
|
||||
let {
|
||||
sha
|
||||
} = _ref,
|
||||
rest = _objectWithoutProperties(_ref, _excluded);
|
||||
return _objectSpread(_objectSpread({}, rest), {}, {
|
||||
oid: sha
|
||||
});
|
||||
})
|
||||
};
|
||||
}
|
||||
async function getResourceUploadURLs({
|
||||
rootURL,
|
||||
makeAuthorizedRequest
|
||||
}, pointerFiles) {
|
||||
const response = await makeAuthorizedRequest({
|
||||
url: `${rootURL}/objects/batch`,
|
||||
method: 'POST',
|
||||
headers: defaultContentHeaders,
|
||||
body: JSON.stringify(uploadOperation(pointerFiles))
|
||||
});
|
||||
const {
|
||||
objects
|
||||
} = await response.json();
|
||||
const uploadUrls = objects.map(object => {
|
||||
if (object.error) {
|
||||
throw new Error(object.error.message);
|
||||
}
|
||||
return object.actions.upload.href;
|
||||
});
|
||||
return uploadUrls;
|
||||
}
|
||||
function uploadBlob(uploadURL, blob) {
|
||||
return _decapCmsLibUtil.unsentRequest.fetchWithTimeout(uploadURL, {
|
||||
method: 'PUT',
|
||||
body: blob
|
||||
});
|
||||
}
|
||||
async function uploadResource(clientConfig, {
|
||||
sha,
|
||||
size
|
||||
}, resource) {
|
||||
const existingFile = await resourceExists(clientConfig, {
|
||||
sha,
|
||||
size
|
||||
});
|
||||
if (existingFile) {
|
||||
return sha;
|
||||
}
|
||||
const [uploadURL] = await getResourceUploadURLs(clientConfig, [{
|
||||
sha,
|
||||
size
|
||||
}]);
|
||||
await uploadBlob(uploadURL, resource);
|
||||
return sha;
|
||||
}
|
||||
|
||||
//
|
||||
// Create Large Media client
|
||||
|
||||
function configureFn(config, fn) {
|
||||
return (...args) => fn(config, ...args);
|
||||
}
|
||||
const clientFns = {
|
||||
resourceExists,
|
||||
getResourceUploadURLs,
|
||||
getDownloadURL,
|
||||
uploadResource,
|
||||
matchPath
|
||||
};
|
||||
function getClient(clientConfig) {
|
||||
return (0, _flow2.default)([Object.keys, (0, _map2.default)(key => [key, configureFn(clientConfig, clientFns[key])]), _fromPairs2.default, configuredFns => _objectSpread(_objectSpread({}, configuredFns), {}, {
|
||||
patterns: clientConfig.patterns,
|
||||
enabled: clientConfig.enabled
|
||||
})])(clientFns);
|
||||
}
|
||||
1
node_modules/decap-cms-backend-git-gateway/dist/esm/types/ini.d.js
generated
vendored
Normal file
1
node_modules/decap-cms-backend-git-gateway/dist/esm/types/ini.d.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";
|
||||
45
node_modules/decap-cms-backend-git-gateway/package.json
generated
vendored
Normal file
45
node_modules/decap-cms-backend-git-gateway/package.json
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "decap-cms-backend-git-gateway",
|
||||
"description": "Git Gateway backend for Decap CMS",
|
||||
"version": "3.2.2",
|
||||
"repository": "https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git-gateway",
|
||||
"bugs": "https://github.com/decaporg/decap-cms/issues",
|
||||
"module": "dist/esm/index.js",
|
||||
"main": "dist/decap-cms-backend-git-gateway.js",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"decap-cms",
|
||||
"backend",
|
||||
"git-gateway",
|
||||
"gateway"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"develop": "npm run build:esm -- --watch",
|
||||
"build": "cross-env NODE_ENV=production webpack",
|
||||
"build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\""
|
||||
},
|
||||
"dependencies": {
|
||||
"gotrue-js": "^0.9.24",
|
||||
"ini": "^2.0.0",
|
||||
"jwt-decode": "^3.0.0",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"decap-cms-backend-bitbucket": "^3.0.0",
|
||||
"decap-cms-backend-github": "^3.0.0",
|
||||
"decap-cms-backend-gitlab": "^3.0.0",
|
||||
"decap-cms-lib-auth": "^3.0.0",
|
||||
"decap-cms-lib-util": "^3.0.0",
|
||||
"decap-cms-ui-default": "^3.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/minimatch": "^5.1.2"
|
||||
},
|
||||
"gitHead": "64d91b8bb3d0a93dd36c53800cdac4ba2e435000"
|
||||
}
|
||||
227
node_modules/decap-cms-backend-git-gateway/src/AuthenticationPage.js
generated
vendored
Normal file
227
node_modules/decap-cms-backend-git-gateway/src/AuthenticationPage.js
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { partial } from 'lodash';
|
||||
import {
|
||||
AuthenticationPage,
|
||||
buttons,
|
||||
shadows,
|
||||
colors,
|
||||
colorsRaw,
|
||||
lengths,
|
||||
zIndex,
|
||||
} from 'decap-cms-ui-default';
|
||||
|
||||
const LoginButton = styled.button`
|
||||
${buttons.button};
|
||||
${shadows.dropDeep};
|
||||
${buttons.default};
|
||||
${buttons.gray};
|
||||
|
||||
padding: 0 30px;
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
margin-left: auto;
|
||||
`;
|
||||
|
||||
const AuthForm = styled.form`
|
||||
width: 350px;
|
||||
margin-top: -80px;
|
||||
`;
|
||||
|
||||
const AuthInput = styled.input`
|
||||
background-color: ${colorsRaw.white};
|
||||
border-radius: ${lengths.borderRadius};
|
||||
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 6px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: ${zIndex.zIndex1};
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 2px ${colors.active};
|
||||
}
|
||||
`;
|
||||
|
||||
const ErrorMessage = styled.p`
|
||||
color: ${colors.errorText};
|
||||
`;
|
||||
|
||||
let component = null;
|
||||
|
||||
if (window.netlifyIdentity) {
|
||||
window.netlifyIdentity.on('login', user => {
|
||||
component && component.handleIdentityLogin(user);
|
||||
});
|
||||
window.netlifyIdentity.on('logout', () => {
|
||||
component && component.handleIdentityLogout();
|
||||
});
|
||||
window.netlifyIdentity.on('error', err => {
|
||||
component && component.handleIdentityError(err);
|
||||
});
|
||||
}
|
||||
|
||||
export default class GitGatewayAuthenticationPage extends React.Component {
|
||||
static authClient;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
component = this;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.loggedIn && window.netlifyIdentity && window.netlifyIdentity.currentUser()) {
|
||||
this.props.onLogin(window.netlifyIdentity.currentUser());
|
||||
window.netlifyIdentity.close();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
component = null;
|
||||
}
|
||||
|
||||
handleIdentityLogin = user => {
|
||||
this.props.onLogin(user);
|
||||
window.netlifyIdentity.close();
|
||||
};
|
||||
|
||||
handleIdentityLogout = () => {
|
||||
window.netlifyIdentity.open();
|
||||
};
|
||||
|
||||
handleIdentityError = err => {
|
||||
if (err?.message?.match(/^Failed to load settings from.+\.netlify\/identity$/)) {
|
||||
window.netlifyIdentity.close();
|
||||
this.setState({
|
||||
errors: { identity: this.props.t('auth.errors.identitySettings') },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleIdentity = () => {
|
||||
const user = window.netlifyIdentity.currentUser();
|
||||
if (user) {
|
||||
this.props.onLogin(user);
|
||||
} else {
|
||||
window.netlifyIdentity.open();
|
||||
}
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
onLogin: PropTypes.func.isRequired,
|
||||
inProgress: PropTypes.bool.isRequired,
|
||||
error: PropTypes.node,
|
||||
config: PropTypes.object.isRequired,
|
||||
t: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
state = { email: '', password: '', errors: {} };
|
||||
|
||||
handleChange = (name, e) => {
|
||||
this.setState({ ...this.state, [name]: e.target.value });
|
||||
};
|
||||
|
||||
handleLogin = async e => {
|
||||
e.preventDefault();
|
||||
|
||||
const { email, password } = this.state;
|
||||
const { t } = this.props;
|
||||
const errors = {};
|
||||
if (!email) {
|
||||
errors.email = t('auth.errors.email');
|
||||
}
|
||||
if (!password) {
|
||||
errors.password = t('auth.errors.password');
|
||||
}
|
||||
|
||||
if (Object.keys(errors).length > 0) {
|
||||
this.setState({ errors });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const client = await GitGatewayAuthenticationPage.authClient();
|
||||
const user = await client.login(this.state.email, this.state.password, true);
|
||||
this.props.onLogin(user);
|
||||
} catch (error) {
|
||||
this.setState({
|
||||
errors: { server: error.description || error.msg || error },
|
||||
loggingIn: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { errors } = this.state;
|
||||
const { error, inProgress, config, t } = this.props;
|
||||
|
||||
if (window.netlifyIdentity) {
|
||||
if (errors.identity) {
|
||||
return (
|
||||
<AuthenticationPage
|
||||
logoUrl={config.logo_url}
|
||||
siteUrl={config.site_url}
|
||||
onLogin={this.handleIdentity}
|
||||
renderPageContent={() => (
|
||||
<a
|
||||
href="https://docs.netlify.com/visitor-access/git-gateway/#setup-and-settings"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{errors.identity}
|
||||
</a>
|
||||
)}
|
||||
t={t}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<AuthenticationPage
|
||||
logoUrl={config.logo_url}
|
||||
siteUrl={config.site_url}
|
||||
onLogin={this.handleIdentity}
|
||||
renderButtonContent={() => t('auth.loginWithNetlifyIdentity')}
|
||||
t={t}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthenticationPage
|
||||
logoUrl={config.logo_url}
|
||||
siteUrl={config.site_url}
|
||||
renderPageContent={() => (
|
||||
<AuthForm onSubmit={this.handleLogin}>
|
||||
{!error ? null : <ErrorMessage>{error}</ErrorMessage>}
|
||||
{!errors.server ? null : <ErrorMessage>{String(errors.server)}</ErrorMessage>}
|
||||
<ErrorMessage>{errors.email || null}</ErrorMessage>
|
||||
<AuthInput
|
||||
type="text"
|
||||
name="email"
|
||||
placeholder="Email"
|
||||
value={this.state.email}
|
||||
onChange={partial(this.handleChange, 'email')}
|
||||
/>
|
||||
<ErrorMessage>{errors.password || null}</ErrorMessage>
|
||||
<AuthInput
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
value={this.state.password}
|
||||
onChange={partial(this.handleChange, 'password')}
|
||||
/>
|
||||
<LoginButton disabled={inProgress}>
|
||||
{inProgress ? t('auth.loggingIn') : t('auth.login')}
|
||||
</LoginButton>
|
||||
</AuthForm>
|
||||
)}
|
||||
t={t}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
133
node_modules/decap-cms-backend-git-gateway/src/GitHubAPI.ts
generated
vendored
Normal file
133
node_modules/decap-cms-backend-git-gateway/src/GitHubAPI.ts
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
import { API as GithubAPI } from 'decap-cms-backend-github';
|
||||
import { APIError } from 'decap-cms-lib-util';
|
||||
|
||||
import type { Config as GitHubConfig, Diff } from 'decap-cms-backend-github/src/API';
|
||||
import type { FetchError } from 'decap-cms-lib-util';
|
||||
import type { Octokit } from '@octokit/rest';
|
||||
|
||||
type Config = Omit<GitHubConfig, 'getUser'> & {
|
||||
apiRoot: string;
|
||||
tokenPromise: () => Promise<string>;
|
||||
commitAuthor: { name: string };
|
||||
isLargeMedia: (filename: string) => Promise<boolean>;
|
||||
};
|
||||
|
||||
export default class API extends GithubAPI {
|
||||
tokenPromise: () => Promise<string>;
|
||||
commitAuthor: { name: string };
|
||||
isLargeMedia: (filename: string) => Promise<boolean>;
|
||||
|
||||
constructor(config: Config) {
|
||||
super({
|
||||
getUser: () => Promise.reject('Never used'),
|
||||
...config,
|
||||
});
|
||||
this.apiRoot = config.apiRoot;
|
||||
this.tokenPromise = config.tokenPromise;
|
||||
this.commitAuthor = config.commitAuthor;
|
||||
this.isLargeMedia = config.isLargeMedia;
|
||||
this.repoURL = '';
|
||||
this.originRepoURL = '';
|
||||
}
|
||||
|
||||
hasWriteAccess() {
|
||||
return this.getDefaultBranch()
|
||||
.then(() => true)
|
||||
.catch((error: FetchError) => {
|
||||
if (error.status === 401) {
|
||||
if (error.message === 'Bad credentials') {
|
||||
throw new APIError(
|
||||
'Git Gateway Error: Please ask your site administrator to reissue the Git Gateway token.',
|
||||
error.status,
|
||||
'Git Gateway',
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (
|
||||
error.status === 404 &&
|
||||
(error.message === undefined || error.message === 'Unable to locate site configuration')
|
||||
) {
|
||||
throw new APIError(
|
||||
`Git Gateway Error: Please make sure Git Gateway is enabled on your site.`,
|
||||
error.status,
|
||||
'Git Gateway',
|
||||
);
|
||||
} else {
|
||||
console.error('Problem fetching repo data from Git Gateway');
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
requestHeaders(headers = {}) {
|
||||
return this.tokenPromise().then(jwtToken => {
|
||||
const baseHeader = {
|
||||
Authorization: `Bearer ${jwtToken}`,
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
...headers,
|
||||
};
|
||||
|
||||
return baseHeader;
|
||||
});
|
||||
}
|
||||
|
||||
handleRequestError(error: FetchError & { msg: string }, responseStatus: number) {
|
||||
throw new APIError(error.message || error.msg, responseStatus, 'Git Gateway');
|
||||
}
|
||||
|
||||
user() {
|
||||
return Promise.resolve({ login: '', ...this.commitAuthor });
|
||||
}
|
||||
|
||||
async getHeadReference(head: string) {
|
||||
if (!this.repoOwner) {
|
||||
// get the repo owner from the branch url
|
||||
// this is required for returning the full head reference, e.g. owner:head
|
||||
// when filtering pull requests based on the head
|
||||
const branch = await this.getDefaultBranch();
|
||||
const self = branch._links.self;
|
||||
const regex = new RegExp('https?://.+?/repos/(.+?)/');
|
||||
const owner = self.match(regex);
|
||||
this.repoOwner = owner ? owner[1] : '';
|
||||
}
|
||||
return super.getHeadReference(head);
|
||||
}
|
||||
|
||||
commit(message: string, changeTree: { parentSha?: string; sha: string }) {
|
||||
const commitParams: {
|
||||
message: string;
|
||||
tree: string;
|
||||
parents: string[];
|
||||
author?: { name: string; date: string };
|
||||
} = {
|
||||
message,
|
||||
tree: changeTree.sha,
|
||||
parents: changeTree.parentSha ? [changeTree.parentSha] : [],
|
||||
};
|
||||
|
||||
if (this.commitAuthor) {
|
||||
commitParams.author = {
|
||||
...this.commitAuthor,
|
||||
date: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
return this.request('/git/commits', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(commitParams),
|
||||
});
|
||||
}
|
||||
|
||||
nextUrlProcessor() {
|
||||
return (url: string) => url.replace(/^(?:[a-z]+:\/\/.+?\/.+?\/.+?\/)/, `${this.apiRoot}/`);
|
||||
}
|
||||
|
||||
async diffFromFile(file: Octokit.ReposCompareCommitsResponseFilesItem): Promise<Diff> {
|
||||
const diff = await super.diffFromFile(file);
|
||||
return {
|
||||
...diff,
|
||||
binary: diff.binary || (await this.isLargeMedia(file.filename)),
|
||||
};
|
||||
}
|
||||
}
|
||||
30
node_modules/decap-cms-backend-git-gateway/src/GitLabAPI.ts
generated
vendored
Normal file
30
node_modules/decap-cms-backend-git-gateway/src/GitLabAPI.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { API as GitlabAPI } from 'decap-cms-backend-gitlab';
|
||||
import { unsentRequest } from 'decap-cms-lib-util';
|
||||
|
||||
import type { Config as GitLabConfig, CommitAuthor } from 'decap-cms-backend-gitlab/src/API';
|
||||
import type { ApiRequest } from 'decap-cms-lib-util';
|
||||
|
||||
type Config = GitLabConfig & { tokenPromise: () => Promise<string>; commitAuthor: CommitAuthor };
|
||||
|
||||
export default class API extends GitlabAPI {
|
||||
tokenPromise: () => Promise<string>;
|
||||
|
||||
constructor(config: Config) {
|
||||
super(config);
|
||||
this.tokenPromise = config.tokenPromise;
|
||||
this.commitAuthor = config.commitAuthor;
|
||||
this.repoURL = '';
|
||||
}
|
||||
|
||||
withAuthorizationHeaders = async (req: ApiRequest) => {
|
||||
const token = await this.tokenPromise();
|
||||
return unsentRequest.withHeaders(
|
||||
{
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
req,
|
||||
);
|
||||
};
|
||||
|
||||
hasWriteAccess = () => Promise.resolve(true);
|
||||
}
|
||||
54
node_modules/decap-cms-backend-git-gateway/src/__tests__/AuthenticationPage.spec.js
generated
vendored
Normal file
54
node_modules/decap-cms-backend-git-gateway/src/__tests__/AuthenticationPage.spec.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import GitGatewayAuthenticationPage from '../AuthenticationPage';
|
||||
|
||||
window.netlifyIdentity = {
|
||||
currentUser: jest.fn(),
|
||||
on: jest.fn(),
|
||||
close: jest.fn(),
|
||||
};
|
||||
|
||||
describe('GitGatewayAuthenticationPage', () => {
|
||||
const props = {
|
||||
config: { logo_url: 'logo_url' },
|
||||
t: jest.fn(key => key),
|
||||
onLogin: jest.fn(),
|
||||
inProgress: false,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
});
|
||||
|
||||
it('should render with identity error', () => {
|
||||
// obtain mock calls
|
||||
require('../AuthenticationPage');
|
||||
|
||||
function TestComponent() {
|
||||
const { asFragment } = render(<GitGatewayAuthenticationPage {...props} />);
|
||||
|
||||
const errorCallback = window.netlifyIdentity.on.mock.calls.find(
|
||||
call => call[0] === 'error',
|
||||
)[1];
|
||||
|
||||
errorCallback(
|
||||
new Error('Failed to load settings from https://site.netlify.com/.netlify/identity'),
|
||||
);
|
||||
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
}
|
||||
|
||||
TestComponent();
|
||||
});
|
||||
|
||||
test('should render with no identity error', () => {
|
||||
function TestComponent() {
|
||||
const { asFragment } = render(<GitGatewayAuthenticationPage {...props} />);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
}
|
||||
|
||||
TestComponent();
|
||||
});
|
||||
});
|
||||
97
node_modules/decap-cms-backend-git-gateway/src/__tests__/GitHubAPI.spec.js
generated
vendored
Normal file
97
node_modules/decap-cms-backend-git-gateway/src/__tests__/GitHubAPI.spec.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
import API from '../GitHubAPI';
|
||||
|
||||
describe('github API', () => {
|
||||
describe('request', () => {
|
||||
beforeEach(() => {
|
||||
const fetch = jest.fn();
|
||||
global.fetch = fetch;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should fetch url with authorization header', async () => {
|
||||
const api = new API({
|
||||
apiRoot: 'https://site.netlify.com/.netlify/git/github',
|
||||
tokenPromise: () => Promise.resolve('token'),
|
||||
});
|
||||
|
||||
fetch.mockResolvedValue({
|
||||
text: jest.fn().mockResolvedValue('some response'),
|
||||
ok: true,
|
||||
status: 200,
|
||||
headers: { get: () => '' },
|
||||
});
|
||||
const result = await api.request('/some-path');
|
||||
expect(result).toEqual('some response');
|
||||
expect(fetch).toHaveBeenCalledTimes(1);
|
||||
expect(fetch).toHaveBeenCalledWith('https://site.netlify.com/.netlify/git/github/some-path', {
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
Authorization: 'Bearer token',
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
},
|
||||
signal: expect.any(AbortSignal),
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error on not ok response with message property', async () => {
|
||||
const api = new API({
|
||||
apiRoot: 'https://site.netlify.com/.netlify/git/github',
|
||||
tokenPromise: () => Promise.resolve('token'),
|
||||
});
|
||||
|
||||
fetch.mockResolvedValue({
|
||||
text: jest.fn().mockResolvedValue({ message: 'some error' }),
|
||||
ok: false,
|
||||
status: 404,
|
||||
headers: { get: () => '' },
|
||||
});
|
||||
|
||||
await expect(api.request('some-path')).rejects.toThrow(
|
||||
expect.objectContaining({
|
||||
message: 'some error',
|
||||
name: 'API_ERROR',
|
||||
status: 404,
|
||||
api: 'Git Gateway',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error on not ok response with msg property', async () => {
|
||||
const api = new API({
|
||||
apiRoot: 'https://site.netlify.com/.netlify/git/github',
|
||||
tokenPromise: () => Promise.resolve('token'),
|
||||
});
|
||||
|
||||
fetch.mockResolvedValue({
|
||||
text: jest.fn().mockResolvedValue({ msg: 'some error' }),
|
||||
ok: false,
|
||||
status: 404,
|
||||
headers: { get: () => '' },
|
||||
});
|
||||
|
||||
await expect(api.request('some-path')).rejects.toThrow(
|
||||
expect.objectContaining({
|
||||
message: 'some error',
|
||||
name: 'API_ERROR',
|
||||
status: 404,
|
||||
api: 'Git Gateway',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('nextUrlProcessor', () => {
|
||||
it('should re-write github url', () => {
|
||||
const api = new API({
|
||||
apiRoot: 'https://site.netlify.com/.netlify/git/github',
|
||||
});
|
||||
|
||||
expect(api.nextUrlProcessor()('https://api.github.com/repositories/10000/pulls')).toEqual(
|
||||
'https://site.netlify.com/.netlify/git/github/pulls',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
277
node_modules/decap-cms-backend-git-gateway/src/__tests__/__snapshots__/AuthenticationPage.spec.js.snap
generated
vendored
Normal file
277
node_modules/decap-cms-backend-git-gateway/src/__tests__/__snapshots__/AuthenticationPage.spec.js.snap
generated
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`GitGatewayAuthenticationPage should render with identity error 1`] = `
|
||||
<DocumentFragment>
|
||||
.emotion-0 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-flex-flow: column nowrap;
|
||||
-webkit-flex-flow: column nowrap;
|
||||
-ms-flex-flow: column nowrap;
|
||||
flex-flow: column nowrap;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
gap: 50px;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.emotion-2 {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.emotion-4 {
|
||||
border: 0;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 12px 0 rgba(68, 74, 87, 0.15),0 1px 3px 0 rgba(68, 74, 87, 0.25);
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-weight: 500;
|
||||
padding: 0 15px;
|
||||
background-color: #798291;
|
||||
color: #fff;
|
||||
background-color: #313d3e;
|
||||
color: #fff;
|
||||
padding: 0 12px;
|
||||
margin-top: 0;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emotion-4:focus,
|
||||
.emotion-4:hover {
|
||||
color: #fff;
|
||||
background-color: #555a65;
|
||||
}
|
||||
|
||||
.emotion-4[disabled] {
|
||||
background-color: #eff0f4;
|
||||
color: #798291;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.emotion-7 {
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-ms-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
color: #c4c6d2;
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.emotion-7 path:not(.no-fill),
|
||||
.emotion-7 circle:not(.no-fill),
|
||||
.emotion-7 polygon:not(.no-fill),
|
||||
.emotion-7 rect:not(.no-fill) {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.emotion-7 path.clipped {
|
||||
fill: transparent;
|
||||
}
|
||||
|
||||
.emotion-7 svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
<section
|
||||
class="emotion-0 emotion-1"
|
||||
>
|
||||
<span
|
||||
class="emotion-2 emotion-3"
|
||||
>
|
||||
<img
|
||||
alt="Logo"
|
||||
src="logo_url"
|
||||
/>
|
||||
</span>
|
||||
<button
|
||||
class="emotion-4 emotion-5"
|
||||
>
|
||||
auth.loginWithNetlifyIdentity
|
||||
</button>
|
||||
<span
|
||||
class="emotion-6 emotion-7 emotion-8"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="90"
|
||||
viewBox="0 0 335 90"
|
||||
width="335"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
class="no-fill"
|
||||
d="M30.73.15 0 2.95l3.67 40.21 20.03-1.83-1.99-21.86 10.71-.98c10.61-.97 19.14 7.53 20.29 20.19l19.67-1.79C70.34 14.72 51.64-1.75 30.73.15ZM73.61 49.51c0 12.72-7.73 21.95-18.37 21.95H44.49V49.47H24.38v40.42h30.86c21.02 0 38.12-18.11 38.12-40.38v-.04H73.61v.04Z"
|
||||
fill="#FF0082"
|
||||
/>
|
||||
<path
|
||||
class="no-fill"
|
||||
d="M131.65 23.71h20.01c14.41 0 24.29 9.09 24.29 23.06 0 13.97-9.88 23.06-24.29 23.06h-20.01V23.71Zm19.51 37.35c8.75 0 14.47-5.47 14.47-14.29s-5.73-14.29-14.47-14.29h-9.31v28.59h9.31v-.01ZM207.61 58.69l5.22 5.93c-3.15 3.75-7.87 5.73-13.97 5.73-11.7 0-19.32-7.71-19.32-18.25s7.68-18.25 18.12-18.25c9.56 0 17.43 6.59 17.49 17.92l-25.04 5.07c1.45 3.49 4.59 5.27 9 5.27 3.59 0 6.17-1.12 8.5-3.43v.01Zm-18.44-7.64 16.49-3.36c-.94-3.62-3.9-6.06-7.99-6.06-4.91 0-8.31 3.43-8.5 9.42ZM218.25 52.1c0-10.67 7.87-18.25 18.88-18.25 7.11 0 12.71 3.23 15.17 9.02l-7.61 4.28c-1.83-3.36-4.53-4.87-7.61-4.87-4.97 0-8.87 3.62-8.87 9.81s3.9 9.81 8.87 9.81c3.08 0 5.79-1.45 7.61-4.87l7.61 4.35c-2.45 5.67-8.05 8.96-15.17 8.96-11.01 0-18.88-7.58-18.88-18.25v.01ZM290.93 34.38v35.44h-9.38v-4.08c-2.45 3.1-6.04 4.61-10.57 4.61-9.57 0-16.93-7.11-16.93-18.25s7.36-18.25 16.93-18.25c4.15 0 7.68 1.38 10.13 4.28v-3.75h9.82ZM281.3 52.1c0-6.13-3.78-9.81-8.62-9.81S264 45.98 264 52.1c0 6.12 3.78 9.81 8.68 9.81s8.62-3.69 8.62-9.81ZM334.54 52.1c0 11.13-7.36 18.25-16.86 18.25-4.22 0-7.68-1.38-10.19-4.28V82.6h-9.82V34.38h9.38v4.08c2.45-3.1 6.1-4.61 10.63-4.61 9.5 0 16.86 7.11 16.86 18.25Zm-9.94 0c0-6.13-3.71-9.81-8.62-9.81-4.91 0-8.62 3.69-8.62 9.81 0 6.12 3.71 9.81 8.62 9.81 4.91 0 8.62-3.69 8.62-9.81Z"
|
||||
fill="#000"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</section>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`GitGatewayAuthenticationPage should render with no identity error 1`] = `
|
||||
<DocumentFragment>
|
||||
.emotion-0 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-flex-flow: column nowrap;
|
||||
-webkit-flex-flow: column nowrap;
|
||||
-ms-flex-flow: column nowrap;
|
||||
flex-flow: column nowrap;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
gap: 50px;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.emotion-2 {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.emotion-4 {
|
||||
border: 0;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 12px 0 rgba(68, 74, 87, 0.15),0 1px 3px 0 rgba(68, 74, 87, 0.25);
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-weight: 500;
|
||||
padding: 0 15px;
|
||||
background-color: #798291;
|
||||
color: #fff;
|
||||
background-color: #313d3e;
|
||||
color: #fff;
|
||||
padding: 0 12px;
|
||||
margin-top: 0;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.emotion-4:focus,
|
||||
.emotion-4:hover {
|
||||
color: #fff;
|
||||
background-color: #555a65;
|
||||
}
|
||||
|
||||
.emotion-4[disabled] {
|
||||
background-color: #eff0f4;
|
||||
color: #798291;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.emotion-7 {
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-ms-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
color: #c4c6d2;
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.emotion-7 path:not(.no-fill),
|
||||
.emotion-7 circle:not(.no-fill),
|
||||
.emotion-7 polygon:not(.no-fill),
|
||||
.emotion-7 rect:not(.no-fill) {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.emotion-7 path.clipped {
|
||||
fill: transparent;
|
||||
}
|
||||
|
||||
.emotion-7 svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
<section
|
||||
class="emotion-0 emotion-1"
|
||||
>
|
||||
<span
|
||||
class="emotion-2 emotion-3"
|
||||
>
|
||||
<img
|
||||
alt="Logo"
|
||||
src="logo_url"
|
||||
/>
|
||||
</span>
|
||||
<button
|
||||
class="emotion-4 emotion-5"
|
||||
>
|
||||
auth.loginWithNetlifyIdentity
|
||||
</button>
|
||||
<span
|
||||
class="emotion-6 emotion-7 emotion-8"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="90"
|
||||
viewBox="0 0 335 90"
|
||||
width="335"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
class="no-fill"
|
||||
d="M30.73.15 0 2.95l3.67 40.21 20.03-1.83-1.99-21.86 10.71-.98c10.61-.97 19.14 7.53 20.29 20.19l19.67-1.79C70.34 14.72 51.64-1.75 30.73.15ZM73.61 49.51c0 12.72-7.73 21.95-18.37 21.95H44.49V49.47H24.38v40.42h30.86c21.02 0 38.12-18.11 38.12-40.38v-.04H73.61v.04Z"
|
||||
fill="#FF0082"
|
||||
/>
|
||||
<path
|
||||
class="no-fill"
|
||||
d="M131.65 23.71h20.01c14.41 0 24.29 9.09 24.29 23.06 0 13.97-9.88 23.06-24.29 23.06h-20.01V23.71Zm19.51 37.35c8.75 0 14.47-5.47 14.47-14.29s-5.73-14.29-14.47-14.29h-9.31v28.59h9.31v-.01ZM207.61 58.69l5.22 5.93c-3.15 3.75-7.87 5.73-13.97 5.73-11.7 0-19.32-7.71-19.32-18.25s7.68-18.25 18.12-18.25c9.56 0 17.43 6.59 17.49 17.92l-25.04 5.07c1.45 3.49 4.59 5.27 9 5.27 3.59 0 6.17-1.12 8.5-3.43v.01Zm-18.44-7.64 16.49-3.36c-.94-3.62-3.9-6.06-7.99-6.06-4.91 0-8.31 3.43-8.5 9.42ZM218.25 52.1c0-10.67 7.87-18.25 18.88-18.25 7.11 0 12.71 3.23 15.17 9.02l-7.61 4.28c-1.83-3.36-4.53-4.87-7.61-4.87-4.97 0-8.87 3.62-8.87 9.81s3.9 9.81 8.87 9.81c3.08 0 5.79-1.45 7.61-4.87l7.61 4.35c-2.45 5.67-8.05 8.96-15.17 8.96-11.01 0-18.88-7.58-18.88-18.25v.01ZM290.93 34.38v35.44h-9.38v-4.08c-2.45 3.1-6.04 4.61-10.57 4.61-9.57 0-16.93-7.11-16.93-18.25s7.36-18.25 16.93-18.25c4.15 0 7.68 1.38 10.13 4.28v-3.75h9.82ZM281.3 52.1c0-6.13-3.78-9.81-8.62-9.81S264 45.98 264 52.1c0 6.12 3.78 9.81 8.68 9.81s8.62-3.69 8.62-9.81ZM334.54 52.1c0 11.13-7.36 18.25-16.86 18.25-4.22 0-7.68-1.38-10.19-4.28V82.6h-9.82V34.38h9.38v4.08c2.45-3.1 6.1-4.61 10.63-4.61 9.5 0 16.86 7.11 16.86 18.25Zm-9.94 0c0-6.13-3.71-9.81-8.62-9.81-4.91 0-8.62 3.69-8.62 9.81 0 6.12 3.71 9.81 8.62 9.81 4.91 0 8.62-3.69 8.62-9.81Z"
|
||||
fill="#000"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</section>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
629
node_modules/decap-cms-backend-git-gateway/src/implementation.ts
generated
vendored
Normal file
629
node_modules/decap-cms-backend-git-gateway/src/implementation.ts
generated
vendored
Normal file
@@ -0,0 +1,629 @@
|
||||
import GoTrue from 'gotrue-js';
|
||||
import jwtDecode from 'jwt-decode';
|
||||
import { get, pick, intersection } from 'lodash';
|
||||
import ini from 'ini';
|
||||
import {
|
||||
APIError,
|
||||
unsentRequest,
|
||||
basename,
|
||||
entriesByFiles,
|
||||
parsePointerFile,
|
||||
getLargeMediaPatternsFromGitAttributesFile,
|
||||
getPointerFileForMediaFileObj,
|
||||
getLargeMediaFilteredMediaFiles,
|
||||
AccessTokenError,
|
||||
PreviewState,
|
||||
} from 'decap-cms-lib-util';
|
||||
import { GitHubBackend } from 'decap-cms-backend-github';
|
||||
import { GitLabBackend } from 'decap-cms-backend-gitlab';
|
||||
import { BitbucketBackend, API as BitBucketAPI } from 'decap-cms-backend-bitbucket';
|
||||
|
||||
import GitHubAPI from './GitHubAPI';
|
||||
import GitLabAPI from './GitLabAPI';
|
||||
import AuthenticationPage from './AuthenticationPage';
|
||||
import { getClient } from './netlify-lfs-client';
|
||||
|
||||
import type { Client } from './netlify-lfs-client';
|
||||
import type {
|
||||
ApiRequest,
|
||||
AssetProxy,
|
||||
PersistOptions,
|
||||
Entry,
|
||||
Cursor,
|
||||
Implementation,
|
||||
DisplayURL,
|
||||
User,
|
||||
Credentials,
|
||||
Config,
|
||||
ImplementationFile,
|
||||
DisplayURLObject,
|
||||
} from 'decap-cms-lib-util';
|
||||
|
||||
const STATUS_PAGE = 'https://www.netlifystatus.com';
|
||||
const GIT_GATEWAY_STATUS_ENDPOINT = `${STATUS_PAGE}/api/v2/components.json`;
|
||||
const GIT_GATEWAY_OPERATIONAL_UNITS = ['Git Gateway'];
|
||||
type GitGatewayStatus = {
|
||||
id: string;
|
||||
name: string;
|
||||
status: string;
|
||||
};
|
||||
|
||||
type NetlifyIdentity = {
|
||||
logout: () => void;
|
||||
currentUser: () => User;
|
||||
on: (event: string, args: unknown) => void;
|
||||
init: () => void;
|
||||
store: { user: unknown; modal: { page: string }; saving: boolean };
|
||||
};
|
||||
|
||||
type AuthClient = {
|
||||
logout: () => void;
|
||||
currentUser: () => unknown;
|
||||
login?(email: string, password: string, remember?: boolean): Promise<unknown>;
|
||||
clearStore: () => void;
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
netlifyIdentity?: NetlifyIdentity;
|
||||
}
|
||||
}
|
||||
|
||||
const localHosts: Record<string, boolean> = {
|
||||
localhost: true,
|
||||
'127.0.0.1': true,
|
||||
'0.0.0.0': true,
|
||||
};
|
||||
const defaults = {
|
||||
identity: '/.netlify/identity',
|
||||
gateway: '/.netlify/git',
|
||||
largeMedia: '/.netlify/large-media',
|
||||
};
|
||||
|
||||
function getEndpoint(endpoint: string, netlifySiteURL: string | null) {
|
||||
if (
|
||||
localHosts[document.location.host.split(':').shift() as string] &&
|
||||
netlifySiteURL &&
|
||||
endpoint.match(/^\/\.netlify\//)
|
||||
) {
|
||||
const parts = [];
|
||||
if (netlifySiteURL) {
|
||||
parts.push(netlifySiteURL);
|
||||
if (!netlifySiteURL.match(/\/$/)) {
|
||||
parts.push('/');
|
||||
}
|
||||
}
|
||||
parts.push(endpoint.replace(/^\//, ''));
|
||||
return parts.join('');
|
||||
}
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
// wait for identity widget to initialize
|
||||
// force init on timeout
|
||||
let initPromise = Promise.resolve() as Promise<unknown>;
|
||||
if (window.netlifyIdentity) {
|
||||
let initialized = false;
|
||||
initPromise = Promise.race([
|
||||
new Promise<void>(resolve => {
|
||||
window.netlifyIdentity?.on('init', () => {
|
||||
initialized = true;
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
new Promise(resolve => setTimeout(resolve, 2500)).then(() => {
|
||||
if (!initialized) {
|
||||
console.log('Manually initializing identity widget');
|
||||
window.netlifyIdentity?.init();
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
interface NetlifyUser extends Credentials {
|
||||
jwt: () => Promise<string>;
|
||||
email: string;
|
||||
user_metadata: { full_name: string; avatar_url: string };
|
||||
}
|
||||
|
||||
async function apiGet(path: string) {
|
||||
const apiRoot = 'https://api.netlify.com/api/v1/sites';
|
||||
const response = await fetch(`${apiRoot}/${path}`).then(res => res.json());
|
||||
return response;
|
||||
}
|
||||
|
||||
export default class GitGateway implements Implementation {
|
||||
config: Config;
|
||||
api?: GitHubAPI | GitLabAPI | BitBucketAPI;
|
||||
branch: string;
|
||||
squashMerges: boolean;
|
||||
cmsLabelPrefix: string;
|
||||
mediaFolder: string;
|
||||
transformImages: boolean;
|
||||
gatewayUrl: string;
|
||||
netlifyLargeMediaURL: string;
|
||||
backendType: string | null;
|
||||
apiUrl: string;
|
||||
authClient?: AuthClient;
|
||||
backend: GitHubBackend | GitLabBackend | BitbucketBackend | null;
|
||||
acceptRoles?: string[];
|
||||
tokenPromise?: () => Promise<string>;
|
||||
_largeMediaClientPromise?: Promise<Client>;
|
||||
|
||||
options: {
|
||||
proxied: boolean;
|
||||
API: GitHubAPI | GitLabAPI | BitBucketAPI | null;
|
||||
initialWorkflowStatus: string;
|
||||
};
|
||||
constructor(config: Config, options = {}) {
|
||||
this.options = {
|
||||
proxied: true,
|
||||
API: null,
|
||||
initialWorkflowStatus: '',
|
||||
...options,
|
||||
};
|
||||
this.config = config;
|
||||
this.branch = config.backend.branch?.trim() || 'master';
|
||||
this.squashMerges = config.backend.squash_merges || false;
|
||||
this.cmsLabelPrefix = config.backend.cms_label_prefix || '';
|
||||
this.mediaFolder = config.media_folder;
|
||||
const { use_large_media_transforms_in_media_library: transformImages = true } = config.backend;
|
||||
this.transformImages = transformImages;
|
||||
|
||||
const netlifySiteURL = localStorage.getItem('netlifySiteURL');
|
||||
this.apiUrl = getEndpoint(config.backend.identity_url || defaults.identity, netlifySiteURL);
|
||||
this.gatewayUrl = getEndpoint(config.backend.gateway_url || defaults.gateway, netlifySiteURL);
|
||||
this.netlifyLargeMediaURL = getEndpoint(
|
||||
config.backend.large_media_url || defaults.largeMedia,
|
||||
netlifySiteURL,
|
||||
);
|
||||
const backendTypeRegex = /\/(github|gitlab|bitbucket)\/?$/;
|
||||
const backendTypeMatches = this.gatewayUrl.match(backendTypeRegex);
|
||||
if (backendTypeMatches) {
|
||||
this.backendType = backendTypeMatches[1];
|
||||
this.gatewayUrl = this.gatewayUrl.replace(backendTypeRegex, '');
|
||||
} else {
|
||||
this.backendType = null;
|
||||
}
|
||||
|
||||
this.backend = null;
|
||||
AuthenticationPage.authClient = () => this.getAuthClient();
|
||||
}
|
||||
|
||||
isGitBackend() {
|
||||
return true;
|
||||
}
|
||||
|
||||
async status() {
|
||||
const api = await fetch(GIT_GATEWAY_STATUS_ENDPOINT)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
return res['components']
|
||||
.filter((statusComponent: GitGatewayStatus) =>
|
||||
GIT_GATEWAY_OPERATIONAL_UNITS.includes(statusComponent.name),
|
||||
)
|
||||
.every((statusComponent: GitGatewayStatus) => statusComponent.status === 'operational');
|
||||
})
|
||||
.catch(e => {
|
||||
console.warn('Failed getting Git Gateway status', e);
|
||||
return true;
|
||||
});
|
||||
|
||||
let auth = false;
|
||||
// no need to check auth if api is down
|
||||
if (api) {
|
||||
auth =
|
||||
(await this.tokenPromise?.()
|
||||
.then(token => !!token)
|
||||
.catch(e => {
|
||||
console.warn('Failed getting Identity token', e);
|
||||
return false;
|
||||
})) || false;
|
||||
}
|
||||
|
||||
return { auth: { status: auth }, api: { status: api, statusPage: STATUS_PAGE } };
|
||||
}
|
||||
|
||||
async getAuthClient() {
|
||||
if (this.authClient) {
|
||||
return this.authClient;
|
||||
}
|
||||
await initPromise;
|
||||
if (window.netlifyIdentity) {
|
||||
this.authClient = {
|
||||
logout: () => window.netlifyIdentity?.logout(),
|
||||
currentUser: () => window.netlifyIdentity?.currentUser(),
|
||||
clearStore: () => {
|
||||
const store = window.netlifyIdentity?.store;
|
||||
if (store) {
|
||||
store.user = null;
|
||||
store.modal.page = 'login';
|
||||
store.saving = false;
|
||||
}
|
||||
},
|
||||
};
|
||||
} else {
|
||||
const goTrue = new GoTrue({ APIUrl: this.apiUrl });
|
||||
this.authClient = {
|
||||
logout: () => {
|
||||
const user = goTrue.currentUser();
|
||||
if (user) {
|
||||
return user.logout();
|
||||
}
|
||||
},
|
||||
currentUser: () => goTrue.currentUser(),
|
||||
login: goTrue.login.bind(goTrue),
|
||||
clearStore: () => undefined,
|
||||
};
|
||||
}
|
||||
return this.authClient;
|
||||
}
|
||||
|
||||
requestFunction = (req: ApiRequest) =>
|
||||
this.tokenPromise!()
|
||||
.then(
|
||||
token => unsentRequest.withHeaders({ Authorization: `Bearer ${token}` }, req) as ApiRequest,
|
||||
)
|
||||
.then(unsentRequest.performRequest);
|
||||
|
||||
authenticate(credentials: Credentials) {
|
||||
const user = credentials as NetlifyUser;
|
||||
this.tokenPromise = async () => {
|
||||
try {
|
||||
const func = user.jwt.bind(user);
|
||||
const token = await func();
|
||||
return token;
|
||||
} catch (error) {
|
||||
throw new AccessTokenError(`Failed getting access token: ${error.message}`);
|
||||
}
|
||||
};
|
||||
return this.tokenPromise!().then(async token => {
|
||||
if (!this.backendType) {
|
||||
const {
|
||||
github_enabled: githubEnabled,
|
||||
gitlab_enabled: gitlabEnabled,
|
||||
bitbucket_enabled: bitbucketEnabled,
|
||||
roles,
|
||||
} = await unsentRequest
|
||||
.fetchWithTimeout(`${this.gatewayUrl}/settings`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
.then(async res => {
|
||||
const contentType = res.headers.get('Content-Type') || '';
|
||||
if (!contentType.includes('application/json') && !contentType.includes('text/json')) {
|
||||
throw new APIError(
|
||||
`Your Git Gateway backend is not returning valid settings. Please make sure it is enabled.`,
|
||||
res.status,
|
||||
'Git Gateway',
|
||||
);
|
||||
}
|
||||
const body = await res.json();
|
||||
|
||||
if (!res.ok) {
|
||||
throw new APIError(
|
||||
`Git Gateway Error: ${body.message ? body.message : body}`,
|
||||
res.status,
|
||||
'Git Gateway',
|
||||
);
|
||||
}
|
||||
|
||||
return body;
|
||||
});
|
||||
this.acceptRoles = roles;
|
||||
if (githubEnabled) {
|
||||
this.backendType = 'github';
|
||||
} else if (gitlabEnabled) {
|
||||
this.backendType = 'gitlab';
|
||||
} else if (bitbucketEnabled) {
|
||||
this.backendType = 'bitbucket';
|
||||
}
|
||||
}
|
||||
|
||||
if (this.acceptRoles && this.acceptRoles.length > 0) {
|
||||
const userRoles = get(jwtDecode(token), 'app_metadata.roles', []);
|
||||
const validRole = intersection(userRoles, this.acceptRoles).length > 0;
|
||||
if (!validRole) {
|
||||
throw new Error("You don't have sufficient permissions to access Decap CMS");
|
||||
}
|
||||
}
|
||||
|
||||
const userData = {
|
||||
name: user.user_metadata.full_name || user.email.split('@').shift()!,
|
||||
email: user.email,
|
||||
avatar_url: user.user_metadata.avatar_url,
|
||||
metadata: user.user_metadata,
|
||||
};
|
||||
const apiConfig = {
|
||||
apiRoot: `${this.gatewayUrl}/${this.backendType}`,
|
||||
branch: this.branch,
|
||||
tokenPromise: this.tokenPromise!,
|
||||
commitAuthor: pick(userData, ['name', 'email']),
|
||||
isLargeMedia: (filename: string) => this.isLargeMediaFile(filename),
|
||||
squashMerges: this.squashMerges,
|
||||
cmsLabelPrefix: this.cmsLabelPrefix,
|
||||
initialWorkflowStatus: this.options.initialWorkflowStatus,
|
||||
};
|
||||
|
||||
if (this.backendType === 'github') {
|
||||
this.api = new GitHubAPI(apiConfig);
|
||||
this.backend = new GitHubBackend(this.config, { ...this.options, API: this.api });
|
||||
} else if (this.backendType === 'gitlab') {
|
||||
this.api = new GitLabAPI(apiConfig);
|
||||
this.backend = new GitLabBackend(this.config, { ...this.options, API: this.api });
|
||||
} else if (this.backendType === 'bitbucket') {
|
||||
this.api = new BitBucketAPI({
|
||||
...apiConfig,
|
||||
requestFunction: this.requestFunction,
|
||||
hasWriteAccess: async () => true,
|
||||
});
|
||||
this.backend = new BitbucketBackend(this.config, { ...this.options, API: this.api });
|
||||
}
|
||||
|
||||
if (!(await this.api!.hasWriteAccess())) {
|
||||
throw new Error("You don't have sufficient permissions to access Decap CMS");
|
||||
}
|
||||
return {
|
||||
name: userData.name,
|
||||
login: userData.email,
|
||||
avatar_url: userData.avatar_url,
|
||||
} as unknown as User;
|
||||
});
|
||||
}
|
||||
async restoreUser() {
|
||||
const client = await this.getAuthClient();
|
||||
const user = client.currentUser();
|
||||
if (!user) return Promise.reject();
|
||||
return this.authenticate(user as Credentials);
|
||||
}
|
||||
authComponent() {
|
||||
return AuthenticationPage;
|
||||
}
|
||||
|
||||
async logout() {
|
||||
const client = await this.getAuthClient();
|
||||
try {
|
||||
client.logout();
|
||||
} catch (e) {
|
||||
// due to a bug in the identity widget (gotrue-js actually) the store is not reset if logout fails
|
||||
// TODO: remove after https://github.com/netlify/gotrue-js/pull/83 is merged
|
||||
client.clearStore();
|
||||
}
|
||||
}
|
||||
getToken() {
|
||||
return this.tokenPromise!();
|
||||
}
|
||||
|
||||
async entriesByFolder(folder: string, extension: string, depth: number) {
|
||||
return this.backend!.entriesByFolder(folder, extension, depth);
|
||||
}
|
||||
allEntriesByFolder(folder: string, extension: string, depth: number, pathRegex?: RegExp) {
|
||||
return this.backend!.allEntriesByFolder(folder, extension, depth, pathRegex);
|
||||
}
|
||||
entriesByFiles(files: ImplementationFile[]) {
|
||||
return this.backend!.entriesByFiles(files);
|
||||
}
|
||||
getEntry(path: string) {
|
||||
return this.backend!.getEntry(path);
|
||||
}
|
||||
|
||||
async unpublishedEntryDataFile(collection: string, slug: string, path: string, id: string) {
|
||||
return this.backend!.unpublishedEntryDataFile(collection, slug, path, id);
|
||||
}
|
||||
|
||||
async isLargeMediaFile(path: string) {
|
||||
const client = await this.getLargeMediaClient();
|
||||
return client.enabled && client.matchPath(path);
|
||||
}
|
||||
|
||||
async unpublishedEntryMediaFile(collection: string, slug: string, path: string, id: string) {
|
||||
const isLargeMedia = await this.isLargeMediaFile(path);
|
||||
if (isLargeMedia) {
|
||||
const branch = this.backend!.getBranch(collection, slug);
|
||||
const { url, blob } = await this.getLargeMediaDisplayURL({ path, id }, branch);
|
||||
return {
|
||||
id,
|
||||
name: basename(path),
|
||||
path,
|
||||
url,
|
||||
displayURL: url,
|
||||
file: new File([blob], basename(path)),
|
||||
size: blob.size,
|
||||
};
|
||||
} else {
|
||||
return this.backend!.unpublishedEntryMediaFile(collection, slug, path, id);
|
||||
}
|
||||
}
|
||||
|
||||
getMedia(mediaFolder = this.mediaFolder) {
|
||||
return this.backend!.getMedia(mediaFolder);
|
||||
}
|
||||
|
||||
// this method memoizes this._getLargeMediaClient so that there can
|
||||
// only be one client at a time
|
||||
getLargeMediaClient() {
|
||||
if (this._largeMediaClientPromise) {
|
||||
return this._largeMediaClientPromise;
|
||||
}
|
||||
this._largeMediaClientPromise = this._getLargeMediaClient();
|
||||
return this._largeMediaClientPromise;
|
||||
}
|
||||
_getLargeMediaClient() {
|
||||
const netlifyLargeMediaEnabledPromise = this.api!.readFile('.lfsconfig')
|
||||
.then(config => ini.decode<{ lfs: { url: string } }>(config as string))
|
||||
.then(({ lfs: { url } }) => new URL(url))
|
||||
.then(lfsURL => ({
|
||||
enabled: lfsURL.hostname.endsWith('netlify.com') || lfsURL.hostname.endsWith('netlify.app'),
|
||||
}))
|
||||
.catch((err: Error) => ({ enabled: false, err }));
|
||||
|
||||
const lfsPatternsPromise = this.api!.readFile('.gitattributes')
|
||||
.then(attributes => getLargeMediaPatternsFromGitAttributesFile(attributes as string))
|
||||
.then((patterns: string[]) => ({ err: null, patterns }))
|
||||
.catch((err: Error) => {
|
||||
if (err.message.includes('404')) {
|
||||
console.log('This 404 was expected and handled appropriately.');
|
||||
return { err: null, patterns: [] as string[] };
|
||||
} else {
|
||||
return { err, patterns: [] as string[] };
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all([netlifyLargeMediaEnabledPromise, lfsPatternsPromise]).then(
|
||||
([{ enabled: maybeEnabled }, { patterns, err: patternsErr }]) => {
|
||||
const enabled = maybeEnabled && !patternsErr;
|
||||
|
||||
// We expect LFS patterns to exist when the .lfsconfig states
|
||||
// that we're using Netlify Large Media
|
||||
if (maybeEnabled && patternsErr) {
|
||||
console.error(patternsErr);
|
||||
}
|
||||
|
||||
return getClient({
|
||||
enabled,
|
||||
rootURL: this.netlifyLargeMediaURL,
|
||||
makeAuthorizedRequest: this.requestFunction,
|
||||
patterns,
|
||||
transformImages: this.transformImages ? { nf_resize: 'fit', w: 560, h: 320 } : false,
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
async getLargeMediaDisplayURL(
|
||||
{ path, id }: { path: string; id: string | null },
|
||||
branch = this.branch,
|
||||
) {
|
||||
const readFile = (
|
||||
path: string,
|
||||
id: string | null | undefined,
|
||||
{ parseText }: { parseText: boolean },
|
||||
) => this.api!.readFile(path, id, { branch, parseText });
|
||||
|
||||
const items = await entriesByFiles(
|
||||
[{ path, id }],
|
||||
readFile,
|
||||
this.api!.readFileMetadata.bind(this.api),
|
||||
'Git-Gateway',
|
||||
);
|
||||
const entry = items[0];
|
||||
const pointerFile = parsePointerFile(entry.data);
|
||||
if (!pointerFile.sha) {
|
||||
console.warn(`Failed parsing pointer file ${path}`);
|
||||
return { url: path, blob: new Blob() };
|
||||
}
|
||||
|
||||
const client = await this.getLargeMediaClient();
|
||||
const { url, blob } = await client.getDownloadURL(pointerFile);
|
||||
return { url, blob };
|
||||
}
|
||||
|
||||
async getMediaDisplayURL(displayURL: DisplayURL) {
|
||||
const { path, id } = displayURL as DisplayURLObject;
|
||||
const isLargeMedia = await this.isLargeMediaFile(path);
|
||||
if (isLargeMedia) {
|
||||
const { url } = await this.getLargeMediaDisplayURL({ path, id });
|
||||
return url;
|
||||
}
|
||||
if (typeof displayURL === 'string') {
|
||||
return displayURL;
|
||||
}
|
||||
|
||||
const url = await this.backend!.getMediaDisplayURL(displayURL);
|
||||
return url;
|
||||
}
|
||||
|
||||
async getMediaFile(path: string) {
|
||||
const isLargeMedia = await this.isLargeMediaFile(path);
|
||||
if (isLargeMedia) {
|
||||
const { url, blob } = await this.getLargeMediaDisplayURL({ path, id: null });
|
||||
return {
|
||||
id: url,
|
||||
name: basename(path),
|
||||
path,
|
||||
url,
|
||||
displayURL: url,
|
||||
file: new File([blob], basename(path)),
|
||||
size: blob.size,
|
||||
};
|
||||
}
|
||||
return this.backend!.getMediaFile(path);
|
||||
}
|
||||
|
||||
async persistEntry(entry: Entry, options: PersistOptions) {
|
||||
const client = await this.getLargeMediaClient();
|
||||
if (client.enabled) {
|
||||
const assets = await getLargeMediaFilteredMediaFiles(client, entry.assets);
|
||||
return this.backend!.persistEntry({ ...entry, assets }, options);
|
||||
} else {
|
||||
return this.backend!.persistEntry(entry, options);
|
||||
}
|
||||
}
|
||||
|
||||
async persistMedia(mediaFile: AssetProxy, options: PersistOptions) {
|
||||
const { fileObj, path } = mediaFile;
|
||||
const displayURL = fileObj ? URL.createObjectURL(fileObj) : '';
|
||||
const client = await this.getLargeMediaClient();
|
||||
const fixedPath = path.startsWith('/') ? path.slice(1) : path;
|
||||
const isLargeMedia = await this.isLargeMediaFile(fixedPath);
|
||||
if (isLargeMedia) {
|
||||
const persistMediaArgument = await getPointerFileForMediaFileObj(
|
||||
client,
|
||||
fileObj as File,
|
||||
path,
|
||||
);
|
||||
return {
|
||||
...(await this.backend!.persistMedia(persistMediaArgument, options)),
|
||||
displayURL,
|
||||
};
|
||||
}
|
||||
return await this.backend!.persistMedia(mediaFile, options);
|
||||
}
|
||||
deleteFiles(paths: string[], commitMessage: string) {
|
||||
return this.backend!.deleteFiles(paths, commitMessage);
|
||||
}
|
||||
async getDeployPreview(collection: string, slug: string) {
|
||||
let preview = await this.backend!.getDeployPreview(collection, slug);
|
||||
if (!preview) {
|
||||
try {
|
||||
// if the commit doesn't have a status, try to use Netlify API directly
|
||||
// this is useful when builds are queue up in Netlify and don't have a commit status yet
|
||||
// and only works with public logs at the moment
|
||||
// TODO: get Netlify API Token and use it to access private logs
|
||||
const siteId = new URL(localStorage.getItem('netlifySiteURL') || '').hostname;
|
||||
const site = await apiGet(siteId);
|
||||
const deploys: { state: string; commit_ref: string; deploy_url: string }[] = await apiGet(
|
||||
`${site.id}/deploys?per_page=100`,
|
||||
);
|
||||
if (deploys.length > 0) {
|
||||
const ref = await this.api!.getUnpublishedEntrySha(collection, slug);
|
||||
const deploy = deploys.find(d => d.commit_ref === ref);
|
||||
if (deploy) {
|
||||
preview = {
|
||||
status: deploy.state === 'ready' ? PreviewState.Success : PreviewState.Other,
|
||||
url: deploy.deploy_url,
|
||||
};
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
}
|
||||
return preview;
|
||||
}
|
||||
unpublishedEntries() {
|
||||
return this.backend!.unpublishedEntries();
|
||||
}
|
||||
unpublishedEntry({ id, collection, slug }: { id?: string; collection?: string; slug?: string }) {
|
||||
return this.backend!.unpublishedEntry({ id, collection, slug });
|
||||
}
|
||||
updateUnpublishedEntryStatus(collection: string, slug: string, newStatus: string) {
|
||||
return this.backend!.updateUnpublishedEntryStatus(collection, slug, newStatus);
|
||||
}
|
||||
deleteUnpublishedEntry(collection: string, slug: string) {
|
||||
return this.backend!.deleteUnpublishedEntry(collection, slug);
|
||||
}
|
||||
publishUnpublishedEntry(collection: string, slug: string) {
|
||||
return this.backend!.publishUnpublishedEntry(collection, slug);
|
||||
}
|
||||
traverseCursor(cursor: Cursor, action: string) {
|
||||
return this.backend!.traverseCursor!(cursor, action);
|
||||
}
|
||||
}
|
||||
8
node_modules/decap-cms-backend-git-gateway/src/index.ts
generated
vendored
Normal file
8
node_modules/decap-cms-backend-git-gateway/src/index.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import GitGatewayBackend from './implementation';
|
||||
import AuthenticationPage from './AuthenticationPage';
|
||||
|
||||
export const DecapCmsBackendGitGateway = {
|
||||
GitGatewayBackend,
|
||||
AuthenticationPage,
|
||||
};
|
||||
export { GitGatewayBackend, AuthenticationPage };
|
||||
180
node_modules/decap-cms-backend-git-gateway/src/netlify-lfs-client.ts
generated
vendored
Normal file
180
node_modules/decap-cms-backend-git-gateway/src/netlify-lfs-client.ts
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
import { flow, fromPairs, map } from 'lodash/fp';
|
||||
import { isPlainObject, isEmpty } from 'lodash';
|
||||
import minimatch from 'minimatch';
|
||||
import { unsentRequest } from 'decap-cms-lib-util';
|
||||
|
||||
import type { ApiRequest, PointerFile } from 'decap-cms-lib-util';
|
||||
|
||||
type MakeAuthorizedRequest = (req: ApiRequest) => Promise<Response>;
|
||||
|
||||
type ImageTransformations = { nf_resize: string; w: number; h: number };
|
||||
|
||||
type ClientConfig = {
|
||||
rootURL: string;
|
||||
makeAuthorizedRequest: MakeAuthorizedRequest;
|
||||
patterns: string[];
|
||||
enabled: boolean;
|
||||
transformImages: ImageTransformations | boolean;
|
||||
};
|
||||
|
||||
export function matchPath({ patterns }: ClientConfig, path: string) {
|
||||
return patterns.some(pattern => minimatch(path, pattern, { matchBase: true }));
|
||||
}
|
||||
|
||||
//
|
||||
// API interactions
|
||||
|
||||
const defaultContentHeaders = {
|
||||
Accept: 'application/vnd.git-lfs+json',
|
||||
['Content-Type']: 'application/vnd.git-lfs+json',
|
||||
};
|
||||
|
||||
async function resourceExists(
|
||||
{ rootURL, makeAuthorizedRequest }: ClientConfig,
|
||||
{ sha, size }: PointerFile,
|
||||
) {
|
||||
const response = await makeAuthorizedRequest({
|
||||
url: `${rootURL}/verify`,
|
||||
method: 'POST',
|
||||
headers: defaultContentHeaders,
|
||||
body: JSON.stringify({ oid: sha, size }),
|
||||
});
|
||||
if (response.ok) {
|
||||
return true;
|
||||
}
|
||||
if (response.status === 404) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: what kind of error to throw here? APIError doesn't seem
|
||||
// to fit
|
||||
}
|
||||
|
||||
function getTransofrmationsParams(t: boolean | ImageTransformations) {
|
||||
if (isPlainObject(t) && !isEmpty(t)) {
|
||||
const { nf_resize: resize, w, h } = t as ImageTransformations;
|
||||
return `?nf_resize=${resize}&w=${w}&h=${h}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
async function getDownloadURL(
|
||||
{ rootURL, transformImages: t, makeAuthorizedRequest }: ClientConfig,
|
||||
{ sha }: PointerFile,
|
||||
) {
|
||||
try {
|
||||
const transformation = getTransofrmationsParams(t);
|
||||
const transformedPromise = makeAuthorizedRequest(`${rootURL}/origin/${sha}${transformation}`);
|
||||
const [transformed, original] = await Promise.all([
|
||||
transformedPromise,
|
||||
// if transformation is defined, we need to load the original so we have the correct meta data
|
||||
transformation ? makeAuthorizedRequest(`${rootURL}/origin/${sha}`) : transformedPromise,
|
||||
]);
|
||||
if (!transformed.ok) {
|
||||
const error = await transformed.json();
|
||||
throw new Error(
|
||||
`Failed getting large media for sha '${sha}': '${error.code} - ${error.msg}'`,
|
||||
);
|
||||
}
|
||||
|
||||
const transformedBlob = await transformed.blob();
|
||||
const url = URL.createObjectURL(transformedBlob);
|
||||
return { url, blob: transformation ? await original.blob() : transformedBlob };
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return { url: '', blob: new Blob() };
|
||||
}
|
||||
}
|
||||
|
||||
function uploadOperation(objects: PointerFile[]) {
|
||||
return {
|
||||
operation: 'upload',
|
||||
transfers: ['basic'],
|
||||
objects: objects.map(({ sha, ...rest }) => ({ ...rest, oid: sha })),
|
||||
};
|
||||
}
|
||||
|
||||
async function getResourceUploadURLs(
|
||||
{
|
||||
rootURL,
|
||||
makeAuthorizedRequest,
|
||||
}: { rootURL: string; makeAuthorizedRequest: MakeAuthorizedRequest },
|
||||
pointerFiles: PointerFile[],
|
||||
) {
|
||||
const response = await makeAuthorizedRequest({
|
||||
url: `${rootURL}/objects/batch`,
|
||||
method: 'POST',
|
||||
headers: defaultContentHeaders,
|
||||
body: JSON.stringify(uploadOperation(pointerFiles)),
|
||||
});
|
||||
|
||||
const { objects } = await response.json();
|
||||
const uploadUrls = objects.map(
|
||||
(object: { error?: { message: string }; actions: { upload: { href: string } } }) => {
|
||||
if (object.error) {
|
||||
throw new Error(object.error.message);
|
||||
}
|
||||
return object.actions.upload.href;
|
||||
},
|
||||
);
|
||||
return uploadUrls;
|
||||
}
|
||||
|
||||
function uploadBlob(uploadURL: string, blob: Blob) {
|
||||
return unsentRequest.fetchWithTimeout(uploadURL, {
|
||||
method: 'PUT',
|
||||
body: blob,
|
||||
});
|
||||
}
|
||||
|
||||
async function uploadResource(
|
||||
clientConfig: ClientConfig,
|
||||
{ sha, size }: PointerFile,
|
||||
resource: Blob,
|
||||
) {
|
||||
const existingFile = await resourceExists(clientConfig, { sha, size });
|
||||
if (existingFile) {
|
||||
return sha;
|
||||
}
|
||||
const [uploadURL] = await getResourceUploadURLs(clientConfig, [{ sha, size }]);
|
||||
await uploadBlob(uploadURL, resource);
|
||||
return sha;
|
||||
}
|
||||
|
||||
//
|
||||
// Create Large Media client
|
||||
|
||||
function configureFn(config: ClientConfig, fn: Function) {
|
||||
return (...args: unknown[]) => fn(config, ...args);
|
||||
}
|
||||
|
||||
const clientFns: Record<string, Function> = {
|
||||
resourceExists,
|
||||
getResourceUploadURLs,
|
||||
getDownloadURL,
|
||||
uploadResource,
|
||||
matchPath,
|
||||
};
|
||||
|
||||
export type Client = {
|
||||
resourceExists: (pointer: PointerFile) => Promise<boolean | undefined>;
|
||||
getResourceUploadURLs: (objects: PointerFile[]) => Promise<string>;
|
||||
getDownloadURL: (pointer: PointerFile) => Promise<{ url: string; blob: Blob }>;
|
||||
uploadResource: (pointer: PointerFile, blob: Blob) => Promise<string>;
|
||||
matchPath: (path: string) => boolean;
|
||||
patterns: string[];
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export function getClient(clientConfig: ClientConfig) {
|
||||
return flow([
|
||||
Object.keys,
|
||||
map((key: string) => [key, configureFn(clientConfig, clientFns[key])]),
|
||||
fromPairs,
|
||||
configuredFns => ({
|
||||
...configuredFns,
|
||||
patterns: clientConfig.patterns,
|
||||
enabled: clientConfig.enabled,
|
||||
}),
|
||||
])(clientFns);
|
||||
}
|
||||
4
node_modules/decap-cms-backend-git-gateway/src/types/ini.d.ts
generated
vendored
Normal file
4
node_modules/decap-cms-backend-git-gateway/src/types/ini.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
declare module 'ini' {
|
||||
const ini: { decode: <T>(ini: string) => T };
|
||||
export default ini;
|
||||
}
|
||||
3
node_modules/decap-cms-backend-git-gateway/webpack.config.js
generated
vendored
Normal file
3
node_modules/decap-cms-backend-git-gateway/webpack.config.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
const { getConfig } = require('../../scripts/webpack.js');
|
||||
|
||||
module.exports = getConfig();
|
||||
Reference in New Issue
Block a user